138 lines
4.6 KiB
C++
138 lines
4.6 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;
|
|
};
|
|
|