forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			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;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 |