Use DirectShow to achieve video capture

xiaoxiao2021-03-06  18

DirectShow is a subset of DirectX, which provides users with powerful, convenient multimedia open interface, and it has direct operating hardware capabilities, which makes it more efficient than the multimedia program written in graphical ways such as GDI. One of the previous articles has been a rough introduction to DirectShow, and the principle and some programming methods are elaborated. Here is a combination of DirectShow to achieve video acquisition (Win32) to deepen the understanding and operational capacity of DirectShow.

1. System environment and development environment

l System support DirectX (Win 2K or higher system)

L VC 6.0 installed with DirectX SDK (the best DirectX version supported by the system)

l Video acquisition equipment (such as USB camera, this article is used as USB PC Camera 310p)

2. Basic idea

The basic principle of DirectShow is that multimedia data flows in filter chaphs, implemented in various filters in the filter chart, and ultimately realizes display and playback of multimedia data in rendering filters. .

As we have known, general filters can be divided into three categories: Source Filters, Transform Filters, Rendering Filters. They complete data provided, data format conversion (compression coding, etc.) and data rendering and playback feature. So, in order to implement video acquisition under Win32 system, we must first construct a suitable filter chart, then through the application of the filter chart to complete the functionality of the video capture.

Here we generally take 2 to 3 filters. Why will this number are not accurate? That is because the driving model of the system acquisition device is uncertain (usually WDM and VFW); on the other hand, the same acquisition device, their Filter, due to the difference in the Filter, the inconsistency in the filter (PIN). There is also the acquisition equipment of different buss (PCI, USB, AGP), their Filter is also inconsistent. For example: the same as a USB camera, some filter has two output pins; and some Filter only has an output pin. Here the preview pin is used to make a video preview, and the Capture pin is used to enter the data for coding, save, etc.

These filters are:

l Video Capture Filter Collection Equipment Filter

l Smart TEE Filter will be divided into two data streams without Preview pin Filter (optional)

l Video Venderer video rendering and playback Filter

Through the above 3 filters, we can construct a complete video capture filter chart (Figure 1)

figure 1

We can also modify the above filter chart, turn it into a chart that can preview video, but also save the video as a media file (Figure 2).

figure 2

After the chart is constructed, it will be concretely realized in the afternoon, and we only need to construct each filter in turn, and then connect the PIN of each letter Filter to complete the structure. Finally, we send commands to the chart (complete through Chart Manager) to control the flow of the entire video. 3. Implementation

First we need to create a few interface global variables.

IgraphBuilder * pgraph; // Filter Chart Manager

IcapturegraphBuilder2 * pbuild; // video capture filter chart

IBaseFilter * PCAP; // Video Capture Filter

Ibasefilter * psmarttee; // smart tee filter

IBasefilter * prender; // video renderer filter

IMediaControl * pControl; // User command interface, used to control filter chart

IMediaEvent * pevent; // Filter chart event interface

1) Collecting equipment enumeration

Before constructing the Video Capture Filter, we must include all the acquisition devices of the system before you can create a Video Capture Filter based on the listed device name. The function of the enumeration device is achieved

Bool ListCaptureDevices ()

{

IcreateDevenum * pdevenum = null; // Device Enumerator Interface

Ienummoniker * penum = null; // Name enumeration Interface

// CREATE The System Device Enumerator.

HRESULT HR = CocreateInstance (CLSID_SYSTEMDEVICEENSTANES, NULL,

CLSCTX_INPROC_SERVER, IID_ICREATEDEVENUM,

Reinterpret_cast (& pdevenum)); // Create a device enumeration COM object

En (ac))

{

// Create an enumerator for the video capture category.

HR = PDEVENUM-> CREATECLASSENUMERATOR

CLSID_VideoInputDeviceCategory,

& penum, 0); // Create a video capture device enumeration COM object

}

IMONIKER * PMONIKER = NULL;

IF (Penum == Null)

{

Return False; // If there is no device, return

}

While (Penum-> Next (1, & PMoniker, NULL) == S_OK) // Enumerate in a session until it is empty

{

IPropertyBag * ppropbag;

HR = PMoniker-> BindtOStorage (0, 0, IID_IPROPERTYBAG,

(void **) (& ppropbag));

IF (Failed (HR))

{

PMoniker-> Release ();

Continue; // Skip this One, Maybe The Next One Will Work.

}

// Find the description or friendly name.

Variant varname;

Variantinit; & VarName;

HR = ppropbag-> read (l "description", & varname, 0);

IF (Failed (HR)) {

HR = ppropbag-> read (l "friendlyname", & varname, 0); // device friendly name

}

En (ac))

{

// add it to the application's list box.

Char displayname [1024];

Widechartomultibyte (CP_ACP, 0, Varname.bstrval, -1, DisplayName, 1024, "", NULL);

m_nlist.addstring (displayName); // Character conversion, enumeration name is Unicode code

VariantClear (& VarName);

}

Ppropbag-> Release ();

PMoniker-> Release ();

}

Return True;

}

2) Creating a Video Capture Filter

Create a Video Capture Filter based on the enumerated device friendly name (FriendlyName).

BOOL CTEST_CAPDLG :: Createhardwarefilter (const char * friendlyname)

