/* 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_VC3_YES)
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#include "MediaInfo/MediaInfo_Config_MediaInfo.h"
#include "MediaInfo/Video/File_Vc3.h"
#if defined(MEDIAINFO_CDP_YES)
#include "MediaInfo/Text/File_Cdp.h"
#endif
#include <sstream>
//---------------------------------------------------------------------------
namespace MediaInfoLib
{
//***************************************************************************
// Infos
//***************************************************************************
//---------------------------------------------------------------------------
static const char* Vc3_Profile[2]=
{
"HD",
"RI",
};
//---------------------------------------------------------------------------
static const char* Vc3_FromCID_Profile(int32u CompressionID)
{
if (CompressionID>=1235 && CompressionID<=1260)
return Vc3_Profile[0];
if (CompressionID>=1270 && CompressionID<=1275)
return Vc3_Profile[1];
return "";
}
//---------------------------------------------------------------------------
static const char* Vc3_Level[6]=
{
"444",
"HQX",
"HQ",
"SQ",
"LB",
"TR",
};
//---------------------------------------------------------------------------
static const char* Vc3_FromCID_Level(int32u CompressionID)
{
switch (CompressionID)
{
case 1256 :
case 1270 :
return Vc3_Level[0];
case 1235 :
case 1241 :
case 1250 :
case 1271 :
return Vc3_Level[1];
case 1238 :
case 1243 :
case 1251 :
case 1272 :
return Vc3_Level[2];
case 1237 :
case 1242 :
case 1252 :
case 1273 :
return Vc3_Level[3];
case 1253 :
case 1274 :
return Vc3_Level[4];
case 1244 :
case 1258 :
case 1259 :
case 1260 :
default : return "";
}
}
//---------------------------------------------------------------------------
static const bool Vc3_FromCID_IsSupported (int32u CompressionID)
{
switch (CompressionID)
{
case 1235 :
case 1237 :
case 1238 :
case 1241 :
case 1242 :
case 1243 :
case 1250 :
case 1251 :
case 1252 :
case 1253 :
case 1256 :
case 1258 :
case 1259 :
case 1260 :
return true;
default : return false;
}
}
//---------------------------------------------------------------------------
static const int32u Vc3_CompressedFrameSize_RI(int64u Size, int16u Width, int16u Height)
{
int32u WidthBlock = Width / 16;
if (Width % 16)
WidthBlock++; // Additional block with padding
int32u HeightBlock = Height / 16;
if (Height % 16)
HeightBlock++; // Additional block with padding
Size *= WidthBlock * HeightBlock;
if (false) //TODO: Alpha
Size /= 12240;
else
Size /= 8160;
int32u Remaining = Size % 4096;
if (Remaining >= 2048) // Round-up limit
Size += 4096 - Remaining; // Round up
else
Size -= Remaining; // Round down
if (Size < 8192) // Lower size limit
Size = 8192;
return (int32u)Size;
}
//---------------------------------------------------------------------------
static const int32u Vc3_CompressedFrameSize(int32u CompressionID, int16u Width, int16u Height)
{
int32u Size;
switch (CompressionID)
{
case 1253 :
case 1274 :
Size= 188416; break;
case 1258 :
Size= 212992; break;
case 1252 :
Size= 303104; break;
case 1259 :
case 1260 :
Size= 417792; break;
case 1250 :
case 1251 :
Size= 458752; break;
case 1237 :
case 1242 :
case 1244 :
case 1273 :
Size= 606208; break;
case 1235 :
case 1238 :
case 1241 :
case 1243 :
case 1271 :
case 1272 :
Size= 917504; break;
case 1256 :
case 1270 :
Size=1835008; break;
default : return 0;
}
if (CompressionID >= 1270)
return Vc3_CompressedFrameSize_RI(Size, Width, Height); // Adaptative
return Size;
};
//---------------------------------------------------------------------------
static const int8u Vc3_SBD(int32u SBD) //Sample Bit Depth
{
switch (SBD)
{
case 1 : return 8;
case 2 : return 10;
case 3 : return 12;
default: return 0;
}
};
//---------------------------------------------------------------------------
static const int8u Vc3_SBD_FromCID (int32u CompressionID)
{
switch (CompressionID)
{
case 1237 :
case 1238 :
case 1242 :
case 1243 :
case 1251 :
case 1252 :
case 1253 :
case 1258 :
case 1259 :
case 1260 :
return 8;
case 1235 :
case 1241 :
case 1250 :
case 1256 :
return 10;
default : return 0;
}
}
//---------------------------------------------------------------------------
static const char* Vc3_FFC[4]=
{
"",
"Progressive",
"Interlaced",
"Interlaced",
};
//---------------------------------------------------------------------------
static const char* Vc3_FFC_ScanOrder[4]=
{
"",
"",
"TFF",
"BFF",
};
//---------------------------------------------------------------------------
static const char* Vc3_FFE[2]=
{
"Interlaced",
"Progressive",
};
//---------------------------------------------------------------------------
static const char* Vc3_SST[2]=
{
"Progressive",
"Interlaced",
};
//---------------------------------------------------------------------------
static const char* Vc3_SST_FromCID (int32u CompressionID)
{
switch (CompressionID)
{
case 1235 :
case 1237 :
case 1238 :
case 1250 :
case 1251 :
case 1252 :
case 1253 :
case 1256 :
case 1258 :
case 1259 :
case 1270:
case 1271:
case 1272:
case 1273:
case 1274:
return Vc3_SST[0];
case 1241 :
case 1242 :
case 1243 :
case 1260 :
return Vc3_SST[1];
default : return "";
}
}
//---------------------------------------------------------------------------
static const int16u Vc3_SPL_FromCID (int32u CompressionID)
{
switch (CompressionID)
{
case 1258 :
return 960;
case 1250 :
case 1251 :
case 1252 :
return 1280;
case 1259:
case 1260:
case 1244:
return 1440;
case 1235 :
case 1237 :
case 1238 :
case 1241 :
case 1242 :
case 1243 :
case 1253 :
return 1920;
default : return 0;
}
}
//---------------------------------------------------------------------------
static const int16u Vc3_ALPF_PerFrame_FromCID (int32u CompressionID)
{
switch (CompressionID)
{
case 1250 :
case 1251 :
case 1252 :
case 1258 :
return 720;
case 1235 :
case 1237 :
case 1238 :
case 1241 :
case 1242 :
case 1243 :
case 1253 :
case 1256 :
case 1259 :
case 1260 :
return 1080;
default : return 0;
}
}
//---------------------------------------------------------------------------
static const char* Vc3_CLV[4]=
{
"BT.709",
"BT.2020 non-constant",
"BT.2020 constant",
"", //Out of band
};
//---------------------------------------------------------------------------
static const char* Vc3_CLF[2]=
{
"YUV",
"RGB",
};
//---------------------------------------------------------------------------
static const char* Vc3_CLR_FromCID (int32u CompressionID)
{
switch (CompressionID)
{
case 1235 :
case 1237 :
case 1238 :
case 1241 :
case 1242 :
case 1243 :
case 1250 :
case 1251 :
case 1252 :
case 1253 :
case 1258 :
case 1259 :
case 1260 :
case 1271:
case 1272:
case 1273:
case 1274:
return Vc3_CLF[0];
case 1256 :
case 1270 :
return Vc3_CLF[1];
default : return "";
}
};
//---------------------------------------------------------------------------
static const char* Vc3_SSC[4]=
{
"4:2:2",
"4:2:0",
"4:4:4",
"",
};
//---------------------------------------------------------------------------
static const char* Vc3_SSC_FromCID (int32u CompressionID)
{
switch (CompressionID)
{
case 1235 :
case 1237 :
case 1238 :
case 1241 :
case 1242 :
case 1243 :
case 1250 :
case 1251 :
case 1252 :
case 1253 :
case 1258 :
case 1259 :
case 1260 :
case 1271:
case 1272:
case 1273:
case 1274:
return Vc3_SSC[0];
case 1256 :
case 1270:
return Vc3_SSC[2];
default : return "";
}
};
//***************************************************************************
// Constructor/Destructor
//***************************************************************************
//---------------------------------------------------------------------------
File_Vc3::File_Vc3()
:File__Analyze()
{
//In
Frame_Count_Valid=2;
FrameRate=0;
//Parsers
#if defined(MEDIAINFO_CDP_YES)
Cdp_Parser=NULL;
#endif //defined(MEDIAINFO_CDP_YES)
//Temp
FFC_FirstFrame=(int8u)-1;
}
//---------------------------------------------------------------------------
File_Vc3::~File_Vc3()
{
#if defined(MEDIAINFO_CDP_YES)
delete Cdp_Parser; //Cdp_Parser=NULL;
#endif //defined(MEDIAINFO_CDP_YES)
}
//***************************************************************************
// Streams management
//***************************************************************************
//---------------------------------------------------------------------------
void File_Vc3::Streams_Fill()
{
//Filling
Stream_Prepare(Stream_Video);
Fill(Stream_Video, 0, Video_Format, "VC-3");
Fill(Stream_Video, 0, Video_BitRate_Mode, VBR?"VBR":"CBR");
if (!VBR && FrameRate && Vc3_CompressedFrameSize(CID, SPL, ALPF*(SST?2:1)))
Fill(Stream_Video, 0, Video_BitRate, Vc3_CompressedFrameSize(CID, SPL, ALPF*(SST?2:1))*8*FrameRate, 0);
Fill(Stream_Video, 0, Video_Format_Version, __T("Version ")+Ztring::ToZtring(HVN));
Fill(Stream_Video, 0, Video_Format_Profile, string(Vc3_FromCID_Profile(CID))+'@'+Vc3_FromCID_Level(CID));
if (FFC_FirstFrame!=(int8u)-1)
Fill(Stream_Video, 0, Video_ScanOrder, Vc3_FFC_ScanOrder[FFC_FirstFrame]);
if (Vc3_FromCID_IsSupported(CID))
{
if (Vc3_SPL_FromCID(CID))
Fill(Stream_Video, 0, Video_Width, Vc3_SPL_FromCID(CID));
if (Vc3_ALPF_PerFrame_FromCID(CID))
Fill(Stream_Video, 0, Video_Height, Vc3_ALPF_PerFrame_FromCID(CID));
if (Vc3_SBD_FromCID(CID))
Fill(Stream_Video, 0, Video_BitDepth, Vc3_SBD_FromCID(CID));
Fill(Stream_Video, 0, Video_ScanType, Vc3_SST_FromCID(CID));
Fill(Stream_Video, 0, Video_ColorSpace, Vc3_CLR_FromCID(CID));
if (!strcmp(Vc3_CLR_FromCID(CID), "YUV")) // YUV
Fill(Stream_Video, 0, Video_ChromaSubsampling, Vc3_SSC_FromCID(CID));
Fill(Stream_Video, 0, Video_PixelAspectRatio, Video_Width==1440?1.333:1.0);
}
else if (HVN <= 3)
{
Fill(Stream_Video, 0, Video_Width, SPL);
Fill(Stream_Video, 0, Video_Height, ALPF*(SST?2:1));
Fill(Stream_Video, 0, Video_BitDepth, Vc3_SBD(SBD));
Fill(Stream_Video, 0, Video_ScanType, Vc3_SST[SST]);
Fill(Stream_Video, 0, Video_ColorSpace, (string(Vc3_CLF[CLF])+(ALP?"A":"")));
if (!CLF) // YUV
Fill(Stream_Video, 0, Video_ChromaSubsampling, (string(Vc3_SSC[SSC])+(ALP?"4":"")));
if (PARC && PARN)
Fill(Stream_Video, 0, Video_PixelAspectRatio, ((float64)PARC)/PARN);
}
if (!TimeCode_FirstFrame.empty())
Fill(Stream_Video, 0, Video_TimeCode_FirstFrame, TimeCode_FirstFrame);
if (FrameInfo.DUR!=(int64u)-1)
Fill(Stream_Video, 0, Video_FrameRate, 1000000000.0/FrameInfo.DUR, 3);
}
//---------------------------------------------------------------------------
void File_Vc3::Streams_Finish()
{
#if defined(MEDIAINFO_CDP_YES)
if (Cdp_Parser && !Cdp_Parser->Status[IsFinished] && Cdp_Parser->Status[IsAccepted])
{
Finish(Cdp_Parser);
for (size_t StreamPos=0; StreamPos<Cdp_Parser->Count_Get(Stream_Text); StreamPos++)
{
Merge(*Cdp_Parser, Stream_Text, StreamPos, StreamPos);
Ztring MuxingMode=Cdp_Parser->Retrieve(Stream_Text, StreamPos, "MuxingMode");
Fill(Stream_Text, StreamPos, "MuxingMode", __T("VC-3 / Nexio user data / ")+MuxingMode, true);
}
Ztring LawRating=Cdp_Parser->Retrieve(Stream_General, 0, General_LawRating);
if (!LawRating.empty())
Fill(Stream_General, 0, General_LawRating, LawRating, true);
Ztring Title=Cdp_Parser->Retrieve(Stream_General, 0, General_Title);
if (!Title.empty() && Retrieve(Stream_General, 0, General_Title).empty())
Fill(Stream_General, 0, General_Title, Title);
}
#endif //defined(MEDIAINFO_CDP_YES)
}
//***************************************************************************
// Buffer - Demux
//***************************************************************************
//---------------------------------------------------------------------------
#if MEDIAINFO_DEMUX
bool File_Vc3::Demux_UnpacketizeContainer_Test()
{
//Handling of the extra 4 bytes in a MOV container having 2 frames in a sample (see "Frame size?" part)
if (IsSub && Buffer_Offset+4==Buffer_Size)
{
int32u FrameSize=BigEndian2int32u(Buffer+Buffer_Offset);
if (FrameSize && (Buffer_Offset%FrameSize)==0) //Checking coherency with last frame size
{
Skip_B4( "Frame size?");
Buffer_Offset+=4;
}
}
if (Buffer_Offset+0x2C>Buffer_Size)
return false;
ALPF= BigEndian2int16u(Buffer+Buffer_Offset+0x18);
SPL = BigEndian2int16u(Buffer+Buffer_Offset+0x1A);
SST =(BigEndian2int16u(Buffer+Buffer_Offset+0x22)&(1<<2)?true:false);
CID = BigEndian2int32u(Buffer+Buffer_Offset+0x28);
size_t Size=Vc3_CompressedFrameSize(CID, SPL, ALPF*(SST?2:1));
if (!Size)
{
if (!IsSub)
{
Reject();
return false;
}
Size=Buffer_Size; //Hoping that the packet is complete. TODO: add a flag in the container parser saying if the packet is complete
}
Demux_Offset=Buffer_Offset+Size;
if (Demux_Offset>Buffer_Size && !Config->IsFinishing)
return false; //No complete frame
Demux_UnpacketizeContainer_Demux();
return true;
}
#endif //MEDIAINFO_DEMUX
//***************************************************************************
// Buffer - Global
//***************************************************************************
//---------------------------------------------------------------------------
void File_Vc3::Read_Buffer_Unsynched()
{
#if defined(MEDIAINFO_CDP_YES)
if (Cdp_Parser)
Cdp_Parser->Open_Buffer_Unsynch();
#endif //defined(MEDIAINFO_CDP_YES)
}
//***************************************************************************
// Buffer - Per element
//***************************************************************************
//---------------------------------------------------------------------------
bool File_Vc3::Header_Begin()
{
//Handling of the extra 4 bytes in a MOV container having 2 frames in a sample
if (IsSub && Buffer_Offset+4==Buffer_Size)
{
int32u FrameSize=BigEndian2int32u(Buffer+Buffer_Offset);
if (FrameSize && (Buffer_Offset%FrameSize)==0)
{
Skip_B4( "Frame size?");
Buffer_Offset+=4;
if (Frame_Count_InThisBlock==Frame_Count)
{
Fill(Stream_Video, 0, "FramesPerContainerBlock", Frame_Count_InThisBlock);
}
if (!Status[IsFilled] && Frame_Count>=Frame_Count_Valid && Buffer_Offset+Element_Size>=Buffer_Size)
{
Fill("VC-3");
if (!IsSub && Config->ParseSpeed<1.0)
Finish("VC-3");
}
}
}
if (Buffer_Offset+0x00000280>Buffer_Size)
return false;
return true;
}
//---------------------------------------------------------------------------
void File_Vc3::Header_Parse()
{
ALPF= BigEndian2int16u(Buffer+Buffer_Offset+0x18);
SPL = BigEndian2int16u(Buffer+Buffer_Offset+0x1A);
SST =(BigEndian2int16u(Buffer+Buffer_Offset+0x22)&(1<<2)?true:false);
CID = BigEndian2int32u(Buffer+Buffer_Offset+0x28);
Header_Fill_Code(0, "Frame");
size_t Size=Vc3_CompressedFrameSize(CID, SPL, ALPF*(SST?2:1));
if (!Size)
{
if (!IsSub)
{
Reject();
return;
}
Size=Buffer_Size; //Hoping that the packet is complete. TODO: add a flag in the container parser saying if the packet is complete
}
Header_Fill_Size(Size);
}
//---------------------------------------------------------------------------
void File_Vc3::Data_Parse()
{
//Parsing
if (Status[IsFilled])
{
Skip_XX(Element_Size, "Data");
}
else
{
Element_Info1(Frame_Count);
Element_Begin1("Header");
HeaderPrefix();
if (HVN <= 3)
{
CodingControlA();
Skip_XX(16, "Reserved");
ImageGeometry();
Skip_XX( 5, "Reserved");
CompressionID();
CodingControlB();
Skip_XX( 3, "Reserved");
TimeCode();
Skip_XX(38, "Reserved");
UserData();
Skip_XX( 3, "Reserved");
MacroblockScanIndices();
Element_End0();
Element_Begin1("Payload");
Skip_XX(Element_Size-Element_Offset-4, "Data");
Element_End0();
Element_Begin1("EOF");
Skip_B4( CRCF?"CRC":"Signature");
Element_End0();
}
else
{
Element_End0();
Skip_XX(Element_Size-Element_Offset, "Data");
}
}
FILLING_BEGIN();
Frame_Count++;
Frame_Count_InThisBlock++;
if (Frame_Count_NotParsedIncluded!=(int64u)-1)
Frame_Count_NotParsedIncluded++;
if (FrameRate)
{
FrameInfo.PTS=FrameInfo.DTS+=float64_int64s(1000000000/FrameRate);
FrameInfo.DUR=float64_int64s(1000000000/FrameRate);
}
else if (FrameInfo.DUR!=(int64u)-1)
{
if (Frame_Count_InThisBlock==1)
FrameInfo.DUR/=Buffer_Size/Element_Size;
FrameInfo.PTS=FrameInfo.DTS+=FrameInfo.DUR;
}
else
{
FrameInfo.PTS=FrameInfo.DTS=FrameInfo.DUR=(int64u)-1;
}
if (!Status[IsAccepted])
Accept("VC-3");
if (!Status[IsFilled] && Frame_Count>=Frame_Count_Valid && Buffer_Offset+Element_Size>=Buffer_Size)
{
Fill("VC-3");
if (!IsSub && Config->ParseSpeed<1.0)
Finish("VC-3");
}
FILLING_END();
}
//***************************************************************************
// Elements
//***************************************************************************
//---------------------------------------------------------------------------
void File_Vc3::HeaderPrefix()
{
//Parsing
Element_Begin1("Header Prefix");
Get_B4 (HS, "HS, Header Size");
Get_B1 (HVN, "HVN, Header Version Number");
Element_End0();
FILLING_BEGIN();
if (HS<0x00000280)
Reject("VC-3");
FILLING_END();
}
//---------------------------------------------------------------------------
void File_Vc3::CodingControlA()
{
//Parsing
Element_Begin1("Coding Control A");
BS_Begin();
int8u FFC;
Mark_0();
Mark_0();
Mark_0();
Get_SB ( VBR, "VBR, Variable Bitrate Encoding");
Mark_0();
Mark_0();
Get_S1 (2, FFC, "FFC, Field/Frame Count"); Param_Info1(Vc3_FFC[FFC]);
Mark_1();
Mark_0();
Skip_SB( "MACF, Macroblock Adaptive Control flag");
Get_SB ( CRCF, "CRCF, CRC flag");
Mark_0();
Mark_0();
Mark_0();
Mark_0();
Mark_1();
Mark_0();
Mark_1();
Mark_0();
Mark_0();
Get_SB ( PMA, "PMA, Pre-multiplied Alpha");
Get_SB ( LLA, "LLA, Lossless Alpha flag");
Get_SB ( ALP, "ALP, Alpha flag");
BS_End();
Element_End0();
FILLING_BEGIN();
if (FFC_FirstFrame==(int8u)-1)
FFC_FirstFrame=FFC;
FILLING_END();
}
//---------------------------------------------------------------------------
void File_Vc3::ImageGeometry()
{
//Parsing
int8u PARC0, PARC1, PARN0, PARN1;
Element_Begin1("Image Geometry");
Get_B2 (ALPF, "Active lines-per-frame");
Get_B2 (SPL, "Samples-per-line");
BS_Begin();
Mark_0();
Mark_0();
Mark_0();
Mark_0();
Get_S1 (2, PARC1, "PARC1, Pixel Aspect Ratio C1");
Get_S1 (2, PARN1, "PARN1, Pixel Aspect Ratio N1");
BS_End();
Skip_B2( "Number of active lines");
Get_B1 (PARC0, "PARC0, Pixel Aspect Ratio C0");
Get_B1 (PARN0, "PARN0, Pixel Aspect Ratio N0");
PARC=(((int16u)PARC1)<<8)|PARC0;
PARN=(((int16u)PARN1)<<8)|PARN0;
BS_Begin();
Get_S1 (3, SBD, "Sample bit depth"); Param_Info1(Vc3_SBD(SBD));
Mark_1();
Mark_1();
Mark_0();
Mark_0();
Mark_0();
Mark_1();
Mark_0();
Mark_0();
Mark_0();
Mark_1();
Get_SB ( SST, "Source scan type"); Param_Info1(Vc3_SST[SST]);
Mark_0();
Mark_0();
BS_End();
Element_End0();
}
//---------------------------------------------------------------------------
void File_Vc3::CompressionID()
{
//Parsing
Element_Begin1("Compression ID");
int32u Data;
Get_B4 (Data, "Compression ID");
Element_End0();
FILLING_BEGIN();
CID=Data;
FILLING_END();
}
//---------------------------------------------------------------------------
void File_Vc3::CodingControlB()
{
//Parsing
Element_Begin1("Coding Control B");
BS_Begin();
Info_SB( FFE, "FFE, Field/Frame Count"); Param_Info1(Vc3_FFE[FFE]);
Get_S1 (2, SSC, "SSC, Sub Sampling Control"); Param_Info1(Vc3_SSC[SSC]);
Mark_0();
Mark_0();
Get_S1 (2, CLV, "CLR, Color Volume"); Param_Info1(Vc3_CLV[CLV]);
Get_SB ( CLF, "CLF, Color Format"); Param_Info1(Vc3_CLF[CLF]);
BS_End();
Element_End0();
}
//---------------------------------------------------------------------------
void File_Vc3::TimeCode()
{
//Parsing
Element_Begin1("Time Code");
bool TCP;
BS_Begin();
Get_SB ( TCP, "TCP, Time Code Present");
Mark_0();
Mark_0();
Mark_0();
Mark_0();
Mark_0();
Mark_0();
if (TCP)
Mark_0();
else
{
TCP=Peek_SB();
if (TCP)
Skip_SB( "TCP, Time Code Present (wrong order)");
else
Mark_0();
}
if (TCP)
{
Element_Begin1("Time Code");
int8u HHT, HHU, MMT, MMU, SST, SSU, FFT, FFU;
bool DF;
Skip_S1(4, "Binary Group 1");
Get_S1 (4, FFU, "Units of Frames");
Skip_S1(4, "Binary Group 2");
Skip_SB( "Color Frame");
Get_SB ( DF, "Drop Frame");
Get_S1 (2, FFT, "Tens of Frames");
Skip_S1(4, "Binary Group 3");
Get_S1 (4, SSU, "Units of Seconds");
Skip_S1(4, "Binary Group 4");
Skip_SB( "Field ID");
Get_S1 (3, SST, "Tens of Seconds");
Skip_S1(4, "Binary Group 5");
Get_S1 (4, MMU, "Units of Minutes");
Skip_S1(4, "Binary Group 6");
Skip_SB( "X");
Get_S1 (3, MMT, "Tens of Minutes");
Skip_S1(4, "Binary Group 7");
Get_S1 (4, HHU, "Units of Hours");
Skip_S1(4, "Binary Group 8");
Skip_SB( "X");
Skip_SB( "X");
Get_S1 (2, HHT, "Tens of Hours");
FILLING_BEGIN();
if (TimeCode_FirstFrame.empty() && FFU<10 && SSU<10 && SST<6 && MMU<10 && MMT<6 && HHU<10)
{
std::ostringstream S;
S<<(size_t)HHT<<(size_t)HHU<<':'<<(size_t)MMT<<(size_t)MMU<<':'<<(size_t)SST<<(size_t)SSU<<(DF?';':':')<<(size_t)FFT<<(size_t)FFU;
TimeCode_FirstFrame=S.str();
}
FILLING_END();
Element_End0();
BS_End();
}
else
{
BS_End();
Skip_B8( "Junk");
}
Element_End0();
}
//---------------------------------------------------------------------------
void File_Vc3::UserData()
{
//Parsing
int8u UserDataLabel;
Element_Begin1("User Data Control");
BS_Begin();
Get_S1 (4, UserDataLabel, "User Data Label");
Mark_0();
Mark_0();
Mark_0();
Mark_1();
BS_End();
Element_End0();
Element_Begin1("User Data Payload");
switch (UserDataLabel)
{
case 0x00: Skip_XX(260, "Reserved"); break;
case 0x08: UserData_8(); break;
default : Skip_XX(260, "Reserved for future use");
}
Element_End0();
}
//---------------------------------------------------------------------------
void File_Vc3::MacroblockScanIndices()
{
Element_Begin1("Macroblock Scan Indices Control");
Skip_XX(9, "ToDo");
Element_End0();
Element_Begin1("Macroblock Scan Indices Payload");
Skip_XX(HS-Element_Offset, "ToDo");
Element_End0();
}
//---------------------------------------------------------------------------
void File_Vc3::UserData_8()
{
if (Element_Offset + 0x104 < Element_Size
&& Buffer[Buffer_Offset + (size_t)Element_Offset + 0xBA] == 0x96
&& Buffer[Buffer_Offset + (size_t)Element_Offset + 0xBB] == 0x69)
{
Skip_XX(0xBA, "Nexio private data?");
#if defined(MEDIAINFO_CDP_YES)
if (Cdp_Parser==NULL)
{
Cdp_Parser=new File_Cdp;
Open_Buffer_Init(Cdp_Parser);
Frame_Count_Valid=300;
}
if (!Cdp_Parser->Status[IsFinished])
{
((File_Cdp*)Cdp_Parser)->AspectRatio=16.0/9.0;
Open_Buffer_Continue(Cdp_Parser, Buffer + Buffer_Offset + (size_t)Element_Offset, 0x49);
}
Element_Offset+=0x49;
Skip_B1( "Nexio private data?");
#else //MEDIAINFO_CDP_YES
Skip_XX(0x4A, "CDP data");
#endif //MEDIAINFO_CDP_YES
}
else
Skip_XX(260, "Nexio private data?");
}
//***************************************************************************
// C++
//***************************************************************************
} //NameSpace
#endif //MEDIAINFO_VC3_*
↑ V1048 The 'FrameInfo.DUR' variable was assigned the same value.
↑ V1051 Consider checking for misprints. It's possible that the 'WidthBlock' should be checked here.
↑ V1051 Consider checking for misprints. It's possible that the 'HeightBlock' should be checked here.
↑ V550 An odd precise comparison. It's probably better to use a comparison with defined precision: fabs(FrameRate) > Epsilon.
↑ V688 The 'SST' local variable possesses the same name as one of the class members, which can result in a confusion.
↑ V730 Not all members of a class are initialized inside the constructor. Consider inspecting: HS, CID, ALPF, SPL, PARC, PARN, ...