Microsoft DirectX 8.0 |
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_BlockStateLock | Critical section that protects the blocking state. |
m_hUnblockOutputPinEvent | Event that is signaled when the pin is not blocked. |
m_hNotifyCallerPinBlockedEvent | Event that is signaled when the pin successfully blocks, or the user cancels a pending block. |
m_BlockState | Blocking state. |
m_dwBlockCallerThreadID | The identifier of the thread that last called the IPinFlowControl::Block method on this pin. |
m_dwNumOutstandingOutputPinUsers | Number of streaming threads using this pin. |
m_hStopEvent | Event that is signaled when the filter stops or the pin flushes data. |
m_pGraphConfig | Pointer to the IGraphConfig interface for performing dynamic reconnections. |
m_bPinUsesReadOnlyAllocator | Flag that specifies whether samples from the pin's allocator are read-only. |
Protected Methods | |
SynchronousBlockOutputPin | Blocks the pin; does not return until the pin is blocked. |
AsynchronousBlockOutputPin | Blocks the pin; might return before the pin is blocked. |
UnblockOutputPin | Unblocks the pin. |
BlockOutputPin | Blocks the pin. |
WaitEvent | Waits until the specified event is signaled. |
Public Methods | |
CDynamicOutputPin | Constructor method. |
~CDynamicOutputPin | Destructor method. |
SetConfigInfo | Specifies the IGraphConfig pointer and the stop event. |
DeliverBeginFlush | Requests the connected input pin to begin a flush operation. |
DeliverEndFlush | Requests the connected input pin to end a flush operation. |
Inactive | Notifies the pin that the filter has stopped. |
Active | Notifies the pin that the filter is now active. |
CompleteConnect | Completes a connection to an input pin. Virtual. |
StartUsingOutputPin | Obtains access to the pin for a streaming operation. Virtual. |
StopUsingOutputPin | Releases access to the pin after a streaming operation. Virtual. |
StreamingThreadUsingOutputPin | Determines whether any thread is performing a streaming operation on the pin. Virtual. |
ChangeOutputFormat | Dynamically changes the media type for the connection, and delivers new segment information. |
ChangeMediaType | Dynamically changes the media type for the connection. |
DynamicReconnect | Performs a dynamic reconnection with a new media type. |
IPin Methods | |
Disconnect | Breaks the current pin connection. |
IPinFlowControl Methods | |
Block | Blocks or unblocks the flow of data from the pin. |
Critical section that protects the blocking state.
Syntax
CCritSec m_BlockStateLock;
Remarks
Hold this critical section before using any of the following member variables:
Event that is signaled when the pin is not blocked.
Syntax
HANDLE m_hUnblockOutputPinEvent;
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.
Blocking state.
Syntax
BLOCK_STATE m_BlockState;
Remarks
The following states are defined:
- NOT_BLOCKED
- PENDING
- BLOCKED
Before accessing this variable, hold the m_BlockStateLock critical section.
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.
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
Event that is signaled when the filter stops or the pin flushes data.
Syntax
HANDLE m_hStopEvent;
Pointer to the IGraphConfig interface for performing dynamic reconnections.
Syntax
IGraphConfig* m_pGraphConfig;
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;
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_OK Success. E_FAIL Failure. 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.
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_OK Success. VFW_E_PIN_ALREADY_BLOCKED Pin is already blocked on another thread. VFW_E_PIN_ALREADY_BLOCKED_ON_THIS_THREAD Pin 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.
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_FALSE Pin is already unblocked. S_OK Success. E_INVALIDARG Invalid argument. VFW_E_PIN_ALREADY_BLOCKED Pin is already blocked on another thread. VFW_E_PIN_ALREADY_BLOCKED_ON_THIS_THREAD Pin 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:
- Block (asynchronous): AsynchronousBlockOutputPin
- Block (synchronous): SynchronousBlockOutputPin
- Unblock: UnblockOutputPin
Unblocking is always performed synchronously.
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.
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.
Destructor method.
Syntax
~CDynamicOutputPin(void);
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_OK Success. E_FAIL Failure. Possibly the owning filter did not call SetConfigInfo. VFW_E_NOT_CONNECTED The 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.
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_OK Success. E_FAIL Failure. Possibly the owning filter did not call SetConfigInfo. VFW_E_NOT_CONNECTED The 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.
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.
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.
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.
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_FALSE The pin was not connected. S_OK Success.
Remarks
This method overrides the CBasePin::Disconnect method to enable disconnecting while the filter is active.
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_OK Success. E_FAIL Failure. 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.
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.
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.
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_OK Success. E_UNEXPECTED Unexpected error. VFW_E_STATE_CHANGED The 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:
- ChangeOutputFormat
- ChangeMediaType
- DynamicReconnect
- CBaseOutputPin::Deliver
- CBaseOutputPin::DeliverEndOfStream
- CBaseOutputPin::DeliverNewSegment
- IMemInputPin::Receive
- IMemInputPin::ReceiveMultiple
- IPin::EndOfStream
- IPin::NewSegment
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.
Releases access to the pin after a streaming operation.
Syntax
virtual void StopUsingOutputPin(void);
See Also
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.
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_OK Success. VFW_E_PIN_ALREADY_BLOCKED Pin is already blocked on another thread. VFW_E_PIN_ALREADY_BLOCKED_ON_THIS_THREAD Pin is already blocked on the calling thread.
Remarks
Do not call this method from the streaming thread.
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_FALSE Pin was already unblocked. S_OK Success.
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_OK Success. E_UNEXPECTED Unexpected error.