/* 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"
//---------------------------------------------------------------------------
//***************************************************************************
// Constants (Common)
//***************************************************************************
//---------------------------------------------------------------------------
#if defined(MEDIAINFO_MPEG4V_YES) || defined(MEDIAINFO_MPEG4_YES) || defined(MEDIAINFO_MXF_YES)
//---------------------------------------------------------------------------
#include "MediaInfo/MediaInfo_Config_MediaInfo.h"
#if MEDIAINFO_EVENTS
#include "MediaInfo/MediaInfo_Events_Internal.h"
#endif //MEDIAINFO_EVENTS
#include "ZenLib/Conf.h"
#include "ZenLib/Utils.h"
using namespace ZenLib;
namespace MediaInfoLib
{
//---------------------------------------------------------------------------
extern const float64 Mpegv_frame_rate[16];
//---------------------------------------------------------------------------
const char* Mpeg4v_Profile_Level(int32u Profile_Level)
{
switch (Profile_Level)
{
case B8(00000001) : return "Simple@L1";
case B8(00000010) : return "Simple@L2";
case B8(00000011) : return "Simple@L3";
case B8(00000100) : return "Simple@L4a";
case B8(00000101) : return "Simple@L5";
case B8(00000110) : return "Simple@L6";
case B8(00001000) : return "Simple@L0";
case B8(00001001) : return "Simple@L0b";
case B8(00010000) : return "Simple Scalable@L0";
case B8(00010001) : return "Simple Scalable@L1";
case B8(00010010) : return "Simple Scalable@L2";
case B8(00010101) : return "AVC"; //For descriptors
case B8(00100001) : return "Core@L1";
case B8(00100010) : return "Core@L2";
case B8(00110010) : return "Main@L2";
case B8(00110011) : return "Main@L3";
case B8(00110100) : return "Main@L4";
case B8(01000010) : return "N-bit@L2";
case B8(01010001) : return "Scalable Texture@L1";
case B8(01100001) : return "Simple Face Animation@L1";
case B8(01100010) : return "Simple Face Animation@L2";
case B8(01100011) : return "Simple FBA@L1";
case B8(01100100) : return "Simple FBA@L2";
case B8(01110001) : return "Basic Animated Texture@L1";
case B8(01110010) : return "Basic Animated Texture@L2";
case B8(01111111) : return "AVC"; //For descriptors
case B8(10000001) : return "Hybrid@L1";
case B8(10000010) : return "Hybrid@L2";
case B8(10010001) : return "Advanced Real Time Simple@L1";
case B8(10010010) : return "Advanced Real Time Simple@L2";
case B8(10010011) : return "Advanced Real Time Simple@L3";
case B8(10010100) : return "Advanced Real Time Simple@L4";
case B8(10100001) : return "Core Scalable@L1";
case B8(10100010) : return "Core Scalable@L2";
case B8(10100011) : return "Core Scalable@L3";
case B8(10110001) : return "Advanced Coding Efficiency@L1";
case B8(10110010) : return "Advanced Coding Efficiency@L2";
case B8(10110011) : return "Advanced Coding Efficiency@L3";
case B8(10110100) : return "Advanced Coding Efficiency@L4";
case B8(11000001) : return "Advanced Core@L1";
case B8(11000010) : return "Advanced Core@L2";
case B8(11010001) : return "Advanced Scalable Texture@L1";
case B8(11010010) : return "Advanced Scalable Texture@L2";
case B8(11010011) : return "Advanced Scalable Texture@L3";
case B8(11100001) : return "Simple Studio@L1";
case B8(11100010) : return "Simple Studio@L2";
case B8(11100011) : return "Simple Studio@L3";
case B8(11100100) : return "Simple Studio@L4";
case B8(11100101) : return "Core Studio@L1";
case B8(11100110) : return "Core Studio@L2";
case B8(11100111) : return "Core Studio@L3";
case B8(11101000) : return "Core Studio@L4";
case B8(11101011) : return "Simple Studio@L5";
case B8(11101100) : return "Simple Studio@L6";
case B8(11110000) : return "Advanced Simple@L0";
case B8(11110001) : return "Advanced Simple@L1";
case B8(11110010) : return "Advanced Simple@L2";
case B8(11110011) : return "Advanced Simple@L3";
case B8(11110100) : return "Advanced Simple@L4";
case B8(11110101) : return "Advanced Simple@L5";
case B8(11110111) : return "Advanced Simple@L3b";
case B8(11111000) : return "Fine Granularity Scalable@L0";
case B8(11111001) : return "Fine Granularity Scalable@L1";
case B8(11111010) : return "Fine Granularity Scalable@L2";
case B8(11111011) : return "Fine Granularity Scalable@L3";
case B8(11111100) : return "Fine Granularity Scalable@L4";
case B8(11111101) : return "Fine Granularity Scalable@L5";
default : return "";
}
}
//---------------------------------------------------------------------------
} //NameSpace
//---------------------------------------------------------------------------
#endif //...
//---------------------------------------------------------------------------
//***************************************************************************
//
//***************************************************************************
//---------------------------------------------------------------------------
#if defined(MEDIAINFO_MPEG4V_YES)
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#include "MediaInfo/Video/File_Mpeg4v.h"
#include "ZenLib/BitStream.h"
#include "ZenLib/Utils.h"
using namespace ZenLib;
//---------------------------------------------------------------------------
namespace MediaInfoLib
{
//***************************************************************************
// Constants
//***************************************************************************
//---------------------------------------------------------------------------
const char* Mpeg4v_ChromaSubsampling[]=
{
"",
"4:2:0",
"4:2:2",
"4:4:4",
};
//---------------------------------------------------------------------------
const char* Mpeg4v_visual_object_type[]=
{
"",
"video",
"still texture",
"mesh",
"FBA",
"3D mesh",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
};
//---------------------------------------------------------------------------
const char* Mpeg4v_visual_object_verid[]=
{
"",
"ISO/IEC 14496-2",
"ISO/IEC 14496-2 AMD 1",
"ISO/IEC 14496-2 AMD 2",
"ISO/IEC 14496-2 AMD 3 (Studio)",
"ISO/IEC 14496-2 AMD 4 (SVP)",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
};
//---------------------------------------------------------------------------
const char* Mpeg4v_video_object_layer_verid[]=
{
"",
"ISO/IEC 14496-2",
"ISO/IEC 14496-2 AMD 1",
"ISO/IEC 14496-2 AMD 2",
"ISO/IEC 14496-2 AMD 3 (Studio)",
"ISO/IEC 14496-2 AMD 4 (SVP)",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
};
//---------------------------------------------------------------------------
const char* Mpeg4v_vop_coding_type[]=
{
"I",
"P",
"B",
"S",
};
//---------------------------------------------------------------------------
const char* Mpegv_colour_primaries(int8u colour_primaries);
const char* Mpegv_transfer_characteristics(int8u transfer_characteristics);
const char* Mpegv_matrix_coefficients(int8u matrix_coefficients);
const char* Mpegv_matrix_coefficients_ColorSpace(int8u matrix_coefficients);
//***************************************************************************
// Constructor/Destructor
//***************************************************************************
//---------------------------------------------------------------------------
File_Mpeg4v::File_Mpeg4v()
:File__Analyze()
{
//Config
#if MEDIAINFO_TRACE
Trace_Layers_Update(8); //Stream
#endif //MEDIAINFO_TRACE
Trusted_Multiplier=2;
MustSynchronize=true;
Buffer_TotalBytes_FirstSynched_Max=64*1024;
PTS_DTS_Needed=true;
StreamSource=IsStream;
//In
Frame_Count_Valid=0;
FrameIsAlwaysComplete=false;
//Temp
video_object_layer_start_IsParsed=false;
colour_description=false;
}
//---------------------------------------------------------------------------
void File_Mpeg4v::OnlyVOP()
{
//Default stream values
Synched_Init();
Streams[0xB3].Searching_Payload=true; //group_of_vop_start
Streams[0xB6].Searching_Payload=true; //vop_start
}
//***************************************************************************
// Buffer - Synchro
//***************************************************************************
//---------------------------------------------------------------------------
bool File_Mpeg4v::Synched_Test()
{
//Must have enough buffer for having header
if (Buffer_Offset+4>Buffer_Size)
return false;
//Quick test of synchro
if (Buffer[Buffer_Offset ]!=0x00
|| Buffer[Buffer_Offset+1]!=0x00
|| Buffer[Buffer_Offset+2]!=0x01)
{
Synched=false;
return true;
}
//Quick search
if (!Header_Parser_QuickSearch())
return false;
#if MEDIAINFO_IBIUSAGE
bool RandomAccess=Buffer[Buffer_Offset+3]==0xB0; //SequenceHeader
if (RandomAccess)
Ibi_Add();
#endif //MEDIAINFO_IBIUSAGE
//We continue
return true;
}
//---------------------------------------------------------------------------
void File_Mpeg4v::Synched_Init()
{
if (!Frame_Count_Valid)
Frame_Count_Valid=Config->ParseSpeed>=0.3?30:2;
//Count of a Packets
IVOP_Count=0;
PVOP_Count=0;
BVOP_Count=0;
BVOP_Count_Max=0;
SVOP_Count=0;
NVOP_Count=0;
Interlaced_Top=0;
Interlaced_Bottom=0;
Frame_Count_InThisBlock_Max=0;
if (Frame_Count_NotParsedIncluded==(int64u)-1)
Frame_Count_NotParsedIncluded=0; //No Frame_Count_NotParsedIncluded in the container
//From VOL, needed in VOP
fixed_vop_time_increment=0;
Time_Begin_Seconds=(int32u)-1;
Time_End_Seconds=(int32u)-1;
bit_rate=(int32u)-1;
vbv_buffer_size=(int32u)-1;
Time_Begin_MilliSeconds=(int16u)-1;
Time_End_MilliSeconds=(int16u)-1;
object_layer_width=0;
object_layer_height=0;
vop_time_increment_resolution=0;
visual_object_verid=1;
profile_and_level_indication=0;
no_of_sprite_warping_points=0;
aspect_ratio_info=0;
par_width=0;
par_height=0;
bits_per_pixel=8;
shape=0;
sprite_enable=0;
estimation_method=0;
chroma_format=(int8u)-1;
colour_primaries=(int8u)-1;
transfer_characteristics=(int8u)-1;
matrix_coefficients=(int8u)-1;
frame_rate_code=(int8u)-1;
quarter_sample=false;
low_delay=false;
load_intra_quant_mat=false;
load_nonintra_quant_mat=false;
load_intra_quant_mat_grayscale=false;
load_nonintra_quant_mat_grayscale=false;
interlaced=false;
newpred_enable=0;
visual_object_type=0;
time_size=0;
reduced_resolution_vop_enable=0;
scalability=0;
enhancement_type=0;
complexity_estimation_disable=false;
opaque=false;
transparent=false;
intra_cae=false;
inter_cae=false;
no_update=false;
upsampling=false;
intra_blocks=false;
inter_blocks=false;
inter4v_blocks=false;
not_coded_blocks=false;
dct_coefs=false;
dct_lines=false;
vlc_symbols=false;
vlc_bits=false;
apm=false;
npm=false;
interpolate_mc_q=false;
forw_back_mc_q=false;
halfpel2=false;
halfpel4=false;
sadct=false;
quarterpel=false;
quant_type=false;
rgb_components=false;
if (!IsSub)
FrameInfo.DTS=0;
//Default stream values
Streams.resize(0x100);
Streams[0x00].Searching_Payload=true; //video_object_start
if (StreamSource!=IsStream) //TODO: better detection in all cases. Currently there are too many false-positives if we test all files
Streams[0x20].Searching_Payload=true; //video_object_layer_start
Streams[0xB0].Searching_Payload=true; //visual_object_sequence_start
NextCode_Add(0x00); //video_object_start
if (StreamSource!=IsStream) //TODO: better detection in all cases. Currently there are too many false-positives if we test all files
NextCode_Add(0x20); //video_object_layer_start
NextCode_Add(0xB0); //visual_object_sequence_start
for (int8u Pos=0xFF; Pos>=0xB9; Pos--)
Streams[Pos].Searching_Payload=true; //Testing MPEG-PS
}
//***************************************************************************
// Streams management
//***************************************************************************
//---------------------------------------------------------------------------
void File_Mpeg4v::Streams_Fill()
{
//Filling
Stream_Prepare(Stream_Video);
Fill(Stream_Video, 0, Video_Format, "MPEG-4 Visual");
Fill(Stream_Video, 0, Video_Codec, "MPEG-4V");
if (profile_and_level_indication>0)
{
Fill(Stream_Video, 0, Video_Format_Profile, Mpeg4v_Profile_Level(profile_and_level_indication));
Fill(Stream_Video, 0, Video_Codec_Profile, Mpeg4v_Profile_Level(profile_and_level_indication));
}
if (frame_rate_code!=(int8u)-1)
Fill(Stream_Video, StreamPos_Last, Video_FrameRate, Mpegv_frame_rate[frame_rate_code]);
if (bit_rate!=(int32u)-1)
Fill(Stream_Video, StreamPos_Last, Video_BitRate_Nominal, bit_rate*400);
if (vbv_buffer_size!=(int32u)-1)
Fill(Stream_Video, StreamPos_Last, Video_BufferSize, vbv_buffer_size*2048);
if (fixed_vop_time_increment && vop_time_increment_resolution)
Fill(Stream_Video, StreamPos_Last, Video_FrameRate, ((float)vop_time_increment_resolution)/fixed_vop_time_increment);
if (object_layer_height)
{
Fill(Stream_Video, StreamPos_Last, Video_Width, object_layer_width);
Fill(Stream_Video, StreamPos_Last, Video_Height, object_layer_height);
float32 PixelAspectRatio_Value=1.0;
if (aspect_ratio_info==0x01) PixelAspectRatio_Value=(float32)1;
if (aspect_ratio_info==0x02) PixelAspectRatio_Value=(float32)12/(float32)11;
else if (aspect_ratio_info==0x03) PixelAspectRatio_Value=(float32)10/(float32)11;
else if (aspect_ratio_info==0x04) PixelAspectRatio_Value=(float32)16/(float32)11;
else if (aspect_ratio_info==0x05) PixelAspectRatio_Value=(float32)40/(float32)33;
else if (aspect_ratio_info==0x0F && par_height) PixelAspectRatio_Value=((float32)par_width)/par_height;
Fill(Stream_Video, 0, Video_PixelAspectRatio, PixelAspectRatio_Value, 3, true);
Fill(Stream_Video, StreamPos_Last, Video_DisplayAspectRatio, ((float)object_layer_width)/object_layer_height*PixelAspectRatio_Value, 3, true);
}
Fill(Stream_Video, 0, Video_ColorSpace, rgb_components?"RGB":"YUV");
Fill(Stream_Video, 0, Video_BitDepth, bits_per_pixel);
if (chroma_format<4)
Fill(Stream_Video, 0, Video_ChromaSubsampling, Mpeg4v_ChromaSubsampling[chroma_format]);
if (colour_description)
{
Fill(Stream_Video, 0, Video_colour_description_present, "Yes");
Fill(Stream_Video, 0, Video_colour_primaries, Mpegv_colour_primaries(colour_primaries));
Fill(Stream_Video, 0, Video_transfer_characteristics, Mpegv_transfer_characteristics(transfer_characteristics));
Fill(Stream_Video, 0, Video_matrix_coefficients, Mpegv_matrix_coefficients(matrix_coefficients));
Fill(Stream_Video, 0, Video_ColorSpace, Mpegv_matrix_coefficients_ColorSpace(matrix_coefficients), Unlimited, true, true);
}
if (low_delay)
{
Fill(Stream_Video, 0, Video_Format_Settings_BVOP, "No");
Fill(Stream_Video, 0, Video_Codec_Settings_BVOP, "No");
}
else
{
Fill(Stream_Video, 0, Video_Format_Settings, "BVOP");
Fill(Stream_Video, 0, Video_Format_Settings_BVOP, "Yes");
Fill(Stream_Video, 0, Video_Codec_Settings, "BVOP");
Fill(Stream_Video, 0, Video_Codec_Settings_BVOP, "Yes");
}
if (no_of_sprite_warping_points)
{
Fill(Stream_Video, 0, Video_Format_Settings, Ztring(__T("GMC"))+Ztring::ToZtring(no_of_sprite_warping_points));
Fill(Stream_Video, 0, Video_Format_Settings_GMC, no_of_sprite_warping_points);
Fill(Stream_Video, 0, Video_Codec_Settings, Ztring(__T("GMC"))+Ztring::ToZtring(no_of_sprite_warping_points));
Fill(Stream_Video, 0, Video_Codec_Settings_GMC, no_of_sprite_warping_points);
}
else
{
Fill(Stream_Video, 0, Video_Format_Settings_GMC, 0);
Fill(Stream_Video, 0, Video_Codec_Settings_GMC, 0);
}
if (quarter_sample)
{
Fill(Stream_Video, 0, Video_Format_Settings, "QPel");
Fill(Stream_Video, 0, Video_Format_Settings_QPel, "Yes");
Fill(Stream_Video, 0, Video_Codec_Settings, "QPel");
Fill(Stream_Video, 0, Video_Codec_Settings_QPel, "Yes");
}
else
{
Fill(Stream_Video, 0, Video_Format_Settings_QPel, "No");
Fill(Stream_Video, 0, Video_Codec_Settings_QPel, "No");
}
if (!quant_type)
{
Fill(Stream_Video, 0, Video_Format_Settings_Matrix, "Default (H.263)");
Fill(Stream_Video, 0, Video_Codec_Settings_Matrix, "Default (H.263)");
}
else if (load_intra_quant_mat_grayscale || load_nonintra_quant_mat_grayscale)
{
Fill(Stream_Video, 0, Video_Format_Settings, "Custom Matrix (Gray)");
Fill(Stream_Video, 0, Video_Format_Settings_Matrix, "Custom (Gray)");
Fill(Stream_Video, 0, Video_Codec_Settings, "Custom Matrix (Gray)");
Fill(Stream_Video, 0, Video_Codec_Settings_Matrix, "Custom (Gray)");
}
else if (load_intra_quant_mat || load_nonintra_quant_mat)
{
Fill(Stream_Video, 0, Video_Format_Settings, "Custom Matrix");
Fill(Stream_Video, 0, Video_Format_Settings_Matrix, "Custom");
Fill(Stream_Video, 0, Video_Format_Settings_Matrix_Data, Matrix_intra);
Fill(Stream_Video, 0, Video_Format_Settings_Matrix_Data, Matrix_nonintra);
Fill(Stream_Video, 0, Video_Codec_Settings, "Custom Matrix");
Fill(Stream_Video, 0, Video_Codec_Settings_Matrix, "Custom");
}
else
{
Fill(Stream_Video, 0, Video_Format_Settings_Matrix, "Default (MPEG)");
Fill(Stream_Video, 0, Video_Codec_Settings_Matrix, "Default (MPEG)");
}
if (interlaced)
{
Fill(Stream_Video, 0, Video_ScanType, "Interlaced");
if ((Interlaced_Top && Interlaced_Bottom) || (!Interlaced_Top && !Interlaced_Bottom))
Fill(Stream_Video, 0, Video_Interlacement, "Interlaced");
else
{
Fill(Stream_Video, 0, Video_ScanOrder, Interlaced_Top?"TFF":"BFF");
Fill(Stream_Video, 0, Video_Interlacement, Interlaced_Top?"TFF":"BFF");
}
}
else
{
Fill(Stream_Video, 0, Video_ScanType, "Progressive");
Fill(Stream_Video, 0, Video_Interlacement, "PPF");
}
if (!Library.empty())
{
Fill(Stream_Video, 0, Video_Encoded_Library, Library);
Fill(Stream_Video, 0, Video_Encoded_Library_Name, Library_Name);
Fill(Stream_Video, 0, Video_Encoded_Library_Version, Library_Version);
Fill(Stream_Video, 0, Video_Encoded_Library_Date, Library_Date);
}
for (size_t Pos=0; Pos<user_data_start_SNC_Data.size(); Pos++)
{
if (user_data_start_SNC_Data[Pos][0]==__T("CamTim"))
Fill(Stream_General, 0, General_Recorded_Date, Ztring().Date_From_String(user_data_start_SNC_Data[Pos][1].To_UTF8().c_str()));
if (user_data_start_SNC_Data[Pos][0]==__T("FrmRate"))
Fill(Stream_Video, 0, Video_FrameRate, user_data_start_SNC_Data[Pos][1].To_float32(), 3);
if (user_data_start_SNC_Data[Pos][0]==__T("TimStamp"))
{
Fill(Stream_Video, 0, Video_Delay, user_data_start_SNC_Data[Pos][1].To_int64u());
Fill(Stream_Video, 0, Video_Delay_Source, "Stream");
}
if (user_data_start_SNC_Data[Pos][0]==__T("CamPos") && user_data_start_SNC_Data[Pos][1].size()==16)
{
Fill(Stream_Video, 0, "Pan / Tilt / Zoom / Status", Ztring(user_data_start_SNC_Data[Pos][1].substr( 3, 4)).To_int8u(16));
Fill(Stream_Video, 0, "Pan / Tilt / Zoom / Status", Ztring(user_data_start_SNC_Data[Pos][1].substr( 7, 4)).To_int8u(16));
Fill(Stream_Video, 0, "Pan / Tilt / Zoom / Status", Ztring(user_data_start_SNC_Data[Pos][1].substr(11, 4)).To_int8u(16));
if (user_data_start_SNC_Data[Pos][1][15]==__T('M'))
Fill(Stream_Video, 0, "Pan / Tilt / Zoom / Status", __T("Move"));
else if (user_data_start_SNC_Data[Pos][1][15]==__T('S'))
Fill(Stream_Video, 0, "Pan / Tilt / Zoom / Status", __T("Stop"));
else
Fill(Stream_Video, 0, "Pan / Tilt / Zoom / Status", user_data_start_SNC_Data[Pos][1][15]);
}
if (user_data_start_SNC_Data[Pos][0]==__T("AlmEvent") && user_data_start_SNC_Data[Pos][1].size()==16)
Fill(Stream_Video, 0, "Alarm event", user_data_start_SNC_Data[Pos][1]);
}
if (!(profile_and_level_indication >= B8(11100001) && profile_and_level_indication <= B8(11101000)) && video_object_layer_start_IsParsed && shape!=2 && !complexity_estimation_disable)
{
Fill(Stream_Video, 0, "data_partitioned", data_partitioned?"Yes":"No");
Fill_SetOptions(Stream_Video, 0 ,"data_partitioned", "N NT");
if (data_partitioned)
{
Fill(Stream_Video, 0, "reversible_vlc", reversible_vlc?"Yes":"No");
Fill_SetOptions(Stream_Video, 0, "reversible_vlc", "N NT");
}
}
//BVOPs
if (BVOP_Count_Max)
{
Ztring Format_Settings=Retrieve(Stream_Video, 0, Video_Format_Settings);
Format_Settings.FindAndReplace(__T("BVOP"), __T("BVOP")+Ztring::ToZtring(BVOP_Count_Max));
Fill(Stream_Video, 0, Video_Format_Settings, Format_Settings, true);
Fill(Stream_Video, 0, Video_Format_Settings_BVOP, BVOP_Count_Max, 10, true);
}
//Packed Bitstream
if (Frame_Count_InThisBlock_Max==2)
{
Fill(Stream_Video, 0, Video_MuxingMode, MediaInfoLib::Config.Language_Get("MuxingMode_PackedBitstream"));
Fill(Stream_Video, 0, Video_Codec_Settings, "Packed Bitstream");
Fill(Stream_Video, 0, Video_Codec_Settings_PacketBitStream, "Yes");
}
else
{
Fill(Stream_Video, 0, Video_Codec_Settings_PacketBitStream, "No");
}
}
//---------------------------------------------------------------------------
void File_Mpeg4v::Streams_Finish()
{
//Duration
if (!IsSub && Time_End_Seconds!=(int32u)-1 && Time_Begin_Seconds!=(int32u)-1)
{
int32u Duration=(Time_End_Seconds-Time_Begin_Seconds)*1000+Time_End_MilliSeconds-Time_Begin_MilliSeconds;
if (fixed_vop_time_increment && vop_time_increment_resolution)
Duration+=float32_int32s(((float)1000)/(((float)vop_time_increment_resolution)/fixed_vop_time_increment));
Fill(Stream_Video, 0, Video_Duration, Duration);
}
#if MEDIAINFO_IBIUSAGE
if (fixed_vop_time_increment)
Ibi_Stream_Finish(vop_time_increment_resolution, fixed_vop_time_increment);
#endif //MEDIAINFO_IBIUSAGE
}
//***************************************************************************
// Buffer - Demux
//***************************************************************************
//---------------------------------------------------------------------------
#if MEDIAINFO_DEMUX
bool File_Mpeg4v::Demux_UnpacketizeContainer_Test()
{
if ((Demux_IntermediateItemFound && Buffer[Buffer_Offset+3]==0xB0) || Buffer[Buffer_Offset+3]==0xB3 || Buffer[Buffer_Offset+3]==0xB6)
{
if (Demux_Offset==0)
{
Demux_Offset=Buffer_Offset;
Demux_IntermediateItemFound=false;
}
while (Demux_Offset+4<=Buffer_Size)
{
//Synchronizing
while(Demux_Offset+3<=Buffer_Size && (Buffer[Demux_Offset ]!=0x00
|| Buffer[Demux_Offset+1]!=0x00
|| Buffer[Demux_Offset+2]!=0x01))
{
Demux_Offset+=2;
while(Demux_Offset<Buffer_Size && Buffer[Buffer_Offset]!=0x00)
Demux_Offset+=2;
if (Demux_Offset>=Buffer_Size || Buffer[Demux_Offset-1]==0x00)
Demux_Offset--;
}
if (Demux_Offset+4<=Buffer_Size)
{
if (Demux_IntermediateItemFound)
{
bool MustBreak;
switch (Buffer[Demux_Offset+3])
{
case 0xB0 :
case 0xB3 :
case 0xB6 :
MustBreak=true; break;
default :
Demux_Offset+=3;
MustBreak=false;
}
if (MustBreak)
break; //while() loop
}
else
{
if (Buffer[Demux_Offset+3]==0xB6)
Demux_IntermediateItemFound=true;
}
}
Demux_Offset++;
}
if (Demux_Offset+4>Buffer_Size && !Config->IsFinishing)
return false; //No complete frame
if (!Status[IsAccepted])
{
if (Config->Demux_EventWasSent)
return false;
File_Mpeg4v* MI=new File_Mpeg4v;
Element_Code=(int64u)-1;
Open_Buffer_Init(MI);
Open_Buffer_Continue(MI, Buffer, Buffer_Size);
bool IsOk=MI->Status[IsAccepted];
delete MI;
if (!IsOk)
return false;
}
Demux_UnpacketizeContainer_Demux(Buffer[Buffer_Offset+3]==0xB0);
}
return true;
}
#endif //MEDIAINFO_DEMUX
//***************************************************************************
// Buffer - Global
//***************************************************************************
//---------------------------------------------------------------------------
void File_Mpeg4v::Read_Buffer_Unsynched()
{
Time_End_Seconds=(int32u)-1;
Time_End_MilliSeconds=(int16u)-1;
}
//***************************************************************************
// Buffer - Per element
//***************************************************************************
//---------------------------------------------------------------------------
void File_Mpeg4v::Header_Parse()
{
//Parsing
int8u start_code;
Skip_B3( "synchro");
Get_B1 (start_code, "start_code");
if (!Header_Parser_Fill_Size())
{
Element_WaitForMoreData();
return;
}
//Filling
Header_Fill_Code(start_code, Ztring().From_CC1(start_code));
}
//---------------------------------------------------------------------------
bool File_Mpeg4v::Header_Parser_Fill_Size()
{
//Look for next Sync word
if (Buffer_Offset_Temp==0) //Buffer_Offset_Temp is not 0 if Header_Parse_Fill_Size() has already parsed first frames
Buffer_Offset_Temp=Buffer_Offset+4;
while (Buffer_Offset_Temp+4<=Buffer_Size
&& CC3(Buffer+Buffer_Offset_Temp)!=0x000001)
{
Buffer_Offset_Temp+=2;
while(Buffer_Offset_Temp<Buffer_Size && Buffer[Buffer_Offset_Temp]!=0x00)
Buffer_Offset_Temp+=2;
if (Buffer_Offset_Temp>=Buffer_Size || Buffer[Buffer_Offset_Temp-1]==0x00)
Buffer_Offset_Temp--;
}
//Must wait more data?
if (Buffer_Offset_Temp+4>Buffer_Size)
{
if (FrameIsAlwaysComplete || Config->IsFinishing)
Buffer_Offset_Temp=Buffer_Size; //We are sure that the next bytes are a start
else
return false;
}
//OK, we continue
Header_Fill_Size(Buffer_Offset_Temp-Buffer_Offset);
Buffer_Offset_Temp=0;
return true;
}
//---------------------------------------------------------------------------
bool File_Mpeg4v::Header_Parser_QuickSearch()
{
while ( Buffer_Offset+4<=Buffer_Size
&& Buffer[Buffer_Offset ]==0x00
&& Buffer[Buffer_Offset+1]==0x00
&& Buffer[Buffer_Offset+2]==0x01)
{
//Getting start_code
int8u start_code=CC1(Buffer+Buffer_Offset+3);
//Searching start
if (Streams[start_code].Searching_Payload)
return true;
//Synchronizing
Buffer_Offset+=4;
Synched=false;
if (!Synchronize())
{
UnSynched_IsNotJunk=true;
return false;
}
if (Buffer_Offset+4>Buffer_Size)
{
UnSynched_IsNotJunk=true;
return false;
}
}
if (Buffer_Offset+3==Buffer_Size)
return false; //Sync is OK, but start_code is not available
Trusted_IsNot("MPEG-4 Visual, Synchronisation lost");
return Synchronize();
}
//---------------------------------------------------------------------------
void File_Mpeg4v::Data_Parse()
{
//Parsing
switch (Element_Code)
{
case 0xB0: visual_object_sequence_start(); break;
case 0xB1: visual_object_sequence_end(); break;
case 0xB2: user_data_start(); break;
case 0xB3: group_of_vop_start(); break;
case 0xB4: video_session_error(); break;
case 0xB5: visual_object_start(); break;
case 0xB6: vop_start(); break;
case 0xB7: slice_start(); break;
case 0xB8: extension_start(); break;
case 0xB9: fgs_vop_start(); break;
case 0xBA: fba_object_start(); break;
case 0xBB: fba_object_plane_start(); break;
case 0xBC: mesh_object_start(); break;
case 0xBD: mesh_object_plane_start(); break;
case 0xBE: still_texture_object_start(); break;
case 0xBF: texture_spatial_layer_start(); break;
case 0xC0: texture_snr_layer_start(); break;
case 0xC1: texture_tile_start(); break;
case 0xC2: texture_shape_layer_start(); break;
case 0xC3: stuffing_start(); break;
default:
if (Element_Code<=0x1F) video_object_start();
else if (Element_Code>=0x20
&& Element_Code<=0x2F) video_object_layer_start();
else if (Element_Code>=0x40
&& Element_Code<=0x4F) fgs_bp_start();
else if (Element_Code<=0xC5) reserved();
else
{
if (Frame_Count==0 && Buffer_TotalBytes>Buffer_TotalBytes_FirstSynched_Max)
Trusted=0;
Trusted_IsNot("Unattended element!");
}
}
}
//***************************************************************************
// Elements
//***************************************************************************
//---------------------------------------------------------------------------
// Packet "00"
void File_Mpeg4v::video_object_start()
{
Element_Name("video_object_start");
//Integrity
if (Element_Size>0)
{
Trusted_IsNot("size is wrong");
return;
}
FILLING_BEGIN();
//NextCode
NextCode_Test();
NextCode_Clear();
NextCode_Add(0x20); //video_object_layer_start
//Autorisation of other streams
Streams[0x20].Searching_Payload=true; //video_object_layer_start
FILLING_END();
}
//---------------------------------------------------------------------------
// Packet "20"
void File_Mpeg4v::video_object_layer_start()
{
Element_Name("video_object_layer_start");
//Default
Matrix_intra.clear();
Matrix_nonintra.clear();
//Parsing
int8u video_object_layer_verid=visual_object_verid;
int8u shape_extension=0;
int32u aux_comp_count=0;
BS_Begin();
Skip_SB( "random_accessible_vol");
Skip_S1(8, "video_object_type_indication");
if (profile_and_level_indication>=B8(11100001) && profile_and_level_indication<=B8(11101000)) // Test if "Studio" profile
{
Get_S1 ( 4, visual_object_verid, "video_object_layer_verid"); Param_Info1(Mpeg4v_video_object_layer_verid[video_object_layer_verid]);
Get_S1 (2, shape, "video_object_layer_shape");
Get_S1 (4, shape_extension, "video_object_layer_shape_extension");
Get_SB (interlaced, "progressive_sequence");
interlaced=!interlaced; //this is progressive_sequence so the opposite
if (shape!=2) //Shape!=BinaryOnly
{
Get_SB ( rgb_components, "rgb_components");
Get_S1 (2, chroma_format, "chroma_format"); Param_Info1(Mpeg4v_ChromaSubsampling[chroma_format]);
Get_S1 (4, bits_per_pixel, "bits_per_pixel");
}
if (shape==0) //Shape=Rectangular
{
Mark_1 ();
Get_S2 (14, object_layer_width, "video_object_layer_width");
Mark_1 ();
Get_S2 (14, object_layer_height, "video_object_layer_height");
Mark_1 ();
}
Get_S1 (4, aspect_ratio_info, "aspect_ratio_info");
if (aspect_ratio_info==0x0F)
{
Get_S1 (8, par_width, "par_width");
Get_S1 (8, par_height, "par_height");
}
Get_S1 (4, frame_rate_code, "frame_rate_code"); Param_Info1(Mpegv_frame_rate[frame_rate_code]);
int16u first_half_bit_rate, latter_half_bit_rate, first_half_vbv_buffer_size, latter_half_vbv_buffer_size;
Get_S2 (15, first_half_bit_rate, "first_half_bit_rate");
Mark_1 ();
Get_S2(15, latter_half_bit_rate, "latter_half_bit_rate");
Mark_1 ();
Get_S2 (15, first_half_vbv_buffer_size, "first_half_vbv_buffer_size");
Mark_1 ();
Get_S2 ( 3, latter_half_vbv_buffer_size, "latter_half_vbv_buffer_size");
Skip_S2(11, "first_half_vbv_occupancy");
Mark_1 ();
Skip_S2(15, "latter_half_vbv_occupancy");
Mark_1 ();
bit_rate=first_half_bit_rate*0x8000+latter_half_bit_rate;
vbv_buffer_size=first_half_vbv_buffer_size*0x8+latter_half_vbv_buffer_size;
Get_SB ( low_delay, "low_delay");
Skip_SB( "mpeg2_stream");
BS_End();
Skip_XX(Element_Size-Element_Offset, "(TODO)");
}
else
{
TEST_SB_SKIP( "is_object_layer_identifier");
Get_S1 (4, video_object_layer_verid, "video_object_layer_verid"); Param_Info1(Mpeg4v_video_object_layer_verid[video_object_layer_verid]);
Skip_S1(3, "video_object_layer_priority");
TEST_SB_END();
Get_S1 (4, aspect_ratio_info, "aspect_ratio_info");
if (aspect_ratio_info==0x0F)
{
Get_S1 (8, par_width, "par_width");
Get_S1 (8, par_height, "par_height");
}
TEST_SB_SKIP( "vol_control_parameters");
Get_S1 (2, chroma_format, "chroma_format"); Param_Info1(Mpeg4v_ChromaSubsampling[chroma_format]);
Get_SB ( low_delay, "low_delay");
TEST_SB_SKIP( "vbv_parameters");
int16u first_half_bit_rate, latter_half_bit_rate, first_half_vbv_buffer_size, latter_half_vbv_buffer_size;
Get_S2 (15, first_half_bit_rate, "first_half_bit_rate");
Mark_1 ();
Get_S2(15, latter_half_bit_rate, "latter_half_bit_rate");
Mark_1 ();
Get_S2 (15, first_half_vbv_buffer_size, "first_half_vbv_buffer_size");
Mark_1 ();
Get_S2 ( 3, latter_half_vbv_buffer_size, "latter_half_vbv_buffer_size");
Skip_S2(11, "first_half_vbv_occupancy");
Mark_1 ();
Skip_S2(15, "latter_half_vbv_occupancy");
Mark_1 ();
bit_rate=first_half_bit_rate*0x8+latter_half_bit_rate;
vbv_buffer_size=first_half_vbv_buffer_size*0x8000+latter_half_vbv_buffer_size;
TEST_SB_END();
TEST_SB_END();
Get_S1 (2, shape, "video_object_layer_shape");
if (shape==3 && video_object_layer_verid!=1) //Shape=GrayScale
Get_S1 (4, shape_extension, "video_object_layer_shape_extension");
switch (shape_extension)
{
case 0 :
case 1 :
case 5 :
case 7 :
case 8 :
aux_comp_count=1; break;
case 2 :
case 3 :
case 6 :
case 9 :
case 11 :
aux_comp_count=2; break;
case 4 :
case 10 :
case 12 :
aux_comp_count=3; break;
default : ;
}
Mark_1 ();
Get_S2 (16, vop_time_increment_resolution, "vop_time_increment_resolution");
int32u PowerOf2=1;
for (time_size=0; time_size<=16; time_size++)
{
if ((int32u)vop_time_increment_resolution<PowerOf2)
break;
PowerOf2<<=1;
}
Mark_1 ();
TEST_SB_SKIP( "fixed_vop_rate");
Get_BS (time_size, fixed_vop_time_increment, "fixed_vop_time_increment"); Param_Info2C((vop_time_increment_resolution), fixed_vop_time_increment*1000/vop_time_increment_resolution, " ms");
TEST_SB_END();
if (shape!=2) //Shape!=BinaryOnly
{
if (shape==0) //Shape=Rectangular
{
Mark_1 ();
Get_S2 (13, object_layer_width, "object_layer_width");
Mark_1 ();
Get_S2 (13, object_layer_height, "object_layer_height");
Mark_1 ();
}
Get_SB (interlaced, "interlaced");
Skip_SB( "obmc_disable");
if (video_object_layer_verid==1)
Get_S1 (1, sprite_enable, "sprite_enable");
else
Get_S1 (2, sprite_enable, "sprite_enable");
if (sprite_enable==1 || sprite_enable==2 ) //static or GMC
{
if (sprite_enable!=2) //No GMC
{
Skip_S2(13, "sprite_width");
Mark_1 ();
Skip_S2(13, "sprite_height");
Mark_1 ();
Skip_S2(13, "sprite_top_coordinate");
Mark_1 ();
Skip_S2(13, "sprite_left_coordinate");
Mark_1 ();
}
Get_S1 (6, no_of_sprite_warping_points, "no_of_sprite_warping_points");
Skip_S1(2, "sprite_warping_accuracy");
Skip_SB( "sprite_brightness_change");
if (sprite_enable!=2) //No GMC
Skip_SB( "low_latency_sprite_enable");
}
if (video_object_layer_verid!=1 && shape!=0) //Shape!=Rectangular
Skip_SB( "sadct_disable");
TEST_SB_SKIP( "bits_per_pixel_not_8_bit");
Skip_S1(4, "quant_precision");
Get_S1 (4, bits_per_pixel, "bits_per_pixel");
TEST_SB_END();
if (shape==3) //Shape=GrayScale
{
Skip_SB( "no_gray_quant_update");
Skip_SB( "composition_method");
Skip_SB( "linear_composition");
}
TEST_SB_GET (quant_type, "quant_type");
Get_SB (load_intra_quant_mat, "load_intra_quant_mat");
if(load_intra_quant_mat)
for (int16u Pos=0; Pos<64; Pos++)
{
int8u intra_quant_mat;
Get_S1 (8, intra_quant_mat, "intra_quant_mat");
if (!intra_quant_mat)
{
if (Matrix_intra.size()<2)
break; //There is a problem
Ztring Value=Matrix_intra.substr(Matrix_intra.size()-2, 2);
for (;Pos<64; Pos++)
Matrix_intra+=Value;
}
else
{
Ztring Value=Ztring::ToZtring(intra_quant_mat, 16);
if (Value.size()==1)
Value.insert(0, __T("0"));
Matrix_intra+=Value;
}
}
else
Matrix_intra="Default";
Get_SB (load_nonintra_quant_mat, "load_nonintra_quant_mat");
if(load_nonintra_quant_mat)
for (int16u Pos=0; Pos<64; Pos++)
{
int8u nonintra_quant_mat;
Get_S1 (8, nonintra_quant_mat, "nonintra_quant_mat");
if (!nonintra_quant_mat)
{
if (Matrix_nonintra.size()<2)
break; //There is a problem
Ztring Value=Matrix_nonintra.substr(Matrix_nonintra.size()-2, 2);
for (;Pos<64; Pos++)
Matrix_nonintra+=Value;
}
else
{
Ztring Value=Ztring::ToZtring(nonintra_quant_mat, 16);
if (Value.size()==1)
Value.insert(0, __T("0"));
Matrix_nonintra+=Value;
}
}
else
Matrix_nonintra="Default";
if(shape==3) //Shape=GrayScale
{
for(size_t aux_comp_Pos=0; aux_comp_Pos<aux_comp_count; aux_comp_Pos++)
{
Get_SB (load_intra_quant_mat_grayscale, "load_intra_quant_mat_grayscale");
if(load_intra_quant_mat_grayscale)
for (int16u Pos=0; Pos<64; Pos++)
{
int8u intra_quant_mat_grayscale;
Get_S1 (8, intra_quant_mat_grayscale, "intra_quant_mat_grayscale");
if (!intra_quant_mat_grayscale)
break;
}
Get_SB (load_nonintra_quant_mat_grayscale, "load_nonintra_quant_mat_grayscale");
if(load_nonintra_quant_mat_grayscale)
for (int16u Pos=0; Pos<64; Pos++)
{
int8u nonintra_quant_mat_grayscale;
Get_S1 (8, nonintra_quant_mat_grayscale, "nonintra_quant_mat_grayscale");
if (!nonintra_quant_mat_grayscale)
break;
}
}
}
TEST_SB_END();
if (video_object_layer_verid!=1)
{
Get_SB (quarter_sample, "quarter_sample");
}
Get_SB (complexity_estimation_disable, "complexity_estimation_disable");
if (!complexity_estimation_disable)
{
Get_S1 (2, estimation_method, "estimation_method");
if (estimation_method==0 || estimation_method==1)
{
TEST_SB_SKIP( "shape_complexity_estimation_disable");
Get_SB (opaque, "opaque");
Get_SB (transparent, "transparent");
Get_SB (intra_cae, "intra_cae");
Get_SB (inter_cae, "inter_cae");
Get_SB (no_update, "no_update");
Get_SB (upsampling, "upsampling");
TEST_SB_END();
TEST_SB_SKIP( "texture_complexity_estimation_set_1_disable");
Get_SB (intra_blocks, "intra_blocks");
Get_SB (inter_blocks, "inter_blocks");
Get_SB (inter4v_blocks, "inter4v_blocks");
Get_SB (not_coded_blocks, "not_coded_blocks");
TEST_SB_END();
Mark_1 ();
TEST_SB_SKIP( "texture_complexity_estimation_set_2_disable");
Get_SB (dct_coefs, "dct_coefs");
Get_SB (dct_lines, "dct_lines");
Get_SB (vlc_symbols, "vlc_symbols");
Get_SB (vlc_bits, "vlc_bits");
TEST_SB_END();
TEST_SB_SKIP( "motion_compensation_complexity_disable");
Get_SB (apm, "apm");
Get_SB (npm, "npm");
Get_SB (interpolate_mc_q, "interpolate_mc_q");
Get_SB (forw_back_mc_q, "forw_back_mc_q");
Get_SB (halfpel2, "halfpel2");
Get_SB (halfpel4, "halfpel4");
TEST_SB_END();
Mark_1 ();
if (estimation_method==1)
{
TEST_SB_SKIP( "version2_complexity_estimation_disable");
Get_SB (sadct, "sadct");
Get_SB (quarterpel, "quarterpel");
TEST_SB_END();
}
}
}
Skip_SB( "resync_marker_disable");
TEST_SB_GET( data_partitioned, "data_partitioned");
Get_SB ( reversible_vlc, "reversible_vlc");
TEST_SB_END();
if (video_object_layer_verid!=1)
{
Get_SB (newpred_enable, "newpred_enable");
if (newpred_enable)
{
Skip_S1(2, "requested_upstream_message_type");
Skip_SB( "newpred_segment_type");
}
Get_SB (reduced_resolution_vop_enable, "reduced_resolution_vop_enable");
}
Get_SB (scalability, "scalability");
if (scalability==1)
{
bool Hierarchy;
Get_SB ( Hierarchy, "hierarchy_type");
Skip_S1(4, "ref_layer_id");
Skip_SB( "ref_layer_sampling_direc");
Skip_S1(5, "hor_sampling_factor_n");
Skip_S1(5, "hor_sampling_factor_m");
Skip_S1(5, "vert_sampling_factor_n");
Skip_S1(5, "vert_sampling_factor_m");
Get_SB ( enhancement_type, "enhancement_type");
if (shape==1 && Hierarchy==0) //Shape=Binary
{
Skip_SB( "use_ref_shape");
Skip_SB( "use_ref_texture");
Skip_S1(5, "shape_hor_sampling_factor_n");
Skip_S1(5, "shape_hor_sampling_factor_m");
Skip_S1(5, "shape_vert_sampling_factor_n");
Skip_S1(5, "shape_vert_sampling_factor_m");
}
}
}
else
{
if (video_object_layer_verid!=1)
{
TEST_SB_SKIP( "scalability");
Skip_S1(4, "ref_layer_id");
Skip_S1(5, "shape_hor_sampling_factor_n");
Skip_S1(5, "shape_hor_sampling_factor_m");
Skip_S1(5, "shape_vert_sampling_factor_n");
Skip_S1(5, "shape_vert_sampling_factor_m");
TEST_SB_END();
}
Skip_SB( "resync_marker_disable");
}
BS_End();
}
//Coherancy
if (shape==0 && (object_layer_width==0 || object_layer_height==0 || ((float32)object_layer_width)/object_layer_height<((float32)0.1) || object_layer_width/object_layer_height>10))
Trusted_IsNot("Problem with width and height!");
FILLING_BEGIN();
//NextCode
NextCode_Test();
NextCode_Clear();
NextCode_Add(0xB2); //user_data
NextCode_Add(0xB3); //group_of_vop_start
NextCode_Add(0xB6); //vop_start
for (int8u Pos=0x00; Pos<0x1F; Pos++)
NextCode_Add(Pos); //video_object_start
//Autorisation of other streams
Streams[0xB2].Searching_Payload=true; //user_data
Streams[0xB3].Searching_Payload=true; //group_of_vop_start
Streams[0xB6].Searching_Payload=true; //vop_start
//Setting as OK
video_object_layer_start_IsParsed=true;
if (!Status[IsAccepted])
Accept("MPEG-4 Visual");
FILLING_END();
}
//---------------------------------------------------------------------------
// Packet "40"
//
void File_Mpeg4v::fgs_bp_start()
{
Element_Name("fgs_bp_start");
}
//---------------------------------------------------------------------------
// Packet "B0"
void File_Mpeg4v::visual_object_sequence_start()
{
Element_Name("visual_object_sequence_start");
//Parsing
Get_B1 (profile_and_level_indication, "profile_and_level_indication"); Param_Info1(Mpeg4v_Profile_Level(profile_and_level_indication));
//Integrity
if (profile_and_level_indication==0)
{
Trusted_IsNot("profile_and_level_indication is wrong");
return;
}
FILLING_BEGIN_PRECISE();
//NextCode
NextCode_Clear();
NextCode_Add(0xB1); //visual_object_sequence_end
NextCode_Add(0xB2); //user_data
NextCode_Add(0xB5); //visual_object_start
//Autorisation of other streams
Streams[0xB1].Searching_Payload=true, //visual_object_sequence_end
Streams[0xB2].Searching_Payload=true; //user_data
Streams[0xB5].Searching_Payload=true; //visual_object_start
FILLING_END();
}
//---------------------------------------------------------------------------
// Packet "B1"
void File_Mpeg4v::visual_object_sequence_end()
{
Element_Name("visual_object_sequence_end");
FILLING_BEGIN_PRECISE();
//NextCode
NextCode_Clear();
NextCode_Add(0xB0); //visual_object_sequence_start
FILLING_END();
}
//---------------------------------------------------------------------------
// Packet "B2", User defined size, this is often used of library name
void File_Mpeg4v::user_data_start()
{
Element_Name("user_data_start");
//Sony SNC files (security video)
if (Element_Size>=120 && Element_Size<=140)
{
int64u SNC_Identifier;
Peek_B8(SNC_Identifier);
if (SNC_Identifier==0x43616D54696D3A20ULL)
{
user_data_start_SNC();
return;
}
}
//Rejecting junk at the begin
size_t Library_Start_Offset=0;
while (Library_Start_Offset+4<=Element_Size)
{
bool OK=true;
for (size_t Pos=0; Pos<4; Pos++)
{
if (!((Buffer[Buffer_Offset+Library_Start_Offset+Pos]==0x20 && Pos)
|| Buffer[Buffer_Offset+Library_Start_Offset+Pos]==0x22
|| Buffer[Buffer_Offset+Library_Start_Offset+Pos]==0x27
|| Buffer[Buffer_Offset+Library_Start_Offset+Pos]==0x28
|| (Buffer[Buffer_Offset+Library_Start_Offset+Pos]==0x29 && Pos)
|| (Buffer[Buffer_Offset+Library_Start_Offset+Pos]>=0x30 && Buffer[Buffer_Offset+Library_Start_Offset+Pos]<=0x3F)
|| (Buffer[Buffer_Offset+Library_Start_Offset+Pos]>=0x41 && Buffer[Buffer_Offset+Library_Start_Offset+Pos]<=0x7D)))
{
OK=false;
break;
}
}
if (OK)
break;
Library_Start_Offset++;
}
if (Library_Start_Offset+4>Element_Size)
{
Skip_XX(Element_Size, "junk");
return; //No good info
}
//Accepting good data after junk
size_t Library_End_Offset=Library_Start_Offset+4;
while (Library_End_Offset<Element_Size
&& (Buffer[Buffer_Offset+Library_End_Offset]==0x0D
|| Buffer[Buffer_Offset+Library_End_Offset]==0x0A
|| (Buffer[Buffer_Offset+Library_End_Offset]>=0x20 && Buffer[Buffer_Offset+Library_End_Offset]<=0x3F)
|| (Buffer[Buffer_Offset+Library_End_Offset]>=0x41 && Buffer[Buffer_Offset+Library_End_Offset]<=0x7D)))
Library_End_Offset++;
//Parsing
string Temp;
if (Library_Start_Offset>0)
Skip_XX(Library_Start_Offset, "junk");
if (Library_End_Offset-Library_Start_Offset)
Get_String(Library_End_Offset-Library_Start_Offset, Temp,"data");
if (Element_Offset<Element_Size)
Skip_XX(Element_Size-Element_Offset, "junk");
//Cleanup
while(Temp.size()>3 && Temp[1]==__T('e') && Temp[2]==__T('n') && Temp[3]==__T('c'))
Temp.erase(0, 1);
while(Temp.size()>5 && Temp[3]==__T('M') && Temp[4]==__T('P') && Temp[5]==__T('E'))
Temp.erase(0, 1);
FILLING_BEGIN();
if (Temp.size()>=4)
{
if (Temp.find("build")==0)
Library+=Ztring().From_UTF8(" "+Temp);
else
Library.From_UTF8(Temp);
//Library
if (Library.find(__T("DivX50"))==0)
{
Library_Name=__T("DivX");
Ztring Version=Library.SubString(__T("Build"), __T(""));
if (Version.empty())
Version=Library.SubString(__T("b"), __T("p"));
if (Version.empty())
Version=Library.SubString(__T("b"), __T(""));
Library_Version=MediaInfoLib::Config.Library_Get(InfoLibrary_Format_DivX, Version, InfoLibrary_Version);
if (Library_Version.empty())
Library_Version=Version;
Library_Date=MediaInfoLib::Config.Library_Get(InfoLibrary_Format_DivX, Version, InfoLibrary_Date);
}
if (Library.find(__T("XviD"))==0)
{
Library_Name=__T("XviD");
if (Library.find(__T("build="))==std::string::npos)
{
Ztring Version=Library.SubString(__T("XviD"), __T(""));
Version.FindAndReplace(__T("C"), __T(""));
Version.TrimLeft(__T('0'));
Library_Version=MediaInfoLib::Config.Library_Get(InfoLibrary_Format_XviD, Version, InfoLibrary_Version);
if (Library_Version.empty())
Library_Version=Version;
Library_Date=MediaInfoLib::Config.Library_Get(InfoLibrary_Format_XviD, Version, InfoLibrary_Date);
}
else
{
Library_Version=Library.SubString(__T("XviD"), __T(""));
Ztring Date=Library.SubString(__T(" build="), __T(""));
if (Date.size()==10)
{
Date[4]=__T('-');
Date[7]=__T('-');
Library_Date=__T("UTC ")+Date;
}
}
}
}
FILLING_END();
}
//---------------------------------------------------------------------------
// Packet "B2", SNC (From Sony SNC surveillance video)
void File_Mpeg4v::user_data_start_SNC()
{
Element_Info1("Sony SNC");
if (!user_data_start_SNC_Data.empty())
{
Skip_XX(Element_Size, "Value");
return;
}
//Parsing
Ztring Value;
Get_UTF8(Element_Size, Value, "Value");
ZtringListList List;
List.Separator_Set(0, __T("\r\n"));
List.Separator_Set(1, __T(": "));
List.Write(Value);
for (size_t Pos=0; Pos<List.size(); Pos++)
{
if (List[Pos].size()==2)
user_data_start_SNC_Data(List[Pos][0])=List[Pos][1];
}
}
//---------------------------------------------------------------------------
// Packet "B3"
void File_Mpeg4v::group_of_vop_start()
{
Element_Name("group_of_vop_start");
//Parsing
int8u Hours, Minutes, Seconds;
bool closed_gop, broken_link;
BS_Begin();
Get_S1 ( 5, Hours, "time_code_hours");
Get_S1 ( 6, Minutes, "time_code_minutes");
Mark_1();
Get_S1 ( 6, Seconds, "time_code_seconds");
Get_SB ( closed_gop, "closed_gop");
Get_SB ( broken_link, "broken_link");
BS_End();
Ztring Time;
Time+=Ztring::ToZtring(Hours);
Time+=__T(':');
Time+=Ztring::ToZtring(Minutes);
Time+=__T(':');
Time+=Ztring::ToZtring(Seconds);
Time+=__T(".000");
Element_Info1(Time);
FILLING_BEGIN();
//Calculating
if (Time_Begin_Seconds==(int32u)-1)
Time_Begin_Seconds=60*60*Hours+60*Minutes+Seconds;
Time_End_Seconds=60*60*Hours+60*Minutes+Seconds;
Time_End_MilliSeconds=(int16u)-1;
//NextCode
NextCode_Test();
NextCode_Clear();
for (int8u Pos=0x00; Pos<0x1F; Pos++)
NextCode_Add(Pos); //video_object_start
NextCode_Add(0xB6); //vop_start
FILLING_END();
}
//---------------------------------------------------------------------------
// Packet "B4"
void File_Mpeg4v::video_session_error()
{
Element_Name("video_session_error");
}
//---------------------------------------------------------------------------
// Packet "B5"
void File_Mpeg4v::visual_object_start()
{
Element_Name("visual_object_start");
//Parsing
BS_Begin();
if (profile_and_level_indication>=B8(11100001) && profile_and_level_indication<=B8(11101000)) // Test if "Studio" profile
{
Get_S1 ( 4, visual_object_verid, "visual_object_verid"); Param_Info1(Mpeg4v_visual_object_verid[visual_object_verid]);
}
else
{
TEST_SB_SKIP( "is_visual_object_identifier");
Get_S1 ( 4, visual_object_verid, "visual_object_verid"); Param_Info1(Mpeg4v_visual_object_verid[visual_object_verid]);
Skip_BS( 3, "visual_object_priority");
TEST_SB_END();
}
Get_S1 ( 4, visual_object_type, "visual_object_type"); Param_Info1(Mpeg4v_visual_object_type[visual_object_type]);
if (profile_and_level_indication<B8(11100001) || (profile_and_level_indication>B8(11101000) && (visual_object_type==1 || visual_object_type==2)))
{
TEST_SB_SKIP( "video_signal_type");
Skip_S1(3, "video_format");
Skip_SB( "video_range");
TEST_SB_GET ( colour_description, "colour_description");
Get_S1 (8, colour_primaries, "colour_primaries"); Param_Info1(Mpegv_colour_primaries(colour_primaries));
Get_S1 (8, transfer_characteristics, "transfer_characteristics"); Param_Info1(Mpegv_transfer_characteristics(transfer_characteristics));
Get_S1 (8, matrix_coefficients, "matrix_coefficients"); Param_Info1(Mpegv_matrix_coefficients(matrix_coefficients));
TEST_SB_END();
TEST_SB_END();
}
BS_End();
//Integrity
if (profile_and_level_indication>=B8(11100001) && profile_and_level_indication<=B8(11101000) && visual_object_type!=1)
{
Param_Info1("Not in specs");
Trusted_IsNot("Not in specs");
}
FILLING_BEGIN_PRECISE();
//NextCode
NextCode_Clear();
NextCode_Add(0xB2); //user_data
for (int8u Pos=0x00; Pos<0x2F; Pos++)
NextCode_Add(Pos); //video_object_start and video_object_layer_start
//Autorisation of other streams
Streams[0xB2].Searching_Payload=true;
for (int8u Pos=0x00; Pos<0x25; Pos++)
Streams[Pos].Searching_Payload=true; //video_object_start and video_object_layer_start
FILLING_END();
}
//---------------------------------------------------------------------------
// Packet "B6"
void File_Mpeg4v::vop_start()
{
Element_Info1C( (FrameInfo.DTS!=(int64u)-1), __T("DTS ")+Ztring().Duration_From_Milliseconds(float64_int64s(((float64)FrameInfo.DTS)/1000000)));
//Counting
if (File_Offset+Buffer_Offset+Element_Size==File_Size)
Frame_Count_Valid=Frame_Count; //Finish frames in case of there are less than Frame_Count_Valid frames
Frame_Count++;
Frame_Count_InThisBlock++;
if (Frame_Count_InThisBlock>Frame_Count_InThisBlock_Max)
Frame_Count_InThisBlock_Max=Frame_Count_InThisBlock;
if (Frame_Count_NotParsedIncluded!=(int64u)-1)
Frame_Count_NotParsedIncluded++;
//Name
Element_Name("vop_start");
Element_Info1(Ztring(__T("Frame ")+Ztring::ToZtring(Frame_Count)));
//Parsing
int32u vop_time_increment;
int8u vop_coding_type;
bool vop_coded;
int8u modulo_time_base=0;
BS_Begin();
if (profile_and_level_indication>=B8(11100001) && profile_and_level_indication<=B8(11101000)) // Test if "Studio" profile
{
Element_Begin1("time_code_smpte12m");
int8u Frames_Units, Frames_Tens, Seconds_Units, Seconds_Tens, Minutes_Units, Minutes_Tens, Hours_Units, Hours_Tens;
bool DropFrame;
BS_Begin();
Skip_SB( "CF - Color fame");
Get_SB ( DropFrame, "DP - Drop frame");
Get_S1 (2, Frames_Tens, "Frames (Tens)");
Get_S1 (4, Frames_Units, "Frames (Units)");
Skip_SB( "FP - Field Phase / BGF0");
Get_S1 (3, Seconds_Tens, "Seconds (Tens)");
Get_S1 (4, Seconds_Units, "Seconds (Units)");
Mark_1();
Skip_SB( "BGF0 / BGF2");
Get_S1 (3, Minutes_Tens, "Minutes (Tens)");
Get_S1 (4, Minutes_Units, "Minutes (Units)");
Skip_SB( "BGF2 / Field Phase");
Skip_SB( "BGF1");
Get_S1 (2, Hours_Tens, "Hours (Tens)");
Get_S1 (4, Hours_Units, "Hours (Units)");
Mark_1();
Skip_S1(4, "BG2");
Skip_S1(4, "BG1");
Skip_S1(4, "BG4");
Skip_S1(4, "BG3");
Mark_1();
Skip_S1(4, "BG6");
Skip_S1(4, "BG5");
Skip_S1(4, "BG8");
Skip_S1(4, "BG7");
Mark_1();
Skip_S4(4, "reserved_bits");
Element_End0();
Skip_S2(10, "temporal_reference");
Skip_S1(2, "vop_structure");
Get_S1 (2, vop_coding_type, "vop_coding_type"); Param_Info1(Mpeg4v_vop_coding_type[vop_coding_type]);
Get_SB ( vop_coded, "vop_coded");
if (vop_coded)
{
if (shape!=0) //Shape!=Rectangular
{
if (sprite_enable==1 //Sprite_Enable=Static
&& vop_coding_type==0) //Type=I
{
Skip_S2(14, "vop_width");
Mark_1 ();
Skip_S2(14, "vop_height");
Mark_1 ();
Skip_S2(14, "vop_horizontal_mc_spatial_ref");
Mark_1 ();
Skip_S2(14, "vop_vertical_mc_spatial_ref");
Mark_1 ();
}
}
Skip_SB( "top_field_first");
Skip_SB( "repeat_first_field");
Skip_SB( "progressive_frame");
BS_End();
Skip_XX(Element_Size-Element_Offset, "(TODO)");
}
}
else
{
Get_S1 (2, vop_coding_type, "vop_coding_type"); Param_Info1(Mpeg4v_vop_coding_type[vop_coding_type]);
Element_Info1(Mpeg4v_vop_coding_type[vop_coding_type]);
bool modulo_time_base_Continue;
do
{
Get_SB (modulo_time_base_Continue, "modulo_time_base");
if (modulo_time_base_Continue)
modulo_time_base++;
}
while (modulo_time_base_Continue);
Mark_1 ();
FILLING_BEGIN();
if (time_size==0)
{
//Filling only if not already done
if (Frame_Count>=Frame_Count_Valid && Count_Get(Stream_Video)==0)
{
Accept("MPEG-4 Visual");
Finish("MPEG-4 Visual");
}
return;
}
FILLING_END();
Get_S4 (time_size, vop_time_increment, "vop_time_increment"); Param_Info2C((vop_time_increment_resolution), vop_time_increment*1000/vop_time_increment_resolution, " ms");
Mark_1 ();
Get_SB (vop_coded, "vop_coded");
if (vop_coded)
{
if (newpred_enable)
{
Skip_S3(time_size+3<15?time_size+3:15, "vop_id");
TEST_SB_SKIP( "vop_id_for_prediction_indication");
Skip_BS(time_size+3<15?time_size+3:15, "vop_id_for_prediction");
TEST_SB_END();
Mark_1 ();
}
if (shape!=2 //Shape!=BinaryOnly
&& (vop_coding_type==1 //Type=P
|| (vop_coding_type==3 //Type=S
&& sprite_enable==2))) //Sprite_Enable=GMC
Skip_SB( "vop_rounding_type");
if (reduced_resolution_vop_enable==1
&& shape==0 //Shape=Rectangular
&& (vop_coding_type==1 //Type=P
|| vop_coding_type==0)) //Type=I
Skip_SB( "vop_reduced_resolution");
if (shape!=0) //Shape!=Rectangular
{
if (sprite_enable==1 //Sprite_Enable=Static
&& vop_coding_type==0) //Type=I
{
Skip_S2(13, "vop_width");
Mark_1 ();
Skip_S2(13, "vop_height");
Mark_1 ();
Skip_S2(13, "vop_horizontal_mc_spatial_ref");
Mark_1 ();
Skip_S2(13, "vop_vertical_mc_spatial_ref");
Mark_1 ();
}
if (shape!=2 //Shape=BinaryOnly
&& scalability==1
&& enhancement_type==1)
Skip_SB( "background_composition");
Skip_SB( "change_conv_ratio_disable");
TEST_SB_SKIP( "vop_constant_alpha");
Skip_S1(8, "vop_constant_alpha_value");
TEST_SB_END();
}
if (shape!=2) //Shape=BinaryOnly
if (complexity_estimation_disable==0)
{
if (estimation_method==0)
{
if (vop_coding_type==0) //I
{
if (opaque) Skip_S1(8, "dcecs_opaque");
if (transparent) Skip_S1(8, "dcecs_transparent");
if (intra_cae) Skip_S1(8, "dcecs_intra_cae");
if (inter_cae) Skip_S1(8, "dcecs_inter_cae");
if (no_update) Skip_S1(8, "dcecs_no_update");
if (upsampling) Skip_S1(8, "dcecs_upsampling");
if (intra_blocks) Skip_S1(8, "dcecs_intra_blocks");
if (not_coded_blocks) Skip_S1(8, "dcecs_not_coded_blocks");
if (dct_coefs) Skip_S1(8, "dcecs_dct_coefs");
if (dct_lines) Skip_S1(8, "dcecs_dct_lines");
if (vlc_symbols) Skip_S1(8, "dcecs_vlc_symbols");
if (vlc_bits) Skip_S1(4, "dcecs_vlc_bits");
if (sadct) Skip_S1(8, "dcecs_sadct");
}
if (vop_coding_type==1) //P
{
if (opaque) Skip_S1(8, "dcecs_opaque");
if (transparent) Skip_S1(8, "dcecs_transparent");
if (intra_cae) Skip_S1(8, "dcecs_intra_cae");
if (inter_cae) Skip_S1(8, "dcecs_inter_cae");
if (no_update) Skip_S1(8, "dcecs_no_update");
if (upsampling) Skip_S1(8, "dcecs_upsampling");
if (intra_blocks) Skip_S1(8, "dcecs_intra_blocks");
if (not_coded_blocks) Skip_S1(8, "dcecs_not_coded_blocks");
if (dct_coefs) Skip_S1(8, "dcecs_dct_coefs");
if (dct_lines) Skip_S1(8, "dcecs_dct_lines");
if (vlc_symbols) Skip_S1(8, "dcecs_vlc_symbols");
if (vlc_bits) Skip_S1(4, "dcecs_vlc_bits");
if (inter_blocks) Skip_S1(8, "dcecs_inter_blocks");
if (inter4v_blocks) Skip_S1(8, "dcecs_inter4v_blocks");
if (apm) Skip_S1(8, "dcecs_apm");
if (npm) Skip_S1(8, "dcecs_npm");
if (forw_back_mc_q) Skip_S1(8, "dcecs_forw_back_mc_q");
if (halfpel2) Skip_S1(8, "dcecs_halfpel2");
if (halfpel4) Skip_S1(8, "dcecs_halfpel4");
if (sadct) Skip_S1(8, "dcecs_sadct");
if (quarterpel) Skip_S1(8, "dcecs_quarterpel");
}
if (vop_coding_type==2) //B
{
if (opaque) Skip_S1(8, "dcecs_opaque");
if (transparent) Skip_S1(8, "dcecs_transparent");
if (intra_cae) Skip_S1(8, "dcecs_intra_cae");
if (inter_cae) Skip_S1(8, "dcecs_inter_cae");
if (no_update) Skip_S1(8, "dcecs_no_update");
if (upsampling) Skip_S1(8, "dcecs_upsampling");
if (intra_blocks) Skip_S1(8, "dcecs_intra_blocks");
if (not_coded_blocks) Skip_S1(8, "dcecs_not_coded_blocks");
if (dct_coefs) Skip_S1(8, "dcecs_dct_coefs");
if (dct_lines) Skip_S1(8, "dcecs_dct_lines");
if (vlc_symbols) Skip_S1(8, "dcecs_vlc_symbols");
if (vlc_bits) Skip_S1(4, "dcecs_vlc_bits");
if (inter_blocks) Skip_S1(8, "dcecs_inter_blocks");
if (inter4v_blocks) Skip_S1(8, "dcecs_inter4v_blocks");
if (apm) Skip_S1(8, "dcecs_apm");
if (npm) Skip_S1(8, "dcecs_npm");
if (forw_back_mc_q) Skip_S1(8, "dcecs_forw_back_mc_q");
if (halfpel2) Skip_S1(8, "dcecs_halfpel2");
if (halfpel4) Skip_S1(8, "dcecs_halfpel4");
if (interpolate_mc_q) Skip_S1(8, "dcecs_interpolate_mc_q");
if (sadct) Skip_S1(8, "dcecs_sadct");
if (quarterpel) Skip_S1(8, "dcecs_sadct");
}
if (vop_coding_type==3 && sprite_enable==1) //B and static
{
if (intra_blocks) Skip_S1(8, "dcecs_intra_blocks");
if (not_coded_blocks) Skip_S1(8, "dcecs_not_coded_blocks");
if (dct_coefs) Skip_S1(8, "dcecs_dct_coefs");
if (dct_lines) Skip_S1(8, "dcecs_dct_lines");
if (vlc_symbols) Skip_S1(8, "dcecs_vlc_symbols");
if (vlc_bits) Skip_S1(4, "dcecs_vlc_bits");
if (inter_blocks) Skip_S1(8, "dcecs_inter_blocks");
if (inter4v_blocks) Skip_S1(8, "dcecs_inter4v_blocks");
if (apm) Skip_S1(8, "dcecs_apm");
if (npm) Skip_S1(8, "dcecs_npm");
if (forw_back_mc_q) Skip_S1(8, "dcecs_forw_back_mc_q");
if (halfpel2) Skip_S1(8, "dcecs_halfpel2");
if (halfpel4) Skip_S1(8, "dcecs_halfpel4");
if (interpolate_mc_q) Skip_S1(8, "dcecs_interpolate_mc_q");
}
}
}
if (shape!=2) //Shape!=BinaryOnly
{
Skip_S1(3, "intra_dc_vlc_thr");
if (interlaced)
{
bool top_field_first;
Get_SB (top_field_first, "top_field_first");
Skip_SB( "alternate_vertical_scan_flag");
//Filling
if (top_field_first)
Interlaced_Top++;
else
Interlaced_Bottom++;
}
}
//...
}
BS_End();
}
if (!vop_coded) //VOP with no data
NVOP_Count++;
else if (vop_coding_type==0) //Type I
{
IVOP_Count++;
PVOP_Count=0;
BVOP_Count=0;
}
else if (vop_coding_type==1) //Type P
{
PVOP_Count++;
BVOP_Count=0;
}
else if (vop_coding_type==2) //Type B
{
BVOP_Count++;
if (BVOP_Count>BVOP_Count_Max)
BVOP_Count_Max=BVOP_Count;
}
else if (vop_coding_type==3)
{
SVOP_Count++; //Type S
BVOP_Count=0;
}
FILLING_BEGIN();
//Duration
if (!Mpeg4v_visual_object_type[visual_object_type][0] && vop_time_increment_resolution)
{
int16u Time=modulo_time_base*1000+(int16u)vop_time_increment*1000/vop_time_increment_resolution;
while (Time_End_MilliSeconds!=(int16u)-1 && Time+500<Time_End_MilliSeconds)
Time+=1000;
Time_End_MilliSeconds=Time;
if (Time_Begin_MilliSeconds==(int16u)-1)
Time_Begin_MilliSeconds=Time_End_MilliSeconds;
Element_Info1C((Time_End_Seconds!=(int32u)-1), Ztring().Duration_From_Milliseconds((int64u)(Time_End_Seconds*1000+Time_End_MilliSeconds)));
if (FrameInfo.DTS!=(int64u)-1)
{
if (fixed_vop_time_increment && vop_time_increment_resolution)
FrameInfo.DTS+=((int64u)fixed_vop_time_increment)*1000000000/vop_time_increment_resolution;
else
FrameInfo.DTS=(int64u)-1;
}
}
//NextCode
NextCode_Test();
NextCode_Clear();
for (int8u Pos=0x00; Pos<0x2F; Pos++)
NextCode_Add(Pos); //video_object_start and video_object_layer_start
NextCode_Add(0xB1); //visual_object_sequence_end
NextCode_Add(0xB3); //group_of_vop_start_code
NextCode_Add(0xB5); //visual_object_start
NextCode_Add(0xB6); //vop_start
//Filling only if not already done
if (Frame_Count==2 && !Status[IsAccepted])
Accept("MPEG-4 Visual");
if (Frame_Count>=Frame_Count_Valid && Count_Get(Stream_Video)==0)
{
//TODO: better handling of the difference
if (IsSub)
Finish("MPEG-4 Visual");
else
{
Fill("MPEG-4 Visual");
if (Config->ParseSpeed<1.0)
{
if (!IsSub)
Open_Buffer_Unsynch();
GoToFromEnd(1024*1024, "MPEG-4 Visual");
}
}
}
#if MEDIAINFO_EVENTS
{
EVENT_BEGIN (Video, SliceInfo, 0)
Event.FieldPosition=Field_Count;
Event.SlicePosition=0;
switch (vop_coding_type)
{
case 0 :
Event.SliceType=0; break;
case 1 :
Event.SliceType=1; break;
case 2 :
Event.SliceType=2; break;
case 3 :
Event.SliceType=3; break;
default:
Event.SliceType=(int8u)-1;
}
Event.Flags=0;
EVENT_END ()
}
#endif //MEDIAINFO_EVENTS
FILLING_END();
}
//---------------------------------------------------------------------------
// Packet "B7"
void File_Mpeg4v::slice_start()
{
Element_Name("slice_start");
}
//---------------------------------------------------------------------------
// Packet "B8"
void File_Mpeg4v::extension_start()
{
Element_Name("extension_start");
}
//---------------------------------------------------------------------------
// Packet "B9"
void File_Mpeg4v::fgs_vop_start()
{
Element_Name("fgs_vop_start");
}
//---------------------------------------------------------------------------
// Packet "BA"
void File_Mpeg4v::fba_object_start()
{
Element_Name("fba_object_start");
}
//---------------------------------------------------------------------------
// Packet "BB"
void File_Mpeg4v::fba_object_plane_start()
{
Element_Name("fba_object_plane_start");
}
//---------------------------------------------------------------------------
// Packet "BC"
void File_Mpeg4v::mesh_object_start()
{
Element_Name("mesh_object_start");
}
//---------------------------------------------------------------------------
// Packet "BD"
void File_Mpeg4v::mesh_object_plane_start()
{
Element_Name("mesh_object_plane_start");
}
//---------------------------------------------------------------------------
// Packet "BE"
void File_Mpeg4v::still_texture_object_start()
{
Element_Name("still_texture_object_start");
}
//---------------------------------------------------------------------------
// Packet "BF"
void File_Mpeg4v::texture_spatial_layer_start()
{
Element_Name("texture_spatial_layer_start");
}
//---------------------------------------------------------------------------
// Packet "C0"
void File_Mpeg4v::texture_snr_layer_start()
{
Element_Name("texture_snr_layer_start");
}
//---------------------------------------------------------------------------
// Packet "C1"
void File_Mpeg4v::texture_tile_start()
{
Element_Name("texture_tile_start");
}
//---------------------------------------------------------------------------
// Packet "C2"
void File_Mpeg4v::texture_shape_layer_start()
{
Element_Name("texture_shape_layer_start");
}
//---------------------------------------------------------------------------
// Packet "C3"
void File_Mpeg4v::stuffing_start()
{
Element_Name("stuffing_start");
}
//---------------------------------------------------------------------------
// Packet "C4" and C5"
void File_Mpeg4v::reserved()
{
Element_Name("reserved");
}
//***************************************************************************
// C++
//***************************************************************************
} //NameSpace
#endif //MEDIAINFO_MPEG4V_YES
↑ V1020 The function exited without calling the 'BS_End' function. Check lines: 1677, 1577.
↑ V1020 The function exited without calling the 'BS_End' function. Check lines: 1938, 1577.
↑ V1020 The function exited without calling the 'BS_End' function. Check lines: 1938, 1583.
↑ V560 A part of conditional expression is always true: Element_Code >= 0x20.
↑ V560 A part of conditional expression is always true: vop_time_increment_resolution.
↑ V728 An excessive check can be simplified. The '(A && B) || (!A && !B)' expression is equivalent to the 'bool(A) == bool(B)' expression.
↑ V1037 Two or more case-branches perform the same actions. Check lines: 57, 71
↑ V1051 Consider checking for misprints. It's possible that the 'Time_End_MilliSeconds' should be checked here.
↑ V730 Not all members of a class are initialized inside the constructor. Consider inspecting: IVOP_Count, PVOP_Count, BVOP_Count, BVOP_Count_Max, SVOP_Count, NVOP_Count, ...
↑ V793 It is odd that the result of the '-' operator is a part of the condition. Perhaps, this statement should have been compared with something else.