Developer on Alibaba Coud: Build your first app with APIs, SDKs, and tutorials on the Alibaba Cloud. Read more ＞
In the last two lectures, I introduced the application principle of DirectShow and some preparations before developing filter. In this case, I will teach you how to write your own filter.
First, start with the VC ++ Project (please confirm that you have configured the DirectX development environment for VC ++ ). Write your own filter. The first step is to use VC ++ to create a filter project. Because the DirectX SDK provides many filter example projects (located in the dxsdk/samples/multimedia/DirectShow/filters directory), the simplest method is to copy one file and then modify it based on it. However, if you are a beginner in filter development, I do not agree to do so.
Creating a filter project by yourself is also very easy. Use the VC ++ Wizard to create an empty "Win32 dynamic-Link Library" project. Note that several files are required :. def file, which defines four export functions and filter class. CPP file and. h file, and. the CPP file defines the registration information of the filter and the registration functions of the two filters: dllregisterserver and dllunregisterserver. (Note: The registration information of the filter is the content that the filter writes to the registry at registration. For the format, see the SDK example .) Code The guidtasks related to filtermust be generated using guidgen.exe .) Next, set the project (project-> Settings ...). In this case, you can open an SDK example project for comparison. Some macro definitions can be copied completely. At last, note that the extension of the output file is changed to. Ax.
As mentioned above, it is vital to select a suitable filter base class before writing a filter. Therefore, you must have a good understanding of several filter base classes. In practice, the base class of the filter is not always cbasefilter. On the contrary, most of the data we write is the intermediate transmission filter (transform filter), so most of the base classes choose ctransformfilter and ctransinplacefilter. If we write the source filter, we can select csource as the base class; if it is Renderer Filter, we can select cbaserenderer or cbasevideorenderer.
In short, it is very important to select the filter base class. Of course, the filter base class is flexible and there is no absolute standard. The filters that can be implemented through ctransformfilter can also be implemented step by step from cbasefilter. Next, I will give some suggestions on the selection of the filter base class based on my actual experience for your reference.
First, you must specify the functions of the filter, that is, analyze the requirements of the filter project. Please try to maintain the singleness of the functions implemented by the filter. If necessary, you can break down the requirements by two (or more) filters with a single function to achieve the overall functional requirements.
Secondly, you should specify the position of the filter in the entire filter graph, the input data of the filter, the output data, the input pin, and the output pin. You can sketch the filter. Find out what is important at 01:10, which directly determines the filter of the "model" you are using. For example, if the filter has only one input pin and one output pin, and the same media type is entered, ctransinplacefilter is generally used as the filter base class. If the media type is different, ctransformfilter is generally used as the base class.
Furthermore, some special requirements for data transmission and processing are considered. For example, the input and output sample of the filter are not one-to-one, which generally requires data caching on the input pin, while the output pin uses a special thread for data processing. In this case, csource is the best choice for the filter base class (although this filter is not the source filter ).
When the filter base class is selected, the pin base class is selected accordingly. Next, the code on the filter and pin is implemented. One thing to note is that, from the software design perspective, you should separate your logic class code from the filter code. Next, let's take a look at the implementation of the input pin. You need to implement all pure virtual functions of the base class, such as checkmediatype. In checkmediatype, you can check the media type to see if it is what you expect. Because most filters use the push mode to transmit data, the receive method is generally implemented on the input pin. Some base classes have implemented receive, while the filter class has a pure virtual function for users to reload data processing. In this case, you generally do not need to reload the receive method unless the implementation of the base class does not meet your actual requirements. If you overload the receive method, the following three functions, namely, endofstream, beginflush, and endflush, will be reloaded at the same time. Let's take a look at the implementation of the output pin. In general, you need to implement all the pure virtual functions of the base class. In addition to checkmediatype for media type check, there is usually decidebuffersize to determine the memory size used by the sample, getmediatype provides supported media types. Finally, let's take a look at the implementation of the filter class. First of all, you must implement all pure virtual functions of the base class. In addition, filter also implements createinstance to provide the com entry and nondelegatingqueryinterface to expose the supported interfaces. If we create a custom Input and Output pin, we usually need to overload the getpincount and getpin functions.
The implementation of the filter framework is roughly like this. You may also want to know how to implement a custom interface on the filter and how to implement the attribute page of the filter. I will not elaborate on this article. In fact, these questions can be found in the SDK sample project. Others, I have sorted out some issues that should be paid attention to in actual programming for your reference.
DirectShow Application Program There must be at least two threads: one main thread and one data transmission thread. Since it is multi-thread, it will certainly encounter thread synchronization problems. Filters have two types of locks: Filter Object locks and data stream locks. Filter Object locks are used at the filter level, such as filter state conversion, beginflush, and endflush. Data Stream locks are used in data processing threads, such as receive and endofstream. If the two locks are not clear, it is easy to generate program deadlocks, which need to be reminded.
2. endofstream Problems
When the filter receives this "message", it means that the data of the filter at the upper level has been sent. After that, if the receive receives data again, you should ignore it. If the filter caches the data on the input pin, after receiving the endofstream, make sure that all cached data has been processed before it can be returned.
3. Media seeking problems
Generally, you only need to implement the nondelegatingqueryinterface method on the output pin of the filter. When the user requests the iid_imediaposition interface or the iid_imediaseeking interface, the request is sent to the output pin of the last filter. When the filter graph performs mediaseeking, it generally calls beginflush, endflush, and newsegment on the filter. If your filter caches the data, you need to reload them and process them accordingly. If your filter is responsible for timestamp the sent sample, you should start from scratch after mediaseeking.
4. Use special threads
If you use a special thread to process and send data, you need to be very careful not to let the thread do an endless loop, and let the thread processing function be able to check thread commands from time to time. Ensure that the thread can end normally when the filter ends. Sometimes, you close the graphedit program, but the graphedit process is still in the memory. This is often because the data thread is not safely closed.
5. How to obtain information from media types
For example, if you want to obtain the width and height of the video image in the media type of the Input Pin Connection, you should implement it in the completeconnect method of the Input Pin, rather than in setmediatype.
This article is an English version of an article which is originally in the Chinese language on aliyun.com and is provided for information purposes only. This website makes no representation or warranty of any kind, either expressed or implied, as to the accuracy, completeness ownership or
reliability of the article or any translations thereof. If you have any concerns or complaints relating to the article, please send an email, providing a detailed description of the concern or
complaint, to email@example.com. A staff member will contact you within 5 working days. Once verified, infringing content will be removed immediately.
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
and provide relevant evidence. A staff member will contact you within 5 working days.