Microsoft DirectX 8.0

CDynamicOutputPin Class

Implements an output pin that supports dynamic reconnections and format changes.

Declaration: Amfilter.h

This class derives from the CBaseOutputPin class and implements the IPinFlowControl interface. It supports several operations that are important for dynamic graph building:

The pin has three possible states: blocked, unblocked, and pending. In the pending state, the pin is waiting for some operation to complete on another thread, before the pin switches to the blocked state. While the pin is blocked, the filter cannot deliver data through the pin, or change the pin's connection.

To coordinate among multiple threads, the owning filter must follow certain rules. (For more information about threads in the filter graph, see Threads and Critical Sections.) First, the streaming thread must always call the StartUsingOutputPin method before it calls any of the following methods:

Afterward, it must call the StopUsingOutputPin method.

Second, the application thread must not call any of the methods in the previous list. Third, the streaming thread must not call the class methods that block or unblock the pin. These methods are: Block, SynchronousBlockOutputPin, AsynchronousBlockOutputPin, and UnblockOutputPin.

These rules ensure that the application thread cannot block the pin while the streaming thread is using it, and vice versa. After the streaming thread has called StartUsingOutputPin, the pin will not block until the streaming thread calls StopUsingOutputPin. Conversely, if the pin is blocked, StartUsingOutputPin waits until the pin is unblocked.

To avoid forgetting to call StopUsingOutputPin, you can use the CAutoUsingOutputPin class. It calls StopUsingOutputPin automatically when it goes out of scope.

When the owning filter joins or leaveds the filter graph (in its IBaseFilter::JoinFilterGraph method), it must call the pin's SetConfigInfo method.

Protected Member Variables
m_BlockStateLockCritical section that protects the blocking state.
m_hUnblockOutputPinEventEvent that is signaled when the pin is not blocked.
m_hNotifyCallerPinBlockedEventEvent that is signaled when the pin successfully blocks, or the user cancels a pending block.
m_BlockStateBlocking state.
m_dwBlockCallerThreadIDThe identifier of the thread that last called the IPinFlowControl::Block method on this pin.
m_dwNumOutstandingOutputPinUsersNumber of streaming threads using this pin.
m_hStopEventEvent that is signaled when the filter stops or the pin flushes data.
m_pGraphConfigPointer to the IGraphConfig interface for performing dynamic reconnections.
m_bPinUsesReadOnlyAllocatorFlag that specifies whether samples from the pin's allocator are read-only.
Protected Methods
SynchronousBlockOutputPinBlocks the pin; does not return until the pin is blocked.
AsynchronousBlockOutputPinBlocks the pin; might return before the pin is blocked.
UnblockOutputPinUnblocks the pin.
BlockOutputPinBlocks the pin.
WaitEventWaits until the specified event is signaled.
Public Methods
CDynamicOutputPinConstructor method.
~CDynamicOutputPinDestructor method.
SetConfigInfoSpecifies the IGraphConfig pointer and the stop event.
DeliverBeginFlushRequests the connected input pin to begin a flush operation.
DeliverEndFlushRequests the connected input pin to end a flush operation.
InactiveNotifies the pin that the filter has stopped.
ActiveNotifies the pin that the filter is now active.
CompleteConnectCompletes a connection to an input pin. Virtual.
StartUsingOutputPinObtains access to the pin for a streaming operation. Virtual.
StopUsingOutputPinReleases access to the pin after a streaming operation. Virtual.
StreamingThreadUsingOutputPinDetermines whether any thread is performing a streaming operation on the pin. Virtual.
ChangeOutputFormatDynamically changes the media type for the connection, and delivers new segment information.
ChangeMediaTypeDynamically changes the media type for the connection.
DynamicReconnectPerforms a dynamic reconnection with a new media type.
IPin Methods
DisconnectBreaks the current pin connection.
IPinFlowControl Methods
BlockBlocks or unblocks the flow of data from the pin.

CDynamicOutputPin.m_BlockStateLock

CDynamicOutputPin Class

Critical section that protects the blocking state.

Syntax

CCritSec m_BlockStateLock;

