Use Directshow to develop the source Filter (favorites)

Source: Internet
Author: User
Abstract:
We generally do not recommend developing our own audio or video capturing filters, because diectshow provides support for audio and video capturing devices. Therefore, this document helps some users capture data from specific devices. This document mainly includes the following content.
1. Pin requirements for capturing Filters
2. How to complete a preview pin
3. How to generate source data

1 pin requirements for capture Filters
Pin name
You can give your filter any name. If your PIN name is ~ When the application calls the igraphbuilder: renderfile method, the filter chart manager does not automatically render the pin. For example, if a filter has a capture pin and a preview pin, you can name them "~ Capture and preview ". If an application render the filter in graph, the preview pin is automatically connected to its default render, but nothing is connected to the capture pin, this is a reasonable default action. This can also be applied to the pin that is not prepared for rendered data transmission, or to the pin that requires attribute settings.
Note: The name contains ~ The pin of the symbol can be manually connected.
Pin Type
A capture filter usually uses a capture pin, and maybe a preview pin. In addition to the two pins, some filter filters also have other pins used to transmit other data, such as control information. Each output pin must expose the ikspropertyset interface. The application uses these interfaces to determine the pin type. Generally, the pin returns pin_category_capture or pin_category_preview. The following example demonstrates how to use ikspropertyset to capture the pin type.
// Set: cannot set any properties.
Hresult cmycapturepin: Set (refguid guidpropset, DWORD dwid,
Void * pinstancedata, DWORD cbinstancedata, void * ppropdata,
DWORD cbpropdata)
{
Return e_notimpl;
}

