## COutputQueue Class

Output pins use the COutputQueue to send samples to another filter by using the local memory-based transport (that is, to input pins that support the IMemInputPin interface). COutputQueue uses IMemInputPin::ReceiveCanBlock to determine if the connected input pin has a blocking implementation of IMemInputPin::Receive. If so, all samples are queued in COutputQueue and a thread is created to pass samples from the queue to the connected input pin. If the input pin's IMemInputPin::Receive method does not block, samples are passed directly to IMemInputPin::Receive. COutputQueue can also batch samples to reduce the number of calls to the downstream pin.

COutputQueue is useful when the filter has other work to do while samples that it has already completed are being processed downstream. This occurs, for example, in a filter that can read more data off disk while data is being processed, or when it has more than one output pin and does not want to starve an output pin because IMemInputPin::Receive has no optional batching of samples.

To use this class, create one COutputQueue object for every output pin for which it will be used. This can either be created when the pin is created and deleted when the pin is disconnected, or it can be created when the pin goes active and deleted when the pin goes inactive.

The samples sent to this object by calling its COutputQueue::Receive or COutputQueue::ReceiveMultiple member function should have references added by means of IUnknown::AddRef (as they usually are if they were obtained directly from an allocator). This object then calls IUnknown::Release on all samples it receives, whether they were processed successfully or not. Note that Release is not called for special (control) samples.

Some control information, such as end of stream, needs to be queued with the data and processed once all the data has been delivered. This information is queued in the form of special control packets. COutputQueue implements a sticky HRESULT so it will not send any more data after it gets a return code that is not S_OK from the downstream ReceiveMultiple call. (A sticky state setting is one that persists even after execution of operations that would normally reset the setting.) This sticky state is reset by the EndFlush and EOS calls. However, if the sticky HRESULT is not S_OK, EOS itself is not sent downstream; the HRESULT is just reset. Because of this, if this object is not deleted when the pin goes inactive, BeginFlush and EndFlush should be called at that time to free the state.

In many ways this object acts as a proxy for the connected input pin, supporting a similar set of methods for stream control.

Protected Data Members

Name | Description
m_bBatchExact | TRUE if commands are batched; FALSE if commands are sent singly.
m_bFlushed | Flag to signify if samples have been flushed.
m_bFlushing | Flag for flushing state.
m_bSendAnyway | Flag to override batch processing.
m_bTerminate | Termination flag.
m_evFlushComplete | Event signaling that flushing has finished.
m_hSem | Handle used for signaling.
m_hr | HRESULT structure for return values; used to implement a sticky return value (one that persists even after operations that would normally change the value).
m_hThread | Worker thread handle.
m_lBatchSize | Work in batches of this batch size. Ignored if m_bBatchExact is not TRUE.
m_List | Pointer to a CSampleList object. The class CSampleList is a generic list (CGenericList) of objects of IMediaSample type. It is defined as follows:
    typedef CGenericList<IMediaSample> CSampleList;
m_lWaiting | Variable set to nonzero value when waiting for a free element.
m_nBatched | Number of samples currently batched awaiting processing.
m_pInputPin | Pointer to the connected input pin.
m_pPin | Pointer to the output pin.
m_ppSamples | Pointer to an array of batched samples.

Member Functions

Name | Description
BeginFlush | Causes all unsent samples to be discarded and sets flushing state.
COutputQueue | Constructs a COutputQueue object.
EndFlush | Finalizes flush of batched or queued samples and resets flushing state.
EOS | Queues an end-of-stream call to the connected input pin after all batched and queued samples have been passed to the input pin.
FreeSamples | Removes and releases batched and queued samples.
InitialThreadProc | Executed by the thread on thread creation.
IsIdle | Determines if the output queue is idle.
IsQueued | Determines if samples are being queued or being sent directly.
IsSpecialSample | Determines if the sample is a control sample.
NotifyThread | Notifies the thread that there is something to do.
NewSegment | Queues an IPin::NewSegment call to the connected input pin after all queued samples have been passed to the input pin.
QueueSample | Queues the prepared sample.
Receive | Passes in a single sample to send to the input pin.
ReceiveMultiple | Passes a set of samples to send to the input pin.
Reset | Resets the deferred return code m_hr to allow the output queue to be ready for more data.
SendAnyway | Frees any batches samples to be sent to the input pin.
ThreadProc | Implements the thread that sends samples downstream.

###

COutputQueue::BeginFlush

COutputQueue Class

Causes all unsent samples to be discarded and sets the flushing state.

void BeginFlush( );

##### Return Values

No return value.

##### Remarks

This member function calls BeginFlush on the connected input pin.

###

COutputQueue::COutputQueue

COutputQueue Class

Constructs a COutputQueue object.