Remarks

Hold this critical section before using any of the following member variables:

CDynamicOutputPin.m_hUnblockOutputPinEvent

CDynamicOutputPin Class

Event that is signaled when the pin is not blocked.

Syntax

HANDLE m_hUnblockOutputPinEvent;

CDynamicOutputPin.m_hNotifyCallerPinBlockedEvent

CDynamicOutputPin Class

Event that is signaled when the pin successfully blocks, or the user cancels a pending block.

Syntax

HANDLE m_hNotifyCallerPinBlockedEvent;

Remarks

Before accessing this variable, hold the m_BlockStateLock critical section.

CDynamicOutputPin.m_BlockState

CDynamicOutputPin Class

Blocking state.

Syntax

BLOCK_STATE m_BlockState;

Remarks

The following states are defined:

Before accessing this variable, hold the m_BlockStateLock critical section.

CDynamicOutputPin.m_dwBlockCallerThreadID

CDynamicOutputPin Class

The identifier of the thread that last called the IPinFlowControl::Block method on this pin. This member variable is only valid while the pin is blocked.

Syntax

DWORD m_dwBlockCallerThreadID;

Remarks

Before accessing this variable, hold the m_BlockStateLock critical section.

CDynamicOutputPin.m_dwNumOutstandingOutputPinUsers

CDynamicOutputPin Class

Number of streaming threads using this pin.

Syntax

DWORD m_dwNumOutstandingOutputPinUsers;

Remarks

The StartUsingOutputPin method increments this variable, and the StopUsingOutputPin method decrements it. When the value is greater than zero, some thread is using this pin to stream data or to change the connection type. The pin cannot be blocked while this is the case.

Before accessing this variable, hold the m_BlockStateLock critical section.

See Also

StreamingThreadUsingOutputPin

CDynamicOutputPin.m_hStopEvent

CDynamicOutputPin Class

Event that is signaled when the filter stops or the pin flushes data.

Syntax

HANDLE m_hStopEvent;

CDynamicOutputPin.m_pGraphConfig

CDynamicOutputPin Class

Pointer to the IGraphConfig interface for performing dynamic reconnections.

Syntax

IGraphConfig* m_pGraphConfig;

CDynamicOutputPin.m_bPinUsesReadOnlyAllocator

CDynamicOutputPin Class

Flag that specifies whether samples from the pin's allocator are read-only. If the value is TRUE, the sample are read-only. The default value is FALSE.

Syntax

BOOL m_bPinUsesReadOnlyAllocator;

CDynamicOutputPin::Active

CDynamicOutputPin Class

Notifies the pin that the filter is now active.

Syntax

HRESULT Active(void);

Return Value

Returns an HRESULT value. Possible values include those shown in the following table.

S_OKSuccess.
E_FAILFailure. SetConfigInfo was not called.

Remarks

This method overrides the CBaseOutputPin::Active method. It resets the m_hStopEvent event. If the owning filter has not called SetConfigInfo, this method returns E_FAIL.

CDynamicOutputPin::AsynchronousBlockOutputPin

CDynamicOutputPin Class

Blocks the pin; might return before the pin is blocked.

Syntax

HRESULT AsynchronousBlockOutputPin(
    HANDLE hNotifyCallerPinBlockedEvent
);

Parameters

hNotifyCallerPinBlockedEvent
Handle to an event. The event is signaled when the output pin is blocked, or if the caller cancels the block operation.

Return Value

Returns an HRESULT value. Possible values include those shown in the following table.

S_OKSuccess.
VFW_E_PIN_ALREADY_BLOCKEDPin is already blocked on another thread.
VFW_E_PIN_ALREADY_BLOCKED_ON_THIS_THREADPin is already blocked on the calling thread.

Remarks

Do not call this method from the streaming thread.

If no streaming thread is using the pin, this method immediately blocks the pin. Otherwise, it sets the pin status to "pending" and returns. When the streaming operation completes, the streaming thread calls the StopUsingOutputPin method, which blocks the pin and signals the hNotifyCallerPinBlockedEvent event. To cancel a pending block, call the UnblockOutputPin method.

