//------------------------------------------------------------------------------
// 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(__in_opt LPCTSTR pName, __inout_opt LPUNKNOWN lpunk, CLSID clsid, __inout HRESULT *phr);
    CSource(__in_opt LPCTSTR pName, __inout_opt LPUNKNOWN lpunk, CLSID clsid);
#ifdef UNICODE
    CSource(__in_opt LPCSTR pName, __inout_opt LPUNKNOWN lpunk, CLSID clsid, __inout HRESULT *phr);
    CSource(__in_opt LPCSTR pName, __inout_opt 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(__in CSourceStream *);
    HRESULT     RemovePin(__in CSourceStream *);

    STDMETHODIMP FindPin(
        LPCWSTR Id,
        __deref_out IPin ** ppPin
    );

    int FindPinNumber(__in 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(__in_opt LPCTSTR pObjectName,
                  __inout HRESULT *phr,
                  __inout CSource *pms,
                  __in_opt LPCWSTR pName);
#ifdef UNICODE
    CSourceStream(__in_opt LPCSTR pObjectName,
                  __inout HRESULT *phr,
                  __inout CSource *pms,
                  __in_opt 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, __inout 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(__inout CMediaType *pMediaType) {return E_UNEXPECTED;}

    STDMETHODIMP QueryId(
        __deref_out LPWSTR * Id
    );
};

#endif // __CSOURCE__