COutputQueue(
IPin *pInputPin,
HRESULT *phr,
BOOL bAuto = TRUE,
BOOL bQueue = TRUE,
LONG lBatchSize,
BOOL bBatchExact,
LONG lListSize,
DWORD dwPriority
);

##### Parameters

pInputPin
  Connected pin to which to send data.
phr
  HRESULT return code.
bAuto
  If TRUE, the queuing mode is determined by asking the connected input pin if the pin can block (by calling IMemInputPin::ReceiveCanBlock). If FALSE, queued or direct mode is set by the bQueue parameter.
bQueue
  Determines if samples are queued for delivery by a worker thread or are being sent directly. Ignored if bAuto is TRUE.
lBatchSize
  Size of the batch (1 for no batching).
bBatchExact
  Batch exactly to lBatchSize (but use SendAnyway to override batching).
lListSize
  Likely number in the list.
dwPriority
  Priority given to the created thread.

##### Return Values

No return value.

##### Remarks

The phr parameter should be updated only to report errors. Usually bAuto will be TRUE. In that case, the constructor calls IMemInputPin::ReceiveCanBlock on the downstream pin to determine whether to create a thread, and so to send samples asynchronously. If bAuto is FALSE, a thread is created if, and only if, bQueue is TRUE.

If the batch size is not 1, data is not sent until lBatchSize samples have been received by the object. The exceptions are that, if fewer than lBatchSize samples are passed to COutputQueue::Receive or COutputQueue::ReceiveMultiple in this object and bBatchExact is FALSE, the samples will be sent anyway.

If bBatchExact is TRUE, the COutputQueue::SendAnyway member function will cause the samples to be sent to the thread (if the thread is created).

###

COutputQueue::EndFlush

COutputQueue Class

Finalizes flush of batched or queued samples and resets the flushing state.

void EndFlush( );

##### Return Values

No return value.

##### Remarks

The downstream pin is guaranteed not to block at this stage.

###

COutputQueue::EOS

COutputQueue Class

Queues an end-of-stream call to the connected input pin after all batched and queued samples have been passed to the input pin.

void EOS( );

##### Return Values

No return value.

##### Remarks

The end-of-stream call is queued as a special control packet when in a queued mode. This member function does not actually send an end-of-stream packet if the m_hr HRESULT value is not S_OK when it is time to make the call.

###

COutputQueue::FreeSamples

COutputQueue Class

Removes and releases batched and queued samples.

void FreeSamples( );

##### Return Values

No return value.

###

COutputQueue::InitialThreadProc

COutputQueue Class

Implements the static member function that the thread executes on thread creation.

static DWORD WINAPI InitialThreadProc(
LPVOID pv
);

##### Parameters

pv
  The this pointer for the COutputQueue object.

##### Return Values

The derived class defines the meaning of the return value.

##### Remarks

On thread creation, the worker thread executes this static function with a pointer to the COutputQueue object as the parameter. This function simply calls the COutputQueue::ThreadProc member function of that object (that is, the function pointed to by pv).

###

COutputQueue::IsIdle

COutputQueue Class

Determines if the output pin is idle.

BOOL IsIdle( );

##### Return Values

Returns TRUE if no threads are in the queue, all data has been sent, and nothing is in the batch. Returns FALSE otherwise.

###

COutputQueue::IsQueued

COutputQueue Class

Determines if the COutputQueue object is in queued or direct mode.

BOOL IsQueued( );

##### Return Values

Returns one of the following values.

Value | Meaning
TRUE | In queued mode. Samples are delivered asynchronously by a worker thread.
FALSE | In direct mode. Receive calls are passed synchronously to the input pin.

###

COutputQueue::IsSpecialSample

COutputQueue Class

Determines if a sample is one of the special control samples (containing no data).

BOOL IsSpecialSample(
IMediaSample *pSample
);

##### Parameters

pSample
  Pointer to the sample to be passed to the connected input pin.

##### Return Values

Returns one of the following values.

Value | Meaning
TRUE | pSample is a special control sample.
FALSE | pSample is an IMediaSample interface.

##### Remarks

Special control samples are queued in line with the data by methods (such as COutputQueue::EOS) that require processing once all queued data has been delivered. The COutputQueue::ThreadProc member function detects these special samples on the queue by using IsSpecialSample and processes them appropriately.

A special sample is one of following types and contains no media data.

EOS_PACKET
NEW_SEGMENT
RESET_PACKET
SEND_PACKET

Special control samples are relevant only if you plan to change or extend the default base class implementation of COutputQueue in a derived class. Normal use of the COutputQueue class does not require the use of control samples.

###

COutputQueue::NewSegment

COutputQueue Class

Queues an IPin::NewSegment call to the connected input pin after all queued samples have been passed to the input pin.