CDynamicOutputPin::Block

CDynamicOutputPin Class

Blocks or unblocks the flow of data from the pin. Implements the IPinFlowControl::Block method.

Syntax

HRESULT Block(
    DWORD dwBlockFlags, 
    HANDLE hEvent
);

Parameters

dwBlockFlags
Flag that indicates whether to block or unblock the pin. Must be one of the following values:
  • Zero: Unblock data flow from the pin.
  • AM_PIN_FLOW_CONTROL_BLOCK: Block data flow from the pin.
hEvent
Handle to an event object, or NULL.

Return Value

Returns an HRESULT value. Possible values include those shown in the following table.

S_FALSEPin is already unblocked.
S_OKSuccess.
E_INVALIDARGInvalid argument.
VFW_E_PIN_ALREADY_BLOCKEDPin is already blocked on another thread.
VFW_E_PIN_ALREADY_BLOCKED_ON_THIS_THREADPin is already blocked on the calling thread.

Remarks

For more information about this method, see IPinFlowControl::Block. Internally, this method calls one of the following protected methods:

Unblocking is always performed synchronously.

CDynamicOutputPin::BlockOutputPin

CDynamicOutputPin Class

Blocks the pin. While the pin is blocked, the StartUsingOutputPin method waits for the pin to become unblocked. The blocked state prevents the output pin from delivering samples, changing its output format, or reconnecting itself.

Syntax

void BlockOutputPin(void);

Remarks

Before calling this method, hold the m_BlockStateLock critical section. Do not call this method if a streaming thread is using the pin, either to deliver data or to change the connection. To check whether a streaming thread is using the pin, call the StreamingThreadUsingOutputPin method.

CDynamicOutputPin::CDynamicOutputPin

CDynamicOutputPin Class

Constructor method.

Syntax

CDynamicOutputPin(
    TCHAR *pObjectName,
    CBaseFilter *pFilter,
    CCritSec *pLock,
    HRESULT *phr,
    LPCWSTR pName
);

Parameters

pObjectName
Pointer to a string containing the name of the object. For more information, see CBaseObject.
pFilter
Pointer to the filter that created this pin.
pLock
Pointer to a CCritSec lock, used to serialize state changes. Use the same critical section as the filter lock, CBaseFilter.m_pLock
phr
Pointer to a variable that receives an HRESULT value indicating the success or failure of the method. Initialize the value to S_OK before creating the object. The value is changed only if an error occurs.
pName
Pointer to a Unicode™ string containing the pin identifier. For more information, see IPin::QueryId.

CDynamicOutputPin::~CDynamicOutputPin

CDynamicOutputPin Class

Destructor method.

Syntax

~CDynamicOutputPin(void);

CDynamicOutputPin::ChangeMediaType

CDynamicOutputPin Class

Dynamically changes the media type for the connection. The change can occur while the filter graph is running. Once this method is called, samples with the old media type cannot be delivered. The caller must ensure that no old samples are pending.

Syntax

HRESULT ChangeMediaType(
    const CMediaType *pmt
);

Parameters

pmt
Pointer to an AM_MEDIA_TYPE structure that specifies the media type.

Return Value

Returns an HRESULT value. Possible values include those shown in the following table.

S_OKSuccess.
E_FAILFailure. Possibly the owning filter did not call SetConfigInfo.
VFW_E_NOT_CONNECTEDThe pin is not connected.

Remarks

Call the StartUsingOutputPin method before calling this method.

This method first checks whether the downstream input pin can accept the new format without reconnecting. It queries the input pin for the IPinConnection interface. If the input pin supports IPinConnection, the method calls the IPinConnection::DynamicQueryAccept method with the proposed media type. If the input pin accepts the new media type, the method calls the IPin::ReceiveConnection method and renegotiates the allocator requirements.

On the other hand, if the downstream pin does not support IPinConnection, or if it rejects the new media type, the method calls the DynamicReconnect method to perform a dynamic reconnection.

CDynamicOutputPin::ChangeOutputFormat

CDynamicOutputPin Class

