Performing the L-shaped items overlay using the CG in MPlatform and MFormats.

What is the L-shaped items overlay?
The main idea of L-shaped items displaying is to transform the video output rectangle (squeeze it) and display some overlay items on a freed space. 



What can it be used for? 
- Advertising.
- "See next..." section displaying.
-  Service information displaying. 

There are 2 ways to make the L-shape overlay: use a CG object (available with MPlatform and MFormats) or use MMixer object (available inMPlatform).

Which way to choose? 

It depends on your requirements. 

L-shape with CG

+ Consumes less system resources.
+ Easier to use. 
+ Can be applied to almost any other object. 
- Underlying property applies to the whole CG object, so if you need to keep some CG items on top of the video, you'll have o use multiple CG plugins.
- Unable to make complex scenes like with MMixer object. 

L-shape with MMixer

Supports complex MMixer scenes. 
Can have multiple CG objects applied to any source or output. 
- Consumes much more system resources than the CG option. 
- A bit harder to use in case of usage CG for underlying stream configuration.

Displaying the L-Shape CG items with Character Generator (CG).
The CG usage is the most simple and natural way of L-shape displaying. It has 2 special methods for this task: SetVideoOutputRect and SetVideoOutputRectWithDelay

The first one switches to L-shape immediately, and the second one makes a smooth transition to L-shape, which makes it more usable in production applications.

Here is a common way of the L-shape displaying with those methods: 

1. Add the CG object to your application.

MPlatform:
Create and the CG object to your main source object (for example, MPlaylist) as a plugin. 
m_objCharGen = new MLCHARGENLib.CoMLCharGen();
m_objPlaylist.PluginsAdd(m_objCharGen, 0);

Check the Internal Playlist Sample for details: 
"C:\Program Files (x86)\Medialooks\MPlatform SDK\Samples Basic\C#\Internal Playlist Sample"

MFormats:
Create the CG object  and process each frame with it: 
((MFORMATSLib.IMFProcess)m_objCharGen).ProcessFrame(pFrameInput, out pFrameOutput, out nFramesRes, "");

Check the  Sample File Playback for details:  
"C:\Program Files (x86)\Medialooks\MFormats SDK\Samples\C#\Sample File Playback"

2. Drop some CG items on a video, load a composition or group as usual. 
This is the common mode of CG usage: in this case, all CG items added to the CG will be displayed on top of the video.
You can use a CG Editor or any other tool for this task.   



3. Compose your L-shape scene by arranging the CG items.
The items will hide the video or part of it behind, but don't worry - that's ok for now. 



4. Move the layer with the CG items behind the video. 
To perform this action, call the SetVideoOutputRect like this:
MLCHARGENLib.tagRECT trSource = new MLCHARGENLib.tagRECT();
MLCHARGENLib.tagRECT trTarget = new MLCHARGENLib.tagRECT();
m_objCharGen.SetVideoOutputRect(trSource, trTarget, 0, 1);

It does not look like there is much sense in this call because the source and target rectangle structures are empty. But the 4=th parameter (_bTopmostVideo) is set to 1, which makes the CG move the overlay layer under the video. 
Now the video looks like there are no CG items on it, but that's not true - all items are behind.

 

4. Perform the L-shape display.
Call the   SetVideoOutputRectWithDelay method to transform the video output rectangle and make CG items hidden behind it visible.
The  squeeze is configured by specifying the source and destination rectangles of the video:
// Source rectangle.
// I'll set all values to 0 to get the whole video rectangle.
MLCHARGENLib.tagRECT trSource = new MLCHARGENLib.tagRECT();
trSource.top = 0;
trSource.left = 0;
trSource.bottom = 0;
trSource.right = 0;

// I specify the destination rectangle assuming that my video resolution is 1920x1080
MLCHARGENLib.tagRECT trTarget = new MLCHARGENLib.tagRECT();
trTarget.top = 0;
trTarget.left = 300;
trTarget.bottom = 800;
trTarget.right = 1920;

// Transform a video from the source to the destination rectangle within 1 second.
// All CG items that were bidden behind, will be visible in empty L-shape space.
m_objCharGen.SetVideoOutputRectWithDelay(trSource, trTarget, 0, 1, 0, 1000);

That's it, now we have our L-shape composition on air. 



5.  Transform a video back to normal size and hide the underlying CG items. 
I can specify the rectangles manually or just use the empty rectangle structures:
// Tatget and source rectangles
MLCHARGENLib.tagRECT trSource = new MLCHARGENLib.tagRECT();
MLCHARGENLib.tagRECT trTarget = new MLCHARGENLib.tagRECT();
// Transform a video into the original state within 1 second
m_objCharGen.SetVideoOutputRectWithDelay(trSource, trTarget, 0, 1, 0, 1000);