You can play numerous media file formats with MFormats SDK. Decoding of files is realized with MFReader object.
Initialization and configuration of source object
To open any sources you should create an instance of this object:
MFReader myReader = new MFReader();
and open your source with the ReaderOpen method:
myReader.ReaderOpen(pathToYourSource, additionalProperties);
Where pathToYourSource may be a path to local file (e.g. "c:\temp\myVideo.mp4"), a URL to network stream (e.g. "rtsp://192.168.0.147/axis-media/media.amp") or path to image sequences (e.g. "c:\myImages\*.png"). Network streams playback and image sequences are described in separated articles. additionalProperties is a string with additional settings that are described in MFReader Properties article.
A source object is ready to work.
Initialization and configuration of receiver object
MFPreview performs a role of the receiver for preview your content on a display. To configure it you should create an instance of this object:
MFPreview myPreview = new MFPreview();
and set up it to be able to preview frames in a required control or in the separated window:
// set myPreviewPanel as control for preview myPreview.PreviewWindowSet("", myPreviewPanel.Handle.ToInt32); // enable audio and video preview int enableAudio = 1; int enableVideo = 1; myPreview.PreviewEnable("", enableAudio, enableVideo);
The receiver object is ready.
Grabbing frames from the source and sending it to the receiver
To grab a frame from the source you should use IMFSource interface members. All the interface is described in another article.
Just for the example, it is enough to use SourceFrameGet method. This method returns you an original frame from your source. It contains the following parameters:
- _rtMaxWait - maximal wait time for the frame in milliseconds. You can limit the duration of frame grabbing by setting this parameter. In case you need to be sure that the frame is grabbed, use '-1'. More detailed information about this parameter is described in Rate Control article.
- _ppFrame - result frame grabbed from the source.
- _bsHints - additional parameters. This parameter requires for playback control and for specific cases (and reserved for future features). In common case, it is recommended to keep it empty.
This method always returns you the next available frame from your source.
To send a frame to the receiver you should use the ReceiverFramePut method of IMFReceiver interface. This method sends a frame to a receiver object that realizes IMFReceiver interfaces (MFPreview or MFDevice objects). It contains the following parameters:
- _pFrame - a frame that is sent to receiver
- _rtMaxWait - maximal wait time for frame sending in milliseconds. You can limit the duration of frame sending by setting this parameter. In case you need to be sure that the frame is received, use '-1'. More detailed information about this parameter is described in Rate Control article.
- _bsHints - additional properties. In common case, it is recommended to keep it empty.
To play your source content you should make a loop-thread that would grab frames from your source and send it to the receiver. In general, this is a core method that you should create for any your application that is based on MFormats SDK.
The simplest loop-thread looks like:
while (true) { if (isThreadWork) { // a core method to grab a frame from source, make a magic and send it to receiver CoreMethod(); } else { break; } }
where isThreadWork indicates that the thread is started.
In this article, a source is myReader (MFReader) and receiver is myPreview (MFPreview) the CoreMethod is:
// a frame object MFFrame myFrame; // grab a frame ((IMFSource)myReader).SourceFrameGet(-1, out myFrame, ""); // send to receiver ((IMFReceiver)myPreview).ReceiverFramePut(myFrame, -1, "");
Keep the thread working until the end of your source or until you need to stop it.
To check that file is over you should get frame flags information and check that the frame is last:
M_TIME myTime; myFrame.MFTimeGet(out myTime); // Check for the last frame if ((myTime.eFFlags & eMFrameFlags.eMFF_Last) != 0) { isThreadWork = false; }
eMFrameFlags enumeration contains all the possible flags for the frame and is listed in the documentation.
After the playback is stopped and you don't need the file anymore you should call ReaderClose method to close all internal decoding processes.