138 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			138 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | //------------------------------------------------------------------------------
 | ||
|  | // File: OutputQ.h
 | ||
|  | //
 | ||
|  | // Desc: DirectShow base classes -  defines the COutputQueue class, which
 | ||
|  | //       makes a queue of samples and sends them to an output pin.  The 
 | ||
|  | //       class will optionally send the samples to the pin directly.
 | ||
|  | //
 | ||
|  | // Copyright (c) 1992-2001 Microsoft Corporation.  All rights reserved.
 | ||
|  | //------------------------------------------------------------------------------
 | ||
|  | 
 | ||
|  | 
 | ||
|  | typedef CGenericList<IMediaSample> CSampleList; | ||
|  | 
 | ||
|  | class COutputQueue : public CCritSec | ||
|  | { | ||
|  | public: | ||
|  |     //  Constructor
 | ||
|  |     COutputQueue(IPin      *pInputPin,          //  Pin to send stuff to
 | ||
|  |                  __inout HRESULT *phr,          //  'Return code'
 | ||
|  |                  BOOL       bAuto = TRUE,       //  Ask pin if blocks
 | ||
|  |                  BOOL       bQueue = TRUE,      //  Send through queue (ignored if
 | ||
|  |                                                 //  bAuto set)
 | ||
|  |                  LONG       lBatchSize = 1,     //  Batch
 | ||
|  |                  BOOL       bBatchExact = FALSE,//  Batch exactly to BatchSize
 | ||
|  |                  LONG       lListSize =         //  Likely number in the list
 | ||
|  |                                 DEFAULTCACHE, | ||
|  |                  DWORD      dwPriority =        //  Priority of thread to create
 | ||
|  |                                 THREAD_PRIORITY_NORMAL, | ||
|  |                  bool       bFlushingOpt = false // flushing optimization
 | ||
|  |                 ); | ||
|  |     ~COutputQueue(); | ||
|  | 
 | ||
|  |     // enter flush state - discard all data
 | ||
|  |     void BeginFlush();      // Begin flushing samples
 | ||
|  | 
 | ||
|  |     // re-enable receives (pass this downstream)
 | ||
|  |     void EndFlush();        // Complete flush of samples - downstream
 | ||
|  |                             // pin guaranteed not to block at this stage
 | ||
|  | 
 | ||
|  |     void EOS();             // Call this on End of stream
 | ||
|  | 
 | ||
|  |     void SendAnyway();      // Send batched samples anyway (if bBatchExact set)
 | ||
|  | 
 | ||
|  |     void NewSegment( | ||
|  |             REFERENCE_TIME tStart, | ||
|  |             REFERENCE_TIME tStop, | ||
|  |             double dRate); | ||
|  | 
 | ||
|  |     HRESULT Receive(IMediaSample *pSample); | ||
|  | 
 | ||
|  |     // do something with these media samples
 | ||
|  |     HRESULT ReceiveMultiple ( | ||
|  |         __in_ecount(nSamples) IMediaSample **pSamples, | ||
|  |         long nSamples, | ||
|  |         __out long *nSamplesProcessed); | ||
|  | 
 | ||
|  |     void Reset();           // Reset m_hr ready for more data
 | ||
|  | 
 | ||
|  |     //  See if its idle or not
 | ||
|  |     BOOL IsIdle(); | ||
|  | 
 | ||
|  |     // give the class an event to fire after everything removed from the queue
 | ||
|  |     void SetPopEvent(HANDLE hEvent); | ||
|  | 
 | ||
|  | protected: | ||
|  |     static DWORD WINAPI InitialThreadProc(__in LPVOID pv); | ||
|  |     DWORD ThreadProc(); | ||
|  |     BOOL  IsQueued() | ||
|  |     { | ||
|  |         return m_List != NULL; | ||
|  |     }; | ||
|  | 
 | ||
|  |     //  The critical section MUST be held when this is called
 | ||
|  |     void QueueSample(IMediaSample *pSample); | ||
|  | 
 | ||
|  |     BOOL IsSpecialSample(IMediaSample *pSample) | ||
|  |     { | ||
|  |         return (DWORD_PTR)pSample > (DWORD_PTR)(LONG_PTR)(-16); | ||
|  |     }; | ||
|  | 
 | ||
|  |     //  Remove and Release() batched and queued samples
 | ||
|  |     void FreeSamples(); | ||
|  | 
 | ||
|  |     //  Notify the thread there is something to do
 | ||
|  |     void NotifyThread(); | ||
|  | 
 | ||
|  | 
 | ||
|  | protected: | ||
|  |     //  Queue 'messages'
 | ||
|  |     #define SEND_PACKET      ((IMediaSample *)(LONG_PTR)(-2))  // Send batch
 | ||
|  |     #define EOS_PACKET       ((IMediaSample *)(LONG_PTR)(-3))  // End of stream
 | ||
|  |     #define RESET_PACKET     ((IMediaSample *)(LONG_PTR)(-4))  // Reset m_hr
 | ||
|  |     #define NEW_SEGMENT      ((IMediaSample *)(LONG_PTR)(-5))  // send NewSegment
 | ||
|  | 
 | ||
|  |     // new segment packet is always followed by one of these
 | ||
|  |     struct NewSegmentPacket { | ||
|  |         REFERENCE_TIME tStart; | ||
|  |         REFERENCE_TIME tStop; | ||
|  |         double dRate; | ||
|  |     }; | ||
|  | 
 | ||
|  |     // Remember input stuff
 | ||
|  |     IPin          * const m_pPin; | ||
|  |     IMemInputPin  *       m_pInputPin; | ||
|  |     BOOL            const m_bBatchExact; | ||
|  |     LONG            const m_lBatchSize; | ||
|  | 
 | ||
|  |     CSampleList   *       m_List; | ||
|  |     HANDLE                m_hSem; | ||
|  |     CAMEvent                m_evFlushComplete; | ||
|  |     HANDLE                m_hThread; | ||
|  |     __field_ecount_opt(m_lBatchSize) IMediaSample  **      m_ppSamples; | ||
|  |     __range(0, m_lBatchSize)         LONG                  m_nBatched; | ||
|  | 
 | ||
|  |     //  Wait optimization
 | ||
|  |     LONG                  m_lWaiting; | ||
|  |     //  Flush synchronization
 | ||
|  |     BOOL                  m_bFlushing; | ||
|  | 
 | ||
|  |     // flushing optimization. some downstream filters have trouble
 | ||
|  |     // with the queue's flushing optimization. other rely on it
 | ||
|  |     BOOL                  m_bFlushed; | ||
|  |     bool                  m_bFlushingOpt; | ||
|  | 
 | ||
|  |     //  Terminate now
 | ||
|  |     BOOL                  m_bTerminate; | ||
|  | 
 | ||
|  |     //  Send anyway flag for batching
 | ||
|  |     BOOL                  m_bSendAnyway; | ||
|  | 
 | ||
|  |     //  Deferred 'return code'
 | ||
|  |     HRESULT volatile         m_hr; | ||
|  | 
 | ||
|  |     // an event that can be fired after every deliver
 | ||
|  |     HANDLE m_hEventPop; | ||
|  | }; | ||
|  | 
 |