DirectShow basic programming is the simplest process of writing transform filter

Source: Internet
Author: User

Compile a transform filter to flip the image.

In msdn, the "Writing transform filters" section lists the six basic steps for writing a transform filter. Follow these six steps one by one.

 

1. Select base class

Derived from cbasefilter, three classes are used to compile the transform filter: ctransformfilter, ctransinplacefilter, and cvideotransformfilter. For the differences between the three base classes, see the description of msdn. We select the ctransformfilter class.

After selecting the base class, we will create an empty DLL project and add three files: flipfilter. H, flipfilter. cpp, and flipfilter. Def.

 

Ii. Declare the filter class

Add the following code declaration to flipfilter. h:

# Include <streams. h> <br/> extern "C" const guid clsid_flipfilter; </P> <p> class cflipfilter: Public ctransformfilter <br/> {<br/> PRIVATE: <br/> cflipfilter (tchar * tszname, lpunknown punk, hresult * phr); </P> <p> Public: <br/> static cunknown * winapi createinstance (lpunknown punk, hresult * phr); </P> <p> hresult checkinputtype (const cmediatype * mtin); <br/> hresult getmediatype (INT iposition, cmediatype * pmediatype ); <br/> hresult checktransform (const cmediatype * mtin, const cmediatype * mtout); <br/> hresult decidebuffersize (imemallocator * pallocator, allocator_properties * pprop ); <br/> hresult transform (imediasample * pin, imediasample * pout); <br/> };

 

Iii. Media type negotiation

This step is required when the filter pin is connected. It mainly reloads three functions:

1. hresult checkinputtype (const cmediatype * mtin );

Hresult cflipfilter: checkinputtype (const cmediatype * mtin) <br/>{< br/> If (mtin-> majortype! = Mediatype_video | <br/> mtin-> subtype! = Mediasubtype_rgb24 | <br/> mtin-> formattype! = Format_videoinfo) <br/>{< br/> return vfw_e_type_not_accepted; <br/>}</P> <p> videoinfo * PVI = (videoinfo *) mtin-> Format (); </P> <p> If (PVI-> bmiheader. bibitcount! = 24) <br/>{< br/> return vfw_e_type_not_accepted; <br/>}</P> <p> return s_ OK; <br/>}

Ctransformfilter uses the ctransforminputpin class as the input pin. In ctransforminputpin: checkmediatype (const cmediatype * PMT), m_ptransformfilter-> checkinputtype (PMT) is called ); therefore, we can simply think that checkinputtype is the checkmediatype of the input pin. This design is designed to avoid the need to redefine the Input Pin class, just need to define the filter class, simplify the process of writing the transform filter, the other interfaces are also such a design principle.

2. hresult getmediatype (INT iposition, cmediatype * pmediatype );

Hresult cflipfilter: getmediatype (INT iposition, cmediatype * pmediatype) <br/>{< br/> If (m_pinput-> isconnected () = false) {<br/> return e_unexpected; <br/>}</P> <p> If (iposition <0) {<br/> return e_invalidarg; <br/>}</P> <p> If (iposition> 0) {<br/> return vfw_s_no_more_items; <br/>}</P> <p> checkpointer (pmediatype, e_pointer); <br/> * pmediatype = m_pinput-> currentmediatype (); </P> <p> return noerror; <br/>}

Similarly, this function is written for the input pin.

3. hresult checktransform (const cmediatype * mtin, const cmediatype * mtout );

Hresult cflipfilter: checktransform (const cmediatype * mtin, const cmediatype * mtout) <br/>{< br/> If (* mtin = * mtout) <br/>{< br/> return noerror; <br/>}</P> <p> return e_fail; <br/>}