Dynamically changes the media type for the connection, and delivers new segment information. The change can occur while the filter graph is running. Once this method is called, samples with the old media type cannot be delivered. The caller must ensure that no old samples are pending.

Syntax

HRESULT ChangeOutputFormat(
    const AM_MEDIA_TYPE *pmt,
    REFERENCE_TIME tSegmentStart,
    REFERENCE_TIME tSegmentStop,
    double dSegmentRate
);

Parameters

pmt
Pointer to an AM_MEDIA_TYPE structure that specifies the media type.
tSegmentStart
Start time of the segment.
tSegmentStop
Stop time of the segment.
dSegmentRate
Segment rate.

Return Value

Returns an HRESULT value. Possible values include those shown in the following table.

S_OKSuccess.
E_FAILFailure. Possibly the owning filter did not call SetConfigInfo.
VFW_E_NOT_CONNECTEDThe pin is not connected.

Remarks

This method changes the format type while the filter is running. If the downstream pin accepts the new format, no reconnection is necessary. Otherwise, the method attempts to reconnect the pin. If the method successfully changes the format, it delivers the new segment information. This method calls the ChangeMediaType method to perform the format change.

You must call the StartUsingOutputPin method before calling this method.

CDynamicOutputPin::CompleteConnect

CDynamicOutputPin Class

Completes a connection to an input pin.

Syntax

virtual HRESULT CompleteConnect(
    IPin *pReceivePin
);

Parameters

pReceivePin
Pointer to the input pin's IPin interface.

Return Value

Returns S_OK if successful, or an HRESULT value indicating the cause of the failure.

Remarks

This method overrides the CBaseOutputPin::CompleteConnect method. To support dynamic reconnections, this method commits the allocator if the filter is active. In the base class, connections can occur only when the filter is stopped, so the allocator is always committed in the CBaseOutputPin::Active method.

CDynamicOutputPin::DeliverBeginFlush

CDynamicOutputPin Class

Requests the connected input pin to begin a flush operation.

Syntax

HRESULT DeliverBeginFlush(void);

Return Value

Returns S_OK if successful, or an HRESULT value indicating the cause of the failure.

Remarks

This method overrides the CBaseOutputPin::DeliverBeginFlush method. It sets the m_hStopEvent event.

CDynamicOutputPin::DeliverEndFlush

CDynamicOutputPin Class

Requests the connected input pin to end a flush operation.

Syntax

HRESULT DeliverEndFlush(void);

Return Value

Returns S_OK if successful, or an HRESULT value indicating the cause of the failure.

Remarks

This method overrides the CBaseOutputPin::DeliverEndFlush method. It resets the m_hStopEvent event.

CDynamicOutputPin::Disconnect

CDynamicOutputPin Class

Breaks the current pin connection. Implements the IPin::Disconnect method.

Syntax

HRESULT Disconnect(void);

Return Value

Returns an HRESULT value. Possible values include those shown in the following table.

S_FALSEThe pin was not connected.
S_OKSuccess.

Remarks

This method overrides the CBasePin::Disconnect method to enable disconnecting while the filter is active.

CDynamicOutputPin::DynamicReconnect

CDynamicOutputPin Class

Performs a dynamic reconnection with a new media type. The reconnection can occur while the filter graph is running.

Syntax

HRESULT DynamicReconnect(
    const CMediaType *pmt
);

Parameters

pmt
Pointer to an AM_MEDIA_TYPE structure that specifies the media type.

Return Value

Returns an HRESULT value. Possible values include those shown in the following table.

S_OKSuccess.
E_FAILFailure. Possibly the owning filter did not call the SetConfigInfo method.

Remarks

This method must be called from the same thread that delivers data to the pin. Once this method is called, samples with the old media type cannot be delivered. The caller must ensure that no old samples are pending.

Call StartUsingOutputPin before calling this method.

CDynamicOutputPin::Inactive

CDynamicOutputPin Class

Notifies the pin that the filter has stopped.

Syntax

HRESULT Inactive(void);

Return Value

Returns S_OK if successful, or an HRESULT value indicating the cause of the failure.

