A source element is the element in which stream data enters the pipeline. There is always exactly one source element in a pipeline. It is the responsibility of the source element to fetch the media stream from the network by using a specific protocol. Support for multiple protocols is achieved by having multiple source elements implementing one protocol each.
A source element is an element that implements the IElement and ISource interfaces. A source element must also query the pump for an ISourceCallback interface so it can acknowledge commands and report its status.
Usually, the source element queries the pump for an IEvent interface. If so, it also has to implement IEventCallback in order to receive notifications of events. Using the IBlackboard interface is optional.
Source element and interfaces.
The ISource interface contains a function, IsFeatureSupported(), that is used to ask the element if it supports a certain feature. This is used to let the Streamer core know what behaviour to expect when playing streams with the element.
Each source element used will be queried for these features:
Pause Indicates whether the element supports the Pause command or not.
Rewind Indicates whether the element supports the Rewind command or not.
FastForward Indicates whether the element supports the Fast Forward command or not.
SetPosition Indicates whether the element supports the Seek command or not.
PositionCounter Indicates whether the streams opened with the element will allow position extraction.
InputClocked Indicates whether the source is transmitting in a clocked fashion, i.e. in the same pace as the stream should be consumed or not. A source connecting to a multicast channel would be "clocked" but a source connecting to a HTTP server would not since the stream would be read as fast as the server and network allows.
NoFlushOnPause Indicates whether the Streamer core should avoid flushing the pipeline and buffers when pausing or not. A source connecting to a file would want to avoid flushing to avoid pre-buffering when starting to play again while a source connecting to an RTSP server would want not. The reason for flushing the pipeline in the RTSP case is that it is not certain that the server resumes playing at the exact same position as the pause occurred which would trigger a twitching image.
In later versions of the Streamer other features might be added. If the element is queried for unknown features it should always return false, since that should be the conservative answer for all features.
The Streamer uses the ISource interface to issue commands to the source element, telling it which stream to fetch. In addition, the Streamer may specify details such as from where in the stream data is to be fetched and if the stream should play forward or backward. The different modes of operation are represented by states, and keeping track of these states and when transitions from one state to another occur is crucial for successful interaction with the Streamer.
Media stream flow control state machine. The arrows originating from the Open state are valid from any sub-state within the Open state.
The state machine for controlling the flow of the media stream through the pipeline has three main states and four additional sub-states:
Closed In Closed state the element does not have any stream resources allocated, which implies that the element does not have access to anything outside the process in which it runs, be it a file on a file system or a server on a network. This is the state of the element when it is created.
Open In Open state the element has established access to the requested stream resource. This state is divided into four sub-states which handles the four modes of stream playback:
Paused Playback of the stream is halted.
Playing The playback is performed at normal speed.
Fast Forwarding The stream is played forward above normal speed.
Rewinding The stream is played backward above normal speed.
Failed In Failed state something has happened with the stream resource which prevents the element from using it. The element is allowed to have stream resources allocated in this state, but since it cannot do anything productive with them, it is recommended to deallocate everything directly when entering Failed state. The element can leave this state only by an explicit command to get closed.
In Playing, Fast Forwarding, and Rewinding states the source element is responsible for feeding the pipeline with media stream data. In Closed, Paused, and Failed states the flow through the pipeline is stalled.
The Open state is not used explicitly in the source element interface. In the interface the Open state is replaced by its four sub-states. For resource handling it is usually helpful to think of them as one open state instead of several sub-states. For flow control, on the other hand, the individual sub-states are generally a better model.
When the source element has changed its state, it is required to inform the Streamer core immediately about the change. The source element is allowed to change its state in the following three cases:
In response to a command issued by the streamer core. The element must enter the state mandated by the command.
When the end of the media stream has been reached (or the beginning of the stream if rewinding). The element must enter Paused state.
When something fails and the element cannot continue to use the stream resource. The element must enter Failed state.
If the source element changes its state in any other way or at any other time, the state change is illegal. If the Streamer core detects an illegal state change it will consider the source element to be untrustworthy and destroy it promptly.
The Streamer core issues commands such as Open, Play, and Close to the source element to control the flow of the media stream. Since these commands have impact on flow control, they also result in state changes in the source element. If the source element is able to carry out a command successfully it changes its state to the target state of the command and then tells the core that it has completed the command.
If the source element cannot carry out a command because the command for some reason is not supported for the current state, the source element will simply inform the Streamer core that the command failed and the state will remain unchanged. If the command failed because the media stream resource behaved in some unexpected way that the source element could not handle, the element must enter Failed state and then inform the core that the command failed.
Command | Allowed in these states | Target state |
---|---|---|
Open | Closed | Paused |
Close | Playing, Paused, Fast Forwarding, Rewinding, Failed | Closed |
Pause | Playing, Fast Forwarding, Rewinding | Paused |
Play | Paused, Fast Forwarding, Rewinding | Playing |
Fast Forward | Paused, Playing, Rewinding | Fast Forwarding |
Rewind | Paused, Playing, Fast Forwarding | Rewinding |
The source element is guaranteed to get these commands only when it is in a state in which the command is allowed, as stated in the table above.
The table also illustrates the special conditions for the Failed state. No command does deliberately end up in the Failed state, but all commands except Close has the potential to cause a transition to the Failed state, if there is something seriously wrong with the media stream resource. The only command accepted in Failed state is Close, which cannot fail.
The source element must change state to Paused state when it is in Playing or Fast Forwarding state and reaches the end of the media stream, or in Rewinding state and reaches the beginning of the stream. If the element is in Paused state at the end of the stream, it is guaranteed it will not get a Play or Fast Forward command. The same restriction is enforced for the Rewind command when the element is in Paused state at the start of the stream. When the source element is in Paused state as a result of a successful Open command, the element is assumed to be at the beginning of the stream and is thereby guaranteed it will not receive a Rewind command in that state.
The source element signals end-of-stream and beginning-of-stream conditions to the Streamer core by going to Paused state when it is not executing a command. If the source element communicates asynchronously to control the delivery of the stream, there is a potential race condition involved in this protocol which the source element must take into account. If the source element reaches end-of-stream while executing a Pause command, the element has no means of expressing this fact to the Streamer core, since going to Paused state would be interpreted as part of the execution of the command. To resolve this situation, the source element must act as if the execution of the Pause command completed successfully. The Streamer core will be unaware of the end-of-stream condition, so it may still issue Play and Fast Forward commands to the source element. If the element receives Play or Fast Forward when it is actually already at end of stream, it must act as if this command was executed successfully and immediately after completing the command go to the Paused state, which will make the Streamer core aware of the end-of-stream condition.
A race condition in which the source element is unable to express the fact that it has reached end-of-stream in the server. Not until the pipeline pump wants to play more from the stream can it be told by the source element that end-of-stream has been reached.
A similar situation must be taken into account at the beginning of the stream, and resolving that situation must be done in the same way as outlined above.