//=========================================================================== // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR // PURPOSE. // // Copyright (c) 1992 - 1998 Microsoft Corporation. All Rights Reserved. // //=========================================================================== // // filename: fvcrctrl.h // // VCR Control filter - CBaseFilter Derived // // This is a prototype "VCR" filter. Depending on the detected VCR, // It has 5 or 6 pins - 2 or 3 Video inputs, 2 Audio inputs // and one Timecode outout (a timecode input pin would be useless). // It's a bit different than the standard source, transform, // and rendering filters because it has both input and output // pins with fairly unrelated behaviors. // // It implements the following External Device interfaces: // // IAMExtDevice // IAMPhysicalPinInfo // IAMExtTransport // IAMTimecodeReader // // The filter also has a couple of property pages that put a simple // user interface on many of the methods and properties of // the supported interfaces. class COutStream; // The class that will handle the timecode output pin //*************************************************/ // CVcrFilter // class CVcrFilter : public CBaseFilter, public CAMExtDevice, public CAMExtTransport, public CAMTcr, public CPersistStream, public ISpecifyPropertyPages { friend class COutStream; // so they can lock friend class CVcrTCOut; public: static CUnknown *CreateInstance(LPUNKNOWN punk, HRESULT *phr); // we replace the DECLARE_IUNKNOWN macro so we can resolve // ambiguous references due to multiple CUnknowns STDMETHODIMP QueryInterface(REFIID riid, void **ppv) { return CBaseFilter::GetOwner()->QueryInterface(riid,ppv); }; STDMETHODIMP_(ULONG) AddRef() { return CBaseFilter::GetOwner()->AddRef(); }; STDMETHODIMP_(ULONG) Release() { return CBaseFilter::GetOwner()->Release(); }; HINSTANCE LoadOLEAut32(); // // --- CBaseFilter Overrides -- // int GetPinCount(); CBasePin * GetPin(int n); // CPersistStream overrides HRESULT WriteToStream(IStream *pStream); HRESULT ReadFromStream(IStream *pStream); int SizeMax(); STDMETHODIMP GetClassID(CLSID *pClsid); // Utilities HRESULT AddPin(CBasePin *); HRESULT RemovePin(CBasePin *); CCritSec* pLock(void) { return &m_StateLock; }// provide our // critical section // override state changes to allow derived Device Control filter // to control its own start/stop STDMETHODIMP Stop(); STDMETHODIMP Pause(); STDMETHODIMP Run(REFERENCE_TIME tStart); // Basic COM - used here to reveal our property interface. STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv); // --- ISpecifyPropertyPages --- // return our property pages STDMETHODIMP GetPages(CAUUID * pPages); private: CVcrFilter(TCHAR *tszName, LPUNKNOWN punk, CLSID clsid, HRESULT *phr); ~CVcrFilter(); int m_iPins; // The number of pins on this filter. // Updated by COutStream and CVcrInputPin // constructors & destructors. protected: CBasePin **m_paStreams; // the pins on this filter. CCritSec m_StateLock; // Lock this to serialize function accesses // to the filter state }; //*************************************************/ // COutStream // // Use this class to manage a stream of data that comes // from a derived pin. // Uses a worker thread to put data on the pin. // class COutStream : public CAMThread, public CBaseOutputPin { public: COutStream(TCHAR *pObjectName, HRESULT *phr, CVcrFilter *pParent, LPCWSTR pName); virtual ~COutStream(void); // virtual destructor ensures derived class // destructors are called too. // thread commands virtual enum Command {CMD_INIT, CMD_PAUSE, CMD_RUN, CMD_STOP, CMD_EXIT}; 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); } protected: CVcrFilter *m_pFilter; // The parent of this stream HANDLE m_hAdviseEvent; // for an advise event IReferenceClock *m_pRefClock; // this graph's sync source // * // * Data Source // * // * The following three functions: FillBuffer, OnThreadCreate/Destroy, are // * called from within the ThreadProc. They are used in the creation of // * the media samples this pin will provide // * // Override this to provide the worker thread a means // of processing a buffer virtual 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;}; // * // * Worker Thread // * HRESULT Active(void); // Starts up the worker thread HRESULT Inactive(void); // Exits the worker thread. Command GetRequest(void) { return (Command) CAMThread::GetRequest(); } BOOL CheckRequest(Command *pCom) { return CAMThread::CheckRequest( (DWORD *) pCom); } // override these if you want to add thread commands // (and the T/C stream will) virtual DWORD ThreadProc(void); // the thread function virtual HRESULT DoBufferProcessingLoop(void); // the loop executed // whilst running // * // * MEDIA_TYPE support // * // Override this - we support multiple media types virtual HRESULT CheckMediaType( const CMediaType *pMediaType) PURE; }; //*************************************************/ // CVcrTCOut // // This filter has an output pin which can output timecode samples // as either a binary sample or as displayable text. // class CVcrTCOut : public COutStream { private: CVcrFilter *m_pFilter; // the external device filter that owns us CCritSec m_cSharedState; // use this to lock access to // m_rtSampleTime and m_pFilter which are // shared with the worker thread. CRefTime m_rtSampleTime; // The time to be stamped on each sample CTimecode *m_ctc; // need this for data conversions static LONGLONG m_llLastTime; // the last time timecode was updated int m_mtype; // 0 for text, 1 for Aux Data long m_DeviceID; // something to identify the source of events // generated here. long m_bNotify; // To notify, or not notify... public: CVcrTCOut( HRESULT *phr, CVcrFilter *pParent, LPCWSTR pPinName); ~CVcrTCOut(); BOOL ReadyToStop(void) {return FALSE;} // stuff a text buffer with the current format HRESULT FillBuffer(IMediaSample *pms); // ask for buffers of the size appropriate to the agreed media type. HRESULT DecideBufferSize(IMemAllocator *pIMemAlloc, ALLOCATOR_PROPERTIES *pRequest); // verify we can handle this format HRESULT CheckMediaType(const CMediaType *pMediaType); // we handle multiple media types HRESULT GetMediaType(int iPosition, CMediaType *pmt); // resets the stream time to zero. HRESULT OnThreadCreate(void); // Tidies up. HRESULT OnThreadDestroy(void); }; //*************************************************/ // // Base Hardware Input Pin Class // // It might be desirable to add hardware output pins in a similar manner // as the following input pins if, for example, an external device // has switchable outputs. // class CVcrInputPin : public CBaseInputPin, public CAMPhysicalPinInfo { public: CVcrInputPin( TCHAR *pObjectName, CVcrFilter *pFilter, HRESULT * phr, LPCWSTR pName); virtual ~CVcrInputPin(); STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** pv); // we aren't supposed to connect to anybody HRESULT CheckMediaType(const CMediaType*) { return E_FAIL; } // CAMPhysicalPinInfo's method - the derived input pins must implement STDMETHODIMP GetPhysicalType(long *pType, LPOLESTR * ppszType){ return E_NOTIMPL;} private: CVcrFilter * m_pFilter; // parent CCritSec m_StateLock; // Lock this to serialize function accesses }; //*************************************************/ // // 1st of 4 (or 5) input pins // class CVcrVideoCompInputPin : public CVcrInputPin { public: CVcrVideoCompInputPin( TCHAR *pObjectName, CVcrFilter *pFilter, HRESULT * phr, LPCWSTR pName); virtual ~CVcrVideoCompInputPin(); // CAMPhysicalPinInfo's method - we must return our physical pin info STDMETHODIMP GetPhysicalType(long *pType, LPOLESTR * ppszType); }; //*************************************************/ // // 2nd of 4 (or 5) input pins // class CVcrVideoSInputPin : public CVcrInputPin { public: CVcrVideoSInputPin( TCHAR *pObjectName, CVcrFilter *pFilter, HRESULT * phr, LPCWSTR pName); virtual ~CVcrVideoSInputPin(); // CAMPhysicalPinInfo's method - we must return our physical pin info STDMETHODIMP GetPhysicalType(long *pType, LPOLESTR * ppszType); }; //*************************************************/ // // 3rd of 4 (or 5) input pins // class CVcrAudioLineInputPin : public CVcrInputPin { public: CVcrAudioLineInputPin( TCHAR *pObjectName, CVcrFilter *pFilter, HRESULT * phr, LPCWSTR pName); virtual ~CVcrAudioLineInputPin(); // CAMPhysicalPinInfo's method - we must return our physical pin info STDMETHODIMP GetPhysicalType(long *pType, LPOLESTR * ppszType); }; //*************************************************/ // // 4th of 4 (or 5) input pins // class CVcrAudioMicInputPin : public CVcrInputPin { public: CVcrAudioMicInputPin( TCHAR *pObjectName, CVcrFilter *pFilter, HRESULT * phr, LPCWSTR pName); virtual ~CVcrAudioMicInputPin(); // CAMPhysicalPinInfo's method - we must return our physical pin info STDMETHODIMP GetPhysicalType(long *pType, LPOLESTR * ppszType); }; //*************************************************/ // // Optional 5th input pin // class CVcrVideoBlackInputPin : public CVcrInputPin { public: CVcrVideoBlackInputPin( TCHAR *pObjectName, CVcrFilter *pFilter, HRESULT * phr, LPCWSTR pName); virtual ~CVcrVideoBlackInputPin(); // CAMPhysicalPinInfo's method - we must return our physical pin info STDMETHODIMP GetPhysicalType(long *pType, LPOLESTR * ppszType); }; // eof fvcrctrl.h