Remarks

This method overrides the CBaseOutputPin::Inactive method. It sets the m_hStopEvent event.

CDynamicOutputPin::SetConfigInfo

CDynamicOutputPin Class

Specifies the IGraphConfig pointer and the stop event.

Syntax

void SetConfigInfo(
    IGraphConfig *pGraphConfig, 
    HANDLE hStopEvent
);

Parameters

pGraphConfig
Pointer to the IGraphConfig interface, or NULL.
hStopEvent
Handle to an event that is signaled when the filter stops, or NULL.

Remarks

The filter must call this method when it joins the filter graph. The filter graph manager supports IGraphConfig. For the hStopEvent parameter, create a manual-reset event. When the filter leaves the filter graph, call this method again with NULL for both parameters.

CDynamicOutputPin::StartUsingOutputPin

CDynamicOutputPin Class

Obtains access to the pin for a streaming operation.

Syntax

virtual HRESULT StartUsingOutputPin(void);

Return Value

Returns an HRESULT value. Possible values include those shown in the following table.

S_OKSuccess.
E_UNEXPECTEDUnexpected error.
VFW_E_STATE_CHANGEDThe filter was stopped, or the pin has begun flushing.

Remarks

Call this method before calling any methods that deliver data to the connected input pin or that change the connection's media type. For example, this rule applies to the following methods:

Afterward, call the StopUsingOutputPin method to release the access to the pin.

If the pin is blocked, StartUsingOutputPin waits for the pin to become unblocked. If the filter stops while the method is waiting, the method immediately returns VFW_E_STATE_CHANGED. The pin maintains a count of how many times StartUsingOutputPin has been called without a corresponding call to StopUsingOutputPin. If another thread tries to block the pin while this count is non-zero, the pin sets its blocking status to "pending." The pin becomes blocked once all of the streaming operations have completed, in the final call to StopUsingOutputPin.

Do not hold the m_BlockStateLock critical section when you call this method. Otherwise, if the pin is blocked, it can never become unblocked, causing a deadlock.

CDynamicOutputPin::StopUsingOutputPin

CDynamicOutputPin Class

Releases access to the pin after a streaming operation.

Syntax

virtual void StopUsingOutputPin(void);

See Also

StartUsingOutputPin

CDynamicOutputPin::StreamingThreadUsingOutputPin

CDynamicOutputPin Class

Determines whether any thread is performing a streaming operation on the pin.

Syntax

virtual bool StreamingThreadUsingOutputPin(void);

Return Value

Returns TRUE if a thread is performing a streaming operation on the pin. Otherwise, returns FALSE.

Remarks

If any threads have successfully returned from the StartUsingOutputPin method and have not made a corresponding call to the StopUsingOutputPin method, this method returns TRUE.

CDynamicOutputPin::SynchronousBlockOutputPin

CDynamicOutputPin Class

Blocks the pin; does not return until the pin is blocked.

Syntax

HRESULT SynchronousBlockOutputPin(void);

Return Value

Returns an HRESULT value. Possible values include those shown in the following table.

S_OKSuccess.
VFW_E_PIN_ALREADY_BLOCKEDPin is already blocked on another thread.
VFW_E_PIN_ALREADY_BLOCKED_ON_THIS_THREADPin is already blocked on the calling thread.

Remarks

Do not call this method from the streaming thread.

CDynamicOutputPin::UnblockOutputPin

CDynamicOutputPin Class

Unblocks the pin. When the pin is unblocked, it can deliver samples, change its output format, and reconnect itself.

Syntax

HRESULT UnblockOutputPin(void);

Return Value

Returns one of the HRESULT values shown in the following table.

S_FALSEPin was already unblocked.
S_OKSuccess.

CDynamicOutputPin::WaitEvent

CDynamicOutputPin Class

Waits until the specified event is signaled.

Syntax

static HRESULT WaitEvent(
    HANDLE hEvent
);

Parameters

hEvent
Handle to an event.

Return Value

Returns an HRESULT value. Possible values include those shown in the following table.

S_OKSuccess.
E_UNEXPECTEDUnexpected error.