HRESULT NewSegment(
REFERENCE_TIME tStart,
REFERENCE_TIME tStop,
double dRate
);

##### Parameters

tStart
  [in] Start time of the segment.
tStop
  [in] Stop time of the segment.
dRate
  [in] Rate of the segment.

##### Return Values

Returns an HRESULT value.

##### Remarks

This member function calls the IPin::NewSegment method on the output pin once all previous data has been delivered. Like COutputQueue::EOS, the COutputQueue::NewSegment call and its parameters are queued as a special control sample if the COutputQueue object is in queued mode, and the IPin::NewSegment method is called from the worker thread in COutputQueue::ThreadProc.

Special control samples, as implemented by this member function, are only relevant if you plan to change or extend the default base class implementation of COutputQueue in a derived class. Normal use of the COutputQueue class does not require the use of control samples.

This member function allows filters that process buffers containing more than one sample to delineate the rendering of the samples between start and stop time, as indicated by the tStart and tStop parameters.

COutputQueue::NewSegment is intended to be implemented on an input pin. A connected output pin on the upstream filter calls this member function after completing delivery of previous data and before calling IMemInputPin::Receive with any new data. It indicates that all data arriving after this call is part of a segment delineated by the parameters.

###

COutputQueue::NotifyThread

COutputQueue Class

Notifies the thread that there is data on the queue to process.

void NotifyThread( );

##### Return Values

No return value.

##### Remarks

The critical section must be held when this is called.

###

COutputQueue::QueueSample

COutputQueue Class

Queues a sample.

void QueueSample(
IMediaSample *pSample
);

##### Parameters

pSample
  Pointer to the sample to be passed to the connected input pin.

##### Return Values

No return value.

##### Remarks

The critical section must be held when this is called.

###

COutputQueue::Receive

COutputQueue Class

Passes in a single sample to send to the input pin.

HRESULT Receive(
IMediaSample *pSample
);

##### Parameters

pSample
  Pointer to the sample to be passed to the connected input pin.

##### Return Values

Returns an HRESULT value, which can include the following values, or others.

Value | Meaning
S_FALSE | End of stream detected before or while processing sample; any further samples will be discarded and this value returned.
Other | An error occurred before or while processing sample; any further samples will be discarded and this value returned.
S_OK | Queued successfully or passed to the connected input pin if there is no queue.

##### Remarks

If the sticky return code (m_hr) is not S_OK, the sample is not sent and the sticky return code is returned. (A sticky return code is one that persists even after operations that would normally change its value.) The samples are all released (by means of Release) after processing, regardless of whether the processing was successful.

###

COutputQueue::ReceiveMultiple

COutputQueue Class

Passes a set of samples to send to the input pin.

HRESULT ReceiveMultiple (
IMediaSample **ppSamples,
long nSamples,
long *nSamplesProcessed
);

##### Parameters

ppSamples
  Pointer to the set of samples to be passed to the connected input pin.
nSamples
  Number of samples pointed to by ppSamples.
nSamplesProcessed
  Updated to be the number of samples processed.

##### Return Values

Returns an HRESULT value, which can include the following values, or others.

Value | Meaning
Other | An error occurred before or while processing sample; any further samples will be discarded and this value returned.
S_FALSE | End of stream detected before or while processing sample; any further samples will be discarded and this value returned.
S_OK | Queued successfully or passed to the connected input pin if there is no queue.

##### Remarks

If the sticky return code is not S_OK, the sample is not sent and the sticky return code is returned. (A sticky return code is one that persists even after operations that would normally change its value.) The samples are all released (by means of Release) after processing, regardless of whether the processing was successful.

###

COutputQueue::Reset

COutputQueue Class

Resets the deferred return code m_hr to ready the output queue for more data.

void Reset( );

##### Return Values

No return value.

##### Remarks

The sticky return code m_hr is set to S_OK if data is queued; otherwise, this function queues the sample and notifies the thread. (A sticky return code is one that persists even after operations that would normally change its value.)

###

COutputQueue::SendAnyway

COutputQueue Class

If bBatchExact was specified on construction, frees batched samples so they can be sent to the input pin.

void SendAnyway( );

##### Return Values

No return value.

###

COutputQueue::ThreadProc

COutputQueue Class

Implements the thread that sends samples downstream.

DWORD ThreadProc( );

##### Return Values

Returns zero when DirectShow terminates the thread.

##### Remarks

This is the main thread procedure for the class, which is called from COutputQueue::InitialThreadProc. It sends a sample or a batch of samples to the connected input pin (depending on the m_bBatchExact, m_nBatched, and m_lBatchSize data members) when conditions are met. Otherwise, it increments the m_lWaiting data member, while holding the critical section and waits for m_hSem to be set (not holding the critical section) to continue.

© 1997 Microsoft Corporation. All rights reserved. Terms of Use.