This function is called by the output pin. Call m_ptransformfilter-> checktransform in ctransformoutputpin: checkmediatype (const cmediatype * pmtout.

 

4. Negotiate the attributes of the distributor to determine the attributes of the data.

Hresult cflipfilter: decidebuffersize (imemallocator * pallocator, allocator_properties * pprop) <br/>{< br/> If (m_pinput-> isconnected () = false) {<br/> return e_unexpected; <br/>}</P> <p> checkpointer (pallocator, e_pointer); <br/> checkpointer (pprop, e_pointer ); <br/> hresult hR = noerror; </P> <p> pprop-> cbuffers = 1; <br/> pprop-> cbbuffer = m_pinput-> currentmediatype (). getsamplesize (); <br/> assert (pprop-> cbbuffer); </P> <p> allocator_properties actual; <br/> hR = pallocator-> setproperties (pprop, & Actual); <br/> If (failed (HR) {<br/> return hr; <br/>}</P> <p> assert (actual. cbuffers = 1); </P> <p> If (pprop-> cbuffers> actual. cbuffers | <br/> pprop-> cbbuffer> actual. cbbuffer) {<br/> return e_fail; <br/>}< br/> return noerror; <br/>}

This function is called by ctransformoutputpin: decidebuffersize.

 

V. Data Conversion

Hresult cflipfilter: Transform (imediasample * pin, imediasample * pout) <br/>{< br/> checkpointer (pin, e_pointer); <br/> checkpointer (pout, e_pointer); </P> <p> byte * psourcebuffer, * pdestbuffer; <br/> long lsourcesize = pin-> getactualdatalength (); </P> <p> pin-> getpointer (& psourcebuffer); <br/> pout-> getpointer (& pdestbuffer ); </P> <p> // flip image <br/> cmediatype pmediatype1 = m_pinput-> currentmediatype (); <br/> videoinfoheader * PVI = (videoinfoheader *) pmediatype1.pbformat; <br/> int nwidth = widthbytes (PVI-> bmiheader. biwidth * PVI-> bmiheader. bibitcount); <br/> for (INT I = 0; I <PVI-> bmiheader. biheight; I ++) <br/>{< br/> copymemory (pvoid) (pdestbuffer + nwidth * I), <br/> (pvoid) (psourcebuffer + nwidth * (PVI-> bmiheader. biheight-I-1), <br/> nwidth); <br/>}</P> <p> reference_time timestart, timeend; <br/> If (noerror = pin-> gettime (& timestart, & timeend) <br/>{< br/> pout-> settime (& timestart, & timeend); <br/>}</P> <p> Longlong mediastart, mediaend; <br/> If (Pin-> getmediatime (& mediastart, & mediaend) = noerror) <br/>{< br/> pout-> setmediatime (& mediastart, & mediaend ); <br/>}</P> <p> hresult hR = pin-> issyncpoint (); <br/> If (hR = s_ OK) <br/>{< br/> pout-> setsyncpoint (true); <br/>}< br/> else if (hR = s_false) <br/>{< br/> pout-> setsyncpoint (false); <br/>}< br/> else <br/>{< br/> return e_unexpected; <br/>}</P> <p> hR = pin-> ispreroll (); <br/> If (hR = s_ OK) <br/>{< br/> pout-> setpreroll (true); <br/>}< br/> else if (hR = s_false) <br/>{< br/> pout-> setpreroll (false); <br/>}< br/> else <br/>{< br/> return e_unexpected; <br/>}</P> <p> hR = pin-> isdiscontinuity (); </P> <p> If (hR = s_ OK) <br/>{< br/> pout-> setdiscontinuity (true); <br/>}< br/> else if (hR = s_false) <br/>{< br/> pout-> setdiscontinuity (false); <br/>}< br/> else <br/>{< br/> return e_unexpected; <br/>}</P> <p> long ldatalength = pin-> getactualdatalength (); <br/> pout-> setactualdatalength (ldatalength ); </P> <p> return noerror; <br/>}

 

6. Add com information to make the DLL Filter

1. Create a filter instance in the standard format.

Cunknown * cflipfilter: createinstance (lpunknown punk, hresult * phr) <br/>{< br/> assert (PHR ); </P> <p> cflipfilter * pnewobject = new cflipfilter (name ("flipfilter"), punk, PHR); </P> <p> If (pnewobject = NULL) {<br/> If (PHR) <br/> * phr = e_outofmemory; <br/>}< br/> return pnewobject; <br/>}

2. Declare a factory Template

Const amoviesetup_mediatype sudinputpintypes = <br/>{< br/> & mediatype_video, <br/> & mediasubtype_null <br/> }; </P> <p> const amoviesetup_mediatype sudoutputpintypes = <br/>{< br/> & mediatype_video, <br/> & mediasubtype_null <br/> }; </P> <p> const amoviesetup_pin sudppins [] = <br/> {L "input", <br/> false, <br/> false, <br/> false, <br/> false, <br/> & clsid_null, <br/> null, <br/> 1, <br/> & sudinputpintypes <br/>}, <br/> {L "output", <br/> false, <br/> true, <br/> false, <br/> false, <br/> & clsid_null, <br/> null, <br/> 1, <br/> & sudoutputpintypes <br/>}< br/>}; </P> <p> const amoviesetup_filter sudflipfilter = <br/>{< br/> & clsid_flipfilter, <br/> L "flipfilter", <br/> merit_do_not_use, <br/> 2, <br/> sudppins <br/> }; </P> <p> cfactorytemplate g_templates [] ={< br/> {L "flipfilter" <br/>, & clsid_flipfilter <br/>, cflipfilter :: createinstance <br/>, null <br/>, & sudflipfilter} <br/>}; <br/> int g_ctemplates = sizeof (g_templates) /sizeof (g_templates [0]); </P> <p> regfilter2 rf2filterreg ={< br/> 1, <br/> merit_do_not_use, <br/> 2, <br/> sudppins <br/>}; <br/>

3. Register and deregister the Global Entry of the filter and DLL.

Bool apientry dllmain (handle hmodule, <br/> DWORD dwreason, <br/> lpvoid lpreserved) <br/>{< br/> return dllentrypoint (hinstance) (hmodule ), dwreason, lpreserved); <br/>}</P> <p> stdapi dllregisterserver () <br/>{< br/> return amoviedllregisterserver2 (true ); </P> <p >}< br/> stdapi dllunregisterserver () <br/> {<br/> return amoviedllregisterserver2 (false); </P> <p>}

 

Filter is compiled.

 

Note: Full download: http://d.download.csdn.net/down/2435821/bwmwm

 

 

 

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.