{// Configure the FriendlyName to all device names, if the same is true, create a Filter

IcreateDevenum * enumhardware = null;

HRESULT HR = CocreateInstance (CLSID_SYSTEMDEVICEENUM, NULL, CLSCTX_ALL

, IID_ICREATEDEVENUM, (void **) & enumhardware);

IF (Failed (HR))

{

Return False;

}

Ienummoniker * enummoniker = null;

HR = enumhardware-> CreateClassenumerator (CLSID_VideoInputDevicecategory, & Enummoniker, 0);

Enummoniker

{

ENUMMONIKER-> RESET ();

Ulong fetched = 0;

IMoniker * Moniker = NULL;

Char FriendlyName [256];

While (! PCAP && successED (Enummoniker-> Next (1, & Moniker, & fetched) && fetched)

{

IF (Moniker)

{

IPropertybag * Propertybag = NULL;

Variant name;

Friendlyname [0] = 0;

HR = Moniker-> BindtOStorage (0, 0, IID_IPROPERTYBAG, (Void **) & propertybag);

En (ac))

{

Name.vt = vt_bstr;

HR = propertybag-> read (l "friendlyname", & name, null;

}

Else

Return False;

En (ac))

{

Widechartomultibyte (CP_ACP, 0, Name.BStrval, -1, FriendlyName, 256, Null, NULL)

Moniker-> BindToObject (0, 0, IID_IBASEFILTER, (Void **) & PCAP);

}

Else

Return False; if (Propertybag)

{

Propertybag-> Release ();

Propertybag = NULL;

}

Moniker-> Release ();

}

}

Enummoniker-> Release ();

}

Enumhardware-> release ();

Return True;

}

3) Creating a video capture filter chart

DirectX is generally provided with an ICAPTUREGRAPHBUILDER2 interface for developers. Developers can create a video capture filter chart via it, and then add it to the IGraphbuilder chart manager (as shown in Figure 3).

image 3

Bool InitcapturegraphBuilder ()

{

HRESULT HR = CocreateInstance (CLSID_CAPTUREGRAPHBUILDER2, NULL,

CLSCTX_INPROC_SERVER, IID_ICAPTUREGRAPHBUILDER2, (VOID **) & PBUILD);

IF (Failed (HR))

Return False;

HR = COCREATEINSTANCE (CLSID_FILTERGRAPH, 0, CLSCTX_INPROC_SERVER,

IID_IGRAPHBUILDER, (void **) & pgraph);

IF (Failed (HR))

{

PBUILD-> Release ();

Return False;

}

PBUILD-> SetFiltergraph (PGRAPH); / Filter chart Add to Manager

PGRAPH-> QueryInterface (IID_IMEDIACONTROL, (void **) & pControl);

PGRAPH-> Queryinterface (IID_IMEDIAEVENT, (VOID **) & PEVENT);

Return True;

}

4) Creating the remaining Smart Tee and Video Renderer Filter and connect to a complete chart

After you have created the Video Capture Filter, we need to add a Filter to the filter chart.

PGRAPH-> AddFilter (PCAP, L "Capture Filter);

Then we create the remaining filter and connected, it is worth noting that ICAPTuregraphBuilder2 provides a renderstream function for users, which can automatically build smart tee and video renderer filter and connect them into a complete chart to complete video capture. Function.

PBUILD-> Renderstream (& pin_category_preview, & mediatype_video,

PCAP, NULL, NULL

To illustrate the entire process, we will move according to the unit, create each filter session.

Smart TEE

CoCreateInstance (CLSID_SMARTTEE, NULL, CLSCTX_INPROC_SERVER, IID_IBASEFILTER, (Void **) & psmarttee);

Video Renderer Filter

CocreateInstance (CLSID_VIDEORERER, NULL, CLSCTX_INPROC_SERVER, IID_IBASEFILTER, (Void **) & prender;

After creating each filter, we obtain their pin (PIN), which can be sequentially connected.

Ipin * getsmartteeinputpin () // gets the Smart TEE input pin {

IF (psmarttee)

{

Ipin * ppin;

HRESULT HR = PSmarttee-> Findpin (L "Input", & PPIN);

En (ac))

{

PPIN-> Release ();

Return PPIN;

}

}

Return NULL;

}

Ipin * getsmartteecapturepin () / / get Smart Tee Capture Pins

{

IF (psmarttee)

{

Ipin * ppin;

HRESULT HR = PSmarttee-> Findpin (L "Capture", & PPIN);

En (ac))

{

PPIN-> Release ();

Return PPIN;

}

}

Return NULL;

}

Ipin * getsmartteepreviewpin () // gets the Smart TEE Preview pin

{

IF (psmarttee)

{

Ipin * ppin;

HRESULT HR = PSmarttee-> Findpin (l "preview", & ppin);

En (ac))

{

PPIN-> Release ();

Return PPIN;

}

}

Return NULL;

}

Ipin * getrenderepin () // Get input of Video Rendere Filter

{

IF (PBUILD)

{

Ipin * ppin;

HRESULT HR = Pbuild-> Findpin (prender, Pindir_INPUT, NULL, NULL, FALSE, 0, & PPIN);

En (ac))

{

PPIN-> Release ();

Return PPIN;

}

}

Return NULL;

}

Connect each pin:

IPIN * Pout = FindVideoPin (& PIN_CATEGORY_CAPTURE);

IPIN * PIN = getSmartteeInputpin ();

PGRAPH-> Connect (Pout, PIN); // Video Capture Filter 'Capture Pin à smart tee'input pin

Ipin * mout = getsmartteepreviewpin ();

Ipin * min = getrenderepin ();

PGRAPH-> Connect (mout, min); // Smart Tee's Preview Pin à Video Renderer Filter's Input Pin

In this way, a complete video capture chart manager is complete.

5) Start video capture

Through the user command interface, we can complete the start, pause, stop video acquisition.

PCONTROL-> Run ();

PCONTROL-> STOP ();

4. summary

Through the implementation of the above video acquisition process, it is not difficult to find that DirectShow is a multimedia development tool that is clear and easy to develop. While using DirectX to build multimedia features for the Filter of us, we can also create a Filter with a specific function. In short, the Direct system is still a huge treasure, waiting for us to discover and exploit.

转载请注明原文地址:https://www.9cbs.com/read-41781.html

New Post(0)