Media States
While a MediaElement has an explicit state, defined by MediaElement.CurrentState, the MediaStreamSource object does not. Rather, the state of the MediaStreamSource is determined by which methods have been invoked. For example, if the SeekAsync method of a MediaStreamSource has been called and it has not yet responded by calling ReportSeekCompleted, it is considered to be in a "seeking" state. In general, a MediaStreamSource is usually performing one of the following activities:
"opening"
The MediaElement has called OpenMediaAsync, but the MediaStreamSource implementation has not responded with ReportOpenMediaCompleted.
"seeking"
The MediaElement has called SeekAsync, but the MediaStreamSource implementation has not responded with ReportSeekCompleted.
"buffering"
The MediaElement has called GetSampleAsync for one of the media streams, and the MediaStreamSource responded with ReportGetSampleProgress.
"streaming"
The MediaStreamSource has not responded with ReportGetSampleProgress. In other words, the MediaStreamSource will respond to GetSampleAsync calls with calls to ReportGetSampleCompleted as soon as a sample is available.
"mediaEnded"
The MediaStreamSource notified the MediaElement that the final samples were delivered for all streams. This is done by reporting special End-of-Stream samples in response to GetSampleAsync.
"closed"
CloseMedia has been called.
Stream States
A MediaStreamSource implementation might find it useful to maintain per-stream state as well. For example, an application might stop downloading audio if its audio buffer queue is full.
Synchronization
The MediaElement will only call one MediaStreamSource method at once. Therefore, a SeekAsync request will not arrive at the same time as a GetSampleAsync request, nor will two GetSampleAsync requests arrive concurrently. However, there are still some cases a MediaStreamSource developer must consider:
Seeking
In desktop Silverlight, a SeekAsync request will not be delivered until all outstanding sample requests have been completed. One solution is to report the previous sample a second time.
In Silverlight for Windows Phone, a SeekAsync request will be delivered if an outstanding sample request is pending. However, when that sample is completed, Silverlight for Windows Phone will erroneously throw it away. If that sample is a key frame, it may be necessary to report the sample a second time.
Buffering transitions
In Silverlight for Windows Phone, calling ReportGetSampleProgress will not prevent subsequent GetSampleAsync calls from arriving. Buffering is a media state, not a stream state. Calling ReportGetSampleCompleted on any stream will cause the MediaElement to exit buffering. As such, a MediaStreamSource should not complete a sample on any stream until buffering is completed for all streams.