1. CSourceStream class, is the csource class Outputpin [Source.h / Source.cpp] derived from Camthread and CBaseOutputpin
l Member variable: csource * m_pfilter; // the Parent of this Stream
l newly added virtual functions: // Override this to provide the worker thread a means of processing a buffervirtual HRESULT FillBuffer (IMediaSample * pSamp) PURE; // Called as the thread is created / destroyed - use to perform // jobs such as start / stop streaming mode // If OnThreadCreate returns an error the thread will exit.virtual HRESULT OnThreadCreate (void) {return NOERROR;}; virtual HRESULT OnThreadDestroy (void) {return NOERROR;}; virtual HRESULT OnThreadStartPlay (void) {return NOERROR ;}; virtual HRESULT DoBufferProcessingLoop (void); // the loop executed whilst running {Command com; OnThreadStartPlay (); do {while (CheckRequest (& com)!) {IMediaSample * pSample; HRESULT hr = GetDeliveryBuffer (& pSample, NULL, NULL , 0); IF (FAILED (HR)) {Sleep (1); Continue;} // Virtual Function User Will Override. Hr = fillbuffer; if (hr == s_ok) {hr = deliver (psample); PSamp Le-> Release (); if (hr! = s_ok) Return S_OK;} else if (hr == s_false) {psample-> release (); DeliverendofStream (); returnifstream (); return s_ok;} else {psample-> release () DeliverendofStream (); m_pfilter-> notifyevent (Ec_ERRORABORT, HR, 0); return hr;}} = =} == cmd_run || COM == cmd_pause) {reply (noerror);} else if (com! = Cmd_stop) {Reply ((DWORD) E_UNEXPECTED;}} while (com! = Cmd_stop); Return S_FALSE;} Virtual HRESULT GETMEDITYPE (CMEDiatype * pmediatype) {return e_unexpected;}
l Inherited CBasepin Virtual function: hResult active (void); // Starts up the worker thread {Cautolock Lock (m_pfilter-> pstatelock ()); if (m_pfilter-> isactive ()) {return s_false;} ISconnected ()) {Return NoError;} hr = cbaseoutputpin :: active (); if (failed (hr)) {return HR;} assert (! Threadexists ()); // Start the thread if (! CREATE ()) {RETURN E_FAIL;} // Tell Thread to Initialize. if ONTHREADCREATE FAILS, SO DOES THIS. HR = INIT (); if (Failed (HR)) Return Hr; Return Pause ();} HRESULT INACTIVE (Void); // EXITES The WORKER Thread. {Cautolock Lock (m_pfilter-> PStateLock ()); if (! Isconnected ()) {Return NoError;} // !!! Need to do this before trying to stop the thread, Because // WE MAY Be stuck waiting for out = cbaseoutputpin :: inactive (); // call this first to decommit the allocator if (Failed (HR)) {Return HR;} if (threadexists ()) {hr = stop (); IF (Failed (HR)) {Return HR;} HR = EXIT (); if (Failed (HR)) {Return HR;} close (); // Wait for the thread to exit, the tidy up.} Return NoError;} Virtual HRESULT CHECKMEDITYPE (CMEDiatyPE * PMEDiatiType); {/ / Default only supports a format, that is, only the newly added GetMediatype function is called to compare mediatype, // and input Type} Virtual HResult getMediatype (int iposition, cmediatype * pmediatype); // List POS. 0-n {/ / Judgment iposition must be 0, return a newly added GetMediaType function} l operation function: hResult init (void) {Return CallWorker (CMD_INIT);} HRESULT EXIT (VOID) {Return CallWorker (cmd_exit);} HRESULT RUN (Void) { Return CallWorker (CMD_RUN); HRESULT PAUSE (VOID) {Return CallWorker (CMD_PAUSE);} HRESULT STOP (Void) {Return CallWorker (CMD_Stop);
l CAMThread of virtual functions // override these if you want to add thread commands // Return codes> 0 indicate an error occuredvirtual DWORD ThreadProc (void); // the thread function {// entire function implements a synchronous communication Thread. Command COM; do {com = getRequest (); if (com! = Cmd_init) {reply ((dword) e_unexpected;}} while (com! = Cmd_init); hr = onthreadcreate (); // perform set up tasks if (FAILED (HR)) {onthreadDestroy (); reply (hr); // send failed return code from onthreadcreate return 1;} reply (noerror); Command cmd; do {cmd = getRequest (); switch (cmd) {casse CMD_EXIT: Reply (NOERROR); break; case CMD_RUN: case CMD_PAUSE: Reply (NOERROR); DoBufferProcessingLoop (); break; case CMD_STOP: Reply (NOERROR); break; default: Reply ((DWORD) E_NOTIMPL); break;}} While (cmd! = cmd_exit); hr = onthreadDestroy (); // tidy up. if (failed (hr)) {return 1;} return 0;} l Constructor: // increments the number of Pins Present on the filtercsourcestream Tchar * POBJECTNAME, HRESULT * Phr, CSource * ps, lpcwstr ppinname: CBASEOUTPUTPIN (POBASEOUTPUTPIN (POBJECTNAME, PS, PS-> PStatelock (), PHR, PPinname), m_pfilter (ps) {* pHR = m_pfilter-> addpin (this);
l Deconstructor: ~ csourceStream (void) {m_pfilter-> removepin (this);}
2. CSource class [source.h / source.cpp] derived from CBASEFILTER
l member variables: int m_iPins; // The number of pins on this filter Updated by CSourceStream constructors & destructors.CSourceStream ** m_paStreams; // the pins on this filter.CCritSec m_cStateLock; // Lock this to serialize function accesses to the. Filter State where m_ipins is initialized to 0, and m_pastreams is initialized to NULL. l Inherited CBasefilter's Virtual function: int getpincount (void); cbasepin * getpin (int N);
l newly added function: CCritSec * pStateLock (void) {return & m_cStateLock;} // provide our critical sectionHRESULT AddPin (CSourceStream *); {CAutoLock lock (& m_cStateLock); / * Allocate space for this pin and the old ones * / CSourceStream ** Pastreams = new csourceStream * [m_ipins 1]; if (pastreams == null) {return e_outofMemory;} // If m_pastreams already exists, copy it to the Pastreams, omitted to the step code ... if (m_pastreams! = NULL) {CopyMemory (pvoid) m_pastreams, m_ipins * sizeof (m_pastreams [0])); // In fact, the following line implementation code can have no Pastreams [m_ipins] = PStream; delete [] m_pastreams = pastreams; m_pastreams [m_ipins] = pstream; m_ipins ;} HRESULT Removepin (csourcestream *); {// Traverse all PIN, if you are the same as the input pointer, if there is only one PIN Presence, release m_pastreams, / / otherwise move the subsequent PIN all forward. } Stdmethodimp findpin (lpcwstr id, ipin ** pppin); {// input ID is actually a numeric string, calling getpin with WSTRTOINT (ID) -1), // Output PIN must call AddRef} int FindPinnumber (IPIN * ipin); {// Traverse all PIN, make a pointer comparison, return the Number of the same PIN, otherwise returns -1}
3. An example of the Source Filter in DirectShow, Ball [fball.h / fball.cpp] Filter Ball is a Source Filter that generates jumping ball.
l Filter class CBOUNCINGBALL:
i. Member function: // The only allowed Way to create bouncing balls! static cunknown * WinAPI CreateInstance (LPUNKNOWN LPUNK, HRESULT * pHR); {Created (New) a new cbouncingball Object. } Ii Constructor (private):. CBouncingBall :: CBouncingBall (LPUNKNOWN lpunk, HRESULT * phr): CSource (NAME ( "Bouncing ball"), lpunk, CLSID_BouncingBall) {// create Output Pin, first creates an array of pointers m_paStreams = (CSourceStream **) New cballstream * [1]; // Create a real Output pin: m_pastreams [0] = new cballstream (phr, this, l "a bouncing ball!");}
l PIN CBallStream: Delivered from CSourceStream. CBall is a class that implements its function, which is not analyzed here.
. I member variables: int m_iImageHeight; // The current image heightint m_iImageWidth; // And current image widthint m_iRepeatTime; // Time in msec between framesconst int m_iDefaultRepeatTime; // Initial m_iRepeatTimeBYTE m_BallPixel [4]; // Represents one coloured ballint m_iPixelSize ; // The pixel size in bytesPALETTEENTRY m_Palette [256]; // The optimal palette for the imageCCritSec m_cSharedState; // Lock on m_rtSampleTime and m_BallCRefTime m_rtSampleTime; // The time stamp for each sampleCBall * m_Ball; // The current ball object
. Ii CBaseOutputPin from CBasePin inheritance and virtual functions: // Ask for buffers of the size appropriate to the agreed media typeHRESULT DecideBufferSize (IMemAllocator * pIMemAlloc, ALLOCATOR_PROPERTIES * pProperties); {CAutoLock cAutoLock (m_pFilter-> pStateLock ()); VIDEOINFO * pvi = (VIDEOINFO *) m_mt.Format (); pProperties-> cBuffers = 1; pProperties-> cbBuffer = pvi-> bmiHeader.biSizeImage; ALLOCATOR_PROPERTIES Actual; hr = pAlloc-> SetProperties (pProperties, & Actual); if (Actual. cbBuffer
Format (); if ((pvi-> bmiheader.biwidth <20) || (ABS (PVI-> bmiheader.biheight) <20) Return E_INVALIDARG; // Other check ...} HRESULT GETMEDITYPE (int iposition, cmediatype) * PMT); {Cautolock Cautolock (m_pfilter-> pstateLock ()); if ((iposition <0) || (IPosition <0))) error. VIDEOINFO * pvi = (VIDEOINFO *) pmt-> AllocFormatBuffer (sizeof (VIDEOINFO)); ZeroMemory (pvi, sizeof (VIDEOINFO)); switch (iPosition) {case 0: // Return our highest quality 32bit format case 1: // RETURN OUR 24bit Format Case 2: // 16 Bit Per Pixel RGB565 Case 3: // 16 Bits Per Pixel RGB555 Case 4: // 8 Bit Palettised} // Plug PMT Different Values} // Quality Control Notifications Sent To USStdMethodimp Notify (IBaseFilter * pSender, Quality q); {// Notify mainly provided in order to adjust a number of members of the variable speed} iii CSourceStream virtual functions inherited from:. // plots a ball into the supplied video frameHRESULT FillBuffer (IMediaSample * pms); {// Get Sample Data Pointer: PMS-> GetPointer (& PDATA); // Call M_Ball member function populates the data field // Setting time PMS-> setTime (Reference_time *) & rtstart, (Reference_time *) & m_rtsampletime); // pms-> setsyncpoint (true);} // resets the stream time to zerohresult onthreadcreate (void); {initialized variable m_rtsampletime and m_irepeattime}
Previous Article:
(4) Part of Helper Classes Class Source Code Analysis