DirectShow Technical Description & Applications (2)

zhaozj2021-02-16  52

Create a filter table

Establishment of standard tables

In order to establish a filter table, you must first create an instance of a filter table manager to obtain an IGRAPHBUILDER interface pointer.

Igraphbuilder * PIGB;

HRESULT HR;

HR = CocreateInstance (CLSID_FILTERGRAPH,

NULL,

CLSCTX_INPROC_SERVER,

IID_IGRAPHBUILDER,

(void **) & pigb);

IGraphBuilder interface, as the AS ITS Name Suggests, which contains methods for establishing a filter table. These methods provide three most basic ways to establish a table.

1. The application allows filter table management to automatically create a complete table.

2. Applications and filter tables can share the establishment of participation tables.

3. The application manually connects each filter to complete the establishment of the entire table.

Approach # 1: The Filter Graph Manager Builds The Entire Graph

Method 1: Filter Table Manager autonomously completes the establishment of the entire table

Method 1 is assumed that you only want to complete media files playing several usual formats, these formats can be AVI, MPEG, WAV, MP3, and more. In DirectShow, the term render is often cited, it means that the video is displayed on the display, the playback of the audio played in the speaker. In order to enable the filter table manager to automatically establish a filter table to restore the specified media file, the application should use the IGraphBuilder :: Render method. Several basic steps for the filter table establishment table will be described below.

Find the corresponding filter (Finding the filters)

The first step in establishing a filter table is to find and establish the required filter instance. Filter selection operation The first is to determine the media file format. This is because if the two filters do not use the same public media format, they cannot be connected. Filter Table Manager can determine the media format (such as .wma, .avi, .ave, etc.) by checking the suffix of the file name. If the media format cannot be determined by the hyperfix name, the filter table manager finds the identification byte (Check Bytes) in the file to determine the media format, which is to read files using different source filters until there is a match. Source filter is implemented. Moreover, this is to measure this task by using IgraphBuilder :: AddSourceFilter.

All DirectShow filters have unique GUIDs in the registry, which also records other information including filters, supported formats, Merit, etc. of filters. Filter Table Manager investigates all of this information to determine the filter and establish a solid example. The filter category describes the main use of the filter. Media Format Information Description Filter What media format can be accepted, but also to the filter format downstream of it. The MERIT value records the priority considered in the table automatic establishment. If there are two media format information in the system, the filter table manager selects the MERIT level filter. (Some filter tables intentionally define lower priority, as they are ideal for custom filter tables, so that the application must manually add the filter table)

In order to search for registry, filter table manager creates a DirectShow Filter Mapper object and calls its iFiltermapper2 :: EnummatchingFilters method to complete the search. This method can enumerate the filter through a type or media format. It returns a standard IEnummoniker object that contains all the names of the search for filters (Monilders).

Add a filter to the table

If you find the name object of the source filter that can read the corresponding file format, the filter table manager uses CocreateInstance to create an instance of the corresponding filter. This source filter will be used as a file source filter. Filter Table Manager calls the iFilterGraph :: AddFilter method to add this filter to the filter table. When the filter is notified to be added, the filter will establish the output needle of the corresponding media format. When the needle is created, the filter table manager finds a filter that can accept the media format output from the output needle from the registry. When the match is found, an instance is added to the table. Connection filter

When the lower swing filter is successfully added, it sets its needle to prepare to connect with the filter upstream. The filter table manager asks the filter in each table to determine its appropriate needle and call the IGRAPHBUILDER :: Connect method to connect them. The input needle of the upstream filter output needle and downstream filter must be negotiated to determine what data media format used, determine which needle to provide the media sample object to allocate memory and store media sample object memory management objects.

Complete the establishment of the table

