home *** CD-ROM | disk | FTP | other *** search
- //==========================================================================;
- //
- // 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 - 1996 Microsoft Corporation. All Rights Reserved.
- //
- //--------------------------------------------------------------------------;
-
- //
- // Video capture stream source filter
- //
-
- // - Uses the CSource/CSourceStream classes to create a video capture filter.
- // - Uses the AVICap capXXX macros to capture from the first driver it finds.
-
- // CLSID_VidCap
- // {fd501040-8ebe-11ce-8183-00aa00577da1}
- DEFINE_GUID(CLSID_VidCap,
- 0xfd501040, 0x8ebe, 0x11ce, 0x81, 0x83, 0x00, 0xaa, 0x00, 0x57, 0x7d, 0xa1);
-
- // The buffer sizes required for driver name and version strings
- const int giDriverNameStrLen = 80;
- const int giDriverVerStrLen = 40;
-
- class CVidStream; // manages the output stream & pin
- class CVideoBufferList; // A place to store filled buffers before we can send
- // them downstream
-
-
- //
- // CVidCap
- //
- // The VidCap filter object. Provides the IFilter & IMediaFilter interfaces.
- class CVidCap : public CSource {
-
- public:
-
- // Construct a VidCap filter
- static CUnknown *CreateInstance(LPUNKNOWN lpunk, HRESULT *phr);
-
- CCritSec m_cStateLock; // Lock this when a function accesses
- // the filter state.
- // Generally _all_ functions, since access to this
- // filter will be by multiple threads.
-
- // overide the Run & Pause methods so that I can notify the pin
- // of the state it should move to
- STDMETHODIMP Run(REFERENCE_TIME tStart);
- STDMETHODIMP Pause(void);
-
- // Stop will tell the pin the state it is moving from
- STDMETHODIMP Stop(void);
-
- // setup helper
- LPAMOVIESETUP_FILTER GetSetupData();
-
- private:
-
- // During construction we create the single CVidStream object that provides the
- // output pin.
- CVidCap(TCHAR *, LPUNKNOWN, HRESULT *);
- ~CVidCap();
-
- };
-
-
- //
- // CVidStream
- //
- // Manages the output pin and the video capture device.
- // Provides an implementation for IVideoCaptureConfigure, to allow the user
- // to select formats, etc.
- class CVidStream : public CSourceStream, IVideoCaptureConfigure {
-
- public:
-
- CVidStream( TCHAR *pObjectName
- , HRESULT *phr
- , CVidCap *pParentFilter
- , unsigned int uiDriverIndex
- , LPCWSTR pPinName
- );
-
- ~CVidStream();
-
- //
- // --- CSourceStream implementation ---
- //
- public:
-
- HRESULT DecideBufferSize(IMemAllocator *pAlloc,
- ALLOCATOR_PROPERTIES *pProperties);
-
- //
- // --- Worker Thread fn's ---
- //
- HRESULT OnThreadCreate(void);
- HRESULT OnThreadDestroy(void);
-
- HRESULT DoBufferProcessingLoop(void);
- HRESULT FillBuffer(IMediaSample *pSamp);
-
- HRESULT Active(FILTER_STATE FromState, FILTER_STATE ToState);
- HRESULT Inactive(FILTER_STATE OldState);
-
- // Override to handle quality messages
- STDMETHODIMP Notify(IFilter * pSender, Quality q);
-
-
- //
- // --- IVideoCaptureConfigure implementation ---
- //
- public:
-
- DECLARE_IUNKNOWN;
-
- // reveals the IVideoCaptureConfigure interface
- STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv);
-
- // Get the drivers details
- STDMETHODIMP get_DriverName(BSTR DriverName);
- STDMETHODIMP get_DriverVersion(BSTR DriverVersion);
-
- // Get the dialogs the driver supports
- // returns: S_OK - supported
- // S_FALSE - unsupported
- STDMETHODIMP get_SupportsVideoSourceDialog(void);
- STDMETHODIMP get_SupportsVideoFormatDialog(void);
- STDMETHODIMP get_SupportsVideoDisplayDialog(void);
- STDMETHODIMP get_SupportsVideoCompressionDialog(void);
-
- // Display dialogs the driver supports
- // returns: E_UNEXPECTED if the dialog is unsupported
- // E_ACCESSDENIED if the pin is active
- // and the dialog cannot be displayed
- // E_FAIL or E_OUTOFMEMORY if an error occured.
- // S_OK if the dialog displayed correctly
- STDMETHODIMP DisplayVideoSourceDialog(void)
- {return DisplayDialog(Source);}
- STDMETHODIMP DisplayVideoDisplayDialog(void)
- {return DisplayDialog(Display);}
- STDMETHODIMP DisplayVideoFormatDialog(void)
- {return DisplayDialog(Format);}
- STDMETHODIMP DisplayVideoCompressionDialog(void)
- {return DisplayDialog(Compression);}
-
- // returns the current number of microseconds per frame
- // in MicroSecondsperFrame.
- STDMETHODIMP get_RequestedMicroSecondsPerFrame (long *MicroSecondsPerFrame);
-
- // Set the number of microseconds per frame to MicroSecondsPerFrame.
- // returns: S_OK if successful
- // E_ACCESSDENIED if you can't change at the moment
- // - e.g. pin is active
- // Use GetMicroSecondsPerFrame to find the actual rate set.
- STDMETHODIMP put_RequestedMicroSecondsPerFrame (long MicroSecondsPerFrame);
-
- private:
-
- static long m_lObjectCount; // I want to make sure there is only ever
- // one CVidStream object
- // because of the other static members.
- // Only change using Interlockedxxx()
-
- private: // State shared between worker & client
- CCritSec m_cSharedState; // Lock this to access this state,
- // shared with the worker thread
-
- unsigned int m_uiDriverIndex; // the device to open when active
- HWND m_hwCapCapturing; // The AVI capture window,
- // used whilst active
- long m_lCountActual; // The number of buffers the
- // allocator is prepared to give us
- CVideoBufferList *m_plFilled; // The buffers AVICap has filled,
- // but that haven't been sent yet.
- // NB This has its own critical
- // section, so m_cSharedState does
- // not need to be locked for access
- BOOL m_fFormatDirty; // True if we need to pass on a
- // format change
- DWORD m_dwMicroSecPerFrame; // The current number of
- // microseconds between each frame
- IReferenceClock *m_pClock; // the clock to use for timestamps.
- // can be NULL. NOT CURRENTLY USED.
-
- private: // thread state. No peeking/writing by anyone else!
-
- enum ThreadState { Stopped, // will exit soon, or just started
- Paused, // generate a poster frame if entered
- // from stop
- Running // streaming data downstream
- };
- ThreadState m_ThreadState;
-
-
- private: // Capture Support
- HRESULT GetMediaType(CMediaType *pmt); // interrogate the capture
- // driver, and set pmt.
- long GetSampleSize(LPBITMAPINFOHEADER pbmi); // Calculate the sample
- // size needed.
-
- HWND CreateCaptureWindow(long lBufferCount);// Create the AVICap window
- // invisibly. Balance with
- // calls to DestroyCaptureWindow.
- // This is the function that grabs
- // resources. The filter holds no
- // resources (the capture driver)
- // until it is called
- BOOL DestroyCaptureWindow(HWND hwnd); // Destroy an AVICap window,
- // release resources
-
- // put the buffer we are given onto the filled list for delivery downstream
- static LRESULT CALLBACK VideoCallback(HWND hwnd, LPVIDEOHDR lpVHdr);
-
-
- private: // IVideoCaptureConfigure support
- enum DialogType {Source, Display, Format, Compression};
-
- HRESULT DisplayDialog(DialogType Dialog); // Manages display of
- // the dialog
- BOOL DisplayVideoDialog(HWND hwnd, DialogType Dialog); // Dialog to screen
- BOOL SupportsVideoDialog(DialogType Dialog); // Do we support
- // this dialog?
-
- WCHAR m_szName[giDriverNameStrLen]; // The driver's name
- WCHAR m_szVersion[giDriverVerStrLen]; // The driver's version
-
- BOOL m_SupportsVideoSourceDialog; // The dialogs this driver supports
- BOOL m_SupportsVideoDisplayDialog; //
- BOOL m_SupportsVideoFormatDialog; //
- BOOL m_UsesPalettes; // does the driver use a palette?
- BOOL m_SuppliesPalettes; // can the driver give us a palette?
- };
-
-
- //
- // CVideoBufferList
- //
- // This list is a place to store a buffer that AVIcap gives to us, before we can
- // pass them on to the next filter downstream.
- // Constructs a list of free buffers on construction.
- class CVideoBufferList {
-
- public:
-
- CVideoBufferList( int iBufferSize
- , CRefTime rtMilliSecPerFrame
- , CVidCap *pFilter
- , int iBuffers = 5
- );
- ~CVideoBufferList();
-
- HRESULT Add(LPVIDEOHDR lpVHdr);
- HRESULT RemoveHeadIntoSample(IMediaSample *pSample);
-
- HANDLE GetWaitHandle() {
- return (HANDLE)m_evList;
- }
-
- // *
- // * CBuffer
- // *
-
- // This is a class to store the data given to us by AVICap.
- // This must copy the data it is given, as we don't know what AVICap
- // does to its buffers.
- class CBuffer {
-
- public:
-
- CBuffer(int iBufferSize); // prepares an iBufferSize'd memory buffer
- ~CBuffer(); // frees the data buffer
-
- BYTE *GetPointer() const {return m_pData;}
- void CopyBuffer(LPVIDEOHDR lpVHdr);
- int GetSize() const {return m_iCaptureDataLength;}
- CRefTime GetCaptureTime() const {return m_rt;} // The time for this
- // sample to be presented
-
- private:
-
- BYTE *m_pData; // The data stored in this buffer
- int m_iDataLength; // m_pData's length
- int m_iCaptureDataLength; // length returned from device
-
- CRefTime m_rt; // The stream time for this sample.
- };
-
- private:
-
- CCritSec m_ListCrit; // Serialize lists
- CAMEvent m_evList; // New element on list
- CGenericList<CBuffer> m_lFilled;
- CGenericList<CBuffer> m_lFree;
-
- CVidCap *m_pFilter;
-
- BOOL m_FirstBuffer;
-
- CRefTime m_rtMilliSecPerFrame;
- CRefTime m_rtStartTime;
- CRefTime m_rtPrevEnd;
- unsigned int m_uiFramesCaptured;
- unsigned int m_uiFramesSkipped;
- unsigned int m_uiFramesDelivered;
- };