/* Copyright (c) MediaArea.net SARL. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license that can
* be found in the License.html file in the root of the source tree.
*/
//---------------------------------------------------------------------------
// Pre-compilation
#include "MediaInfo/PreComp.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#include "MediaInfo/Setup.h"
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#if defined(MEDIAINFO_SCTE20_YES)
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#include "MediaInfo/Text/File_Scte20.h"
#if defined(MEDIAINFO_EIA608_YES)
#include "MediaInfo/Text/File_Eia608.h"
#endif
#include "MediaInfo/MediaInfo_Config_MediaInfo.h"
#if MEDIAINFO_EVENTS
#include "MediaInfo/MediaInfo_Events.h"
#endif //MEDIAINFO_EVENTS
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
namespace MediaInfoLib
{
//---------------------------------------------------------------------------
//***************************************************************************
// Infos
//***************************************************************************
//---------------------------------------------------------------------------
static const char* Scte20_field_number (int8u field_number)
{
switch (field_number)
{
case 0 : return "Forbidden";
case 1 : return "1st display field";
case 2 : return "2nd display field";
case 3 : return "3rd display field";
default : return "";
}
}
//***************************************************************************
// Constructor/Destructor
//***************************************************************************
//---------------------------------------------------------------------------
File_Scte20::File_Scte20()
:File__Analyze()
{
//Configuration
ParserName="SCTE 20";
#if MEDIAINFO_EVENTS
ParserIDs[0]=MediaInfo_Parser_Scte20;
StreamIDs_Width[0]=1;
#endif //MEDIAINFO_EVENTS
PTS_DTS_Needed=true;
//In
picture_structure=(int8u)-1;
progressive_sequence=false;
progressive_frame=false;
top_field_first=false;
repeat_first_field=false;
//Temp
Streams.resize(2); //CEA-608 Field 1, CEA-608 Field 2
Streams_Count=0;
}
//---------------------------------------------------------------------------
File_Scte20::~File_Scte20()
{
for (size_t Pos=0; Pos<Streams.size(); Pos++)
delete Streams[Pos]; //Streams[Pos]=NULL
}
//***************************************************************************
// Streams management
//***************************************************************************
//---------------------------------------------------------------------------
void File_Scte20::Streams_Update()
{
Clear(Stream_Text);
//Per stream
for (size_t Pos=0; Pos<Streams.size(); Pos++)
if (Streams[Pos] && Streams[Pos]->Parser && Streams[Pos]->Parser->Status[IsFilled] /*&& Streams[Pos]->Parser->Status[IsUpdated]*/ && Streams[Pos]->Parser->Count_Get(Stream_Text))
Streams_Update_PerStream(Pos);
}
//---------------------------------------------------------------------------
void File_Scte20::Streams_Update_PerStream(size_t Pos)
{
if (Streams[Pos]==NULL)
return;
Update(Streams[Pos]->Parser);
if (Streams[Pos]->Parser)
{
for (size_t Pos2=0; Pos2<Streams[Pos]->Parser->Count_Get(Stream_Text); Pos2++)
{
Stream_Prepare(Stream_Text);
Merge(*Streams[Pos]->Parser, Stream_Text, Pos2, StreamPos_Last);
Fill(Stream_Text, StreamPos_Last, "MuxingMode", "SCTE 20");
Fill(Stream_Text, StreamPos_Last, Text_ID, Streams[Pos]->Parser->Retrieve(Stream_Text, Pos2, Text_ID), true);
}
Ztring LawRating=Streams[Pos]->Parser->Retrieve(Stream_General, 0, General_LawRating);
if (!LawRating.empty())
Fill(Stream_General, 0, General_LawRating, LawRating, true);
Ztring Title=Streams[Pos]->Parser->Retrieve(Stream_General, 0, General_Title);
if (!Title.empty() && Retrieve(Stream_General, 0, General_Title).empty())
Fill(Stream_General, 0, General_Title, Title);
}
}
//---------------------------------------------------------------------------
void File_Scte20::Streams_Finish()
{
Clear(Stream_Text);
//Per stream
for (size_t Pos=0; Pos<Streams.size(); Pos++)
if (Streams[Pos] && Streams[Pos]->Parser && Streams[Pos]->Parser->Status[IsAccepted] /*&& Streams[Pos]->Parser->Status[IsUpdated]*/)
{
Finish(Streams[Pos]->Parser);
Streams_Update_PerStream(Pos);
}
}
//***************************************************************************
// Buffer - Synchro
//***************************************************************************
//---------------------------------------------------------------------------
void File_Scte20::Read_Buffer_Init()
{
//Global information
#if defined(MEDIAINFO_EIA608_YES)
Config->File_Scte20_IsPresent=true;
#endif //defined(MEDIAINFO_EIA608_YES)
//Configuration
Eia608_DisplayEmptyStream=Config->File_Eia608_DisplayEmptyStream_Get();
}
//---------------------------------------------------------------------------
void File_Scte20::Read_Buffer_Unsynched()
{
//Parsing
for (size_t Pos=0; Pos<Streams.size(); Pos++)
if (Streams[Pos] && Streams[Pos]->Parser)
Streams[Pos]->Parser->Open_Buffer_Unsynch();
}
//***************************************************************************
// Buffer - Global
//***************************************************************************
//---------------------------------------------------------------------------
void File_Scte20::Read_Buffer_Continue()
{
//Parsing
Element_Begin1("SCTE 20");
int8u cc_count;
bool vbi_data_flag;
BS_Begin();
Mark_1_NoTrustError();
Mark_0_NoTrustError();
Mark_0_NoTrustError();
Mark_0_NoTrustError();
Mark_0_NoTrustError();
Mark_0_NoTrustError();
Mark_0_NoTrustError();
Get_SB (vbi_data_flag, "vbi_data_flag");
if (vbi_data_flag)
{
Get_S1 (5, cc_count, "cc_count");
for (int8u Pos=0; Pos<cc_count; Pos++)
{
Element_Begin1("cc");
int8u cc_data[2];
int8u field_number, cc_data_1, cc_data_2;
Skip_S1(2, "cc_priority");
Get_S1 (2, field_number, "field_number"); Param_Info1(Scte20_field_number(field_number));
Skip_S1(5, "line_offset");
Get_S1 (8, cc_data_1, "cc_data_1");
cc_data[0]=ReverseBits(cc_data_1);
Param_Info1(Ztring::ToZtring(cc_data[0], 16));
Get_S1 (8, cc_data_2, "cc_data_2");
cc_data[1]=ReverseBits(cc_data_2);
Param_Info1(Ztring::ToZtring(cc_data[1], 16));
Mark_1_NoTrustError();
if (field_number!=0 && picture_structure!=(int8u)-1 && picture_structure!=0)
{
Element_Begin1("cc_data");
//Finding the corresponding cc_type (CEA-608 1st field or 2nd field)
int8u cc_type;
if (progressive_sequence)
cc_type=0;
else if (picture_structure!=3)
cc_type=picture_structure-1;
else if (field_number==2)
cc_type=top_field_first?1:0;
else //if (field_number==1 || field_number==3)
cc_type=top_field_first?0:1;
//Parsing
#if MEDIAINFO_DEMUX
Element_Code=cc_type;
#endif //MEDIAINFO_DEMUX
if (Streams[cc_type]==NULL)
Streams[cc_type]=new stream;
if (Streams[cc_type]->Parser==NULL)
{
#if defined(MEDIAINFO_EIA608_YES)
Streams[cc_type]->Parser=new File_Eia608();
((File_Eia608*)Streams[cc_type]->Parser)->cc_type=cc_type;
#else //defined(MEDIAINFO_EIA608_YES)
Streams[cc_type]->Parser=new File__Analyze();
#endif //defined(MEDIAINFO_EIA608_YES)
Open_Buffer_Init(Streams[cc_type]->Parser);
}
Demux(cc_data, 2, ContentType_MainStream);
if (!Streams[cc_type]->Parser->Status[IsFinished])
{
//Parsing
if (Streams[cc_type]->Parser->PTS_DTS_Needed)
{
Streams[cc_type]->Parser->FrameInfo.PCR=FrameInfo.PCR;
Streams[cc_type]->Parser->FrameInfo.PTS=FrameInfo.PTS;
Streams[cc_type]->Parser->FrameInfo.DTS=FrameInfo.DTS;
}
Open_Buffer_Continue(Streams[cc_type]->Parser, cc_data, 2);
Element_Show();
//Filled
if (!Status[IsAccepted])
Accept("SCTE 20");
}
else
Skip_XX(2, "Data");
Element_End0();
}
Element_End0();
}
}
Skip_S1(4, "non_real_time_video_count");
BS_End();
if (Element_Size-Element_Offset)
Skip_XX(Element_Size-Element_Offset, "non_real_time_video + reserved");
Element_End0();
Element_Show();
FILLING_BEGIN();
//Filled
if (!Status[IsAccepted] && Eia608_DisplayEmptyStream)
{
Accept("SCTE 20");
//TODO: merge duplicated content
for (int8u cc_type=0; cc_type<2; cc_type++)
{
//Parsing
#if MEDIAINFO_DEMUX
Element_Code=cc_type;
#endif //MEDIAINFO_DEMUX
if (Streams[cc_type]==NULL)
Streams[cc_type]=new stream;
if (Streams[cc_type]->Parser==NULL)
{
#if defined(MEDIAINFO_EIA608_YES)
Streams[cc_type]->Parser=new File_Eia608();
((File_Eia608*)Streams[cc_type]->Parser)->cc_type=cc_type;
#else //defined(MEDIAINFO_EIA608_YES)
Streams[cc_type]->Parser=new File__Analyze();
#endif //defined(MEDIAINFO_EIA608_YES)
Open_Buffer_Init(Streams[cc_type]->Parser);
Streams[cc_type]->Parser->Accept();
}
}
}
FILLING_END();
}
//***************************************************************************
// C++
//***************************************************************************
} //NameSpace
#endif //MEDIAINFO_SCTE20_YES
↑ V730 Not all members of a class are initialized inside the constructor. Consider inspecting: Eia608_DisplayEmptyStream.
↑ V793 It is odd that the result of the 'Element_Size - Element_Offset' statement is a part of the condition. Perhaps, this statement should have been compared with something else.
↑ V807 Decreased performance. Consider creating a pointer to avoid using the 'Streams[Pos]->Parser' expression repeatedly.
↑ V807 Decreased performance. Consider creating a reference to avoid using the 'Streams[cc_type]->Parser->FrameInfo' expression repeatedly.