// Get: return the pin category (our only property ).
Hresult cmycapturepin: Get (
Refguid guidpropset, // which property set.
DWORD dwpropid, // which property in that set.
Void * pinstancedata, // instance data (ignore ).
DWORD cbinstancedata, // size of the instance data (ignore ).
Void * ppropdata, // buffer to receive the property data.
DWORD cbpropdata, // size of the buffer.
DWORD * pcbreturned // return the size of the property.
)
{
If (guidpropset! = Ampro1_tid_pin)
Return e_prop_set_unsupported;
If (dwpropid! = Amproperty_pin_category)
Return e_prop_id_unsupported;
If (ppropdata = NULL & pcbreturned = NULL)
Return e_pointer;
If (pcbreturned)
* Pcbreturned = sizeof (guid );
If (ppropdata = NULL) // caller just wants to know the size.
Return s_ OK;
If (cbpropdata <sizeof (guid) // the buffer is too small.
Return e_unexpected;
* (Guid *) ppropdata = pin_category_capture;
Return s_ OK;
}

// Querysupported: query whether the pin supports the specified property.
Hresult cmycapturepin: querysupported (refguid guidpropset, DWORD dwpropid,
DWORD * ptypesupport)
{
If (guidpropset! = Ampro1_tid_pin)
Return e_prop_set_unsupported;
If (dwPropID! = AMPROPERTY_PIN_CATEGORY)
Return E_PROP_ID_UNSUPPORTED;
If (pTypeSupport)
// We support getting this property, but not setting it.
* PTypeSupport = KSPROPERTY_SUPPORT_GET;
Return S_ OK;
}

2. How to complete a Preview pin Implementing a Preview Pin (Optional)
If your filter has a preview pin, the data sent by the preview pin is a copy of the data transmitted by the capture pin. Previewing the data sent by a pin does not reduce the preview rate of the captured pin. capturing a pin has a higher priority than previewing a pin.
Capture pin and preview pin must send data in the same format. In this way, they are connected through the same media data type. If the pin is captured first, the preview pin should provide the same media type, and reject other data media types. If the preview pin is connected first, if the capture pin is connected to another media type, the preview pin should be reconnected with the new media type, if the downstream filter connected to the filter preview pin rejects the new data type, the capture pin rejects the new media type. You can use the IPin: QueryAccept method to view the data media connected by the filter's preview pin downstream filter, and then use the IFilterGraph: Reconnect method to Reconnect the pin.
This rule also applies when the chart manager reconnects to the capture pin.
The following code roughly describes the process above
// Override CBasePin: CheckMediaType.
CCapturePin: CheckMediaType (CMediaType * pmt)
{
If (m_pmypreviewpin-> isconnected ())
{
// The preview pin is already connected, so query the pin it is
// Connected to. If the other PIN rejects it, so do we.
HR = m_pmypreviewpin-> getconnected ()-> queryaccept (PMT );
If (HR! = S_ OK)
{
// The preview pin cannot reconnect with this media type.
Return e_invalidarg;
}
// The preview pin will reconnect when setmediatype is called.
}
// Decide whether the capture pin accepts the format.
Bool facceptthistype =... // (not shown .)
Return (facceptthistype? S_ OK: e_fail );
}

// Override cbasepin: setmediatype.
Ccapturepin: setmediatype (cmediatype * PMT );
{
If (m_pmypreviewpin-> isconnected ())
{
// The preview pin is already connected, so it must reconnect.
If (m_pmypreviewpin-> getconnected ()-> queryaccept (PMT) = s_ OK)
{
// The downstream pin will accept the new type, so it's safe
// To reconnect.
M_pfilter-> m_pgraph-> reconnect (m_pmypreviewpin );
}
Else
{
Return vfw_e_invalidmediatype;
}
}
// Now do anything that the capture pin needs to set the type.
HR = myinternalsetmediatype (PMT );

// And finally, call the base-class method.
Return cbasepin: setmediatype (PMT );
}

Cpreviewpin: checkmediatype (cmediatype * PMT)
{
If (m_pmycapturepin-> isconnected ())
{
// The preview pin must connect with the same type.
Cmediatype CMT = m_pmycapturepin-> m_mt;
Return (* PMT = CMT? S_ OK: vfw_e_invalidmediatype );
}
// Decide whether the preview pin accepts the format. You can use your
// Knowledge of which types the capture pin will accept. Regardless,
// When the capture pin connects, the preview pin will reconnect.
Return (facceptthistype? S_ OK: e_fail );
}

3. generate data producing data in a capture filter in the Source Filter
Status Change
A capture filter will generate data streams at runtime. When filter paused is used, do not send data. In this case, the chart manager calls the cbasefilter: getstate method to return vfw_s_cant_cue. The returned value indicates that the filter is in the paused state, stop sending data. The following code shows how to derive the getstate method.
Cmyvidcapfilter: getstate (dword dw, filter_state * pstate)
{
Checkpointer (pstate, e_pointer );
* Pstate = m_state;
If (m_state = state_paused)
Return vfw_s_cant_cue;
Else
Return s_ OK;
}
Control different data streams
A capture filter should support the iamstreamcontrol interface, so the application should open and close each pin separately. For example, an application can only preview but not capture, you can then switch to the capture mode without rebuilding the graph chart. You can use the cbasestreamcontrol class to implement this interface.
Timestamp
When a filter captures a sample, it marks the timestamp of the current time on each sample. The end time is the start time plus the duration. For example, if a filter captures ten samples per second, and the stream time is 200,000,000 units when the filter captures the sample, the time stamps shocould be 200000000 and 201000000. (There are 10,000,000 units per second .) you can use the ireferenceclock: gettime method to obtain the current reference time, and use imediasample: settime to set a timestamp for the sample.
The timestamp on the connected sample must be incremental, even if the filter pauses is the same. If a filter runs, stops, and then runs again, the timestamp on the sample generated after restarting must be larger than the timestamp on the sample before stopping.
The sample on the preview pin does not have a timestamp. However, the preview pin is generally a little later than the capture pin to the render pin. Therefore, the render filter regards the sample on the preview pin as a late sample, some data may be lost to catch up with other times.

Contact Us

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: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.