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?
- "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 in MPlatform).
Which way to choose?
It depends on your requirements.
Advantages and disadvantages of L-shape with CG
- Consumes fewer 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.
Advantages and disadvantages of 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
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:
Add the CG object to your application.
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);
Create the CG object and process each frame with it:
((MFORMATSLib.IMFProcess)m_objCharGen).ProcessFrame(pFrameInput, out pFrameOutput, out nFramesRes, "");
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.
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.
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.
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);
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);