DirectShow Learning (2): CBasepin class, CBASEOUTPUTPIN class and CBaseInputPin class source code resolution
1. IPIN interface ipin: public iunknown {public: // Connect two PIN, actively connect inputCallType connect (/ * [in] * / ipin * preceivepin, / * [in] * / const am_media_type * pmt) = 0; // Connect two PIN, passively connected Virtual HRESULT stdmethodCallType ReceiveConnection (/ * [in] * / ipin * pConnector, / * [in] * / const am_media_type * pmt) = 0; // Disconnect, only Remove the Virtual HRESULT stdmethodCallType Disconnect (Void) = 0; // Get the connection of the connected PIN, successfully returned the connected PIN called AddRef Virtual HRESULT stdmethodCallType Connectedto (/ * [out] * / ipin ** PPIN) = 0; // get MediaType virtual HRESULT STDMETHODCALLTYPE ConnectionMediaType (/ * [out] * / AM_MEDIA_TYPE * pmt) = 0 in the connected state; // get the information of Pin, filling PIN_INFO structure virtual HRESULT STDMETHODCALLTYPE QueryPinInfo (/ * [out] * / Pin_INFO * PINFO) = 0; // Get the connection direction of the PIN Virtual HRESULT stdmethodCallType QueryDirection (/ * [out] * / pin_direction * ppindir) = 0; // Get id - actually is the NA in the PIN me virtual HRESULT STDMETHODCALLTYPE QueryId (/ * [out] * / LPWSTR * Id) = 0; // Determines whether the pin accepts a specified media type virtual HRESULT STDMETHODCALLTYPE QueryAccept (/ * [in] * / const AM_MEDIA_TYPE * pmt) =. 0; // enumerates the pin's preferred media types virtual HRESULT STDMETHODCALLTYPE EnumMediaTypes (/ * [out] * / IEnumMediaTypes ** ppEnum) = 0;. // Retrieves the pins that are connected internally to this pin (within the filter) virtual. HRESULT STDMETHODCALLTYPE QueryinternalConnections (/ * [out] * / ipin ** appin, / * [out] [in] * / ulong * npin) = 0;
// Notifies the pin that no additional data is expected virtual HRESULT STDMETHODCALLTYPE EndOfStream (void) = 0;. // Begins / End a flush operation virtual HRESULT STDMETHODCALLTYPE BeginFlush (void) = 0; virtual HRESULT STDMETHODCALLTYPE EndFlush (void) = 0; // Notifies the pin that media samples received after this call are grouped as a segment. virtual HRESULT STDMETHODCALLTYPE NewSegment (/ * [in] * / REFERENCE_TIME tStart, / * [in] * / REFERENCE_TIME tStop, / * [in] * / double dRate) = 0;}; 2 IQualityControl Interface IQualityControl:.. public IUnknown {public: // Notifies the recipient that a quality change is requested virtual HRESULT STDMETHODCALLTYPE Notify (/ * [in] * / IBaseFilter * pSelf, / * [ In] * / Quality q) = 0; Virtual HRESULT stdmethodCallType setsink (/ * [in] * / iQualityControl * PIQC) = 0;
3. CBasepin class [amfilter.h / amfilter.cpp]
o derived from CUnknown, IPin, IQualityControl member variables: WCHAR * m_pName; // This pin's name IPin * m_Connected; // Pin we have connected to PIN_DIRECTION m_dir; // Direction of this pin CCritSec * m_pLock; // Object we use for locking bool m_bRunTimeError; // Run time error generated bool m_bCanReconnectWhenActive; // OK to reconnect when active bool m_bTryMyTypesFirst; // When connecting enumerate CBaseFilter * m_pFilter; // Filter we were created by IQualityControl * m_pQSink; // Target for Quality messages LONG m_typeversion; // Holds Current Type Version CMEDiatype m_mt; // media type of connection creftime m_tstart; // time from newsegment call crEFTIME M_TSTOP; // Time from N ewSegment double m_dRate; // rate from NewSegment wherein m_bRunTimeError default is FALSE, m_pQSink defaults to NULL, m_TypeVersion default is 1, m_tStart is empty, m_tStop to MAX_TIME, m_bCanReconnectWhenActive and m_bTryMyTypesFirst are FALSE, m_dRate 1.0.
o Constructor: CBasePin (TCHAR * pObjectName, // Object description CBaseFilter * pFilter, // Owning filter who knows about pins CCritSec * pLock, // Object who implements the lock HRESULT * phr, // General OLE return code LPCWSTR pName, / / PIN Name for US Pin_Direction Dir); // Either Pindir_INPUT or PIIR_OTPUT M_PFILTER is initialized by Pfilter, and M_PLOCK is initialized by PLOCK, and m_dir is initialized by DIR. The link between o PIN [Detailed Code explains the second chapter of Lu Ming "DirectShow Development Guide] AttempConnect (CBasepin's Protected function). Which AttempConnect function first calls CheckConnect (CBasePin of Virtual function), then call CheckMediaType (CBasePin of Virtual function), if the MediaType accepted, call ReceiveConnection (IPin interface function) function on the Receive Pin, if successful call CompleteConnection (CBasePin of Virtual function), otherwise call BREAKCONNECT (Virtual function on CBasepin).
And explain the newly added virtual functions and virtual o CBasePin the codes: virtual LONG GetMediaTypeVersion (); {return m_TypeVersion;} // switch the pin to active (paused or running) mode not an error to call this if already active, virtual HRESULT Active (void); {return NOERROR;} // switch the pin to inactive state - may already be inactive virtual HRESULT inactive (void); {return NOERROR;} // Notify of Run () from filter, virtual HRESULT Run (REFERENCE_TIME tStart); {return NOERROR;} // check if the pin can support this specific proposed type and forma virtual HRESULT CheckMediaType (const CMediaType *) PURE; must Override // set the connection to use this format (previously agreed) virtual HRESULT SetMediaType (const CMediaType *); {HRESULT hr = m_mt.Set (* pmt);} // check that the connection is ok before verifying it can be overridden eg to check what interfaces will be supported.virtual HRESULT CheckConnect (IPin *); {CBasepin only checks the direction of the PIN and whether the current direction is consistent} // set and release resources Required for a connectionVirtual hResult BreakConnect (); {RET urn NOERROR;} virtual HRESULT CompleteConnect (IPin * pReceivePin); {return NOERROR;} // returns the preferred formats for a pin virtual HRESULT GetMediaType (int iPosition, CMediaType * pMediaType); Overrideo CBasePin must implement the function QueryAccept IPin - direct call Checkmediatype and return the results to enummediatypes - Enumm.newSegment in the MEDIATYPE through the secondary class CenumMediatypes - just returning the NOERRORDISCONNECT - Call function disconnectinternalconnect / ReceiveConnection - see the above entry. Other simple interface functions ConnectionMediatype, QueryPinInfo, QueryDirection, etc.
o CBASepin's function is directly set to NoError partial function: Endofstream is directly set to the Impl error code: QueryinternalConnectionSnotify [iQualityControl interface] Some parties completely unrealized: Beginflushendflush
4. CBASEOUTPUTPIN Class [AMFILTER.H / AMFILTER.CPP]
o CBASEOUTPUTPIN specifically implements pseudo code distribution from the CBasepin variable portion (all initialized to null): IMEMALLOCATOR * m_pallocator; // memory allocatoriminputpin * m_pinputpin; // interface on the downstreaminput PIN
o the newly added virtual functions: // negotiate the allocator and its buffer size / count and other properties // Calls DecideBufferSize to set propertiesvirtual HRESULT DecideAllocator (IMemInputPin * pPin, IMemAllocator ** pAlloc); {// call pPin-> GetAllocatorRequirements. Get an Input Pin's prop. // Call PPIN-> GetAllocator to determine whether PPIN and allocator, / / otherwise create and initialize (initaloc) and call DecideBuffersize to get the required size // call PPIN-> NotifyAllocator Let Input Pin get updated the Allocator} // override this to set the buffer size and count Return an errorvirtual HRESULT DecideBufferSize (IMemAllocator * pAlloc, ALLOCATOR_PROPERTIES * ppropInputRequest) PURE;. // returns an empty sample buffer from the allocatorvirtual HRESULT GetDeliveryBuffer (IMediaSample ** ppSample, REFERENCE_TIME * PstartTime, Reference_time * PENDTIME, DWORD DWFLAGS; {Call m_pallocator-> getBuffer (...)} // Deliver A Filled-in Sample To The Connected Input Pin // Note - You NEED TO RELEAS e it after calling this The receivingvirtual HRESULT Deliver (IMediaSample *);. {m_pInputPin-> Receive (pSample);} // override this to control the connectionvirtual HRESULT InitAllocator (IMemAllocator ** ppAlloc); {CreateMemoryAllocator (ppAlloc);} / / called from elsewhere in our filter to pass EOS downstream to our connected input pinvirtual HRESULT DeliverEndOfStream (void); {m_Connected-> EndOfStream ();} virtual HRESULT DeliverBeginFlush (void); {m_Connected-> BeginFlush ();} virtual HRESULT DeliverEndFlush (void); {m_connected-> endflush ();} Virtual HRESULT DELIVERNEWSEGMENT (Reference_time TStart, Reference_time Tstop, Double Drate); {m_connected->
NewSegment (...);} o IPin inherited virtual function or interface functions: // Complete connectionvirtual HRESULT CompleteConnect (IPin * pReceivePin); {DecideAllocator ()} // Check connectionHRESULT CheckConnect (IPin * pPin); {Input Pin checks whether the increased Support IMEMINPUTPIN interface, m_pinputpin assignments here} // Break connectionHResult BreakConnect (); {// Call m_pallocator-> decommit () release m_pallocator and set to empty, // Release M_PINPUTPIN and set to empty} HRESULT ACTIVE (Void); {m_pAllocator-> Commit ();} HRESULT Inactive (void); {m_pAllocator-> decommit ();} return directly following three functions E_UNEXPECTEDSTDMETHODIMP EndOfStream (void); STDMETHODIMP BeginFlush (void); STDMETHODIMP EndFlush (void);
5. IMemInputPin interface functions: IMemInputPin:. Public IUnknown {// Retrieves the memory allocator proposed by this pin virtual HRESULT STDMETHODCALLTYPE GetAllocator (/ * [out] * / IMemAllocator ** ppAllocator) = 0; // Specifies an allocator for the connection . virtual HRESULT STDMETHODCALLTYPE NotifyAllocator (/ * [in] * / IMemAllocator * pAllocator, / * [in] * / BOOL bReadOnly) = 0; // Retrieves allocator properties that are requested by the input pin virtual HRESULT STDMETHODCALLTYPE GetAllocatorRequirements (/ *. [out] * / ALLOCATOR_PROPERTIES * pProps) = 0;. // Receives the next media sample in the stream virtual HRESULT STDMETHODCALLTYPE Receive (/ * [in] * / IMediaSample * pSample) = 0; // Receives multiple samples in the stream Virtual HRESULT stdmethodCallType ReceiveMultiple (/ * [size_is] [in] * / iMediasample ** psamples, / * [in] * / long nsamples, / * [out] * / long * nsamplesprocessed) = 0; / / DETERMINES WHETHER CALLS to the Recive Method Might Block. Virtual HResult stdmethodCallType ReceiveCanblock (void) = 0;}
6. CBaseInputPin class [amfilter.h / amfilter.cpp] o CBaseInputPin embodied pseudocode: derived from CBasePin, IMemInputPin variable part: IMemAllocator * m_pAllocator; // Default memory allocator // Allocator is read only or notBYTE m_bReadOnly; // in flushing state (between BeginFlush and EndFlush) // if TRUE, all Receives are returned with S_FALSEBYTE m_bFlushing; // Sample properties - initalized in ReceiveAM_SAMPLE2_PROPERTIES m_SampleProps; INonDelegationUnknown interface functions: // rewrite the function is to support IMemInputPin interface. STDMETHODIMP NonDelegatingQueryInterface (REFIID riid, void ** ppv); concrete realization function: HRESULT PassNotify (Quality & q); {// if m_pQSink is not empty, a direct call m_pQSink-> Notify (...) // otherwise the query IQualityControl Connect on the Pin Exciptures, call notify (...)}
o The new virtual functions // Override this for checking whether it's OK to process samples // Also call this from EndOfStream.virtual HRESULT CheckStreaming (); {were determined IsStopped, m_bFlushing and m_bRunTimeError}
o IMemInputPin interface functions: // return the allocator interface that this input pin // would like the output pin to useSTDMETHODIMP GetAllocator (IMemAllocator ** ppAllocator); {// if m_pAllocator is empty, then CreateMemoryAllocator. // Call m_pAllocator-> AddRef, returns m_pAllocator} // tell the input pin which allocator the output pin is actually going to use.STDMETHODIMP NotifyAllocator (IMemAllocator * pAllocator, BOOL bReadOnly); {// release current m_pAllocator, provided m_pAllocator = pAllocator // call m_pAllocator-> AddRef} // do something with this media sampleSTDMETHODIMP Receive (IMediaSample * pSample); // Sample if the property is not changed CheckStreaming // {// called first Psample derived attribute, i.e. filling member m_SampleProps ( ! (m_SampleProps.dwSampleFlags & AM_SAMPLE_TYPECHANGED)) // returns directly NOERROR, or call CheckMediaType check whether to accept the new MediaType, if you accept // returns NOERROR, otherwise call EndOfStream, set RuntimeError, and notify Filter // m_pFilter-> NotifyEvent ( EC_ERRORABORT, VFW_E_TYPE_NOT_ACCEPTED, 0);} // do something with these media samplesSTDMETHODIMP ReceiveMultiple (IMediaSample ** pSamples, long nSamples, long * nSamplesProcessed); {// each call Receive function on each Sample. } // see if receiver () blockSstdMethodimp receivecanblock (); {// If there is no Output Pin on the current Filter, return S_OK / / Otherwise, it is traversed to each Output Pin on the current filter, and draws their Connected INPUT PIN to determine these / / Connected Input Pin support Block, as long as there is a support, when compared with S_OK // none of these conditions are not satisfied, return S_FALSE} // default implementation returns E_NOTIMPL. Override if you have // specific alignment or prefix needs, but could use An Upstream AllocatorstdMethodimp getAllocatorRequirements (allocator_properties * pprops); {e_impl}
o Inherited Virtual functions implement STDMETHODIMP BEGINFLUSH (Void); {only m_bflushing is true.} stdmethodimp endflush (void); {{just setting m_bflushing to false while clearing M_BruntimeError. } HRESULT BREAKCONNECT (); {// If m_pallocator is non-empty, call m_pallocator-> decommit () // Release M_Pallocator-> Release and set it off. } Virtual HRESULT Inactive (void); {// clean m_bRunTimeError and m_bFlushing, return m_pAllocator-> Decommit ()} STDMETHODIMP Notify (IBaseFilter * pSender, Quality q);. {Which is IQualityControl interface function, CBaseInputPin described simply given DbgBreak Not implemented} Previous article:
(1) COM implementation part and part of the auxiliary source code