/* 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" //--------------------------------------------------------------------------- //*************************************************************************** // Infos (Global) //*************************************************************************** //--------------------------------------------------------------------------- #if defined(MEDIAINFO_MPEGV_YES) || defined(MEDIAINFO_MPEG4V_YES) || defined(MEDIAINFO_AVC_YES) || defined(MEDIAINFO_HEVC_YES) || defined(MEDIAINFO_MPEG4_YES) || defined(MEDIAINFO_PRORES_YES) || defined(MEDIAINFO_PNG_YES) //--------------------------------------------------------------------------- namespace MediaInfoLib { #include "ZenLib/Conf.h" using namespace ZenLib; //--------------------------------------------------------------------------- extern const char* Mpegv_colour_primaries(int8u colour_primaries) { switch (colour_primaries) { case 1 : return "BT.709"; case 4 : return "BT.470 System M"; case 5 : return "BT.601 PAL"; case 6 : return "BT.601 NTSC"; case 7 : return "SMPTE 240M"; //Same as BT.601 NTSC case 8 : return "Generic film"; case 9 : return "BT.2020"; //Added in HEVC case 10 : return "XYZ"; //Added in HEVC 2014 case 11 : return "DCI P3"; //Added in HEVC 2016 case 12 : return "Display P3"; //Added in HEVC 2016 case 22 : return "EBU Tech 3213"; //Added in HEVC 2016 default : return ""; } } //--------------------------------------------------------------------------- extern const char* Mpegv_transfer_characteristics(int8u transfer_characteristics) { switch (transfer_characteristics) { case 1 : return "BT.709"; //Same as BT.601 case 4 : return "BT.470 System M"; case 5 : return "BT.470 System B/G"; case 6 : return "BT.601"; case 7 : return "SMPTE 240M"; case 8 : return "Linear"; case 9 : return "Logarithmic (100:1)"; //Added in MPEG-4 Visual case 10 : return "Logarithmic (316.22777:1)"; //Added in MPEG-4 Visual case 11 : return "xvYCC"; //Added in AVC case 12 : return "BT.1361"; //Added in AVC case 13 : return "sRGB/sYCC"; //Added in HEVC case 14 : return "BT.2020 (10-bit)"; //Same a BT.601 //Added in HEVC, 10/12-bit difference is in ISO 23001-8 case 15 : return "BT.2020 (12-bit)"; //Same a BT.601 //Added in HEVC, 10/12-bit difference is in ISO 23001-8 case 16 : return "PQ"; //Added in HEVC 2015 case 17 : return "SMPTE 428M"; //Added in HEVC 2015 case 18 : return "HLG"; //Added in HEVC 2016 default : return ""; } } //--------------------------------------------------------------------------- extern const char* Mpegv_matrix_coefficients(int8u matrix_coefficients) { switch (matrix_coefficients) { case 0 : return "Identity"; //Added in AVC case 1 : return "BT.709"; case 4 : return "FCC 73.682"; case 5 : return "BT.470 System B/G"; case 6 : return "BT.601"; //Same as BT.470 System B/G case 7 : return "SMPTE 240M"; case 8 : return "YCgCo"; //Added in AVC case 9 : return "BT.2020 non-constant"; //Added in HEVC case 10 : return "BT.2020 constant"; //Added in HEVC case 11 : return "Y'D'zD'x"; //Added in HEVC 2016 case 12 : return "Chromaticity-derived non-constant"; //Added in HEVC 2016 case 13 : return "Chromaticity-derived constant"; //Added in HEVC 2016 case 14 : return "ICtCp"; //Added in HEVC 2016 default : return ""; } } //--------------------------------------------------------------------------- extern const char* Mpegv_matrix_coefficients_ColorSpace(int8u matrix_coefficients) { switch (matrix_coefficients) { case 0 : return "RGB"; case 1 : case 4 : case 5 : case 6 : case 7 : case 8 : case 9 : case 10 : case 11 : case 12 : case 14 : return "YUV"; default : return ""; } } } //NameSpace //--------------------------------------------------------------------------- #endif //... //--------------------------------------------------------------------------- //*************************************************************************** // Infos (Global) //*************************************************************************** //--------------------------------------------------------------------------- #if defined(MEDIAINFO_MPEGV_YES) || defined(MEDIAINFO_MPEGTS_YES) || defined(MEDIAINFO_MPEGPS_YES) || defined(MEDIAINFO_MXF_YES) //--------------------------------------------------------------------------- namespace MediaInfoLib { #include "ZenLib/Conf.h" using namespace ZenLib; //--------------------------------------------------------------------------- extern const float64 Mpegv_frame_rate[16]= { (float64) 0, (float64)24000/(float64)1001, (float64)24, (float64)25, (float64)30000/(float64)1001, (float64)30, (float64)50, (float64)60000/(float64)1001, (float64)60, (float64) 0, (float64) 0, (float64) 0, (float64) 0, (float64) 0, (float64) 0, (float64) 0, }; //--------------------------------------------------------------------------- const char* Mpegv_chroma_format[4]= { "", "4:2:0", "4:2:2", "4:4:4", }; //--------------------------------------------------------------------------- const char* Mpegv_chroma_format_Colorspace[4] = { "", "YUV", "YUV", "", }; //--------------------------------------------------------------------------- const char* Mpegv_profile_and_level_indication (int8u profile_and_level_indication) { switch (profile_and_level_indication) { case 0x82 : return "4:2:2@High"; case 0x85 : return "4:2:2@Main"; case 0x8A : return "Multi-view@High"; case 0x8B : return "Multi-view@High-1440"; case 0x8D : return "Multi-view@Main"; case 0x8E : return "Multi-view@Low"; default : return ""; } }; //--------------------------------------------------------------------------- const char* Mpegv_profile_and_level_indication_profile[]= { "0", "High", "Spatially Scalable", "SNR Scalable", "Main", "Simple", "6", "7", }; //4:2:2 Profile? //--------------------------------------------------------------------------- const char* Mpegv_profile_and_level_indication_level[]= { "0", "1", "2", "3", "High", "4", "High 1440", "5", "Main", "6", "Low", "7", "8", "9", "10", "11", }; } //NameSpace //--------------------------------------------------------------------------- #endif //... //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- #if defined(MEDIAINFO_MPEGV_YES) //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- #include "MediaInfo/Video/File_Mpegv.h" #include "MediaInfo/TimeCode.h" #include "ZenLib/BitStream.h" #include "ZenLib/Utils.h" #if defined(MEDIAINFO_DTVCCTRANSPORT_YES) #include "MediaInfo/Text/File_DtvccTransport.h" #endif //defined(MEDIAINFO_DTVCCTRANSPORT_YES) #if defined(MEDIAINFO_SCTE20_YES) #include "MediaInfo/Text/File_Scte20.h" #endif //defined(MEDIAINFO_SCTE20_YES) #if defined(MEDIAINFO_CDP_YES) #include "MediaInfo/Text/File_Cdp.h" #include #endif //defined(MEDIAINFO_CDP_YES) #if defined(MEDIAINFO_AFDBARDATA_YES) #include "MediaInfo/Video/File_AfdBarData.h" #include #endif //defined(MEDIAINFO_AFDBARDATA_YES) #include "MediaInfo/MediaInfo_Config_MediaInfo.h" #if MEDIAINFO_EVENTS #include "MediaInfo/MediaInfo_Events.h" #include "MediaInfo/MediaInfo_Events_Internal.h" #endif //MEDIAINFO_EVENTS #include using namespace ZenLib; using namespace std; #undef FILLING_BEGIN #define FILLING_BEGIN() \ while (Element_OffsetStatus[IsUpdated]) { Update(*Text_Positions[Text_Positions_Pos].Parser); for (size_t Pos=0; Pos<(*Text_Positions[Text_Positions_Pos].Parser)->Count_Get(Stream_Text); Pos++) { //Saving previous Muxing mode Ztring MuxingMode=Retrieve(Stream_Text, Text_Positions[Text_Positions_Pos].StreamPos+Pos, "MuxingMode"); bool IsNewStream=false; if (Retrieve(Stream_Text, Text_Positions[Text_Positions_Pos].StreamPos+Pos, Text_ID)!=(*Text_Positions[Text_Positions_Pos].Parser)->Get(Stream_Text, Pos, Text_ID)) { Stream_Prepare(Stream_Text, Text_Positions[Text_Positions_Pos].StreamPos+Pos); for (size_t Text_Positions_Pos2=Text_Positions_Pos+1; Text_Positions_Pos2Retrieve(Stream_General, 0, General_LawRating); if (!LawRating.empty()) Fill(Stream_General, 0, General_LawRating, LawRating, true); Ztring Title=(*Text_Positions[Text_Positions_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); if (IsNewStream) { #if defined(MEDIAINFO_DTVCCTRANSPORT_YES) if ((*Text_Positions[Text_Positions_Pos].Parser)==GA94_03_Parser) MuxingMode=__T("A/53 / ")+Retrieve(Stream_Text, Text_Positions[Text_Positions_Pos].StreamPos+Pos, "MuxingMode"); #endif //defined(MEDIAINFO_DTVCCTRANSPORT_YES) #if defined(MEDIAINFO_SCTE20_YES) if ((*Text_Positions[Text_Positions_Pos].Parser)==Scte_Parser) MuxingMode=Retrieve(Stream_Text, Text_Positions[Text_Positions_Pos].StreamPos+Pos, "MuxingMode"); #endif //defined(MEDIAINFO_DTVCCTRANSPORT_YES) #if defined(MEDIAINFO_GXF_YES) && defined(MEDIAINFO_CDP_YES) if ((*Text_Positions[Text_Positions_Pos].Parser)==Cdp_Parser) MuxingMode=__T("Ancillary data / ")+Retrieve(Stream_Text, Text_Positions[Text_Positions_Pos].StreamPos+Pos, "MuxingMode"); #endif //defined(MEDIAINFO_GXF_YES) && defined(MEDIAINFO_CDP_YES) } Fill(Stream_Text, Text_Positions[Text_Positions_Pos].StreamPos+Pos, "MuxingMode", MuxingMode, true); } } } } //--------------------------------------------------------------------------- void File_Mpegv::Streams_Fill() { //Version if (MPEG_Version==2) { Fill(Stream_General, 0, General_Format_Version, "Version 2"); Fill(Stream_Video, 0, Video_Format, "MPEG Video"); Fill(Stream_Video, 0, Video_Format_Version, "Version 2"); Fill(Stream_Video, 0, Video_Format_Commercial, "MPEG-2 Video"); Fill(Stream_Video, 0, Video_Codec, "MPEG-2V"); Fill(Stream_Video, 0, Video_Codec_String, "MPEG-2 Video", Unlimited, true, true); } else { Fill(Stream_General, 0, General_Format_Version, "Version 1"); Fill(Stream_Video, 0, Video_Format, "MPEG Video"); Fill(Stream_Video, 0, Video_Format_Version, "Version 1"); Fill(Stream_Video, 0, Video_Format_Commercial, "MPEG-1 Video"); Fill(Stream_Video, 0, Video_Codec, "MPEG-1V"); Fill(Stream_Video, 0, Video_Codec_String, "MPEG-1 Video", Unlimited, true, true); } Fill(Stream_Video, 0, Video_Width, 0x1000*horizontal_size_extension+horizontal_size_value); Fill(Stream_Video, 0, Video_Height, 0x1000*vertical_size_extension+vertical_size_value); Fill(Stream_Video, 0, Video_ChromaSubsampling, Mpegv_chroma_format[chroma_format]); Fill(Stream_Video, 0, Video_ColorSpace, Mpegv_chroma_format_Colorspace[chroma_format]); Fill(Stream_Video, 0, Video_BitDepth, 8); //AspectRatio if (MPEG_Version==2) { if (aspect_ratio_information==0) ;//Forbidden else if (aspect_ratio_information==1) Fill(Stream_Video, 0, Video_PixelAspectRatio, 1.000, 3, true); else if (display_horizontal_size && display_vertical_size) { if (vertical_size_value && Mpegv_aspect_ratio2[aspect_ratio_information]) Fill(Stream_Video, StreamPos_Last, Video_DisplayAspectRatio, (float)(0x1000*horizontal_size_extension+horizontal_size_value)/(0x1000*vertical_size_extension+vertical_size_value) *Mpegv_aspect_ratio2[aspect_ratio_information]/((float)display_horizontal_size/display_vertical_size), 3, true); } else if (Mpegv_aspect_ratio2[aspect_ratio_information]) Fill(Stream_Video, StreamPos_Last, Video_DisplayAspectRatio, Mpegv_aspect_ratio2[aspect_ratio_information], 3, true); } else //Version 1 { if (vertical_size_value && Mpegv_aspect_ratio1[aspect_ratio_information]) Fill(Stream_Video, StreamPos_Last, Video_DisplayAspectRatio, (float)(0x1000*horizontal_size_extension+horizontal_size_value)/(0x1000*vertical_size_extension+vertical_size_value)/Mpegv_aspect_ratio1[aspect_ratio_information], 3, true); } //FrameRate if (Mpegv_frame_rate[frame_rate_code]) Fill(Stream_Video, StreamPos_Last, Video_FrameRate, Mpegv_frame_rate[frame_rate_code] * (frame_rate_extension_n + 1) / (frame_rate_extension_d + 1)); //BitRate if (vbv_delay==0xFFFF || (MPEG_Version==1 && bit_rate_value==0x3FFFF)) Fill(Stream_Video, 0, Video_BitRate_Mode, "VBR"); else Fill(Stream_Video, 0, Video_BitRate_Mode, "CBR"); if (bit_rate_value_IsValid && (bit_rate_extension>0 || bit_rate_value!=0x3FFFF)) Fill(Stream_Video, 0, Video_BitRate_Maximum, ((((int32u)bit_rate_extension<<12))+bit_rate_value)*400); //Interlacement if (MPEG_Version==1) { Fill(Stream_Video, 0, Video_ScanType, "Progressive"); Fill(Stream_Video, 0, Video_Interlacement, "PPF"); } else if (progressive_frame_Count && progressive_frame_Count!=Frame_Count && progressive_frame_Count!=Frame_Count+1) //In case the stream is cut before a slice { //This is mixed } else if (Frame_Count>0) //Only if we have at least one progressive_frame definition { if (progressive_sequence || progressive_frame_Count==Frame_Count || progressive_frame_Count==Frame_Count+1) { Fill(Stream_Video, 0, Video_ScanType, "Progressive"); Fill(Stream_Video, 0, Video_Interlacement, "PPF"); if (!progressive_sequence && !(Interlaced_Top && Interlaced_Bottom) && !(!Interlaced_Top && !Interlaced_Bottom)) Fill(Stream_Video, 0, Video_ScanOrder, Interlaced_Top?"TFF":"BFF"); } else { 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"); } if (!(PictureStructure_Field && PictureStructure_Frame) && !(!PictureStructure_Field && !PictureStructure_Frame)) Fill(Stream_Video, 0, Video_Format_Settings_PictureStructure, PictureStructure_Field?"Field":"Frame"); } std::string TempRef; for (size_t Pos=0; PosHasPictureCoding) { TempRef+=TemporalReference[Pos]->top_field_first?"T":"B"; TempRef+=TemporalReference[Pos]->repeat_first_field?"3":"2"; } if (TempRef.find('3')!=std::string::npos) { if (TempRef.find("T2T3B2B3T2T3B2B3")!=std::string::npos || TempRef.find("B2B3T2T3B2B3T2T3")!=std::string::npos) { Fill(Stream_Video, 0, Video_ScanOrder, "2:3 Pulldown", Unlimited, true, true); Fill(Stream_Video, 0, Video_FrameRate, FrameRate*24/30, 3, true); //Real framerate Fill(Stream_Video, 0, Video_ScanType, "Progressive", Unlimited, true, true); Fill(Stream_Video, 0, Video_Interlacement, "PPF", Unlimited, true, true); } if (TempRef.find("T2T2T2T2T2T2T2T2T2T2T2T3B2B2B2B2B2B2B2B2B2B2B2B3")!=std::string::npos || TempRef.find("B2B2B2B2B2B2B2B2B2B2B2B3T2T2T2T2T2T2T2T2T2T2T2T3")!=std::string::npos) { Fill(Stream_Video, 0, Video_ScanOrder, "2:2:2:2:2:2:2:2:2:2:2:3 Pulldown", Unlimited, true, true); Fill(Stream_Video, 0, Video_FrameRate, FrameRate*24/25, 3, true); //Real framerate Fill(Stream_Video, 0, Video_ScanType, "Progressive", Unlimited, true, true); Fill(Stream_Video, 0, Video_Interlacement, "PPF", Unlimited, true, true); } } } //Profile if (!profile_and_level_indication_escape && profile_and_level_indication_profile!=(int8u)-1 && profile_and_level_indication_level!=(int8u)-1) { Fill(Stream_Video, 0, Video_Format_Profile, Ztring().From_UTF8(Mpegv_profile_and_level_indication_profile[profile_and_level_indication_profile])+__T("@")+Ztring().From_UTF8(Mpegv_profile_and_level_indication_level[profile_and_level_indication_level])); Fill(Stream_Video, 0, Video_Codec_Profile, Ztring().From_UTF8(Mpegv_profile_and_level_indication_profile[profile_and_level_indication_profile])+__T("@")+Ztring().From_UTF8(Mpegv_profile_and_level_indication_level[profile_and_level_indication_level])); } else if (profile_and_level_indication_escape) { Fill(Stream_Video, 0, Video_Format_Profile, Ztring().From_UTF8(Mpegv_profile_and_level_indication(profile_and_level_indication))); Fill(Stream_Video, 0, Video_Codec_Profile, Ztring().From_UTF8(Mpegv_profile_and_level_indication(profile_and_level_indication))); } //Standard Fill(Stream_Video, 0, Video_Standard, Mpegv_video_format[video_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)); if (matrix_coefficients!=2) Fill(Stream_Video, 0, Video_ColorSpace, Mpegv_matrix_coefficients_ColorSpace(matrix_coefficients), Unlimited, true, true); } //Matrix if (load_intra_quantiser_matrix || load_non_intra_quantiser_matrix) { Fill(Stream_Video, 0, Video_Format_Settings, "CustomMatrix"); 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, "CustomMatrix"); Fill(Stream_Video, 0, Video_Codec_Settings_Matrix, "Custom"); } else { Fill(Stream_Video, 0, Video_Format_Settings_Matrix, "Default"); Fill(Stream_Video, 0, Video_Codec_Settings_Matrix, "Default"); } //library if (Library.size()>=8) { 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_General, 0, General_Encoded_Library, Library); Fill(Stream_General, 0, General_Encoded_Library_Name, Library_Name); Fill(Stream_General, 0, General_Encoded_Library_Version, Library_Version); } //Delay if (group_start_FirstPass && !TimeCodeIsNotTrustable && Time_Begin_Seconds!=Error) { float64 Time_Begin=((float64)Time_Begin_Seconds)*1000; if (FrameRate) Time_Begin+=((float64)Time_Begin_Frames)*1000/FrameRate; Fill(Stream_Video, 0, Video_Delay, Time_Begin, 0); Fill(Stream_Video, 0, Video_Delay_Settings, Ztring(__T("drop_frame_flag="))+(group_start_drop_frame_flag?__T("1"):__T("0"))); Fill(Stream_Video, 0, Video_Delay_Settings, Ztring(__T("closed_gop="))+(group_start_closed_gop?__T("1"):__T("0"))); Fill(Stream_Video, 0, Video_Delay_Settings, Ztring(__T("broken_link="))+(group_start_broken_link?__T("1"):__T("0"))); Fill(Stream_Video, 0, Video_Delay_Source, "Stream"); Fill(Stream_Video, 0, Video_Delay_DropFrame, group_start_drop_frame_flag?"Yes":"No"); if (group_start_closed_gop_Closed+group_start_closed_gop_Open>=4 && ((group_start_closed_gop && group_start_closed_gop_Closed==1) || group_start_closed_gop_Closed==0 || group_start_closed_gop_Open==0)) // Testing a couple of GOPs, and coherant { if (group_start_closed_gop_Open) { Fill(Stream_Video, 0, Video_Gop_OpenClosed, "Open"); if (group_start_closed_gop) Fill(Stream_Video, 0, Video_Gop_OpenClosed_FirstFrame, "Closed"); } else { Fill(Stream_Video, 0, Video_Gop_OpenClosed, "Closed"); } } Fill(Stream_Video, 0, Video_TimeCode_FirstFrame, TimeCode_FirstFrame.c_str()); if (IsSub) Fill(Stream_Video, 0, Video_TimeCode_Source, "Group of pictures header"); } //BVOP if (BVOP_Count>0) { Fill(Stream_Video, 0, Video_Format_Settings, "BVOP"); Fill(Stream_Video, 0, Video_Format_Settings_BVOP, "Yes"); } else Fill(Stream_Video, 0, Video_Format_Settings_BVOP, "No"); //Buffer Fill(Stream_Video, 0, Video_BufferSize, 2*1024*((((int32u)vbv_buffer_size_extension)<<10)+vbv_buffer_size_value)); //Autorisation of other streams if (!Status[IsAccepted]) { NextCode_Clear(); NextCode_Add(0x00); NextCode_Add(0xB8); } #if MEDIAINFO_MACROBLOCKS if (!Macroblocks_Parse) #endif //MEDIAINFO_MACROBLOCKS for (int8u Pos=0x01; Pos<=0xAF; Pos++) Streams[Pos].Searching_Payload=false; Streams[0xB8].Searching_TimeStamp_End=true; if (IsSub) { Streams[0xB3].Searching_TimeStamp_End=true; Streams[0x00].Searching_TimeStamp_End=true; } //Caption may be in user_data, must be activated if full parsing is requested #if defined(MEDIAINFO_DTVCCTRANSPORT_YES) || defined(MEDIAINFO_SCTE20_YES) || (defined(MEDIAINFO_GXF_YES) && defined(MEDIAINFO_CDP_YES)) Streams[0x00].Searching_Payload=GA94_03_IsPresent || Cdp_IsPresent; Streams[0xB2].Searching_Payload=GA94_03_IsPresent || CC___IsPresent || Scte_IsPresent; Streams[0xB3].Searching_Payload=GA94_03_IsPresent || Cdp_IsPresent; #endif //defined(MEDIAINFO_DTVCCTRANSPORT_YES) || defined(MEDIAINFO_SCTE20_YES) || (defined(MEDIAINFO_GXF_YES) && defined(MEDIAINFO_CDP_YES)) if (Config->ParseSpeed>=1) { Streams[0x00].Searching_Payload=true; Streams[0xB2].Searching_Payload=true; Streams[0xB3].Searching_Payload=true; Streams[0xB5].Searching_Payload=true; } #if defined(MEDIAINFO_AFDBARDATA_YES) if (DTG1_Parser) Merge(*DTG1_Parser, Stream_Video, 0, 0); if (GA94_06_Parser) { Merge(*GA94_06_Parser, Stream_Video, 0, 0); Ztring LawRating=GA94_06_Parser->Retrieve(Stream_General, 0, General_LawRating); if (!LawRating.empty()) Fill(Stream_General, 0, General_LawRating, LawRating, true); Ztring Title=GA94_06_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_AFDBARDATA_YES) #if defined(MEDIAINFO_AFDBARDATA_YES) if (AfdBarData_Parser) Merge(*AfdBarData_Parser, Stream_Video, 0, 0); #endif //defined(MEDIAINFO_AFDBARDATA_YES) //extra if (intra_dc_precision!=(int8u)-1) { Fill(Stream_Video, 0, "intra_dc_precision", 8+intra_dc_precision); Fill_SetOptions(Stream_Video, 0, "intra_dc_precision", "N NT"); } //Commercial name if (Retrieve(Stream_Video, 0, Video_Format_Version)==__T("Version 2") && Retrieve(Stream_Video, 0, Video_DisplayAspectRatio)==__T("1.778") && Retrieve(Stream_Video, 0, Video_BitDepth)==__T("8") && Retrieve(Stream_Video, 0, Video_ChromaSubsampling)==__T("4:2:0")) { //HDV1 if (Retrieve(Stream_Video, 0, Video_Width)==__T("1280") && Retrieve(Stream_Video, 0, Video_Height)==__T("720") && Retrieve(Stream_Video, 0, Video_ScanType)==__T("Progressive") && (Retrieve(Stream_Video, 0, Video_FrameRate)==__T("60.000") || Retrieve(Stream_Video, 0, Video_FrameRate)==__T("59.940") || Retrieve(Stream_Video, 0, Video_FrameRate)==__T("30.000") || Retrieve(Stream_Video, 0, Video_FrameRate)==__T("29.970") || Retrieve(Stream_Video, 0, Video_FrameRate)==__T("24.000") || Retrieve(Stream_Video, 0, Video_FrameRate)==__T("23.976") || Retrieve(Stream_Video, 0, Video_FrameRate)==__T("50.000") || Retrieve(Stream_Video, 0, Video_FrameRate)==__T("25.000")) && (Retrieve(Stream_Video, 0, Video_Format_Profile)==__T("Main@High") || Retrieve(Stream_Video, 0, Video_Format_Profile)==__T("Main@High 1440")) && Retrieve(Stream_Video, 0, Video_BitRate).To_int64u()<20000000 && Retrieve(Stream_Video, 0, Video_BitRate_Maximum).To_int64u()<20000000) Fill(Stream_Video, 0, Video_Format_Commercial_IfAny, "HDV 720p"); //HDV2 if (Retrieve(Stream_Video, 0, Video_Width)==__T("1440") && Retrieve(Stream_Video, 0, Video_Height)==__T("1080") && Retrieve(Stream_Video, 0, Video_Format_Profile)==__T("Main@High 1440") && Retrieve(Stream_Video, 0, Video_BitRate).To_int64u()<27000000 && Retrieve(Stream_Video, 0, Video_BitRate_Maximum).To_int64u()<27000000) { //Interlaced if (Retrieve(Stream_Video, 0, Video_ScanType)==__T("Interlaced") && (Retrieve(Stream_Video, 0, Video_FrameRate)==__T("30.000") || Retrieve(Stream_Video, 0, Video_FrameRate)==__T("29.970") || Retrieve(Stream_Video, 0, Video_FrameRate)==__T("50.000") || Retrieve(Stream_Video, 0, Video_FrameRate)==__T("25.000"))) Fill(Stream_Video, 0, Video_Format_Commercial_IfAny, "HDV 1080i"); //Progressive if (Retrieve(Stream_Video, 0, Video_ScanType)==__T("Progressive") && (Retrieve(Stream_Video, 0, Video_FrameRate)==__T("30.000") || Retrieve(Stream_Video, 0, Video_FrameRate)==__T("29.970") || Retrieve(Stream_Video, 0, Video_FrameRate)==__T("24.000") || Retrieve(Stream_Video, 0, Video_FrameRate)==__T("23.976") || Retrieve(Stream_Video, 0, Video_FrameRate)==__T("50.000") || Retrieve(Stream_Video, 0, Video_FrameRate)==__T("25.000"))) Fill(Stream_Video, 0, Video_Format_Commercial_IfAny, "HDV 1080p"); } } } //--------------------------------------------------------------------------- void File_Mpegv::Streams_Finish() { //Duration if (PTS_End>PTS_Begin) { if (PTS_End_temporal_reference=ceilFrameRate) { auto AddToSeconds=Time_End_Frames/ceilFrameRate; auto NewFrames=Time_End_Frames%ceilFrameRate; Time_End_Seconds+=AddToSeconds; Time_End_Frames=NewFrames; } bool DropFrame=group_start_IsParsed?group_start_drop_frame_flag:((FrameRate==ceilFrameRate)?true:false); int32u FramesMax=ceilFrameRate-1; TimeCode Time_Begin_TC(Time_Begin_Seconds/3600, (int8u)((Time_Begin_Seconds%3600)/60), (int8u)(Time_Begin_Seconds%60), Time_Begin_Frames, FramesMax, TimeCode::DropFrame(DropFrame)); TimeCode Time_End_TC (Time_End_Seconds /3600, (int8u)((Time_End_Seconds %3600)/60), (int8u)(Time_End_Seconds %60), Time_End_Frames , FramesMax, TimeCode::DropFrame(DropFrame)); if (Time_Begin_TC.IsValid() && Time_End_TC.IsValid()) { int64u FrameCount=Time_End_TC.ToFrames()-Time_Begin_TC.ToFrames(); if (FrameCount) { Fill(Stream_Video, 0, Video_FrameCount, FrameCount, 0); Fill(Stream_Video, 0, Video_Duration, FrameCount/FrameRate*1000, 0); } } } //picture_coding_types if (!picture_coding_types.empty()) { int64u MaxCount=0; int64u Total=0; string MaxCount_type; for (std::map::iterator Temp=picture_coding_types.begin(); Temp!=picture_coding_types.end(); ++Temp) { if (Temp->second>MaxCount) { MaxCount=Temp->second; MaxCount_type=Temp->first; } Total+=Temp->second; } if (Total>=4) { int64u Count=0; for (std::map::iterator Temp=picture_coding_types.begin(); Temp!=picture_coding_types.end(); ++Temp) if (Temp->first!=MaxCount_type) Count+=Temp->second; if (CountM_Max) M_Max=M; } else M=1; Ztring GOP; if (M_Max>1) { GOP+=__T("M="); GOP+=Ztring::ToZtring(M_Max); GOP+=__T(", "); } GOP+=__T("N="); GOP+=Ztring::ToZtring(MaxCount_type.size()); Fill(Stream_Video, 0, Video_Format_Settings_GOP, GOP, true); } else Fill(Stream_Video, 0, Video_Format_Settings_GOP, "Variable", Unlimited, true, true); } } //InitDataNotRepeated #if MEDIAINFO_ADVANCED if (!InitDataNotRepeated_Optional && Config_InitDataNotRepeated_Occurences!=(int64u)-1) Fill(Stream_Video, 0, "InitDataRepeated", InitDataNotRepeated>=Config_InitDataNotRepeated_Occurences?"No":"Yes", Unlimited, true, true); #endif // MEDIAINFO_ADVANCED //Other parsers #if defined(MEDIAINFO_DTVCCTRANSPORT_YES) if (GA94_03_Parser && !GA94_03_Parser->Status[IsFinished] && GA94_03_Parser->Status[IsAccepted]) Finish(GA94_03_Parser); if (CC___Parser && !CC___Parser->Status[IsFinished] && CC___Parser->Status[IsAccepted]) Finish(CC___Parser); #endif //defined(MEDIAINFO_DTVCCTRANSPORT_YES) #if defined(MEDIAINFO_SCTE20_YES) if (Scte_Parser && !Scte_Parser->Status[IsFinished] && Scte_Parser->Status[IsAccepted]) Finish(Scte_Parser); #endif //defined(MEDIAINFO_SCTE20_YES) #if defined(MEDIAINFO_AFDBARDATA_YES) if (DTG1_Parser && !DTG1_Parser->Status[IsFinished] && DTG1_Parser->Status[IsAccepted]) { Finish(DTG1_Parser); Merge(*DTG1_Parser, Stream_Video, 0, 0); } if (GA94_06_Parser && !GA94_06_Parser->Status[IsFinished] && GA94_06_Parser->Status[IsAccepted]) { Finish(GA94_06_Parser); Merge(*GA94_06_Parser, Stream_Video, 0, 0); } #endif //defined(MEDIAINFO_AFDBARDATA_YES) #if defined(MEDIAINFO_CDP_YES) if (Cdp_Parser && !Cdp_Parser->Status[IsFinished] && Cdp_Parser->Status[IsAccepted]) Finish(Cdp_Parser); #endif //defined(MEDIAINFO_CDP_YES) #if defined(MEDIAINFO_AFDBARDATA_YES) if (AfdBarData_Parser && !AfdBarData_Parser->Status[IsFinished] && AfdBarData_Parser->Status[IsAccepted]) { Finish(AfdBarData_Parser); Merge(*AfdBarData_Parser, Stream_Video, 0, 0); } #endif //defined(MEDIAINFO_AFDBARDATA_YES) #if MEDIAINFO_IBIUSAGE int64u Numerator=0, Denominator=0; switch (frame_rate_code) { case 1 : Numerator=24000; Denominator=1001; break; case 2 : Numerator=24; Denominator=1; break; case 3 : Numerator=25; Denominator=1; break; case 4 : Numerator=30000; Denominator=1001; break; case 5 : Numerator=30; Denominator=1; break; case 6 : Numerator=50; Denominator=1; break; case 7 : Numerator=60000; Denominator=1001; break; case 8 : Numerator=60; Denominator=1; break; default: ; } if (Numerator) { Numerator*=frame_rate_extension_n+1; Denominator*=frame_rate_extension_d+1; Ibi_Stream_Finish(Numerator, Denominator); } #endif //MEDIAINFO_IBIUSAGE } //*************************************************************************** // Buffer - Synchro //*************************************************************************** //--------------------------------------------------------------------------- bool File_Mpegv::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 if ((Ibi_SliceParsed && (Buffer[Buffer_Offset+3]==0x00)) || Buffer[Buffer_Offset+3]==0xB3) // picture_start without sequence_header or sequence_header { if (Buffer_Offset+6>Buffer_Size) return false; bool RandomAccess=(Buffer[Buffer_Offset+5]&0x38)==0x08 || Buffer[Buffer_Offset+3]==0xB3; //picture_start with I-Frame || sequence_header if (RandomAccess) Ibi_Add(); Ibi_SliceParsed=false; } #endif //MEDIAINFO_IBIUSAGE //We continue return true; } //--------------------------------------------------------------------------- void File_Mpegv::Synched_Init() { if (!Frame_Count_Valid) Frame_Count_Valid=Config->ParseSpeed>=0.3?512:(IsSub?1:2); //Temp BVOP_Count=0; progressive_frame_Count=0; Interlaced_Top=0; Interlaced_Bottom=0; PictureStructure_Field=0; PictureStructure_Frame=0; display_horizontal_size=0; display_vertical_size=0; vbv_delay=0; vbv_buffer_size_value=0; Time_Current_Seconds=Error; Time_Current_Frames=(int8u)-1; Time_Begin_Seconds=Error; Time_Begin_Frames=(int8u)-1; Time_End_Seconds=Error; Time_End_Frames=(int8u)-1; picture_coding_type=(int8u)-1; bit_rate_value=0; FrameRate=0; horizontal_size_value=0; vertical_size_value=0; bit_rate_extension=0; temporal_reference_Old=(int16u)-1; temporal_reference_Max=0; aspect_ratio_information=0; frame_rate_code=0; profile_and_level_indication_profile=(int8u)-1; profile_and_level_indication_level=(int8u)-1; chroma_format=1; //Default is 4:2:0 horizontal_size_extension=0; vertical_size_extension=0; frame_rate_extension_n=0; frame_rate_extension_d=0; video_format=5; //Unspecified video format colour_primaries=(int8u)-1; transfer_characteristics=(int8u)-1; matrix_coefficients=(int8u)-1; vbv_buffer_size_extension=0; intra_dc_precision=(int8u)-1; load_intra_quantiser_matrix=false; load_non_intra_quantiser_matrix=false; progressive_sequence=true; //progressive by default top_field_first=false; repeat_first_field=false; FirstFieldFound=false; group_start_IsParsed=false; group_start_FirstPass=false; PTS_LastIFrame=(int64u)-1; PTS_End_temporal_reference=(int16u)-1; bit_rate_value_IsValid=false; profile_and_level_indication_escape=false; colour_description=false; low_delay=false; RefFramesCount=0; BVOPsSinceLastRefFrames=0; temporal_reference_LastIFrame=0; tc=0; IFrame_IsParsed=false; IFrame_Count=0; #if MEDIAINFO_IBIUSAGE Ibi_SliceParsed=true; #endif //MEDIAINFO_IBIUSAGE #if MEDIAINFO_ADVANCED Config_VariableGopDetection_Occurences=MediaInfoLib::Config.VariableGopDetection_Occurences_Get(); Config_VariableGopDetection_GiveUp=MediaInfoLib::Config.VariableGopDetection_GiveUp_Get(); InitDataNotRepeated=0; Config_InitDataNotRepeated_Occurences=MediaInfoLib::Config.InitDataNotRepeated_Occurences_Get(); Config_InitDataNotRepeated_GiveUp=MediaInfoLib::Config.InitDataNotRepeated_GiveUp_Get(); #endif //MEDIAINFO_ADVANCED //Default stream values Streams.resize(0x100); Streams[0xB3].Searching_Payload=true; for (int8u Pos=0xFF; Pos>=0xB9; Pos--) Streams[Pos].Searching_Payload=true; //Testing MPEG-PS //Macroblocks #if MEDIAINFO_MACROBLOCKS Macroblocks_Parse=Config->File_Macroblocks_Parse_Get(); if (Macroblocks_Parse) { macroblock_address_increment_Vlc.Array=NULL; macroblock_address_increment_Vlc.Vlc=Mpegv_macroblock_address_increment; macroblock_address_increment_Vlc.Size=11; Get_VL_Prepare(macroblock_address_increment_Vlc); dct_dc_size_luminance.Array=NULL; dct_dc_size_luminance.Vlc=Mpegv_dct_dc_size_luminance; dct_dc_size_luminance.Size=9; Get_VL_Prepare(dct_dc_size_luminance); dct_dc_size_chrominance.Array=NULL; dct_dc_size_chrominance.Vlc=Mpegv_dct_dc_size_chrominance; dct_dc_size_chrominance.Size=10; Get_VL_Prepare(dct_dc_size_chrominance); dct_coefficients_0.Array=NULL; dct_coefficients_0.Vlc=Mpegv_dct_coefficients_0; dct_coefficients_0.Size=17; Get_VL_Prepare(dct_coefficients_0); dct_coefficients_1.Array=NULL; dct_coefficients_1.Vlc=Mpegv_dct_coefficients_1; dct_coefficients_1.Size=17; Get_VL_Prepare(dct_coefficients_1); macroblock_type_I.Array=NULL; macroblock_type_I.Vlc=Mpegv_macroblock_type_I; macroblock_type_I.Size=2; Get_VL_Prepare(macroblock_type_I); macroblock_type_P.Array=NULL; macroblock_type_P.Vlc=Mpegv_macroblock_type_P; macroblock_type_P.Size=6; Get_VL_Prepare(macroblock_type_P); macroblock_type_B.Array=NULL; macroblock_type_B.Vlc=Mpegv_macroblock_type_B; macroblock_type_B.Size=6; Get_VL_Prepare(macroblock_type_B); motion_code.Array=NULL; motion_code.Vlc=Mpegv_motion_code; motion_code.Size=11; Get_VL_Prepare(motion_code); dmvector.Array=NULL; dmvector.Vlc=Mpegv_dmvector; dmvector.Size=2; Get_VL_Prepare(dmvector); coded_block_pattern.Array=NULL; coded_block_pattern.Vlc=Mpegv_coded_block_pattern; coded_block_pattern.Size=9; Get_VL_Prepare(coded_block_pattern); } #endif //MEDIAINFO_MACROBLOCKS } //*************************************************************************** // Buffer - Demux //*************************************************************************** //--------------------------------------------------------------------------- #if MEDIAINFO_DEMUX bool File_Mpegv::Demux_UnpacketizeContainer_Test() { if ((Demux_IntermediateItemFound && Buffer[Buffer_Offset+3]==0x00) || Buffer[Buffer_Offset+3]==0xB3) { if (Demux_Offset==0) { Demux_Offset=Buffer_Offset; Demux_IntermediateItemFound=false; } if (IsSub && ParserIDs[0]==MediaInfo_Parser_Mxf) //TODO: find a better way to demux, currently implemeted this way because we need I-frame status info from MXF { Demux_Offset=Buffer_Size; Demux_IntermediateItemFound=true; } else { while (Demux_Offset+4<=Buffer_Size) { //Synchronizing while(Demux_Offset+4<=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[Demux_Offset-1]==0x00) Demux_Offset--; } if (Demux_Offset+4>Buffer_Size) { if (Config->IsFinishing) Demux_Offset=Buffer_Size; break; } if (Demux_IntermediateItemFound) { bool MustBreak; switch (Buffer[Demux_Offset+3]) { case 0x00 : case 0xB3 : MustBreak=true; break; default : Demux_Offset+=3; MustBreak=false; } if (MustBreak) break; //while() loop } else { if (!Buffer[Demux_Offset+3]) Demux_IntermediateItemFound=true; } Demux_Offset++; } if (Demux_Offset+4>Buffer_Size && !Config->IsFinishing) return false; //No complete frame } bool RandomAccess=Buffer[Buffer_Offset+3]==0xB3; if (!Status[IsAccepted]) { if (Config->Demux_EventWasSent) return false; File_Mpegv* MI=new File_Mpegv; 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; } if (IFrame_IsParsed || RandomAccess) Demux_UnpacketizeContainer_Demux(RandomAccess); else Demux_UnpacketizeContainer_Demux_Clear(); } return true; } #endif //MEDIAINFO_DEMUX //*************************************************************************** // Buffer - Global //*************************************************************************** //--------------------------------------------------------------------------- void File_Mpegv::Read_Buffer_Unsynched() { for (int8u Pos=0x00; Pos<0xB9; Pos++) { Streams[Pos].Init_Stream(false); } Streams[0xB3].Searching_TimeStamp_End=true; //sequence_header Streams[0xB8].Searching_TimeStamp_End=true; //group_start Time_End_Seconds=Error; Time_End_Frames=(int8u)-1; RefFramesCount=0; sequence_header_IsParsed=false; group_start_IsParsed=false; PTS_LastIFrame=(int64u)-1; IFrame_IsParsed=false; picture_coding_types_Current.clear(); #if MEDIAINFO_IBIUSAGE Ibi_SliceParsed=true; #endif //MEDIAINFO_IBIUSAGE #if MEDIAINFO_MACROBLOCKS if (Macroblocks_Parse) { macroblock_x_PerFrame=0; macroblock_y_PerFrame=0; } #endif //MEDIAINFO_MACROBLOCKS temporal_reference_Old=(int16u)-1; for (size_t Pos=0; PosOpen_Buffer_Unsynch(); if (CC___Parser) CC___Parser->Open_Buffer_Unsynch(); #endif //defined(MEDIAINFO_DTVCCTRANSPORT_YES) #if defined(MEDIAINFO_SCTE20_YES) Scte_TemporalReference_Offset=0; if (Scte_Parser) Scte_Parser->Open_Buffer_Unsynch(); #endif //defined(MEDIAINFO_SCTE20_YES) #if defined(MEDIAINFO_AFDBARDATA_YES) if (DTG1_Parser) DTG1_Parser->Open_Buffer_Unsynch(); if (GA94_06_Parser) GA94_06_Parser->Open_Buffer_Unsynch(); #endif //defined(MEDIAINFO_AFDBARDATA_YES) #if defined(MEDIAINFO_CDP_YES) if (Cdp_Parser) Cdp_Parser->Open_Buffer_Unsynch(); #endif //defined(MEDIAINFO_CDP_YES) #if defined(MEDIAINFO_AFDBARDATA_YES) if (AfdBarData_Parser) AfdBarData_Parser->Open_Buffer_Unsynch(); #endif //defined(MEDIAINFO_AFDBARDATA_YES) #if defined(MEDIAINFO_ANCILLARY_YES) && defined(MEDIAINFO_CDP_YES) if (Ancillary && *Ancillary && (*Ancillary)->Cdp_Data.empty()) (*Ancillary)->AspectRatio=0; #endif //defined(MEDIAINFO_ANCILLARY_YES) //NextCode if (!Status[IsAccepted]) { NextCode_Clear(); NextCode_Add(0xB3); NextCode_Add(0xB8); } } //*************************************************************************** // Buffer - Per element //*************************************************************************** //--------------------------------------------------------------------------- void File_Mpegv::Header_Parse() { #if MEDIAINFO_TRACE if (Trace_Activated) { //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)); } else { #endif //MEDIAINFO_TRACE //Parsing int8u start_code=Buffer[Buffer_Offset+3]; Element_Offset+=4; if (!Header_Parser_Fill_Size()) { Element_WaitForMoreData(); return; } //Filling Header_Fill_Code(start_code, Ztring().From_CC1(start_code)); #if MEDIAINFO_TRACE } #endif //MEDIAINFO_TRACE } //--------------------------------------------------------------------------- bool File_Mpegv::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-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_Mpegv::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=Buffer[Buffer_Offset+3]; //Searching start or timestamp if (Streams[start_code].Searching_Payload || Streams[start_code].Searching_TimeStamp_Start || Streams[start_code].Searching_TimeStamp_End) return true; #if MEDIAINFO_ADVANCED || MEDIAINFO_EVENTS if (start_code==0xB3) // sequence_header { // Has_sequence_header=true; } if (start_code==0xB5) // extension_start { if (Buffer_Offset+5>Buffer_Size) return false; if ((Buffer[Buffer_Offset+4]&0xF0)==0x10) // sequence_extension Has_sequence_extension=true; } #endif // MEDIAINFO_ADVANCED || MEDIAINFO_EVENTS //Synchronizing Buffer_Offset+=4; Synched=false; if (!Synchronize()) { UnSynched_IsNotJunk=true; return false; } if (Buffer_Offset+4>Buffer_Size) { UnSynched_IsNotJunk=true; return false; } } Trusted_IsNot("MPEG Video, Synchronisation lost"); return Synchronize(); } //--------------------------------------------------------------------------- void File_Mpegv::Data_Parse() { //Parsing switch (Element_Code) { case 0x00: picture_start(); break; case 0xB0: Skip_XX(Element_Size, "Unknown"); break; case 0xB1: Skip_XX(Element_Size, "Unknown"); break; case 0xB2: user_data_start(); break; case 0xB3: sequence_header(); break; case 0xB4: sequence_error(); break; case 0xB5: extension_start(); break; case 0xB6: Skip_XX(Element_Size, "Unknown"); break; case 0xB7: sequence_end(); break; case 0xB8: group_start(); break; default: if (Element_Code>=0x01 && Element_Code<=0xAF) slice_start(); else Trusted_IsNot("Unattended element"); } } //*************************************************************************** // EOF //*************************************************************************** //--------------------------------------------------------------------------- void File_Mpegv::Detect_EOF() { if ((IsSub && Status[IsFilled]) || (!IsSub && File_Size>SizeToAnalyse_Begin+SizeToAnalyse_End && File_Offset+Buffer_Offset+Element_Offset>SizeToAnalyse_Begin && File_Offset+Buffer_Offset+Element_OffsetParseSpeed<=0.5)) { if (MustExtendParsingDuration && Frame_CountSizeToAnalyse_Begin*10+SizeToAnalyse_End*10 && File_Offset+Buffer_Offset+Element_Offset>SizeToAnalyse_Begin*10 && File_Offset+Buffer_Offset+Element_OffsetIsValid=true; //picture_coding_types if (picture_coding_type==1 && !FirstFieldFound) //I-Frame { if (!picture_coding_types_Current.empty()) { picture_coding_types[picture_coding_types_Current]++; #if MEDIAINFO_ADVANCED // Testing if we must give up if (Config_VariableGopDetection_GiveUp && picture_coding_types.size()>1) { int64u MaxCount=0; string MaxCount_type; for (std::map::iterator Temp=picture_coding_types.begin(); Temp!=picture_coding_types.end(); ++Temp) if (Temp->second>MaxCount) { MaxCount=Temp->second; MaxCount_type=Temp->first; } int64u Count=0; for (std::map::iterator Temp=picture_coding_types.begin(); Temp!=picture_coding_types.end(); ++Temp) if (Temp->first!=MaxCount_type) Count+=Temp->second; if (Count>=Config_VariableGopDetection_Occurences) Config->ParseSpeed=0; // Give up } #endif // MEDIAINFO_ADVANCED } picture_coding_types_Current='I'; } else if (!picture_coding_types_Current.empty() && !FirstFieldFound) //If an I-Frame is already found picture_coding_types_Current+=Mpegv_picture_coding_type[picture_coding_type]; //Detecting streams with only I-Frames if (picture_coding_type==1 && picture_coding_type_Old==1 && !FirstFieldFound) temporal_reference_Old=(int16u)-1; //Resetting temporal_reference_Old //NextCode if (!Status[IsAccepted]) { NextCode_Clear(); for (int64u Element_Name_Next=0x01; Element_Name_Next<=0xAF; Element_Name_Next++) NextCode_Add(Element_Name_Next); NextCode_Add(0xB2); NextCode_Add(0xB5); NextCode_Add(0xB8); } //Autorisation of other streams for (int8u Pos=0x01; Pos<=0xAF; Pos++) Streams[Pos].Searching_Payload=true; FILLING_END(); } //--------------------------------------------------------------------------- // Packet "01" --> "AF" void File_Mpegv::slice_start() { //Encryption management if (CA_system_ID_MustSkipSlices) { //Is not decodable Finish("MPEG Video"); return; } if (!Status[IsAccepted]) { if (!NextCode_Test()) return; } Element_Name("slice_start"); //Parsing #if MEDIAINFO_MACROBLOCKS if (Macroblocks_Parse && MPEG_Version==2) { BS_Begin(); bool intra_slice_flag; if (0x1000*vertical_size_extension+vertical_size_value>2800) //vertical_size Skip_S1(3, "slice_vertical_position_extension"); if (sequence_scalable_extension_Present) Skip_S1(7, "priority_breakpoint"); Skip_S1(5, "quantiser_scale_code"); Peek_SB(intra_slice_flag); if (intra_slice_flag) { Skip_SB( "intra_slice_flag"); Skip_SB( "intra_slice"); Skip_S1(7, "reserved_bits"); for (;;) { bool extra_bit_slice; Peek_SB(extra_bit_slice); if (extra_bit_slice) { Skip_S1(8, "extra_information_slice"); } else break; if (!Data_BS_Remain()) { Trusted_IsNot("extra_bit_slice is missing"); return; } } } Skip_SB( "extra_bit_slice (must be 0)"); macroblock_x=(int64u)-1; while (Synched) //Synched: testing if this is still valid { int8u Remain; if (Data_BS_Remain()%8) Peek_S1(Data_BS_Remain()%8, Remain); else if (Data_Remain()) Remain=Buffer[Buffer_Offset+(size_t)(Element_Size-Data_Remain())]; else Remain=0; if (Remain==0) { int32u Remain3; size_t Bits=Data_BS_Remain(); if (Bits>23) Bits=23; Peek_S3((int8u)Bits, Remain3); if (Remain3==0) break; } slice_start_macroblock(); } if (Data_BS_Remain()) Skip_BS(Data_BS_Remain(), "padding"); BS_End(); } else #endif //MEDIAINFO_MACROBLOCK Skip_XX(Element_Size, "data"); FILLING_BEGIN(); int64u tc_ToAdd=tc/((progressive_sequence || picture_structure==3)?1:2); //Progressive of Frame //Timestamp if (!TimeCodeIsNotTrustable && group_start_FirstPass && (Time_Begin_Seconds==Error || (Frame_Count<16 && Time_Current_Seconds*FrameRate+Time_Current_Frames+temporal_referenceAspectRatio=MPEG_Version==1?Mpegv_aspect_ratio1[aspect_ratio_information]:Mpegv_aspect_ratio2[aspect_ratio_information]; (*Ancillary)->FrameRate=FrameRate; if ((*Ancillary)->PTS_DTS_Needed) (*Ancillary)->FrameInfo.DTS=FrameInfo.DTS; if ((*Ancillary)->Status[IsAccepted]) //In order to test if there is a parser using ancillary data Open_Buffer_Continue((*Ancillary), Buffer+Buffer_Offset, 0); Element_Trace_End0(); } #endif //defined(MEDIAINFO_CDP_YES) //Active Format Description & Bar Data #if defined(MEDIAINFO_AFDBARDATA_YES) && defined(MEDIAINFO_ANCILLARY_YES) if (Ancillary && *Ancillary && !(*Ancillary)->AfdBarData_Data.empty()) { Element_Trace_Begin1("Active Format Description & Bar Data"); //Parsing if (AfdBarData_Parser==NULL) { AfdBarData_Parser=new File_AfdBarData; Open_Buffer_Init(AfdBarData_Parser); ((File_AfdBarData*)AfdBarData_Parser)->Format=File_AfdBarData::Format_S2016_3; } if (AfdBarData_Parser->PTS_DTS_Needed) AfdBarData_Parser->FrameInfo.DTS=FrameInfo.DTS; if (!AfdBarData_Parser->Status[IsFinished]) Open_Buffer_Continue(AfdBarData_Parser, (*Ancillary)->AfdBarData_Data[0]->Data, (*Ancillary)->AfdBarData_Data[0]->Size); //Removing data from stack delete (*Ancillary)->AfdBarData_Data[0]; //(*Ancillary)->AfdBarData_Data[0]=NULL; (*Ancillary)->AfdBarData_Data.erase((*Ancillary)->AfdBarData_Data.begin()); Element_Trace_End0(); } #endif //defined(MEDIAINFO_AFDBARDATA_YES) //Counting if (!MustExtendParsingDuration && 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 if (!TimeCodeIsNotTrustable && (picture_coding_type==1 || picture_coding_type==2)) //IFrame or PFrame { Time_End_Frames++; //One frame if (progressive_sequence && repeat_first_field) { Time_End_Frames++; //Frame repeated a second time if (top_field_first) Time_End_Frames++; //Frame repeated a third time } } Frame_Count++; Frame_Count_InThisBlock++; if (IFrame_IsParsed && Frame_Count_NotParsedIncluded!=(int64u)-1) Frame_Count_NotParsedIncluded++; if (!(progressive_sequence || picture_structure==3)) { Field_Count++; Field_Count_InThisBlock++; } if (picture_coding_type==3) BVOP_Count++; else BVOPsSinceLastRefFrames=0; if (RefFramesCount<2 && (picture_coding_type==1 || picture_coding_type==2)) RefFramesCount++; if (repeat_first_field) { if (progressive_sequence) { tc_ToAdd+=tc; if (top_field_first) tc_ToAdd+=tc; } else tc_ToAdd+=tc/2; } if (FrameInfo.DTS!=(int64u)-1) { FrameInfo.DTS+=tc_ToAdd; if (DTS_EndPTS_End || (PTS_End>1000000000 && FrameInfo.PTS+tc_ToAdd<=PTS_End-1000000000)) //More than current PTS_End or less than current PTS_End minus 1 second (there is a problem?) { PTS_End=FrameInfo.PTS+tc_ToAdd; PTS_End_temporal_reference=temporal_reference; } if (low_delay) FrameInfo.PTS+=tc_ToAdd; else FrameInfo.PTS=(int64u)-1; //With repeat_first_field option, it is impossible to know what is the next PTS } //NextCode if (!Status[IsAccepted]) { NextCode_Clear(); NextCode_Add(0x00); NextCode_Add(0xB3); NextCode_Add(0xB8); } //Autorisation of other streams #if MEDIAINFO_MACROBLOCKS if (!Macroblocks_Parse) #endif //MEDIAINFO_MACROBLOCKS for (int8u Pos=0x01; Pos<=0xAF; Pos++) Streams[Pos].Searching_Payload=false; //Filling only if not already done if (!Status[IsAccepted]) Accept("MPEG Video"); if (!MustExtendParsingDuration && IFrame_Count==8) Frame_Count_Valid=Frame_Count; //We have enough frames if (!Status[IsFilled] && Frame_Count>=Frame_Count_Valid) { Fill("MPEG Video"); if (File_Size==(int64u)-1) Finish("MPEG Video"); else if (!IsSub && 2*(File_Offset+Buffer_Size+SizeToAnalyse_End)ParseSpeed<1.0) { Open_Buffer_Unsynch(); GoToFromEnd(SizeToAnalyse_End); } } //Skipping slices (if already unpacketized) #if MEDIAINFO_DEMUX if (Demux_UnpacketizeContainer && Buffer_TotalBytes+Buffer_Offset=Config_InitDataNotRepeated_Occurences) Config->ParseSpeed=0; // Give up } #endif // MEDIAINFO_ADVANCED } #endif // MEDIAINFO_ADVANCED || MEDIAINFO_EVENTS #if MEDIAINFO_ADVANCED || MEDIAINFO_EVENTS //Packets Has_sequence_header=false; Has_sequence_extension=false; #endif // MEDIAINFO_ADVANCED || MEDIAINFO_EVENTS FILLING_END(); } //--------------------------------------------------------------------------- // Packet Packet "01" --> "AF", slice_start, macroblock #if MEDIAINFO_MACROBLOCKS enum Mpegv_macroblock_type_config //bitwise { spatial_temporal_weight_code_flag =0x01, macroblock_intra =0x02, macroblock_pattern =0x04, macroblock_motion_backward =0x08, macroblock_motion_forward =0x10, macroblock_quant =0x20, }; void File_Mpegv::slice_start_macroblock() { frame_motion_type=(int8u)-1; spatial_temporal_weight_code=0; Element_Trace_Begin1("macroblock"); size_t macroblock_address_increment; do { Get_VL(macroblock_address_increment_Vlc, macroblock_address_increment, "macroblock_address_increment"); Element_Info1(__T("macroblock_address_increment=")+Ztring::ToZtring(Mpegv_macroblock_address_increment[macroblock_address_increment].mapped_to3)); if (macroblock_x!=(int64u)-1) macroblock_x+=Mpegv_macroblock_address_increment[macroblock_address_increment].mapped_to3; } while (Mpegv_macroblock_address_increment[macroblock_address_increment].mapped_to1==2); //Escape code if (macroblock_x==(int64u)-1) macroblock_x=0; Element_Info1(__T("macroblock_x=")+Ztring::ToZtring(macroblock_x)); Element_Trace_Begin1("macroblock_modes"); vlc_fast* macroblock_type_X; switch(picture_coding_type) { case 1: macroblock_type_X=¯oblock_type_I; break; case 2: macroblock_type_X=¯oblock_type_P; break; case 3: macroblock_type_X=¯oblock_type_B; break; default : Element_DoNotTrust("Wrong picture_coding_type"); Element_Trace_End0(); Element_Trace_End0(); return; } size_t macroblock_type_offset; Get_VL(*macroblock_type_X, macroblock_type_offset, "macroblock_type"); macroblock_type=macroblock_type_X->Vlc[macroblock_type_offset].mapped_to3; if (!Synched) { BS_End(); Element_Offset=Element_Size; return; } Element_Info1(__T("macroblock_quant=")+Ztring::ToZtring(macroblock_type¯oblock_quant)); Element_Info1(__T("macroblock_motion_forward=")+Ztring::ToZtring(macroblock_type¯oblock_motion_forward)); Element_Info1(__T("macroblock_motion_backward=")+Ztring::ToZtring(macroblock_type¯oblock_motion_backward)); Element_Info1(__T("macroblock_pattern=")+Ztring::ToZtring(macroblock_type¯oblock_pattern)); Element_Info1(__T("macroblock_intra=")+Ztring::ToZtring(macroblock_type¯oblock_intra)); Element_Info1(__T("spatial_temporal_weight_code_flag=")+Ztring::ToZtring(macroblock_type&spatial_temporal_weight_code_flag)); if (macroblock_type&spatial_temporal_weight_code_flag && spatial_temporal_weight_code_table_index) Get_S1 (2, spatial_temporal_weight_code, "spatial_temporal_weight_code"); if (macroblock_type¯oblock_intra && concealment_motion_vectors) frame_motion_type=2; if (macroblock_type¯oblock_motion_forward || macroblock_type¯oblock_motion_backward) { if (picture_structure==3) //Frame { if (!frame_pred_frame_dct) Get_S1(2, frame_motion_type, "frame_motion_type"); else frame_motion_type=2; } else Get_S1 (2, field_motion_type, "field_motion_type"); } if (picture_structure==3 //Frame && !frame_pred_frame_dct && (macroblock_type¯oblock_intra || macroblock_type¯oblock_pattern)) Skip_SB( "dct_type"); Element_Trace_End0(); if (macroblock_type¯oblock_quant) Skip_S1(5, "quantiser_scale_code"); if (macroblock_type¯oblock_motion_forward || (macroblock_type¯oblock_intra && concealment_motion_vectors)) slice_start_macroblock_motion_vectors(false); if (macroblock_type¯oblock_motion_backward) slice_start_macroblock_motion_vectors(true); if (macroblock_type¯oblock_intra && concealment_motion_vectors) Mark_1(); if (macroblock_type¯oblock_pattern) slice_start_macroblock_coded_block_pattern(); for (int8u i=0; i "AF", slice_start, macroblock, motion_vectors #if MEDIAINFO_MACROBLOCKS void File_Mpegv::slice_start_macroblock_motion_vectors(bool s) { Element_Trace_Begin1("motion_vectors"); int8u motion_vector_count; switch (frame_motion_type) { case 1 : switch (spatial_temporal_weight_code) { case 0 : case 1 : motion_vector_count=2; break; case 2 : case 3 : motion_vector_count=1; break; default: Trusted_IsNot("spatial_temporal_weight_code problem"); Element_Trace_End0(); return; } break; case 2 : motion_vector_count=1; break; case 3 : switch (spatial_temporal_weight_code) { case 1 : Trusted_IsNot("spatial_temporal_weight_code problem"); Element_Trace_End0(); return; default: motion_vector_count=1; break; } break; default : Trusted_IsNot("frame_motion_type problem"); Element_Trace_End0(); return; } if (motion_vector_count==1) { if (!(picture_structure==3 //Frame && frame_motion_type==2) //mv_format==Frame && frame_motion_type!=3) //dmv!=1 Skip_SB( "motion_vertical_field_select[0][s]"); slice_start_macroblock_motion_vectors_motion_vector(false, s); } else { Skip_SB( "motion_vertical_field_select[0][s]"); slice_start_macroblock_motion_vectors_motion_vector(false, s); Skip_SB( "motion_vertical_field_select[1][s]"); slice_start_macroblock_motion_vectors_motion_vector(true, s); } Element_Trace_End0(); } #endif //MEDIAINFO_MACROBLOCKS //--------------------------------------------------------------------------- // Packet Packet "01" --> "AF", slice_start, macroblock, motion_vectors, motion_vector #if MEDIAINFO_MACROBLOCKS void File_Mpegv::slice_start_macroblock_motion_vectors_motion_vector(bool r, bool s) { Element_Trace_Begin1("motion_vector"); size_t motion_code_; Get_VL(motion_code, motion_code_, "motion_code[r][s][0]"); Param_Info1(Mpegv_motion_code[motion_code_].mapped_to3); if (Mpegv_motion_code[motion_code_].mapped_to3) Skip_SB( "motion_code[r][s][0] sign"); if (f_code[s][0]>1 && Mpegv_motion_code[motion_code_].mapped_to3) Skip_S1(f_code[s][0]-1, "motion_residual[r][s][0]"); if (frame_motion_type==3) //dmv==1 { Info_VL(dmvector, dmvector_, "dmvector[0]"); Param_Info1(Mpegv_dmvector[dmvector_].mapped_to3); } Get_VL(motion_code, motion_code_, "motion_code[r][s][1]"); Param_Info1(Mpegv_motion_code[motion_code_].mapped_to3); if (Mpegv_motion_code[motion_code_].mapped_to3) Skip_SB( "motion_code[r][s][1] sign"); if (f_code[s][1]>1 && Mpegv_motion_code[motion_code_].mapped_to3) Skip_S1(f_code[s][1]-1, "motion_residual[r][s][1]"); if (frame_motion_type==3) //dmv==1 { Info_VL(dmvector, dmvector_, "dmvector[1]"); Param_Info1(Mpegv_dmvector[dmvector_].mapped_to3); } Element_Trace_End0(); } #endif //MEDIAINFO_MACROBLOCKS //--------------------------------------------------------------------------- // Packet Packet "01" --> "AF", slice_start, macroblock, coded_block_pattern #if MEDIAINFO_MACROBLOCKS void File_Mpegv::slice_start_macroblock_coded_block_pattern() { Element_Trace_Begin1("coded_block_pattern"); size_t coded_block_pattern_; Get_VL(coded_block_pattern, coded_block_pattern_, "coded_block_pattern_420"); cbp=Mpegv_coded_block_pattern[coded_block_pattern_].mapped_to3; switch (chroma_format) { case 2 : //4:2:2 { int8u coded_block_pattern_1; Get_S1 (2, coded_block_pattern_1, "coded_block_pattern_1"); cbp<<=2; cbp|=coded_block_pattern_1; } break; case 3 : //4:4:4 { int8u coded_block_pattern; Get_S1 (8, coded_block_pattern, "coded_block_pattern_1/2"); cbp<<=8; cbp|=coded_block_pattern; } break; default : ; } Element_Info1(Ztring::ToZtring((int16u)cbp, 2)); Element_Trace_End0(); } #endif //MEDIAINFO_MACROBLOCKS //--------------------------------------------------------------------------- // Packet Packet "01" --> "AF", slice_start, macroblock, block #if MEDIAINFO_MACROBLOCKS void File_Mpegv::slice_start_macroblock_block(int8u i) { //pattern_code if (!(macroblock_type¯oblock_intra) && !((macroblock_type¯oblock_pattern) && (cbp&(1<<(block_count-1-i))))) return; Element_Trace_Begin1("block"); Element_Info1(i); bool IsFirst; const vlc* Mpegv_dct_coefficients; vlc_fast* Mpegv_dct_coefficients2; if (macroblock_type¯oblock_intra) { IsFirst=false; Mpegv_dct_coefficients=intra_vlc_format?Mpegv_dct_coefficients_1:Mpegv_dct_coefficients_0; Mpegv_dct_coefficients2=&(intra_vlc_format?dct_coefficients_1:dct_coefficients_0); if (i<4) { size_t dct_dc_size_luminance_; Get_VL(dct_dc_size_luminance, dct_dc_size_luminance_, "dct_dc_size_luminance"); Param_Info1(Mpegv_dct_dc_size_luminance[dct_dc_size_luminance_].mapped_to3); if (Mpegv_dct_dc_size_luminance[dct_dc_size_luminance_].mapped_to3) Skip_S2(Mpegv_dct_dc_size_luminance[dct_dc_size_luminance_].mapped_to3, "dct_dc_differential"); } else { size_t dct_dc_size_chrominance_; Get_VL(dct_dc_size_chrominance, dct_dc_size_chrominance_, "dct_dc_size_chrominance"); Param_Info1(Mpegv_dct_dc_size_chrominance[dct_dc_size_chrominance_].mapped_to3); if (Mpegv_dct_dc_size_chrominance[dct_dc_size_chrominance_].mapped_to3) Skip_S2((int8u)dct_dc_size_chrominance_, "dct_dc_differential"); } } else { IsFirst=true; Mpegv_dct_coefficients=Mpegv_dct_coefficients_0; Mpegv_dct_coefficients2=&dct_coefficients_0; } for (;;) { Element_Trace_Begin1("dct_coefficient"); size_t dct_coefficient; Get_VL(*Mpegv_dct_coefficients2, dct_coefficient, "dct_coefficient"); switch (Mpegv_dct_coefficients[dct_coefficient].mapped_to1) { case 1 : Element_Trace_End1("End of block"); Element_Trace_End0(); return; case 2 : #if MEDIAINFO_TRACE if (Trace_Activated) { Info_S1( 6, Run, "Run"); Element_Info1(Run); Info_S2(12, Level, "Level"); Element_Info1(Level-(Level>0x800?4096:0)); } else #endif //MEDIAINFO_MACROBLOCKS Skip_S3(18, "Run + Level"); break; case 3 : if (!IsFirst) { if (Mpegv_dct_coefficients[dct_coefficient].bit_increment) { Element_Trace_End1("End of block"); Element_Trace_End0(); return; } Skip_SB( "dct_coefficient sign"); } break; default: Element_Info1(Mpegv_dct_coefficients[dct_coefficient].mapped_to2); Element_Info1(Mpegv_dct_coefficients[dct_coefficient].mapped_to3); } if (IsFirst) IsFirst=false; Element_Trace_End0(); } } #endif //MEDIAINFO_MACROBLOCKS //--------------------------------------------------------------------------- // Packet "B2" void File_Mpegv::user_data_start() { Element_Name("user_data_start"); //GA94 stuff if (Element_Size>=4) { int32u GA94_Identifier; Peek_B4(GA94_Identifier); switch (GA94_Identifier) { case 0x434301F8 : user_data_start_CC(); return; case 0x44544731 : user_data_start_DTG1(); return; case 0x47413934 : user_data_start_GA94(); return; default : { int8u SCTE20_Identifier; Peek_B1(SCTE20_Identifier); if (SCTE20_Identifier==0x03) { user_data_start_3(); 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=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 Ztring Temp; if (Library_Start_Offset>0) Skip_XX(Library_Start_Offset, "junk"); if (Library_End_Offset-Library_Start_Offset) Get_UTF8(Library_End_Offset-Library_Start_Offset, Temp, "data"); if (Element_Offset3 && 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); //Cleanup while(!Temp.empty() && Temp[0]==__T('0')) Temp.erase(0, 1); FILLING_BEGIN(); if (!Temp.empty()) { if (Temp.find(__T("build"))==0) Library+=Ztring(__T(" "))+Temp; else Library=Temp; //Library if (Temp.find(__T("Created with Nero"))==0) { Library_Name=__T("Ahead Nero"); } else if (Library.find(__T("encoded by avi2mpg1 ver "))==0) { Library_Name=__T("avi2mpg1"); Library_Version=Library.SubString(__T("encoded by avi2mpg1 ver "), __T("")); } else if (Library.find(__T("encoded by TMPGEnc (ver. "))==0) { Library_Name=__T("TMPGEnc"); Library_Version=Library.SubString(__T("encoded by TMPGEnc (ver. "), __T(")")); } else if (Library.find(__T("encoded by TMPGEnc 4.0 XPress Version. "))==0) { Library_Name=__T("TMPGEnc XPress"); Library_Version=Library.SubString(__T("encoded by TMPGEnc 4.0 XPress Version. "), __T("")); } else if (Library.find(__T("encoded by TMPGEnc MPEG Editor "))==0) { Library_Name=__T("TMPGEnc MPEG Editor"); Library_Version=Library.SubString(__T("Version. "), __T("")); } else if (Library.find(__T("encoded by TMPGEnc "))==0) { Library_Name=__T("TMPGEnc"); Library_Version=Library.SubString(__T("encoded by TMPGEnc "), __T("")); } else if (Library.find(__T("MPEG Encoder v"))==0) { Library_Name=__T("MPEG Encoder by Tristan Savatier"); Library_Version=Library.SubString(__T("MPEG Encoder v"), __T(" by")); } else Library_Name=Library; } FILLING_END(); } //--------------------------------------------------------------------------- // Packet "B2", CC (From DVD) void File_Mpegv::user_data_start_CC() { Skip_B4( "identifier"); #if defined(MEDIAINFO_DTVCCTRANSPORT_YES) Element_Info1("DVD Captions"); //Parsing #if MEDIAINFO_DEMUX Element_Code=0x434301F800000000LL; #endif //MEDIAINFO_DEMUX if (CC___Parser==NULL) { CC___IsPresent=true; MustExtendParsingDuration=true; Buffer_TotalBytes_Fill_Max=(int64u)-1; //Disabling this feature for this format, this is done in the parser CC___Parser=new File_DtvccTransport; Open_Buffer_Init(CC___Parser); ((File_DtvccTransport*)CC___Parser)->Format=File_DtvccTransport::Format_DVD; } if (CC___Parser->PTS_DTS_Needed) { CC___Parser->FrameInfo.PCR=FrameInfo.PCR; CC___Parser->FrameInfo.PTS=FrameInfo.PTS; CC___Parser->FrameInfo.DTS=FrameInfo.DTS; } #if MEDIAINFO_DEMUX int8u Demux_Level_Save=Demux_Level; Demux_Level=8; //Ancillary Demux(Buffer+Buffer_Offset+(size_t)Element_Offset, (size_t)(Element_Size-Element_Offset), ContentType_MainStream); Demux_Level=Demux_Level_Save; #endif // MEDIAINFO_DEMUX Open_Buffer_Continue(CC___Parser, Buffer+Buffer_Offset+(size_t)Element_Offset, (size_t)(Element_Size-Element_Offset)); Element_Offset=Element_Size; #else //defined(MEDIAINFO_DTVCCTRANSPORT_YES) Skip_XX(Element_Size-Element_Offset, "DVD Captions"); #endif //defined(MEDIAINFO_DTVCCTRANSPORT_YES) } //--------------------------------------------------------------------------- // Packet "B2", 0x03 (SCTE20) void File_Mpegv::user_data_start_3() { Skip_B1( "identifier"); #if defined(MEDIAINFO_SCTE20_YES) Scte_IsPresent=true; MustExtendParsingDuration=true; Buffer_TotalBytes_Fill_Max=(int64u)-1; //Disabling this feature for this format, this is done in the parser Element_Info1("SCTE 20"); //Coherency if (TemporalReference_Offset+temporal_reference>=TemporalReference.size()) return; //Purging too old orphelins if (Scte_TemporalReference_Offset+8IsValid || TemporalReference[Pos]->Scte.empty()) break; Pos--; } while (Pos>0); Scte_TemporalReference_Offset=Pos+1; } temporalreference* Ref=GetTemporalReference(); buffer_data* BufferData=new buffer_data(Buffer+Buffer_Offset+(size_t)Element_Offset,(size_t)(Element_Size-Element_Offset)); Ref->Scte.push_back(BufferData); Ref->Scte_Parsed.push_back(false); if (Ref->Scte_Parsed.size()>=2 && Ref->Scte_Parsed[Ref->Scte_Parsed.size()-2] && Scte_TemporalReference_Offset==TemporalReference_Offset+temporal_reference+1) Scte_TemporalReference_Offset--; //Parsing Skip_XX(Element_Size-Element_Offset, "SCTE 20 data"); //Parsing Captions after reordering bool CanBeParsed=true; size_t FirstSize=(size_t)-1; for (size_t Scte20_Pos=Scte_TemporalReference_Offset; Scte20_PosIsValid || TemporalReference[Scte20_Pos]->Scte.empty()) CanBeParsed=false; //There is a missing field/frame if (CanBeParsed) { if (FirstSize==(size_t)-1) FirstSize=TemporalReference[Scte20_Pos]->Scte.size(); else if (!progressive_sequence && !TemporalReference[Scte20_Pos]->progressive_frame && TemporalReference[Scte20_Pos]->picture_structure==3 && TemporalReference[Scte20_Pos]->Scte.size()!=FirstSize) CanBeParsed=false; //There is a missing field in a frame duo } } if (CanBeParsed) { for (size_t Scte20_Pos=Scte_TemporalReference_Offset; Scte20_PosAspectRatio=MPEG_Version==1?Mpegv_aspect_ratio1[aspect_ratio_information]:Mpegv_aspect_ratio2[aspect_ratio_information]; ((File_Scte20*)Scte_Parser)->picture_structure=TemporalReference[Scte20_Pos]->picture_structure; ((File_Scte20*)Scte_Parser)->progressive_sequence=progressive_sequence; ((File_Scte20*)Scte_Parser)->progressive_frame=TemporalReference[Scte20_Pos]->progressive_frame; ((File_Scte20*)Scte_Parser)->top_field_first=TemporalReference[Scte20_Pos]->top_field_first; ((File_Scte20*)Scte_Parser)->repeat_first_field=TemporalReference[Scte20_Pos]->repeat_first_field; for (size_t Pos=0; PosScte.size(); Pos++) if (!TemporalReference[Scte20_Pos]->Scte_Parsed[Pos]) { if (Scte_Parser->PTS_DTS_Needed) { Scte_Parser->FrameInfo.PCR=FrameInfo.PCR; Scte_Parser->FrameInfo.PTS=FrameInfo.PTS-(TemporalReference.size()-1-Scte20_Pos)*tc; Scte_Parser->FrameInfo.DTS=FrameInfo.DTS-(TemporalReference.size()-1-Scte20_Pos)*tc; } #if MEDIAINFO_DEMUX int8u Demux_Level_Save=Demux_Level; Demux_Level=8; //Ancillary Demux(TemporalReference[Scte20_Pos]->Scte[Pos]->Data, TemporalReference[Scte20_Pos]->Scte[Pos]->Size, ContentType_MainStream); Demux_Level=Demux_Level_Save; #endif // MEDIAINFO_DEMUX Open_Buffer_Continue(Scte_Parser, TemporalReference[Scte20_Pos]->Scte[Pos]->Data, TemporalReference[Scte20_Pos]->Scte[Pos]->Size); TemporalReference[Scte20_Pos]->Scte_Parsed[Pos]=true; } Element_End0(); } Scte_TemporalReference_Offset=TemporalReference.size(); } #else //defined(MEDIAINFO_SCTE20_YES) Skip_XX(Element_Size-Element_Offset, "SCTE 20 data"); #endif //defined(MEDIAINFO_SCTE20_YES) } //--------------------------------------------------------------------------- // Packet "B2", DTG1 void File_Mpegv::user_data_start_DTG1() { Skip_B4( "identifier"); #if defined(MEDIAINFO_AFDBARDATA_YES) Element_Info1("Active Format Description"); //Parsing if (DTG1_Parser==NULL) { DTG1_Parser=new File_AfdBarData; Open_Buffer_Init(DTG1_Parser); ((File_AfdBarData*)DTG1_Parser)->Format=File_AfdBarData::Format_A53_4_DTG1; //Aspect ratio for AFD float32 DAR=0; if (MPEG_Version==2) { if (aspect_ratio_information==0) ; //Forbidden else if (aspect_ratio_information==1) DAR=((float32)(0x1000*horizontal_size_extension+horizontal_size_value))/(0x1000*vertical_size_extension+vertical_size_value); else if (display_horizontal_size && display_vertical_size) { if (vertical_size_value && Mpegv_aspect_ratio2[aspect_ratio_information]) DAR=((float32)(0x1000*horizontal_size_extension+horizontal_size_value))/(0x1000*vertical_size_extension+vertical_size_value) *Mpegv_aspect_ratio2[aspect_ratio_information]/((float32)display_horizontal_size/display_vertical_size); } else if (Mpegv_aspect_ratio2[aspect_ratio_information]) DAR=Mpegv_aspect_ratio2[aspect_ratio_information]; } else //Version 1 { if (vertical_size_value && Mpegv_aspect_ratio1[aspect_ratio_information]) DAR=((float32)(0x1000*horizontal_size_extension+horizontal_size_value))/(0x1000*vertical_size_extension+vertical_size_value)/Mpegv_aspect_ratio1[aspect_ratio_information]; } if (DAR>=4.0/3.0*0.95 && DAR<4.0/3.0*1.05) ((File_AfdBarData*)DTG1_Parser)->aspect_ratio_FromContainer=0; //4/3 if (DAR>=16.0/9.0*0.95 && DAR<16.0/9.0*1.05) ((File_AfdBarData*)DTG1_Parser)->aspect_ratio_FromContainer=1; //16/9 } if (DTG1_Parser->PTS_DTS_Needed) { DTG1_Parser->FrameInfo.PCR=FrameInfo.PCR; DTG1_Parser->FrameInfo.PTS=FrameInfo.PTS; DTG1_Parser->FrameInfo.DTS=FrameInfo.DTS; } Open_Buffer_Continue(DTG1_Parser, Buffer+Buffer_Offset+(size_t)Element_Offset, (size_t)(Element_Size-Element_Offset)); Element_Offset=Element_Size; #else //defined(MEDIAINFO_AFDBARDATA_YES) Skip_XX(Element_Size-Element_Offset, "Active Format Description"); #endif //defined(MEDIAINFO_AFDBARDATA_YES) } //--------------------------------------------------------------------------- // Packet "B2", GA94 void File_Mpegv::user_data_start_GA94() { //Parsing int8u user_data_type_code; Skip_B4( "GA94_identifier"); Get_B1 (user_data_type_code, "user_data_type_code"); switch (user_data_type_code) { case 0x03 : user_data_start_GA94_03(); break; case 0x06 : user_data_start_GA94_06(); break; default : Skip_XX(Element_Size-Element_Offset, "GA94_reserved_user_data"); } } //--------------------------------------------------------------------------- // Packet "B2", GA94 0x03 (styled captioning) void File_Mpegv::user_data_start_GA94_03() { #if defined(MEDIAINFO_DTVCCTRANSPORT_YES) GA94_03_IsPresent=true; MustExtendParsingDuration=true; Buffer_TotalBytes_Fill_Max=(int64u)-1; //Disabling this feature for this format, this is done in the parser Element_Info1("DTVCC Transport"); //Coherency if (TemporalReference_Offset+temporal_reference>=TemporalReference.size()) return; //Purging too old orphelins if (GA94_03_TemporalReference_Offset+8IsValid || TemporalReference[Pos]->GA94_03==NULL) break; Pos--; } while (Pos>0); GA94_03_TemporalReference_Offset=Pos+1; } temporalreference* Ref=GetTemporalReference(); if (Ref->GA94_03==NULL) Ref->GA94_03=new buffer_data; buffer_data* NewBuffer=Ref->GA94_03; int8u* NewData=new int8u[NewBuffer->Size+(size_t)(Element_Size-Element_Offset)]; if (NewBuffer->Size) { //Data already present, copying in the new buffer std::memcpy(NewData, NewBuffer->Data, NewBuffer->Size); delete[] NewBuffer->Data; //Reassignement done below } NewBuffer->Data=NewData; std::memcpy(NewBuffer->Data+ NewBuffer->Size, Buffer+Buffer_Offset+(size_t)Element_Offset, (size_t)(Element_Size-Element_Offset)); NewBuffer->Size+=(size_t)(Element_Size-Element_Offset); //Parsing Skip_XX(Element_Size-Element_Offset, "CC data"); //Parsing Captions after reordering bool CanBeParsed=true; for (size_t GA94_03_Pos=GA94_03_TemporalReference_Offset; GA94_03_PosIsValid || TemporalReference[GA94_03_Pos]->GA94_03==NULL) CanBeParsed=false; //There is a missing field/frame if (CanBeParsed) { for (size_t GA94_03_Pos=GA94_03_TemporalReference_Offset; GA94_03_PosFormat=File_DtvccTransport::Format_A53_4_GA94_03; } if (GA94_03_Parser->PTS_DTS_Needed) { GA94_03_Parser->FrameInfo.PCR=FrameInfo.PCR; GA94_03_Parser->FrameInfo.PTS=FrameInfo.PTS-(FrameInfo.PTS!=(int64u)-1?((TemporalReference.size()-1-GA94_03_Pos)*tc):0); GA94_03_Parser->FrameInfo.DTS=FrameInfo.DTS-(FrameInfo.DTS!=(int64u)-1?((TemporalReference.size()-1-GA94_03_Pos)*tc):0); } #if MEDIAINFO_DEMUX int8u Demux_Level_Save=Demux_Level; Demux_Level=8; //Ancillary Demux(TemporalReference[GA94_03_Pos]->GA94_03->Data, TemporalReference[GA94_03_Pos]->GA94_03->Size, ContentType_MainStream); Demux_Level=Demux_Level_Save; #endif // MEDIAINFO_DEMUX #if defined(MEDIAINFO_EIA608_YES) || defined(MEDIAINFO_EIA708_YES) GA94_03_Parser->ServiceDescriptors=ServiceDescriptors; #endif ((File_DtvccTransport*)GA94_03_Parser)->AspectRatio=MPEG_Version==1?Mpegv_aspect_ratio1[aspect_ratio_information]:Mpegv_aspect_ratio2[aspect_ratio_information]; Open_Buffer_Continue(GA94_03_Parser, TemporalReference[GA94_03_Pos]->GA94_03->Data, TemporalReference[GA94_03_Pos]->GA94_03->Size); Element_End0(); } GA94_03_TemporalReference_Offset=TemporalReference.size(); } #else //defined(MEDIAINFO_DTVCCTRANSPORT_YES) Skip_XX(Element_Size-Element_Offset, "DTVCC Transport data"); #endif //defined(MEDIAINFO_DTVCCTRANSPORT_YES) } //--------------------------------------------------------------------------- // Packet "B2", GA94 0x06 (bar data) void File_Mpegv::user_data_start_GA94_06() { #if defined(MEDIAINFO_AFDBARDATA_YES) Element_Info1("Bar Data"); //Parsing if (GA94_06_Parser==NULL) { GA94_06_Parser=new File_AfdBarData; Open_Buffer_Init(GA94_06_Parser); ((File_AfdBarData*)GA94_06_Parser)->Format=File_AfdBarData::Format_A53_4_GA94_06; } if (GA94_06_Parser->PTS_DTS_Needed) { GA94_06_Parser->FrameInfo.PCR=FrameInfo.PCR; GA94_06_Parser->FrameInfo.PTS=FrameInfo.PTS; GA94_06_Parser->FrameInfo.DTS=FrameInfo.DTS; } Open_Buffer_Init(GA94_06_Parser); Open_Buffer_Continue(GA94_06_Parser, Buffer+Buffer_Offset+(size_t)Element_Offset, (size_t)(Element_Size-Element_Offset)); Element_Offset=Element_Size; #else //defined(MEDIAINFO_AFDBARDATA_YES) Skip_XX(Element_Size-Element_Offset, "Bar Data"); #endif //defined(MEDIAINFO_AFDBARDATA_YES) } //--------------------------------------------------------------------------- // Packet "B3" void File_Mpegv::sequence_header() { Element_Name("sequence_header"); //Reset display_horizontal_size=0; display_vertical_size=0; //Reading int32u bit_rate_value_temp; BS_Begin(); Get_S2 (12, horizontal_size_value, "horizontal_size_value"); Get_S2 (12, vertical_size_value, "vertical_size_value"); Get_S1 ( 4, aspect_ratio_information, "aspect_ratio_information"); Param_Info1C((vertical_size_value && Mpegv_aspect_ratio1[aspect_ratio_information]), (float)horizontal_size_value/vertical_size_value/Mpegv_aspect_ratio1[aspect_ratio_information]); Param_Info1(Mpegv_aspect_ratio2[aspect_ratio_information]); Get_S1 ( 4, frame_rate_code, "frame_rate_code"); Param_Info1(Mpegv_frame_rate[frame_rate_code]); Get_S3 (18, bit_rate_value_temp, "bit_rate_value"); Param_Info1(bit_rate_value_temp*400); Mark_1 (); Get_S2 (10, vbv_buffer_size_value, "vbv_buffer_size_value"); Param_Info2(2*1024*((int32u)vbv_buffer_size_value), " bytes"); Skip_SB( "constrained_parameters_flag"); TEST_SB_GET(load_intra_quantiser_matrix, "load_intra_quantiser_matrix"); bool FillMatrix=Matrix_intra.empty(); for (size_t Pos=0; Pos<64; Pos++) { int8u intra_quantiser; Get_S1 (8, intra_quantiser, "intra_quantiser"); if (FillMatrix) { Ztring Value=Ztring::ToZtring(intra_quantiser, 16); if (Value.size()==1) Value.insert(0, __T("0")); Matrix_intra+=Value; } } TEST_SB_END(); TEST_SB_GET(load_non_intra_quantiser_matrix, "load_non_intra_quantiser_matrix"); bool FillMatrix=Matrix_nonintra.empty(); for (size_t Pos=0; Pos<64; Pos++) { int8u non_intra_quantiser; Get_S1 (8, non_intra_quantiser, "non_intra_quantiser"); if (FillMatrix) { Ztring Value=Ztring::ToZtring(non_intra_quantiser, 16); if (Value.size()==1) Value.insert(0, __T("0")); Matrix_nonintra+=Value; } } TEST_SB_END(); BS_End(); //0x00 at the end if (Element_OffsetElement_Offset && Buffer[Buffer_Offset+(size_t)NullBytes_Begin]==0x00) NullBytes_Begin--; if (NullBytes_Begin==Element_Offset) Skip_XX(Element_Size-Element_Offset, "Padding"); } FILLING_BEGIN_PRECISE(); temporal_reference_Adapt(); //TODO: this line should not exist but some streams do not have group_start and/or do not start from temporal_reference 0, fast and dirty patch //Bit_rate if (bit_rate_value_IsValid && bit_rate_value_temp!=bit_rate_value) bit_rate_value_IsValid=false; //two bit_rate_values, not handled. else if (bit_rate_value==0) { bit_rate_value=bit_rate_value_temp; bit_rate_value_IsValid=true; } //NextCode if (!Status[IsAccepted]) { NextCode_Clear(); NextCode_Add(0x00); NextCode_Add(0xB2); NextCode_Add(0xB5); NextCode_Add(0xB8); } //Autorisation of other streams Streams[0x00].Searching_Payload=true; Streams[0xB2].Searching_Payload=true; Streams[0xB5].Searching_Payload=true; if (Frame_Count==0) Streams[0xB8].Searching_TimeStamp_Start=true; Streams[0xB8].Searching_TimeStamp_End=true; //Temp if (Mpegv_frame_rate[frame_rate_code]) tc=float64_int64s(((float64)1000000000)/Mpegv_frame_rate[frame_rate_code]); if (Frame_Countpicture_coding_type=picture_coding_type; Ref->progressive_frame=progressive_frame; Ref->picture_structure=picture_structure; Ref->top_field_first=top_field_first; Ref->repeat_first_field=repeat_first_field; Ref->HasPictureCoding=true; } else //Field { if (!FirstFieldFound) { if (picture_structure==1) //-Top Interlaced_Top++; else //-Bottom Interlaced_Bottom++; } FirstFieldFound=!FirstFieldFound; PictureStructure_Field++; } } else { progressive_frame_Count++; if (top_field_first) Interlaced_Top++; else Interlaced_Bottom++; PictureStructure_Frame++; if (picture_structure==3) //Frame { temporalreference* Ref=GetTemporalReference(); Ref->picture_coding_type=picture_coding_type; Ref->progressive_frame=progressive_frame; Ref->picture_structure=picture_structure; Ref->top_field_first=top_field_first; Ref->repeat_first_field=repeat_first_field; Ref->HasPictureCoding=true; } } FILLING_END(); break; case 9 : //Picture Spatial Scalable Extension { //Parsing Skip_S1(4, "data"); BS_End(); Skip_XX(Element_Size-Element_Offset, "data"); } break; case 10 : //Picture Temporal Scalable Extension { //Parsing Skip_S1(4, "data"); BS_End(); Skip_XX(Element_Size-Element_Offset, "data"); } break; default : { //Parsing Skip_S1(4, "data"); BS_End(); Skip_XX(Element_Size-Element_Offset, "data"); } } } //--------------------------------------------------------------------------- // Packet "B7" void File_Mpegv::sequence_end() { Element_Name("sequence_end"); if (!Status[IsFilled] && sequence_header_IsParsed) { //End of file, and we have some frames Accept("MPEG Video"); Finish("MPEG Video"); } } //--------------------------------------------------------------------------- // Packet "B8" void File_Mpegv::group_start() { if (!Status[IsAccepted]) { if (!NextCode_Test()) return; } Element_Name("group_start"); //Reading int8u Hours, Minutes, Seconds, Frames; bool drop_frame_flag, closed_gop, broken_link; #if MEDIAINFO_TRACE if (Trace_Activated) { //Parsing BS_Begin(); Get_SB ( drop_frame_flag, "time_code_drop_frame_flag"); Get_S1 ( 5, Hours, "time_code_time_code_hours"); Get_S1 ( 6, Minutes, "time_code_time_code_minutes"); Mark_1(); Get_S1 ( 6, Seconds, "time_code_time_code_seconds"); Get_S1 ( 6, Frames, "time_code_time_code_pictures"); 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); if (FrameRate!=0) { Time+=__T('.'); Time+=Ztring::ToZtring(Frames*1000/FrameRate, 0); } Element_Info1(Time); } else { #endif //MEDIAINFO_TRACE //Parsing size_t Buffer_Pos=Buffer_Offset+(size_t)Element_Offset; drop_frame_flag = (Buffer[Buffer_Pos ]&0x80)?true:false; Hours =((Buffer[Buffer_Pos ]&0x7C)>> 2); Minutes =((Buffer[Buffer_Pos ]&0x03)<< 4) | ((Buffer[Buffer_Pos+1] )>> 4); Seconds =((Buffer[Buffer_Pos+1]&0x07)<< 3) | ((Buffer[Buffer_Pos+2] )>> 5); Frames =((Buffer[Buffer_Pos+2]&0x1F)<< 1) | ((Buffer[Buffer_Pos+3] )>> 7); closed_gop = (Buffer[Buffer_Pos+3]&0x40)?true:false; broken_link = (Buffer[Buffer_Pos+3]&0x20)?true:false; Element_Offset+=4; #if MEDIAINFO_TRACE } #endif //MEDIAINFO_TRACE FILLING_BEGIN(); temporal_reference_Adapt(); //NextCode if (!Status[IsAccepted]) { NextCode_Clear(); NextCode_Add(0x00); NextCode_Add(0xB2); NextCode_Add(0xB5); NextCode_Add(0xB8); } if (TimeCodeIsNotTrustable) return; if (Time_Current_Seconds==0 && Time_Current_Frames==0 && Hours==0 && Minutes==0 && Seconds==0 && Frames==0) { //Time code is always 0 TimeCodeIsNotTrustable=true; Time_End_Seconds=(size_t)-1; TimeCode_FirstFrame.clear(); return; } //Calculating Time_Current_Seconds=60*60*Hours+60*Minutes+Seconds; Time_Current_Frames =Frames; if (!group_start_IsParsed) group_start_IsParsed=true; if (!group_start_FirstPass) { group_start_FirstPass=true; group_start_drop_frame_flag=drop_frame_flag; group_start_closed_gop=closed_gop; group_start_broken_link=broken_link; TimeCode_FirstFrame+=('0'+Hours/10); TimeCode_FirstFrame+=('0'+Hours%10); TimeCode_FirstFrame+=':'; TimeCode_FirstFrame+=('0'+Minutes/10); TimeCode_FirstFrame+=('0'+Minutes%10); TimeCode_FirstFrame+=':'; TimeCode_FirstFrame+=('0'+Seconds/10); TimeCode_FirstFrame+=('0'+Seconds%10); TimeCode_FirstFrame+=drop_frame_flag?';':':'; TimeCode_FirstFrame+=('0'+Frames/10); TimeCode_FirstFrame+=('0'+Frames%10); group_start_closed_gop_Closed=0; group_start_closed_gop_Open=0; } if (closed_gop) group_start_closed_gop_Closed++; else group_start_closed_gop_Open++; RefFramesCount=0; //Autorisation of other streams if (Searching_TimeStamp_Start_DoneOneTime) Streams[0xB8].Searching_TimeStamp_Start=false; //group_start else Searching_TimeStamp_Start_DoneOneTime=true; Streams[0x00].Searching_TimeStamp_End=true; //picture_start FILLING_END(); } //*************************************************************************** // Helpers //*************************************************************************** //--------------------------------------------------------------------------- // Packet "B8" void File_Mpegv::temporal_reference_Adapt() { //Temporal reference temporal_reference_Old=(int16u)-1; temporal_reference_Max=0; TemporalReference_Offset=TemporalReference.size(); if (TemporalReference_Offset>=0x800) { for (size_t Pos=0; Pos<0x400; Pos++) delete TemporalReference[Pos]; //TemporalReference[Pos]=NULL; TemporalReference.erase(TemporalReference.begin(), TemporalReference.begin()+0x400); if (0x400