190 likes | 212 Views
親愛的我把 DirectShow. 了. Ha Ha Py Py learn DirectShow Ⅱ. Fei-tian 1998 12/24. Outline …. Interface 簡述 Filter之間的默契 Pin與Filter之間的對話 DirectShow SDK COM的Aggreation模型. Specially thank …. 英濠學長 籃球國手志興 本組嘴吧最髒的小腿 G(Littleg). Data Flow in Filter. Receive. SourceStream. Deliver. FillBuffer.
E N D
親愛的我把 DirectShow 了 Ha Ha Py Py learn DirectShow Ⅱ Fei-tian 1998 12/24
Outline ….. Interface簡述 Filter之間的默契 Pin與Filter之間的對話 DirectShow SDK COM的Aggreation模型 Specially thank ….. 英濠學長 籃球國手志興 本組嘴吧最髒的小腿G(Littleg)
Data Flow in Filter Receive SourceStream Deliver FillBuffer Receive Receive DoBuffer Processing Loop Transform Receive Deliver EndOf Stream DeliverEnd OfStream EndOfStream DeliverEnd OfStream Output pin Input pin Output pin Input pin EndOfStream EndOfStream Source Filter Transform Filter Render Filter
IUnknown IUnknown Basic Renderer Filter Basic Source Filter IMediaPosition ISpecifyPropertyPages IBaseFilter IBaseFilter IFileSinkFilter IBasicAudio IFileSourceFiler IFileSinkFilter2 ISpecifyPropertyPages IAMovieSetup IAMovieSetup IMediaSeeking IVideoWindow IBaseFilter ::EnumPins IBaseFilter ::EnumPins IUnknown IUnknown IPin IPin Input Pin Output Pin IAsyncReader IQualityControl IMemInputPin IMediaSeeking IQualityControl IUnknown IBaseFilter Basic Transform Filter IAMovieSetup ISpecifyPropertyPages IBaseFilter ::EnumPins IUnknown IUnknown IPin IPin IQualityControl Input Pin Output Pin IMediaPosition IMemInputPin IMediaSeeking IMediaSeeking IQualityControl
Filter之間的默契(1/4) Pin Connect Modal(1/2) Step 1: Exchange interfaces (IPin, IMemInputPin) Ipin, IMemInputPin Step 2: 呼叫OutputPin的IPin::Connect(InputPin) IPin::QueryAccept IPin::EnumMediaTypes (1). Out呼叫In的IPin::EnumMediaTypes 並利用自己的IPin::QueryAccept檢查 是否接受 Out In IPin::EnumMediaTypes (2). 若1失敗 IPin::QueryAccept Out呼叫自己的IPin::EnumMediaTypes 並In的IPin::QueryAccept檢查是否接受 Out In (3). 若1或2有一成功 IPin::ReceiveConnect Out利用IPin::ReceiveConnect通知In 最後決定的Media Type Out In
Filter之間的默契(2/4) Pin Connect Modal(2/2) Step 3: Decide Allocator and Remember it(略) IMemInputPin::GetAllocator Step 4: Set Property of Allocator (1). Check that if the Allocator can access us Property IMemAllocator::SetProperty (2). If can, Set the Allocator’s Property IMemInputpin::NotifyAllocator
Filter之間的默契(3/4) MediaSample IMemInputPin::Receive IMemInputPin::Receive Information(BeginFlush,EndFlush,NewSegment) IMemInputPin::Informatin IMemInputPin::Informatin QualityNotify IPin::Notify IPin::Notify
Filter之間的默契(4/4) Allocator IMemInputPin::GetAllocator Case 1: Return an new allocator Allocator Allocator Case 2: Return the Back Allocator Allocator Use itself IMemInputPin::GetAllocator Allocator
DirectShow SDK的 COM Aggregation模型(1/3) IUnknown* m_pUnknow 1. 從建構式傳入 2. 若傳入值是NULL, 則等於 reinterpret_cast< IUnknown > ( static_cast<INonDelegatingUnknown>(this)) INonDelegatingUnknown CUnknow m_pUnknown IUnknown InterfaceA #define DECLARE_IUNKNOWN\ STDMETHODIMP QueryInterface(REFIID riid, void **ppv) {\ return GetOwner()->QueryInterface(riid,ppv); \ }; \ STDMETHODIMP_(ULONG) AddRef() {\ return GetOwner()->AddRef(); \ }; \ STDMETHODIMP_(ULONG) Release() {\ return GetOwner()->Release(); \ }; ClassA DECLARE_IUNKNOWN
DirectShow SDK的 COM Aggregation模型(2/3) InterfaceA->QueryInterface GetOwner()->QueryInterface m_pUnknown ->QueryInterface INonDelegatingUnknown ->NonDelegatingQueryInterface IUnknown INonDelegatingUnknown AddRef Release QueryInterface NonDelegatingAddRef NonDelegatingRelease NonDelegatingQueryInterface
DirectShow SDK的 COM Aggregation模型(3/3) INonDelegatingUnknown INonDelegatingUnknown CUnknow CUnknow m_pUnknown m_pUnknown InterfaceA InterfaceB ClassA ClassB ClassB *b = new ClassB(GetOwner()); DECLARE_IUNKNOWN NonDelegatingQueryInterface { if Query InterfaceB return (InterfaceB*)b; if Query InterfaceA return (InterfaceA*) this; return BassClass :: NonDelegatingQueryInterface } ClassA InterfaceA ClassB InterfaceB
CBaseFilter的使用 Run 利用EnumPins取得所有的Pins, 並Call他們的Run() Stop Pause ? GetPin 重要的可Overwrite function: virtual int GetPinCount(); virtual CBasePin *GetPin(int n); ? GetCount CBaseFilter
CBasePin的使用 ? BeginFlush ? EndFlush ? Notify ? NewSegment ? EndOfStream ? CheckMediaType 重要的可Overwrite function: CheckMediaType(const CMediaType *); GetMediaType(int iPosition, CMediaType *pMediaType); EndOfStream(void); Notify(IBaseFilter * pSender, Quality q); Run(REFERENCE_TIME tStart); NewSegment( REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate ); ? GetMediaType Run CBasePin
CBaseInputPin的使用 ? Receive ? BeginFlush ? EndFlush PassNotify ? NewSegment ? EndOfStream ? CheckMediaType GetMediaType Run 重要的可Overwrite function: Receive(IMediaSample *pSample); BeginFlush(void); EndFlush(void); GetAllocator CBaseInputpin
CBaseOutputPin的使用 Deliver DeliverBeginFlush DeliverEndFlush ? Notify DeliverNewSegment DeliverEndOfStream ? CheckMediaType ? GetMediaType ? DecideBufferSize Run 重要的可Overwrite function: DecideBufferSize( IMemAllocator * pAlloc, ALLOCATOR_PROPERTIES * ppropInputRequest ); CBaseOutputpin
? Receive Run 利用EnumPins取得所有的Pins, 並Call他們的Run() Deliver ? BeginFlush DeliverBeginFlush ? EndFlush DeliverEndFlush Stop ? PassNotify Notify Pause ? NewSegment DeliverNewSegment ? EndOfStream DeliverEndOfStream ? ? CheckMediaType CheckMediaType ? GetMediaType GetMediaType ? ? Run GetPin DecideBufferSize ? GetAllocator GetCount Run CBaseOutputpin CBaseInputpin CBaseFilter
Receive ? Receive Transform Deliver BeginFlush BeginFlush DeliverBeginFlush EndFlush EndFlush DeliverEndFlush PassNotify AlterQuality Notify NewSegment NewSegment DeliverNewSegment EndOfStream EndOfStream DeliverEndOfStream ? CheckMediaType CheckInputType ? GetMediaType GetMediaType GetMediaType ? CheckTransform CheckMediaType ? DecideBufferSize DecideBufferSize 0 1 GetPin CTransformInputpin CTransformOutputpin GetCount = 2 CTransformFilter
CTransformFilter的Receive的行為 Receive ? Receive Transform Deliver CTransformFilter::Receive(InSample) { } 1. OutputPin跟所連結InputPin的Allocator要一個 新buffer, OutSample 2. 初始化OutSample(包含將TimeStamp拷貝過去) 3. Transform(InSample, OutSample) 4. OutputPin->InputPin->Receive(OutSample)
另一種Stream的架構 Push thread Push thread Request Respond AnsynReader