Performing the L-shaped items overlay using the MMixer object in MPlatform.

What is the L-shaped items overlaying? 
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. 



The L-shaped items overlay is very useful for advertising, "see next" section displaying and other service purposes. 

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 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 items with MMixer object. 
The idea behind the making of L-shape with MMixer object is to make 2 MMixer layers one under another. The upper one will playback the content and the lower one will contain underlying L-shape composition. After that, you can switch the views to make a smooth transition from the original view to the L-shaped one and backward. 

The concept description
1 . Add the content stream to MMixer object and add it's representation to the scene. It can be a file, a playlist or any other required stream source. This is your main stream that will be transformed during the L-shape displaying. 

2. Add the underlying stream. This one will contain your L-shape content, for example, "see next" section.
The L-shape content stream can have any preferred configuration according to your requirements: 
- Common MMixer stream. In this case, the L-shape content is represented by a stream source. It can be a picture, a movie, a playlist, etc.

- Transparent MMixer stream, with a CG object on it.  In this case, the L-shape content is represented by a CG overlay items that will be placed on the stream.

- A bunch of  MMixer streams in a composition.  

In my demo code I'll use a transparent MMixer stream with a CG object on top of it.

3. Configure your scene. Make sure that your L-shape stream is in a right position and the correct areas will be visible after the main content stream squeeze. Make sure that the main content stream on top of the L-shape one.

4. Add 2 views of your scene. The first one is the current scene state when the base stream is displayed on full mixer area. The second one is L-shaped state when the base stream is reduced to display the L-shape of underlying video.   
This views will let MMixer know how to transform the base video item to display the underlying one. 

5. Invoke required views to perform a smooth transition from the original view to L-shaped one and backward.

A code sample
// 1. Add the base stream source video
MItem myMainSourceStream;
m_objMixer.StreamsAdd("myMainSourceStream", null, @"d:/temp/!SharkTale.avi", "", out myMainSourceStream, 0.0);

// Add the base video to the scene
// I pick the 0 element - it's a foreground when youe scene is empty
// If you have a complex scene thhen I would recommed you to enumerate elements
// and choose the required one
MElement rootElement;
m_objMixer.ElementsGetByIndex(0, out rootElement);

// Add my main video element to the foreground
MElement mainVideoElement;
((IMElements)rootElement).ElementsAdd("", "video", "stream_id=myMainSourceStream h=1 w=1 show=1", out mainVideoElement, 0.0);

// 2. Add the underlying source stream to MMixer
MItem myUnderlyingSourceItem;
m_objMixer.StreamsAdd("myUnderlyingSourceItem", null, "transparent", "", out myUnderlyingSourceItem, 0.0);

// Add a CG item to this stream.
// Note that CG is applied to this particular input stream only, not the whole MMixer output
m_objCharGen = new MLCHARGENLib.CoMLCharGen();
(myUnderlyingSourceItem as IMPlugins).PluginsAdd(m_objCharGen, 0);
// Add the L-shape content to the CG and show it
string cGItemId = "";
m_objCharGen.AddNewItem(@"D:\Medialooks\Sample Videos\L-Shape CG\bunny2.jpg", -0.3, 0, 1, 1, ref cGItemId);
m_objCharGen.ShowItem(cGItemId, 1, 0);

// Add the underlying video to the scene
// I pick the 0 element - it's a foreground when your scene is empty
// If you have a complex scene then I would recommend you to enumerate elements
// and choose the required one
MElement rootElement1;
m_objMixer.ElementsGetByIndex(0, out rootElement1);

// Add my underlying video element to the foreground
MElement underlyingVideoElement;
((IMElements)rootElement1).ElementsAdd("", "video", "stream_id=myUnderlyingSourceItem h=1 w=1 show=1", out underlyingVideoElement, 0.0);

// 3. Reorder elements - put the main on top of the underlying
underlyingVideoElement.ElementReorder(0);
mainVideoElement.ElementReorder(10);

// 4. Add views for the L-shape transition performing
MElement rootElement2;
m_objMixer.ElementsGetByIndex(1, out rootElement2);

// Add the main view.
// Here I have a main video on a full screen
MElement view1;
((IMElements)rootElement2).ElementsAdd("", "view", "id=base_view", out view1, 0.0);
MElement tempElement1;
((IMElements)view1).ElementsAdd("", "video", "target_id='foreground::video_000' h=1 w=1 x=0 y=0", out tempElement1, 0.0);

// Add the L-shaped view.
// Here my main video size is reduced by 70% and located in top-right position.
// Note that I do not specify the X any Y position in a second view.
// I just reduce it's size and set the position to "top-right" to avoid the manual position calculation.
MElement view2;
((IMElements)rootElement2).ElementsAdd("", "view", "id=l_shaped_view", out view2, 0.0);
MElement tempElement2;
((IMElements)view2).ElementsAdd("", "video", "target_id='foreground::video_000' h=0.7 w=0.7 pos='top-right' ", out tempElement2, 0.0);

// 5. Invoke the views to make a transition form the base view to L-shaped one and backward.
// ... some code here ...
// Make a smooth transition to L-shaped view within 2 seconds
view2.ElementInvoke("select", "true", 2);
// ... some code here ...
// Make a smooth transition to base view within 2 seconds
view1.ElementInvoke("", "true", 1);

Once you're done you can save your MMIxer configuration to the XML file and load it further for L-shape performing.
Note: When you save the XML configuration, it saves the content of MMixer object only. So if you perform the L-shape displaying with the CG on top of the transparent stream, like I did in this example, your CG content would not be saved. Sou you need to save the CG configuration separately and add it as a plugin to transparent MMixer stream manually. 

Try loading your configuration and making L-shape with Mixer sample application