Sink elements are the elements at the end of the pipeline. The sink elements are responsible for finalizing the processing performed by the Streamer. This usually involves pushing stream data to devices provided by the Hardware Abstraction Layer (HAL), and releasing the segments in the pipeline so the buffer space can be reused. A sink element may not open any output pads.
A sink element is an element that implements the IElement and ISink interfaces. A sink element must also query the pump for an ISinkCallback interface to be able to report when the buffers are empty in the layer below.
Sink element and interfaces.
In many common cases, like audio stream and video stream processing, the sink element is responsible for pushing the stream data to HAL. In order to avoid buffer underflow situations in HAL, the sink must make sure to push data to HAL as soon it is available on the input pad. When HAL notifies the element about consumed stream data, the element should request to be processed by the Streamer by calling the RequestProcess() function in the ISinkCallback interface. The element will receive a call to the Process() function on its IInputPad interface, with all the segments and metadata that are available on the element's input pad at that moment.
The sinks should also tell the Streamer core about buffer underflow situations. This might indicate that the end of the stream is reached and all the data in the buffers have been played, or some kind of problem earlier in the pipeline or in the network. The Streamer core will take appropriate actions to handle either condition.
The Streamer relies on the sinks to block and unblock stream
processing in HAL when the Block(ISink::TBlockReason) and Unblock() functions
are called in the ISink interface. Blocking can be done to pause stream
processing or to pre-buffer stream data in buffers. Block should be
done on as low level as possible to prevent the Streamer buffer level
to dramatically drop when the stream processing is resumed when
unblocking.
The parameter to the Block() function tells the element the reason for
blocking. A block may be initiated by the user when pausing, or it may be
initiated by the system due to, for example, buffer underflow caused by a bad
network. An element might want to take different actions depending on the block
reason. For example, a video sink element that blanks the video when the user
pauses the stream, would use this parameter to recognize when to
"freeze" the video instead. Otherwise network errors could cause the
stream to flicker with black screens.
In some situations the Streamer core will request all buffers to be flushed. This means that all segments should be released and that all data in all possible buffers should be thrown away. There are many different situations when flushing is needed, e.g. when the user decides to fast forward or rewind there is no need to play the data in the buffers since it would only slow system response times.
The descriptor of an audio or video sink must indicate the fact that the element is an audio/video sink. This is done by adding the "AudioSink" or "VideoSink" trait to the element.
The Element Packaging section describes how to add traits to the descriptor by returning true in the HasTrait() function.