When the needle (Pins) establishes a good connection, the filter table manager checks the media format and search for a filter that supports the media format of the output pin of the newly added filter and adds it again. Until the required filters are added to the table. In a file playback table, when a raw data stream is read, the second filter is usually parsing or decomposing the filter. Such as: AVI, MPEG, breaking it into a sound frequency flow and video stream. And build an output needle for each stream. If there is any one in the data stream being compressed, the next filter must be a decompression device, which will be added to add a reduced filter.

When the table is established, the application simply uses the filter table manager Queryinterface out of the ImediaControl interface, and the RUN method can start playing the file.

Method 2: Application and Filter Table Manager participate in the establishment of the table

When your filter table needs to be more complex than simple play files, your program is at least part of the table's establishment. For example, if you want to create a table that converts AVI to MPEG, you can still create an AVI reposition table via the IgraphBuilder :: Renderfile method. But you must notify the table to set the output to the MPEG file instead of the display and speaker. This includes disconnection and removal of audio reduction filters and video restore filters (this can be used using iFiltergraph :: Disconnect and Ifiltergraph :: Removefilter) and add MPEG video compression filter, MPEG audio compression filter, MPEG mixed filter, and one Write the File Writer Filter.

It may need to add an intermediate filter to convert MPEG compression supported media formats. The application can add intermediate filters directly, or you can use the IGraphBuilder :: Connect method to add. When this method is called, the Filter Table Manager first attempts to connect directly to the filter, and if they do not support the same media format, the filter table manager searches and adds a corresponding intermediate filter. If the filter table manager is prevented from trying to add an intermediate filter, you should use the iFilterGraph :: ConnectDirect method.

On the above part, the application participates in the output of the establishment table. If, the application only participates in the input section of the table (ie the source section). The IGRAPHBUILDER:: Render method can be used to make the filter table manager automatically complete the establishment of the output section of the table.

Method 3: The application creates the entire table yourself.

In some cases, your application needs to complete the entire table. Of course, here include the addition of a filter and the connection of each filter. In this situation, you should know which filters need to be added to the table, so this is not required to search for filters using the Filter Mapper object. You can use the iGraphBuilder :: AddFilter method to add a filter to the table and connect the filter using Connect or ConnectDirect. Data flow in the filter table

This part will further describe how the media data moves in the filter table. Typically, you don't need this when writing DirectShow applications. However, in some cases, these materials may be helpful to you. If you are writing a DirectShow filter, then you need to understand this information.

Transmission Agreement (Transports)

In order to make the media data can flow in the filter table, the DirectShow filter must support one of several internal protocols. These protocols are referred to as transport protocols. When two filter is connected, it must support an identical transport protocol; otherwise they cannot exchange media data. Typically, the transmitter requires a needle that supports special interfaces. When the filter is connected, the query will be queried to the interface of other needles.

Most filters processed media data in the main memory, passed the media data to other filters through the connections. This transmission is called a local storage transfer protocol (Local Memory Transport). This local storage transfer protocol is very common in DirectShow, but not, all filters use this protocol. Such as: Some filters are transmitted by hardware paths, which only use the needle to transmit control information.

DirectShow defines two mechanisms for local storage transfer protocols, which are PUSH mode and PULL mode. In the PUSH mode, media data is generated by the source filter and passed to the downstream filter. In the PUSH mode, the downstream filter always passively receives data, processing it, and delivers the downstream filter. In the PULL mode, the source filter connection parses the filter. The parsing filter sends a data request to the source filter, and the source filter transmits data to respond to its request. The PUSH mode uses the IMEMINPUTPIN interface, and the PULL mode uses the IASYNCREADER interface.

In DirectShow, the application of the PUSH mode is more common than the PULL mode. Therefore, this article will only consider the application of PUSH mode. Let's describe the last section of this section, PULL mode, tells what the IASYNCREADER interface is different from the IMEMINPUTPIN interface.

Sample and Distributor (Allocators)

