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