//------------------------------------------------------------------------------

// File: Source.h

//

// Desc: DirectShow base classes - defines classes to simplify creation of

//       ActiveX source filters that support continuous generation of data.

//       No support is provided for IMediaControl or IMediaPosition.

//

// Copyright (c) 1992-2001 Microsoft Corporation.  All rights reserved.

//------------------------------------------------------------------------------





//

// Derive your source filter from CSource.

// During construction either:

//    Create some CSourceStream objects to manage your pins

//    Provide the user with a means of doing so eg, an IPersistFile interface.

//

// CSource provides:

//    IBaseFilter interface management

//    IMediaFilter interface management, via CBaseFilter

//    Pin counting for CBaseFilter

//

// Derive a class from CSourceStream to manage your output pin types

//  Implement GetMediaType/1 to return the type you support. If you support multiple

//   types then overide GetMediaType/3, CheckMediaType and GetMediaTypeCount.

//  Implement Fillbuffer() to put data into one buffer.

//

// CSourceStream provides:

//    IPin management via CBaseOutputPin

//    Worker thread management



#ifndef __CSOURCE__

#define __CSOURCE__



class CSourceStream;  // The class that will handle each pin





//

// CSource

//

// Override construction to provide a means of creating

// CSourceStream derived objects - ie a way of creating pins.

class CSource : public CBaseFilter {

public:



    CSource(TCHAR *pName, LPUNKNOWN lpunk, CLSID clsid, HRESULT *phr);

    CSource(TCHAR *pName, LPUNKNOWN lpunk, CLSID clsid);

#ifdef UNICODE

    CSource(CHAR *pName, LPUNKNOWN lpunk, CLSID clsid, HRESULT *phr);

    CSource(CHAR *pName, LPUNKNOWN lpunk, CLSID clsid);

#endif

    ~CSource();



    int       GetPinCount(void);

    CBasePin *GetPin(int n);



    // -- Utilities --



    CCritSec*   pStateLock(void) { return &m_cStateLock; }  // provide our critical section



    HRESULT     AddPin(CSourceStream *);

    HRESULT     RemovePin(CSourceStream *);



    STDMETHODIMP FindPin(

        LPCWSTR Id,

        IPin ** ppPin

    );



    int FindPinNumber(IPin *iPin);

    

protected:



    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



};





//

// CSourceStream

//

// Use this class to manage a stream of data that comes from a

// pin.

// Uses a worker thread to put data on the pin.

class CSourceStream : public CAMThread, public CBaseOutputPin {

public:



    CSourceStream(TCHAR *pObjectName,

                  HRESULT *phr,

                  CSource *pms,

                  LPCWSTR pName);

#ifdef UNICODE

    CSourceStream(CHAR *pObjectName,

                  HRESULT *phr,

                  CSource *pms,

                  LPCWSTR pName);

#endif

    virtual ~CSourceStream(void);  // virtual destructor ensures derived class destructors are called too.



protected:



    CSource *m_pFilter; // The parent of this stream



    // *

    // * 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.



public:

    // thread commands

    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:

    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

    virtual DWORD ThreadProc(void);         // the thread function



    virtual HRESULT DoBufferProcessingLoop(void);    // the loop executed whilst running





    // *

    // * AM_MEDIA_TYPE support

    // *



    // If you support more than one media type then override these 2 functions

    virtual HRESULT CheckMediaType(const CMediaType *pMediaType);

    virtual HRESULT GetMediaType(int iPosition, CMediaType *pMediaType);  // List pos. 0-n



    // If you support only one type then override this fn.

    // This will only be called by the default implementations

    // of CheckMediaType and GetMediaType(int, CMediaType*)

    // You must override this fn. or the above 2!

    virtual HRESULT GetMediaType(CMediaType *pMediaType) {return E_UNEXPECTED;}



    STDMETHODIMP QueryId(

        LPWSTR * Id

    );

};



#endif // __CSOURCE__



