//===========================================================================
//
// 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 - 1997 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();
};
HINSTANCELoadOLEAut32();
//
// --- 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
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);
};
//*************************************************/
//
//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