home *** CD-ROM | disk | FTP | other *** search
/ The Net: Ultimate Internet Guide / WWLCD1.ISO / mac / SiteBldr / AMOVIE / SDK / _SETUP / COMMON.Z / vidcap.h < prev    next >
Encoding:
Text File  |  1996-04-15  |  12.1 KB  |  310 lines

  1. //==========================================================================;
  2. //
  3. //  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  4. //  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  5. //  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  6. //  PURPOSE.
  7. //
  8. //  Copyright (c) 1992 - 1996  Microsoft Corporation.  All Rights Reserved.
  9. //
  10. //--------------------------------------------------------------------------;
  11.  
  12. //
  13. //  Video capture stream source filter
  14. //
  15.  
  16. // - Uses the CSource/CSourceStream classes to create a video capture filter.
  17. // - Uses the AVICap capXXX macros to capture from the first driver it finds.
  18.  
  19. // CLSID_VidCap
  20. // {fd501040-8ebe-11ce-8183-00aa00577da1}
  21. DEFINE_GUID(CLSID_VidCap,
  22. 0xfd501040, 0x8ebe, 0x11ce, 0x81, 0x83, 0x00, 0xaa, 0x00, 0x57, 0x7d, 0xa1);
  23.  
  24. // The buffer sizes required for driver name and version strings
  25. const int giDriverNameStrLen = 80;
  26. const int giDriverVerStrLen  = 40;
  27.  
  28. class CVidStream;       // manages the output stream & pin
  29. class CVideoBufferList; // A place to store filled buffers before we can send
  30.                         // them downstream
  31.  
  32.  
  33. //
  34. // CVidCap
  35. //
  36. // The VidCap filter object. Provides the IFilter & IMediaFilter interfaces.
  37. class CVidCap : public CSource {
  38.  
  39. public:
  40.  
  41.     // Construct a VidCap filter
  42.     static CUnknown *CreateInstance(LPUNKNOWN lpunk, HRESULT *phr);
  43.  
  44.     CCritSec m_cStateLock;      // Lock this when a function accesses
  45.                                 // the filter state.
  46.                                 // Generally _all_ functions, since access to this
  47.                                 // filter will be by multiple threads.
  48.  
  49.     // overide the Run & Pause methods so that I can notify the pin
  50.     // of the state it should move to
  51.     STDMETHODIMP Run(REFERENCE_TIME tStart);
  52.     STDMETHODIMP Pause(void);
  53.  
  54.     // Stop will tell the pin the state it is moving from
  55.     STDMETHODIMP Stop(void);
  56.  
  57.     // setup helper
  58.     LPAMOVIESETUP_FILTER GetSetupData();
  59.  
  60. private:
  61.  
  62.     // During construction we create the single CVidStream object that provides the
  63.     // output pin.
  64.     CVidCap(TCHAR *, LPUNKNOWN, HRESULT *);
  65.     ~CVidCap();
  66.  
  67. };
  68.  
  69.  
  70. //
  71. // CVidStream
  72. //
  73. // Manages the output pin and the video capture device.
  74. // Provides an implementation for IVideoCaptureConfigure, to allow the user
  75. // to select formats, etc.
  76. class CVidStream : public CSourceStream, IVideoCaptureConfigure {
  77.  
  78. public:
  79.  
  80.     CVidStream( TCHAR           *pObjectName
  81.               , HRESULT         *phr
  82.               , CVidCap         *pParentFilter
  83.               , unsigned int    uiDriverIndex
  84.               , LPCWSTR         pPinName
  85.               );
  86.  
  87.     ~CVidStream();
  88.  
  89.     //
  90.     //  --- CSourceStream implementation ---
  91.     //
  92. public:
  93.  
  94.     HRESULT DecideBufferSize(IMemAllocator *pAlloc,
  95.                              ALLOCATOR_PROPERTIES *pProperties);
  96.  
  97.     //
  98.     // --- Worker Thread fn's ---
  99.     //
  100.     HRESULT OnThreadCreate(void);
  101.     HRESULT OnThreadDestroy(void);
  102.  
  103.     HRESULT DoBufferProcessingLoop(void);
  104.     HRESULT FillBuffer(IMediaSample *pSamp);
  105.  
  106.     HRESULT Active(FILTER_STATE FromState, FILTER_STATE ToState);
  107.     HRESULT Inactive(FILTER_STATE OldState);
  108.  
  109.     // Override to handle quality messages
  110.     STDMETHODIMP Notify(IFilter * pSender, Quality q);
  111.  
  112.  
  113.     //
  114.     // --- IVideoCaptureConfigure implementation ---
  115.     //
  116. public:
  117.  
  118.     DECLARE_IUNKNOWN;
  119.  
  120.     // reveals the IVideoCaptureConfigure interface
  121.     STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv);
  122.  
  123.     // Get the drivers details
  124.     STDMETHODIMP get_DriverName(BSTR DriverName);
  125.     STDMETHODIMP get_DriverVersion(BSTR DriverVersion);
  126.  
  127.     // Get the dialogs the driver supports
  128.     // returns: S_OK    - supported
  129.     //          S_FALSE - unsupported
  130.     STDMETHODIMP get_SupportsVideoSourceDialog(void);
  131.     STDMETHODIMP get_SupportsVideoFormatDialog(void);
  132.     STDMETHODIMP get_SupportsVideoDisplayDialog(void);
  133.     STDMETHODIMP get_SupportsVideoCompressionDialog(void);
  134.  
  135.     // Display dialogs the driver supports
  136.     // returns: E_UNEXPECTED    if the dialog is unsupported
  137.     //          E_ACCESSDENIED  if the pin is active
  138.     //                          and the dialog cannot be displayed
  139.     //          E_FAIL or E_OUTOFMEMORY if an error occured.
  140.     //          S_OK            if the dialog displayed correctly
  141.     STDMETHODIMP DisplayVideoSourceDialog(void)
  142.                                     {return DisplayDialog(Source);}
  143.     STDMETHODIMP DisplayVideoDisplayDialog(void)
  144.                                     {return DisplayDialog(Display);}
  145.     STDMETHODIMP DisplayVideoFormatDialog(void)
  146.                                     {return DisplayDialog(Format);}
  147.     STDMETHODIMP DisplayVideoCompressionDialog(void)
  148.                                     {return DisplayDialog(Compression);}
  149.  
  150.     // returns the current number of microseconds per frame
  151.     // in MicroSecondsperFrame.
  152.     STDMETHODIMP get_RequestedMicroSecondsPerFrame (long *MicroSecondsPerFrame);
  153.  
  154.     // Set the number of microseconds per frame to MicroSecondsPerFrame.
  155.     // returns: S_OK if successful
  156.     //          E_ACCESSDENIED if you can't change at the moment
  157.     //                         - e.g. pin is active
  158.     // Use GetMicroSecondsPerFrame to find the actual rate set.
  159.     STDMETHODIMP put_RequestedMicroSecondsPerFrame (long MicroSecondsPerFrame);
  160.  
  161. private:
  162.  
  163.     static long         m_lObjectCount; // I want to make sure there is only ever
  164.                                         // one CVidStream object
  165.                                         // because of the other static members.
  166.                                         // Only change using Interlockedxxx()
  167.  
  168. private:        // State shared between worker & client
  169.     CCritSec            m_cSharedState;         // Lock this to access this state,
  170.                                                 // shared with the worker thread
  171.  
  172.     unsigned int        m_uiDriverIndex;        // the device to open when active
  173.     HWND                m_hwCapCapturing;       // The AVI capture window,
  174.                                                 // used whilst active
  175.     long                m_lCountActual;         // The number of buffers the
  176.                                                 // allocator is prepared to give us
  177.     CVideoBufferList    *m_plFilled;            // The buffers AVICap has filled,
  178.                                                 // but that haven't been sent yet.
  179.                                                 // NB This has its own critical
  180.                                                 // section, so m_cSharedState does
  181.                                                 // not need to be locked for access
  182.     BOOL                m_fFormatDirty;         // True if we need to pass on a
  183.                                                 // format change
  184.     DWORD               m_dwMicroSecPerFrame;   // The current number of
  185.                                                 // microseconds between each frame
  186.     IReferenceClock     *m_pClock;              // the clock to use for timestamps.
  187.                                                 // can be NULL.  NOT CURRENTLY USED.
  188.  
  189. private:        // thread state. No peeking/writing by anyone else!
  190.  
  191.     enum ThreadState { Stopped,         // will exit soon, or just started
  192.                        Paused,          // generate a poster frame if entered
  193.                                         // from stop
  194.                        Running          // streaming data downstream
  195.                      };
  196.     ThreadState m_ThreadState;
  197.  
  198.  
  199. private:        // Capture Support
  200.     HRESULT GetMediaType(CMediaType *pmt);              // interrogate the capture
  201.                                                         // driver, and set pmt.
  202.     long    GetSampleSize(LPBITMAPINFOHEADER pbmi);     // Calculate the sample
  203.                                                         // size needed.
  204.  
  205.     HWND CreateCaptureWindow(long lBufferCount);// Create the AVICap window
  206.                                                 // invisibly. Balance with
  207.                                                 // calls to DestroyCaptureWindow.
  208.                                                 // This is the function that grabs
  209.                                                 // resources. The filter holds no
  210.                                                 // resources (the capture driver)
  211.                                                 // until it is called
  212.     BOOL DestroyCaptureWindow(HWND hwnd);       // Destroy an AVICap window,
  213.                                                 // release resources
  214.  
  215.     // put the buffer we are given onto the filled list for delivery downstream
  216.     static LRESULT CALLBACK VideoCallback(HWND hwnd, LPVIDEOHDR lpVHdr);
  217.  
  218.  
  219. private:        // IVideoCaptureConfigure support
  220.     enum DialogType {Source, Display, Format, Compression};
  221.  
  222.     HRESULT DisplayDialog(DialogType Dialog);                 // Manages display of
  223.                                                               // the dialog
  224.     BOOL    DisplayVideoDialog(HWND hwnd, DialogType Dialog); // Dialog to screen
  225.     BOOL    SupportsVideoDialog(DialogType Dialog);           // Do we support
  226.                                                               // this dialog?
  227.  
  228.     WCHAR m_szName[giDriverNameStrLen];         // The driver's name
  229.     WCHAR m_szVersion[giDriverVerStrLen];       // The driver's version
  230.  
  231.     BOOL m_SupportsVideoSourceDialog;           // The dialogs this driver supports
  232.     BOOL m_SupportsVideoDisplayDialog;          //
  233.     BOOL m_SupportsVideoFormatDialog;           //
  234.     BOOL m_UsesPalettes;            // does the driver use a palette?
  235.     BOOL m_SuppliesPalettes;            // can the driver give us a palette?
  236. };
  237.  
  238.  
  239. //
  240. // CVideoBufferList
  241. //
  242. // This list is a place to store a buffer that AVIcap gives to us, before we can
  243. // pass them on to the next filter downstream.
  244. // Constructs a list of free buffers on construction.
  245. class CVideoBufferList {
  246.  
  247. public:
  248.  
  249.     CVideoBufferList( int iBufferSize
  250.                     , CRefTime rtMilliSecPerFrame
  251.                     , CVidCap *pFilter
  252.                     , int iBuffers = 5
  253.                     );
  254.     ~CVideoBufferList();
  255.  
  256.     HRESULT Add(LPVIDEOHDR lpVHdr);
  257.     HRESULT RemoveHeadIntoSample(IMediaSample *pSample);
  258.  
  259.     HANDLE GetWaitHandle() {
  260.         return (HANDLE)m_evList;
  261.     }
  262.  
  263.     // *
  264.     // * CBuffer
  265.     // *
  266.  
  267.     // This is a class to store the data given to us by AVICap.
  268.     // This must copy the data it is given, as we don't know what AVICap
  269.     // does to its buffers.
  270.     class CBuffer {
  271.  
  272.     public:
  273.  
  274.         CBuffer(int iBufferSize);       // prepares an iBufferSize'd memory buffer
  275.         ~CBuffer();                     // frees the data buffer
  276.  
  277.         BYTE            *GetPointer() const {return m_pData;}
  278.         void            CopyBuffer(LPVIDEOHDR lpVHdr);
  279.         int             GetSize() const {return m_iCaptureDataLength;}
  280.         CRefTime        GetCaptureTime() const {return m_rt;}   // The time for this
  281.                                                           // sample to be presented
  282.  
  283.     private:
  284.  
  285.         BYTE            *m_pData;       // The data stored in this buffer
  286.         int             m_iDataLength;  // m_pData's length
  287.     int             m_iCaptureDataLength;  // length returned from device
  288.  
  289.         CRefTime        m_rt;           // The stream time for this sample.
  290.     };
  291.  
  292. private:
  293.  
  294.     CCritSec                    m_ListCrit;     // Serialize lists
  295.     CAMEvent                      m_evList;       // New element on list
  296.     CGenericList<CBuffer>       m_lFilled;
  297.     CGenericList<CBuffer>       m_lFree;
  298.  
  299.     CVidCap                     *m_pFilter;
  300.  
  301.     BOOL                        m_FirstBuffer;
  302.  
  303.     CRefTime                    m_rtMilliSecPerFrame;
  304.     CRefTime                    m_rtStartTime;
  305.     CRefTime                    m_rtPrevEnd;
  306.     unsigned int                m_uiFramesCaptured;
  307.     unsigned int                m_uiFramesSkipped;
  308.     unsigned int                m_uiFramesDelivered;
  309. };
  310.