Duplication of streams

Introduction

MediaInfo has a specific feature, which permit to duplicate streams from a stream having multiple substreams.
You can modify the count of Vidoeo/Audio/Text stream for each programs in a stream.
Currently, this feature is supported with the following parsers:
  • MPEP-TS (MPEG Transport Stream)

Steps

Initialization

MediaInfo::Options("File_Duplicate", ***A string with parameters***)

The 2nd string is a list of parameters, with the form: Parameter1;Parameter2;...
List of available parameters:
  • file://***the file name for the destination***". Specify the file name for the duplicated stream.
    Note: There is nothing more to do: the file will be filled during the parsing
  • memory://***the memory pointer for the destination***". Specify the memory pointer for the duplicated stream (to a buffer).
    Note: The format of the memory pointer is memory://pointer:size, with pointer and size in Decimal format. "size" is the size of the allocated data pointed by the pointer.
  • program_number=***the program number value***". Specify which program number should be duplicated (this value is in Decimal format).
    By default, all streams from this program number are duplicated
  • program_map_PID=***the program_map_PID value***". Specify which program_map_PID should be duplicated (this value is in Decimal format).
    By default, all streams from this program_map_PID are duplicated
  • elementary_PID=***the elementary_PID value***". Specify which elementary_PID should be duplicated (this value is in Decimal format).
    By default, all streams from a program_number or a program_map_PID are duplicated, specifying at least one elementary_PID will disable the other streams duplication

Parsing data

If you use a memomry pointer, you must retrieve the count of written bytes during the parsing. The method is:
MediaInfo::Output_Buffer_Get()

Examples

Basic example

The user has configured 1 memory buffer for input
  • a memory pointer 1111111111, with 1316 reserved bytes
The user has configured 1 memory buffer for output:
  • a memory pointer 1234567890, with 1316 reserved bytes
The streams has multiple programs, one of these program is named "1".
The user wants to have this program, and only this one, in the output.

//Registering for duplication
MI.Option(_T("File_Duplicate"), _T("memory://1234567890:1316;program_number=1"));

//Setting MediaInfo as parsing a non seakable file, because we want the complete stream
MI.Option(_T("File_IsSeekable"), _T("0"));

//Preparing to fill MediaInfo with a buffer
MI.Open_Buffer_Init();

//The parsing loop
size_t From_Buffer_Size;
do
{
//Reading data somewhere, do what you want for this.
From_Buffer_Size=From.Read(From_Buffer, 1316); //From is a object able to read data (a file, a socket, what you want)

//Sending the buffer to MediaInfo
if ((MI.Open_Buffer_Continue(From_Buffer, From_Buffer_Size)&0x1)==0 && !CanWrite_OnlyIfParsingIsOk)

//Retrieving data written in memory
size_t To_Buffer_Size=MI.Output_Buffer_Get(_T("memory://1234567890:1316"));

//Writing data to somewhere, do what you want for this.
To.Write(To_Buffer, To_Buffer_Size);
}
while (From_Buffer_Size>0);

If we want streaming output only when MediaInfo has detected the streams

The user has configured 1 memory buffer for input
  • a memory pointer 1111111111, with 1316 reserved bytes
The user has configured 2 memory buffer for output:
  • a memory pointer 1234567890, with 1316 reserved bytes
  • a memory pointer 0987654321, with 1316 reserved bytes
The streams has multiple programs, and program "1" with:
  • 1 Video stream, named "1000"
  • 1 Audio stream, named "1001"
  • 1 Audio stream, named "1002"
The user wants to have:
  • Video 1000 + Audio 1001 in one output
  • Video 1000 + Audio 1002 in one output
The user want to fill output only when the stream information has been completed.

//Registering for duplication
MI.Option(_T("File_Duplicate"), _T("memory://1234567890:1316;program_number=1;elementary_PID=1000;elementary_PID=1001"));
MI.Option(_T("File_Duplicate"), _T("memory://0987654321:1316;program_number=1;elementary_PID=1000;elementary_PID=1002"));

//Setting MediaInfo as parsing a non seakable file, because we want the complete stream
MI.Option(_T("File_IsSeekable"), _T("0"));

//Preparing to fill MediaInfo with a buffer
MI.Open_Buffer_Init();

//The parsing loop
bool CanWrite_OnlyIfParsingIsOk=false;
size_t From_Buffer_Size;
do
{
//Reading data somewhere, do what you want for this.
From_Buffer_Size=From.Read(From_Buffer, 1316); //From is a object able to read data (a file, a socket, what you want)

//Sending the buffer to MediaInfo
if ((MI.Open_Buffer_Continue(From_Buffer, From_Buffer_Size)&0x1)==0 && !CanWrite_OnlyIfParsingIsOk)
CanWrite_OnlyIfParsingIsOk=true;

if (CanWrite_OnlyIfParsingIsOk)
{
//Retrieving data written in memory
size_t To_Buffer_Size_1=MI.Output_Buffer_Get(_T("memory://1234567890:1316"));
size_t To_Buffer_Size_2=MI.Output_Buffer_Get(_T("memory://0987654321:1316"));

//Writing data to somewhere, do what you want for this.
To_1.Write(To_Buffer_1, To_Buffer_Size_1);
To_2.Write(To_Buffer_2, To_Buffer_Size_2);
}
}
while (From_Buffer_Size>0);