When the needle passes the data to other stamps, it does not directly pass the pointer of its data memory. Instead, pass a COM object pointer to manage memory data. This object is a media sample that exposes an IMEDISAMPLE interface outward. Receiving a method of calling an IMEDIASAMPLE interface to access memory. Compare classic methods include iMediasample :: getPointer, iMediasample :: getSize and iMediaMple :: getActualDatalength method.

Media samples are always spread downstream by outputting the needle to the input needle. In the PUSH mode, the output needle calls IMEMINPUTPIN:: Receive to transfer media samples to the input needle, and the input needle processes the data in synchronization (actually, which are completed in the Receive method). Or in a working thread (Worker Thread). If the input needle needs to wait for the resource when processing data, you can block the Receive method.

Another COM object named a dispenser is used to establish and manage media samples. The dispenser exposes an IMallocator interface outward. When the filter requires a media sample, it can call the IMallocator :: GetBuffer method to return the pointer of this sample. A dispenser is shared in the connection of each needle. When two needles are connected, they will determine which filter to propose a dispenser, which sets the size of the memory area and other memory. Sample reference count

The dispenser can only establish a poored media sample. Some samples may be used when other people call GetBuffer. In order to avoid this, the dispenser uses a reference number to retain the use record of the sample. The GetBuffer method returns a media sample with a reference number of 1. When the reference count is turned 0, the sample is incorporated into the recipient box (Pool) of the assignment, which can be used when the next GetBuffer call. When the sample of the sample is greater than 0, the sample will not be returned by GetBuffer. When all the samples belonging to the dispenser are used (ie, the reference count is greater than 0), the getBuffer method is blocked until a sample becomes available. (Ie, the way is abandoned, the reference number is equal to 0)

For example, if the input needle is accepted as a medium. If it processes the media sample synchronously in the Receive method, it does not increase the reference count. When Receive returns, the output needle abandoned (Release) media sample, the reference number is reduced to 0, and the media sample is used to reciproculate the recipient box. If the input pin processes the media sample in the working thread, it is to increase the reference count before the Receive method returns. So now the reference is 2. When the output needle abandon the sample, the reference count becomes 1, but the sample is still not returned to the recipient box. After the work thread is completed, the thread calls Release to release the sample.

When a needle receives the sample, it can copy its data to other samples, or modify this sample and pass it to it next filter. Therefore, a media sample can flow throughout the table. Each filter When you change its data, you will call its AddRef and Release methods to change its reference count. Therefore, the output needle may not be used after it is called after the Receive method is called because the downstream filter may also use this sample. The output needle can call the GetBuffer method to get a new sample.

This mechanism avoids the number of memory used because the filter is repeatedly used in the same memory area. It can also avoid the case where the filter accesss the outfelient when the filter is processed. Since the dispenser maintains a list of samples that use the sample.

A filter can use separate allocators for input and output. It might do this if it expands the input data (for example, by decompressing it). If the output is no larger than the input, a filter might process the data in place, without Copying it to a new sample. in That Case, Two or More Allocator.

Filters can create different distributors for input and output. This method is usually used when the output is larger than the amount of data input, and this method is usually used (for example, unzipped). If the output data is not entered, the filter can directly modify the data on the sample to the next filter. In this case, two or more needles can be shared with a dispenser.

Submit and release the submission dispenser (Commatch and Decommitting Allocators)

When filters set a dispenser for the first time, the dispenser does not have a memory area to be managed. Based on this, any GetBuffer call operation will fail. When the table starts running, the output needle calls the ImemAllocator :: Commit method to submit the dispenser, use it to start memory allocation. Thereafter, the needles can call the GetBuffer method. When the table stops operation, the needle calls the ImemAllocator :: Decommit method to release the submitting dispenser. After that, any GetBuffer call operation will be failed, and it is really submitted once again. Similarly, those blocked GetBuffers will be returned immediately in order to get the call of the sample available. (Execute the DECOMIT method does not actually release memory. For example, the CMEMEAllocator class needs to call its destructor to release memory.)

(to be continued...)

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

New Post(0)