In the previous talk, the author introduces the overall system framework of DirectShow. From this lecture, we must further explore the application of DirectShow from the perspective of programmers and the development of Filter. Prior to this, the author first had to mention a FILTER test tool provided by Microsoft, and its path in Dxsdk / Bin / DXUTILS / Graphedit.exe. (If you haven't installed DirectX SDK yet, please download it on Microsoft's website.) Through this tool, we can visually see the Filter Graph's operation and processing processes, so that we can make program debugging. (If you have a computer in your hand, what are you waiting for, you will experience it: Run your graphedit, perform file-> render media file ... Select a media file; after the Filter Graph builds successfully, press the toolbar's run button; you It can be seen that the media files just selected are played back! See it, write a media player is also the same!) Next, we will talk about the development of Filter. Learn the development of DirectShow Filter, not more than the following ways: see help documents, see example code and see SDK base class source code. See the help documentation should focus on the overall concept of understanding; see the example code should be in synchronization with the research of the base source code, because you write Filter, the key first step is to select a suitable Filter base class and PIN base class . For Filter's grasp, it is generally considered to master the following three aspects: the connection between the Filter PIN connection, the data transfer between the FITER and the random access of the streaming (or the positioning of the stream). The following will be set forth below. The connection between the Filter Pin is actually a negotiation process of the Media Type (media type) between the PIN. The connection always points from the output PIN to the input PIN. To learn more about the specific connection process, you must carefully study the SDK's base source code (located in DXSDK / Samples / MultiMedia / DirectShow / BaseClasses / amfilter.cpp, CBASepin's Connect method). The approach process of the connection is to connect all media types on the input PIN of enumeration, and use these media types one by one to connect to the output PIN. If the output PIN is also accepted, the connection between the PIN is successful; if All media type output PINs that enumerate on the input PIN do not support, and enumerate all media types on the PIN, and use these media types one by one to connect to the input PIN. If you enter a media type of the PIN accepts, the connection between the PIN also declares successfully; if all media types on the PIN are output, the input PIN does not support, the connection process between the two PINs declares failed . One thing to note is that the above input PIN is generally not the same filter, typically the previous FILTER (also called Upstream Filter) output PIN is connected next to FILTER (also called DownStream Filter). Enter the PIN. As shown below:
When the connection between the Filter's PIN is completed, that is, the connection between the two parties has obtained a media type that everyone supports by negotiation, and begins to prepare data transmission. In these preparations, the most important thing is that the negotiation of the memory distributor on the PIN is generally initiated by the output PIN. Between DirectShow filters, the data is transmitted through a packet, this packet is called SAMPLE. Sample itself is a COM object with a memory to load data, and SAMPLE is managed by the memory distributor (Allocator). A pair of outputs that have been successfully connected, the input PIN uses the same memory distributor, so the data is transferred from the output PIN to the input PIN is not required to copy. The typical data copy, typically occurs inside the FILTER, after reading data from the input PIN of the FILTER, performs a sense of intent, and then populates the data on the Filter's output PIN, then continue to transfer. Below, we will specifically explain the data transfer between the filter. First, everyone must distinguish between two main data transfer modes of Filter: Push Model and Pull Model. The reference is as follows:
The so-called push mode, that is, the source filter (Source Filter) can generate data, and generally there is a separate sub-thread on its output PIN, which is responsible for sending data, common cases, such as the Live Source Filter of the capture card representing the WDM model; The so-called pull mode, that is, the source filter does not have the ability to send his own data. In this case, the general source filter is tightened with a Parser Filter or Splitter filter, which is generally independent on the input PIN. The sub-thread is responsible for continuously requesting data from the source filter, and then transmits the data after processing, common situations such as file sources. In the push mode, the source filter is active; pulling the mode, the source filter is passive. In fact, if the source filter and splitter filter in the Tula mode appear as another virtual source filter, the data transfer between the following filters is identical to the push mode. So how do data transferred by connecting PIN? First, look at the push mode. On the Filter input PIN behind the source filter, a IMEMINPUTPIN interface must be implemented, and the data is transmitted by calling the previous FILTER calling this interface. It is worth noting that (above has been mentioned), the data is transferred from the output PIN to the input PIN, and there is no memory copy, which is just a "notification" equivalent to the data arrival. Look at the pull mode. On the output PIN of the source FILTER, the output PIN under the pull mode, it must be implemented; the Splitter filter behind it is to obtain data by calling the request method or SyncRead method in this interface. Splitter Filter then calls the next level of Filter Enter the IMEMINPUTPIN Interface Receive method to implement data down transfer. In-depth understanding of this part, please study the SDK's base source code (located in DxSDK / Samples / MultiMedia / DirectShow / BaseClasses / Source.cpp and Pullpin.cpp). Below, let's talk about a downstream positioning. In Graphedit, we can play it after we successfully build a Filter Graph. In playback, we can see that the progress bar is also advancing accordingly. Of course, we can also achieve random access by dragging progress bars. To do this, you should know how long the application level will play for how long is the current playback, or now, where is the location. So, how is this implementation at the Filter level? We know that several filters consist of Filter Graph through the interconnection of the PIN. This Filter Graph is managed by another COM object Filter Graph Manager. With Filter Graph Manager, we can get an iMediaseEKing interface to achieve the positioning of the convection media. In the Filter level, we can see that Filter Graph Manager begins with the last Filter (Rendere Filter), asks if the previous FILTER output PIN supports the iMediaseEKing interface. If support, return to this interface; if you do not support, continue in the first-level Filter to ask until the source filter.