Besides using the OnFrame event (as described, for example, in this article — Draw on frames), you can use a frame-by-frame approach. Let's call this the MFormats-style approach and explain in the current article how to handle file playback in the MPlatform SDK this way. Please note, using MFormats methods in MPlatform SDK doesn't require any additional licenses.
This MFormats-like approach is based on a separated thread where you get a frame from a source, process it, and send the frame to an output device or a preview:
In general, you should configure source and output objects as usual. The main difference here is that you should create a new thread to process frames:
Thread body = new Thread(FrameProcessing);
body.Start();
isThread = true;
Where the FrameProcessing method looks like:
private void FrameProcessing()
{
while (isThread) // isThread is a flag that is true when playback is running
{
MFrame sourceFrame;
// get frame from source object
m_objFile.SourceFrameGet(-1, out sourceFrame, 0);
// send result frame to preview
m_objPreview.ReceiverPutFrame("", sourceFrame);
// you can also send result frame to an output device
m_objRenderer.ReceiverPutFrame("", sourceFrame);
// do not forget to release frames
Marshal.ReleaseComObject(sourceFrame);
}
}
Between the SourceFrameGet and ReceiverPutFrame methods, you can process the received frame with plugins or other methods available for frames — frame overlay, text overlay, etc.
For example, an overlay:
if (m_overlayFrame != null)
{
// Need clone because input frames can have reference to previous frame (e.g. convert 25p -> 30p);
// cloned frame will be clear without previous overlay.
MFrame cloneFrame;
sourceFrame.FrameClone(out cloneFrame, eMFrameClone.eMFC_Full, eMFCC.eMFCC_Default);
// overlay frame with image
cloneFrame.FrameOverlay(m_overlayFrame, 50, 50, 0.5, "");
// Release source frame and replace it cloned frame
Marshal.ReleaseComObject(sourceFrame);
sourceFrame = cloneFrame;
}
The approach described above is implemented in the Async Frame Processing Sample
C:\Program Files (x86)\Medialooks\MPlatform SDK\Samples Basic\C#\Async Frame Processing Sample
This approach can be very useful, for example, for synchronized launch of multiple MWriter objects, for example:
private void FrameProcessing()
{
while (isThread)
{
// get frame from source object
m_objLive.SourceFrameGet(-1, out MFrame sourceFrame, 0);
if (sourceFrame != null)
{
// send result frame to preview
m_objPreview.ReceiverPutFrame("", sourceFrame);
// also send to two writers (may be more)
if (isRecord)
{
writer1.ReceiverPutFrame("", sourceFrame);
writer2.ReceiverPutFrame("", sourceFrame);
}
// release frame
Marshal.ReleaseComObject(sourceFrame);
}
else
Thread.Sleep(3);
}
}