/* 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. */ //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // // Contributor: Lionel Duchateau, kurtnoise@free.fr // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //--------------------------------------------------------------------------- // Pre-compilation #include "MediaInfo/PreComp.h" #ifdef __BORLANDC__ #pragma hdrstop #endif //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- #include "MediaInfo/Setup.h" using namespace ZenLib; //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- #if defined(MEDIAINFO_MPEGPS_YES) || defined(MEDIAINFO_MPEGTS_YES) || defined(MEDIAINFO_HEVC_YES) //--------------------------------------------------------------------------- namespace MediaInfoLib { //--------------------------------------------------------------------------- extern const char* Hevc_tier_flag(bool tier_flag) { return tier_flag ? "High" : "Main"; } //--------------------------------------------------------------------------- extern const char* Hevc_profile_idc(int32u profile_idc) { switch (profile_idc) { case 1 : return "Main"; case 2 : return "Main 10"; case 3 : return "Main Still"; case 4 : return "Format Range"; // extensions case 5 : return "High Throughput"; case 6 : return "Multiview Main"; case 7 : return "Scalable Main"; // can be "Scalable Main 10" depending on general_max_8bit_constraint_flag case 8 : return "3D Main"; case 9 : return "Screen Content"; // coding extensions case 10 : return "Scalable Format Range"; // extensions default : return ""; } } } //NameSpace //--------------------------------------------------------------------------- #endif //... //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- #if defined(MEDIAINFO_HEVC_YES) //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- #include "MediaInfo/Video/File_Hevc.h" #if defined(MEDIAINFO_AFDBARDATA_YES) #include "MediaInfo/Video/File_AfdBarData.h" #endif //defined(MEDIAINFO_AFDBARDATA_YES) #if defined(MEDIAINFO_DTVCCTRANSPORT_YES) #include "MediaInfo/Text/File_DtvccTransport.h" #endif //defined(MEDIAINFO_DTVCCTRANSPORT_YES) #include #include #include "MediaInfo/TimeCode.h" #include "MediaInfo/MediaInfo_Config_MediaInfo.h" #if MEDIAINFO_EVENTS #include "MediaInfo/MediaInfo_Config_PerPackage.h" #include "MediaInfo/MediaInfo_Events.h" #include "MediaInfo/MediaInfo_Events_Internal.h" #endif //MEDIAINFO_EVENTS using namespace std; //--------------------------------------------------------------------------- namespace MediaInfoLib { //*************************************************************************** // Info //*************************************************************************** //--------------------------------------------------------------------------- static const int8u Hevc_SubWidthC[]= { 1, 2, 2, 1, }; //--------------------------------------------------------------------------- static const int8u Hevc_SubHeightC[]= { 1, 2, 1, 1, }; //--------------------------------------------------------------------------- static const char* Hevc_chroma_format_idc(int8u chroma_format_idc) { switch (chroma_format_idc) { case 1: return "4:2:0"; case 2: return "4:2:2"; case 3: return "4:4:4"; default: return ""; } } //--------------------------------------------------------------------------- static const char* Hevc_chroma_format_idc_ColorSpace(int8u chroma_format_idc) { switch (chroma_format_idc) { case 0: return "Y"; case 1: return "YUV"; case 2: return "YUV"; default: return ""; } } //--------------------------------------------------------------------------- static const char* Hevc_pic_type[]= { "I", "I, P", "I, P, B", "", "", "", "", "", "", "", }; //--------------------------------------------------------------------------- static const char* Hevc_slice_type(int32u slice_type) { switch (slice_type) { case 0 : return "P"; case 1 : return "B"; case 2 : return "I"; default: return ""; } }; //--------------------------------------------------------------------------- extern const char* Mpegv_colour_primaries(int8u colour_primaries); extern const char* Mpegv_transfer_characteristics(int8u transfer_characteristics); extern const char* Mpegv_matrix_coefficients(int8u matrix_coefficients); const char* Mpegv_matrix_coefficients_ColorSpace(int8u matrix_coefficients); //--------------------------------------------------------------------------- extern const int8u Avc_PixelAspectRatio_Size; extern const float32 Avc_PixelAspectRatio[]; extern const char* Avc_video_format[]; extern const char* Avc_video_full_range[]; //*************************************************************************** // Constructor/Destructor //*************************************************************************** //--------------------------------------------------------------------------- File_Hevc::File_Hevc() { //Config #if MEDIAINFO_EVENTS ParserIDs[0]=MediaInfo_Parser_Hevc; StreamIDs_Width[0]=0; #endif //MEDIAINFO_EVENTS #if MEDIAINFO_TRACE Trace_Layers_Update(8); //Stream #endif //MEDIAINFO_TRACE MustSynchronize=true; PTS_DTS_Needed=true; StreamSource=IsStream; Frame_Count_NotParsedIncluded=0; //In Frame_Count_Valid=0; FrameIsAlwaysComplete=false; MustParse_VPS_SPS_PPS=false; MustParse_VPS_SPS_PPS_FromMatroska=false; MustParse_VPS_SPS_PPS_FromFlv=false; MustParse_VPS_SPS_PPS_FromLhvc=false; SizedBlocks=false; SizedBlocks_FileThenStream=0; //File specific lengthSizeMinusOne=(int8u)-1; //Specific RiskCalculationN=0; RiskCalculationD=0; //Temporal references TemporalReferences_DelayedElement=NULL; TemporalReferences_Min=0; TemporalReferences_Max=0; TemporalReferences_Reserved=0; TemporalReferences_Offset=0; TemporalReferences_Offset_pic_order_cnt_lsb_Last=0; TemporalReferences_pic_order_cnt_Min=0; pic_order_cnt_DTS_Ref=(int64u)-1; //Text #if defined(MEDIAINFO_DTVCCTRANSPORT_YES) GA94_03_IsPresent=false; GA94_03_Parser=NULL; #endif //defined(MEDIAINFO_DTVCCTRANSPORT_YES) } //--------------------------------------------------------------------------- File_Hevc::~File_Hevc() { Clean_Seq_Parameter(); Clean_Temp_References(); #if defined(MEDIAINFO_DTVCCTRANSPORT_YES) delete GA94_03_Parser; //GA94_03_Parser=NULL; #endif //defined(MEDIAINFO_DTVCCTRANSPORT_YES) } //--------------------------------------------------------------------------- void File_Hevc::Clean_Seq_Parameter() { for (size_t Pos = 0; Pos < seq_parameter_sets.size(); Pos++) delete seq_parameter_sets[Pos]; //seq_parameter_sets[Pos]=NULL; seq_parameter_sets.clear(); for (size_t Pos = 0; Pos::iterator video_parameter_set_Item=video_parameter_sets.begin(); video_parameter_set_Item!=video_parameter_sets.end(); ++video_parameter_set_Item) if ((*video_parameter_set_Item)) Streams_Fill(video_parameter_set_Item); for (std::vector::iterator seq_parameter_set_Item=seq_parameter_sets.begin(); seq_parameter_set_Item!=seq_parameter_sets.end(); ++seq_parameter_set_Item) if ((*seq_parameter_set_Item)) Streams_Fill(seq_parameter_set_Item); //Library name Fill(Stream_General, 0, General_Encoded_Library, Encoded_Library); Fill(Stream_General, 0, General_Encoded_Library_Name, Encoded_Library_Name); Fill(Stream_General, 0, General_Encoded_Library_Version, Encoded_Library_Version); Fill(Stream_General, 0, General_Encoded_Library_Settings, Encoded_Library_Settings); Fill(Stream_Video, 0, Video_Encoded_Library, Encoded_Library); Fill(Stream_Video, 0, Video_Encoded_Library_Name, Encoded_Library_Name); Fill(Stream_Video, 0, Video_Encoded_Library_Version, Encoded_Library_Version); Fill(Stream_Video, 0, Video_Encoded_Library_Settings, Encoded_Library_Settings); //Merge info about different HDR formats auto HDR_Format=HDR.find(Video_HDR_Format); if (HDR_Format!=HDR.end()) { bitset HDR_Present; size_t HDR_FirstFormatPos=(size_t)-1; for (size_t i=0; isecond[i].empty()) { if (HDR_FirstFormatPos==(size_t)-1) HDR_FirstFormatPos=i; HDR_Present[i]=true; } bool LegacyStreamDisplay=MediaInfoLib::Config.LegacyStreamDisplay_Get(); for (const auto& HDR_Item: HDR) { size_t i=HDR_FirstFormatPos; size_t HDR_FirstFieldNonEmpty=(size_t)-1; if (HDR_Item.first>Video_HDR_Format_Compatibility) { for (; i=HdrFormat_SmpteSt2086) break; if (!HDR_Present[i]) continue; Value.push_back(HDR_Item.second[i]); } auto Value_Flat = Value.Read(); if (!Value.empty() && Value_Flat.size() > (Value.size() - 1) * 3) Fill(Stream_Video, 0, HDR_Item.first, Value.Read()); } } } if (!EtsiTS103433.empty()) { Fill(Stream_Video, 0, "EtsiTS103433", EtsiTS103433); Fill_SetOptions(Stream_Video, 0, "EtsiTS103433", "N NTN"); } if (!maximum_content_light_level.empty()) Fill(Stream_Video, 0, Video_MaxCLL, maximum_content_light_level); if (!maximum_frame_average_light_level.empty()) Fill(Stream_Video, 0, Video_MaxFALL, maximum_frame_average_light_level); if (chroma_sample_loc_type_top_field != (int32u)-1) { Fill(Stream_Video, 0, "ChromaSubsampling_Position", __T("Type ") + Ztring::ToZtring(chroma_sample_loc_type_top_field)); if (chroma_sample_loc_type_bottom_field != (int32u)-1 && chroma_sample_loc_type_bottom_field != chroma_sample_loc_type_top_field) Fill(Stream_Video, 0, "ChromaSubsampling_Position", __T("Type ") + Ztring::ToZtring(chroma_sample_loc_type_bottom_field)); } } //--------------------------------------------------------------------------- void File_Hevc::Streams_Fill_Profile(const profile_tier_level_struct& p) { bool LegacyStreamDisplay=MediaInfoLib::Config.LegacyStreamDisplay_Get(); if (!LegacyStreamDisplay && !Retrieve_Const(Stream_Video, 0, Video_Format_Profile).empty()) return; Ztring Profile; if (p.profile_space==0) { if (p.profile_idc) { Profile=Ztring().From_UTF8(Hevc_profile_idc(p.profile_idc)); int8u Profile_Addition_Bits=0; switch (p.profile_idc) { case 6 : case 7 : if (!p.general_max_8bit_constraint_flag) { if (!p.general_max_10bit_constraint_flag) { if (!p.general_max_12bit_constraint_flag) { if (!p.general_max_14bit_constraint_flag) Profile_Addition_Bits=4; else Profile_Addition_Bits=3; } else Profile_Addition_Bits=2; } else Profile_Addition_Bits=1; } } if (Profile_Addition_Bits) { Profile+=' '; Profile+=Ztring::ToZtring(8+Profile_Addition_Bits*2); } } if (p.level_idc) { if (p.profile_idc) Profile+=__T('@'); Profile+=__T('L')+Ztring().From_Number(((float)p.level_idc)/30, (p.level_idc%10)?1:0); Profile+=__T('@'); Profile+=Ztring().From_UTF8(Hevc_tier_flag(p.tier_flag)); } } Fill(Stream_Video, 0, Video_Format_Profile, Profile); Fill(Stream_Video, 0, Video_Codec_Profile, Profile); } //--------------------------------------------------------------------------- void File_Hevc::Streams_Fill(std::vector::iterator video_parameter_set_Item) { if ((*video_parameter_set_Item)->profile_tier_level_info_layers.size()==1) return; //Priority on seq_parameter_set const auto&p=(*video_parameter_set_Item)->profile_tier_level_info_layers.back(); Streams_Fill_Profile(p); if (!(*video_parameter_set_Item)->view_id_val.empty()) { size_t Count=0; for (const auto val : (*video_parameter_set_Item)->view_id_val) if (val!=(int16u)-1) Count++; Fill(Stream_Video, 0, Video_MultiView_Count, Count); } } //--------------------------------------------------------------------------- void File_Hevc::Streams_Fill(std::vector::iterator seq_parameter_set_Item) { if ((*seq_parameter_set_Item)->nuh_layer_id) return; int32u Width = (*seq_parameter_set_Item)->pic_width_in_luma_samples; int32u Height= (*seq_parameter_set_Item)->pic_height_in_luma_samples; int8u chromaArrayType = (*seq_parameter_set_Item)->ChromaArrayType(); if (chromaArrayType >= 4) chromaArrayType = 0; int32u CropUnitX=Hevc_SubWidthC [chromaArrayType]; int32u CropUnitY=Hevc_SubHeightC[chromaArrayType]; Width -=((*seq_parameter_set_Item)->conf_win_left_offset+(*seq_parameter_set_Item)->conf_win_right_offset)*CropUnitX; Height-=((*seq_parameter_set_Item)->conf_win_top_offset +(*seq_parameter_set_Item)->conf_win_bottom_offset)*CropUnitY; const auto& p=(*seq_parameter_set_Item)->profile_tier_level_info; Streams_Fill_Profile(p); Fill(Stream_Video, StreamPos_Last, Video_Width, Width); Fill(Stream_Video, StreamPos_Last, Video_Height, Height); if ((*seq_parameter_set_Item)->conf_win_left_offset || (*seq_parameter_set_Item)->conf_win_right_offset) Fill(Stream_Video, StreamPos_Last, Video_Stored_Width, (*seq_parameter_set_Item)->pic_width_in_luma_samples); if ((*seq_parameter_set_Item)->conf_win_top_offset || (*seq_parameter_set_Item)->conf_win_bottom_offset) Fill(Stream_Video, StreamPos_Last, Video_Stored_Height, (*seq_parameter_set_Item)->pic_height_in_luma_samples); Fill(Stream_Video, 0, Video_ColorSpace, Hevc_chroma_format_idc_ColorSpace((*seq_parameter_set_Item)->chroma_format_idc)); Fill(Stream_Video, 0, Video_ChromaSubsampling, Hevc_chroma_format_idc((*seq_parameter_set_Item)->chroma_format_idc)); if ((*seq_parameter_set_Item)->bit_depth_luma_minus8==(*seq_parameter_set_Item)->bit_depth_chroma_minus8) Fill(Stream_Video, 0, Video_BitDepth, (*seq_parameter_set_Item)->bit_depth_luma_minus8+8); if (preferred_transfer_characteristics!=2) Fill(Stream_Video, 0, Video_transfer_characteristics, Mpegv_transfer_characteristics(preferred_transfer_characteristics)); if ((*seq_parameter_set_Item)->vui_parameters) { if ((*seq_parameter_set_Item)->vui_parameters->timing_info_present_flag) { if ((*seq_parameter_set_Item)->vui_parameters->time_scale && (*seq_parameter_set_Item)->vui_parameters->num_units_in_tick) Fill(Stream_Video, StreamPos_Last, Video_FrameRate, (float64)(*seq_parameter_set_Item)->vui_parameters->time_scale / (*seq_parameter_set_Item)->vui_parameters->num_units_in_tick); } if ((*seq_parameter_set_Item)->vui_parameters->aspect_ratio_info_present_flag) { float64 PixelAspectRatio = 1; if ((*seq_parameter_set_Item)->vui_parameters->aspect_ratio_idcvui_parameters->aspect_ratio_idc]; else if ((*seq_parameter_set_Item)->vui_parameters->aspect_ratio_idc == 0xFF && (*seq_parameter_set_Item)->vui_parameters->sar_height) PixelAspectRatio = ((float64) (*seq_parameter_set_Item)->vui_parameters->sar_width) / (*seq_parameter_set_Item)->vui_parameters->sar_height; Fill(Stream_Video, 0, Video_PixelAspectRatio, PixelAspectRatio, 3, true); if(Height) Fill(Stream_Video, 0, Video_DisplayAspectRatio, Width*PixelAspectRatio/Height, 3, true); //More precise } //Colour description if ((*seq_parameter_set_Item)->vui_parameters->video_signal_type_present_flag) { Fill(Stream_Video, 0, Video_Standard, Avc_video_format[(*seq_parameter_set_Item)->vui_parameters->video_format]); Fill(Stream_Video, 0, Video_colour_range, Avc_video_full_range[(*seq_parameter_set_Item)->vui_parameters->video_full_range_flag]); if ((*seq_parameter_set_Item)->vui_parameters->colour_description_present_flag) { Fill(Stream_Video, 0, Video_colour_description_present, "Yes"); Fill(Stream_Video, 0, Video_colour_primaries, Mpegv_colour_primaries((*seq_parameter_set_Item)->vui_parameters->colour_primaries)); Fill(Stream_Video, 0, Video_transfer_characteristics, Mpegv_transfer_characteristics((*seq_parameter_set_Item)->vui_parameters->transfer_characteristics)); Fill(Stream_Video, 0, Video_matrix_coefficients, Mpegv_matrix_coefficients((*seq_parameter_set_Item)->vui_parameters->matrix_coefficients)); if ((*seq_parameter_set_Item)->vui_parameters->matrix_coefficients!=2) Fill(Stream_Video, 0, Video_ColorSpace, Mpegv_matrix_coefficients_ColorSpace((*seq_parameter_set_Item)->vui_parameters->matrix_coefficients), Unlimited, true, true); } } } } //--------------------------------------------------------------------------- void File_Hevc::Streams_Finish() { //GA94 captions #if defined(MEDIAINFO_DTVCCTRANSPORT_YES) if (GA94_03_Parser && GA94_03_Parser->Status[IsAccepted]) { Clear(Stream_Text); Finish(GA94_03_Parser); Merge(*GA94_03_Parser); Ztring LawRating=GA94_03_Parser->Retrieve(Stream_General, 0, General_LawRating); if (!LawRating.empty()) Fill(Stream_General, 0, General_LawRating, LawRating, true); Ztring Title=GA94_03_Parser->Retrieve(Stream_General, 0, General_Title); if (!Title.empty() && Retrieve(Stream_General, 0, General_Title).empty()) Fill(Stream_General, 0, General_Title, Title); for (size_t Pos=0; Pos=Buffer_Size || Buffer[Buffer_Offset-1]==0x00) Buffer_Offset--; } if (Buffer_Offset>Buffer_Offset_Min && Buffer[Buffer_Offset-1]==0x00) Buffer_Offset--; //Parsing last bytes if needed if (Buffer_Offset+4==Buffer_Size && (Buffer[Buffer_Offset ]!=0x00 || Buffer[Buffer_Offset+1]!=0x00 || Buffer[Buffer_Offset+2]!=0x00 || Buffer[Buffer_Offset+3]!=0x01)) Buffer_Offset++; if (Buffer_Offset+3==Buffer_Size && (Buffer[Buffer_Offset ]!=0x00 || Buffer[Buffer_Offset+1]!=0x00 || Buffer[Buffer_Offset+2]!=0x01)) Buffer_Offset++; if (Buffer_Offset+2==Buffer_Size && (Buffer[Buffer_Offset ]!=0x00 || Buffer[Buffer_Offset+1]!=0x00)) Buffer_Offset++; if (Buffer_Offset+1==Buffer_Size && Buffer[Buffer_Offset ]!=0x00) Buffer_Offset++; if (Buffer_Offset+4>Buffer_Size) return false; if (File_Offset==0 && Buffer_Offset==0 && (Buffer[3]==0xE0 || Buffer[3]==0xFE)) { //It is from MPEG-PS Reject(); return false; } //Synched is OK Synched=true; return true; } //--------------------------------------------------------------------------- bool File_Hevc::Synched_Test() { //Must have enough buffer for having header if (Buffer_Offset+6>Buffer_Size) return false; //Quick test of synchro if (Buffer[Buffer_Offset ]!=0x00 || Buffer[Buffer_Offset+1]!=0x00 || (Buffer[Buffer_Offset+2]!=0x01 && (Buffer[Buffer_Offset+2]!=0x00 || Buffer[Buffer_Offset+3]!=0x01))) { Synched=false; return true; } //Quick search if (!Header_Parser_QuickSearch()) return false; //We continue return true; } //*************************************************************************** // Buffer - Demux //*************************************************************************** //--------------------------------------------------------------------------- #if MEDIAINFO_DEMUX bool File_Hevc::Demux_UnpacketizeContainer_Test() { const int8u* Buffer_Temp=NULL; size_t Buffer_Temp_Size=0; bool RandomAccess=true; //Default, in case of problem if ((MustParse_VPS_SPS_PPS || SizedBlocks) && Demux_Transcode_Iso14496_15_to_AnnexB) { if (MustParse_VPS_SPS_PPS) return true; //Wait for SPS and PPS //Random access check RandomAccess=false; //Computing final size size_t TranscodedBuffer_Size=0; size_t Buffer_Offset_Save=Buffer_Offset; while (Buffer_Offset+lengthSizeMinusOne+1+1<=Buffer_Size) { size_t Size; if (Buffer_Offset+lengthSizeMinusOne>Buffer_Size) { Size=0; Buffer_Offset=Buffer_Size; } else switch (lengthSizeMinusOne) { case 0: Size=Buffer[Buffer_Offset]; TranscodedBuffer_Size+=2; break; case 1: Size=BigEndian2int16u(Buffer+Buffer_Offset); TranscodedBuffer_Size++; break; case 2: Size=BigEndian2int24u(Buffer+Buffer_Offset); break; case 3: Size=BigEndian2int32u(Buffer+Buffer_Offset); TranscodedBuffer_Size--; break; default: return true; //Problem } Size+=lengthSizeMinusOne+1; //Coherency checking if (SizeBuffer_Size || (Buffer_Offset+Size!=Buffer_Size && Buffer_Offset+Size+lengthSizeMinusOne+1>Buffer_Size)) Size=Buffer_Size-Buffer_Offset; size_t Buffer_Offset_Temp=Buffer_Offset+lengthSizeMinusOne+1; //In case there are more than 1 NAL in the block (in Stream format), trying to find the first NAL being a slice size_t Buffer_Offset_Temp_Max=Buffer_Offset+Size; if (!RandomAccess && Buffer_Offset_Temp=Buffer_Offset_Temp_Max || Buffer[Buffer_Offset_Temp]==0x00) Buffer_Offset_Temp--; } } //Random access check if (!RandomAccess && Buffer_Offset_Temp+2>1; //nal_unit_type RapPicFlag=Element_Code>=16 && Element_Code<=23; if (RapPicFlag) Skip_SB( "no_output_of_prior_pics_flag"); Get_UE ( slice_pic_parameter_set_id, "slice_pic_parameter_set_id"); int8u num_extra_slice_header_bits=(int8u)-1; std::vector::iterator pic_parameter_set_Item; if (MustParse_VPS_SPS_PPS_FromFlv) num_extra_slice_header_bits=0; // We bet it is old, so without num_extra_slice_header_bits else if (!(slice_pic_parameter_set_id>=pic_parameter_sets.size() || (*(pic_parameter_set_Item=pic_parameter_sets.begin()+slice_pic_parameter_set_id))==NULL)) { num_extra_slice_header_bits=(*pic_parameter_set_Item)->num_extra_slice_header_bits; } if (num_extra_slice_header_bits!=(int8u)-1) { int32u slice_type; Skip_S1(num_extra_slice_header_bits, "slice_reserved_flags"); Get_UE (slice_type, "slice_type"); switch (slice_type) { case 2 : case 7 : RandomAccess=true; } } } BS_End(); } TranscodedBuffer_Size+=Size; Buffer_Offset+=Size; } Buffer_Offset=Buffer_Offset_Save; //Adding VPS/SPS/PPS sizes if (RandomAccess) { for (video_parameter_set_structs::iterator Data_Item=video_parameter_sets.begin(); Data_Item!=video_parameter_sets.end(); ++Data_Item) TranscodedBuffer_Size+=(*Data_Item)->AnnexB_Buffer_Size; for (seq_parameter_set_structs::iterator Data_Item=seq_parameter_sets.begin(); Data_Item!=seq_parameter_sets.end(); ++Data_Item) TranscodedBuffer_Size+=(*Data_Item)->AnnexB_Buffer_Size; for (pic_parameter_set_structs::iterator Data_Item=pic_parameter_sets.begin(); Data_Item!=pic_parameter_sets.end(); ++Data_Item) TranscodedBuffer_Size+=(*Data_Item)->AnnexB_Buffer_Size; } //Copying int8u* TranscodedBuffer=new int8u[TranscodedBuffer_Size+100]; size_t TranscodedBuffer_Pos=0; if (RandomAccess) { for (video_parameter_set_structs::iterator Data_Item=video_parameter_sets.begin(); Data_Item!=video_parameter_sets.end(); ++Data_Item) { std::memcpy(TranscodedBuffer+TranscodedBuffer_Pos, (*Data_Item)->AnnexB_Buffer, (*Data_Item)->AnnexB_Buffer_Size); TranscodedBuffer_Pos+=(*Data_Item)->AnnexB_Buffer_Size; } for (seq_parameter_set_structs::iterator Data_Item=seq_parameter_sets.begin(); Data_Item!=seq_parameter_sets.end(); ++Data_Item) { std::memcpy(TranscodedBuffer+TranscodedBuffer_Pos, (*Data_Item)->AnnexB_Buffer, (*Data_Item)->AnnexB_Buffer_Size); TranscodedBuffer_Pos+=(*Data_Item)->AnnexB_Buffer_Size; } for (pic_parameter_set_structs::iterator Data_Item=pic_parameter_sets.begin(); Data_Item!=pic_parameter_sets.end(); ++Data_Item) { std::memcpy(TranscodedBuffer+TranscodedBuffer_Pos, (*Data_Item)->AnnexB_Buffer, (*Data_Item)->AnnexB_Buffer_Size); TranscodedBuffer_Pos+=(*Data_Item)->AnnexB_Buffer_Size; } } while (Buffer_OffsetBuffer_Size || (Buffer_Offset+Size!=Buffer_Size && Buffer_Offset+Size+lengthSizeMinusOne+1>Buffer_Size)) Size=Buffer_Size-Buffer_Offset; std::memcpy(TranscodedBuffer+TranscodedBuffer_Pos, Buffer+Buffer_Offset, Size); TranscodedBuffer_Pos+=Size; Buffer_Offset+=Size; } Buffer_Offset=0; Buffer_Temp=Buffer; Buffer=TranscodedBuffer; Buffer_Temp_Size=Buffer_Size; Buffer_Size=TranscodedBuffer_Size; Demux_Offset=Buffer_Size; } else { bool zero_byte=Buffer[Buffer_Offset+2]==0x00; if (!(((Buffer[Buffer_Offset+(zero_byte?4:3)]&0x40)==0 && (Buffer[Buffer_Offset+(zero_byte?6:5)]&0x80)!=0x80) || (Buffer[Buffer_Offset+(zero_byte?4:3)]&0x7E)==(38<<1))) { if (Demux_Offset==0) { Demux_Offset=Buffer_Offset; Demux_IntermediateItemFound=false; } while (Demux_Offset+6<=Buffer_Size) { //Synchronizing while(Demux_Offset+6<=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+6>Buffer_Size) { if (Config->IsFinishing) Demux_Offset=Buffer_Size; break; } zero_byte=Buffer[Demux_Offset+2]==0x00; int8u nal_unit_type=Buffer[Demux_Offset+(zero_byte?4:3)]>>1; bool Next; switch (nal_unit_type) { case 0 : case 1 : case 2 : case 3 : case 4 : case 5 : case 6 : case 7 : case 8 : case 9 : case 16 : case 17 : case 18 : case 19 : case 20 : case 21 : if (Demux_IntermediateItemFound) { if (Buffer[Demux_Offset+(zero_byte?6:5)]&0x80) Next=true; else Next=false; } else { Next=false; Demux_IntermediateItemFound=true; } break; case 32 : case 33 : case 34 : case 35 : if (Demux_IntermediateItemFound) Next=true; else Next=false; break; default : Next=false; } if (Next) { Demux_IntermediateItemFound=false; break; } Demux_Offset++; } if (Demux_Offset+6>Buffer_Size && !FrameIsAlwaysComplete && !Config->IsFinishing) return false; //No complete frame if (Demux_Offset && Buffer[Demux_Offset-1]==0x00) Demux_Offset--; zero_byte=Buffer[Buffer_Offset+2]==0x00; size_t Buffer_Offset_Random=Buffer_Offset; if ((Buffer[Buffer_Offset_Random+(zero_byte?4:3)]&0x7E)==(35<<1)) { Buffer_Offset_Random++; if (zero_byte) Buffer_Offset_Random++; while(Buffer_Offset_Random+6<=Buffer_Size && (Buffer[Buffer_Offset_Random ]!=0x00 || Buffer[Buffer_Offset_Random+1]!=0x00 || Buffer[Buffer_Offset_Random+2]!=0x01)) Buffer_Offset_Random++; zero_byte=Buffer[Buffer_Offset_Random+2]==0x00; } RandomAccess=Buffer_Offset_Random+6<=Buffer_Size && (Buffer[Buffer_Offset_Random+(zero_byte?4:3)]&0x7E)==(32<<1); //video_parameter_set } } if (!Status[IsAccepted]) { if (Config->Demux_EventWasSent) return false; File_Hevc* MI=new File_Hevc; Element_Code=(int64u)-1; Open_Buffer_Init(MI); #ifdef MEDIAINFO_EVENTS MediaInfo_Config_PerPackage* Config_PerPackage_Temp=MI->Config->Config_PerPackage; MI->Config->Config_PerPackage=NULL; #endif //MEDIAINFO_EVENTS Open_Buffer_Continue(MI, Buffer, Buffer_Size); #ifdef MEDIAINFO_EVENTS MI->Config->Config_PerPackage=Config_PerPackage_Temp; #endif //MEDIAINFO_EVENTS bool IsOk=MI->Status[IsAccepted]; delete MI; if (!IsOk) return false; } if (IFrame_Count || RandomAccess) { int64u PTS_Temp=FrameInfo.PTS; if (!IsSub) FrameInfo.PTS=(int64u)-1; Demux_UnpacketizeContainer_Demux(RandomAccess); if (!IsSub) FrameInfo.PTS=PTS_Temp; } else Demux_UnpacketizeContainer_Demux_Clear(); if (Buffer_Temp) { Demux_TotalBytes-=Buffer_Size; Demux_TotalBytes+=Buffer_Temp_Size; delete[] Buffer; Buffer=Buffer_Temp; Buffer_Size=Buffer_Temp_Size; } return true; } #endif //MEDIAINFO_DEMUX //--------------------------------------------------------------------------- void File_Hevc::Synched_Init() { if (!Frame_Count_Valid) Frame_Count_Valid=Config->ParseSpeed>=0.3?16:(IsSub?1:2); //Note: should be replaced by "512:2" when I-frame/GOP detection is OK //FrameInfo PTS_End=0; if (!IsSub) FrameInfo.DTS=0; //No DTS in container DTS_Begin=FrameInfo.DTS; DTS_End=FrameInfo.DTS; //Status IFrame_Count=0; //Temp chroma_sample_loc_type_top_field=(int32u)-1; chroma_sample_loc_type_bottom_field=(int32u)-1; preferred_transfer_characteristics=2; chroma_format_idc=0; //Default values Streams.resize(0x100); Streams[32].Searching_Payload=true; //video_parameter_set Streams[35].Searching_Payload=true; //access_unit_delimiter Streams[39].Searching_Payload=true; //sei for (int8u Pos=0xFF; Pos>=48; Pos--) Streams[Pos].Searching_Payload=true; //unspecified #if MEDIAINFO_DEMUX Demux_Transcode_Iso14496_15_to_AnnexB=Config->Demux_Hevc_Transcode_Iso14496_15_to_AnnexB_Get(); #endif //MEDIAINFO_DEMUX } //*************************************************************************** // Buffer - Global //*************************************************************************** //--------------------------------------------------------------------------- void File_Hevc::Read_Buffer_Unsynched() { //Impossible to know TimeStamps now PTS_End=0; DTS_End=0; //Temporal references Clean_Temp_References(); delete TemporalReferences_DelayedElement; TemporalReferences_DelayedElement=NULL; TemporalReferences_Min=0; TemporalReferences_Max=0; TemporalReferences_Reserved=0; TemporalReferences_Offset=0; TemporalReferences_Offset_pic_order_cnt_lsb_Last=0; TemporalReferences_pic_order_cnt_Min=0; pic_order_cnt_DTS_Ref=(int64u)-1; //Text #if defined(MEDIAINFO_DTVCCTRANSPORT_YES) if (GA94_03_Parser) GA94_03_Parser->Open_Buffer_Unsynch(); #endif //defined(MEDIAINFO_DTVCCTRANSPORT_YES) } //*************************************************************************** // Buffer - Per element //*************************************************************************** //--------------------------------------------------------------------------- void File_Hevc::Header_Parse() { //Specific case if (MustParse_VPS_SPS_PPS) { Header_Fill_Size(Element_Size); Header_Fill_Code((int64u)-1, "Specific"); return; } //Parsing int8u nal_unit_type, nuh_temporal_id_plus1; if (!SizedBlocks || SizedBlocks_FileThenStream) { if (Buffer[Buffer_Offset+2]==0x00) Skip_B1( "zero_byte"); Skip_B3( "start_code_prefix_one_3bytes"); BS_Begin(); Mark_0 (); Get_S1 (6, nal_unit_type, "nal_unit_type"); Get_S1 (6, nuh_layer_id, "nuh_layer_id"); Get_S1 (3, nuh_temporal_id_plus1, "nuh_temporal_id_plus1"); BS_End(); if (!Header_Parser_Fill_Size()) { Element_WaitForMoreData(); return; } //if (nuh_temporal_id_plus1==0) // Found 1 stream with nuh_temporal_id_plus1==0, lets disable this coherency test for the moment // Trusted_IsNot("nuh_temporal_id_plus1"); //In case there are more than 1 NAL in the block (in Stream format), trying to find the first NAL being a slice if (SizedBlocks_FileThenStream && Element[Element_Level-1].Next>=SizedBlocks_FileThenStream) { if (Element[Element_Level-1].Next>SizedBlocks_FileThenStream) Header_Fill_Size(SizedBlocks_FileThenStream-(File_Offset+Buffer_Offset)); SizedBlocks_FileThenStream=0; //TODO: more integrity tests, handling of first element size of first element (wrong in the trace) } } else { int32u Size; switch (lengthSizeMinusOne) { case 0: { int8u Size_; Get_B1 (Size_, "size"); Size=Size_; } break; case 1: { int16u Size_; Get_B2 (Size_, "size"); Size=Size_; } break; case 2: { int32u Size_; Get_B3 (Size_, "size"); Size=Size_; } break; case 3: Get_B4 (Size, "size"); break; default: Trusted_IsNot("No size of NALU defined"); Header_Fill_Size(Buffer_Size-Buffer_Offset); return; } if (Element_Size<(int64u)lengthSizeMinusOne+1+2 || Size>Element_Size-Element_Offset) return RanOutOfData("HEVC"); //In case there are more than 1 NAL in the block (in Stream format), trying to find the first NAL being a slice size_t Buffer_Offset_Temp=Buffer_Offset+lengthSizeMinusOne+1; size_t Buffer_Offset_Temp_Max=Buffer_Offset+Size; while (Buffer_Offset_Temp+3<=Buffer_Offset+Size) { if (CC3(Buffer+Buffer_Offset_Temp)==0x000001 || CC3(Buffer+Buffer_Offset_Temp)==0x000000) { break; } Buffer_Offset_Temp+=2; while (Buffer_Offset_Temp=Buffer_Offset_Temp_Max || Buffer[Buffer_Offset_Temp]==0x00) Buffer_Offset_Temp--; } if (Buffer_Offset_Temp+3<=Buffer_Offset+Size) { SizedBlocks_FileThenStream=File_Offset+Buffer_Offset+Size; Size=Buffer_Offset_Temp-(Buffer_Offset+Element_Offset); } Header_Fill_Size(Element_Offset+Size); BS_Begin(); Mark_0 (); Get_S1 (6, nal_unit_type, "nal_unit_type"); Get_S1 (6, nuh_layer_id, "nuh_layer_id"); Get_S1 (3, nuh_temporal_id_plus1, "nuh_temporal_id_plus1"); BS_End(); //if (nuh_temporal_id_plus1==0) // Found 1 stream with nuh_temporal_id_plus1==0, lets disable this coherency test for the moment // Trusted_IsNot("nuh_temporal_id_plus1"); } //Filling #if MEDIAINFO_TRACE if (Trace_Activated) Header_Fill_Code(nal_unit_type, Ztring().From_CC1(nal_unit_type)); else #endif //MEDIAINFO_TRACE Header_Fill_Code(nal_unit_type); } //--------------------------------------------------------------------------- bool File_Hevc::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+5<=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+5>Buffer_Size) { if (FrameIsAlwaysComplete || Config->IsFinishing) Buffer_Offset_Temp=Buffer_Size; //We are sure that the next bytes are a start else return false; } if (Buffer[Buffer_Offset_Temp-1]==0x00) Buffer_Offset_Temp--; //OK, we continue Header_Fill_Size(Buffer_Offset_Temp-Buffer_Offset); Buffer_Offset_Temp=0; return true; } //--------------------------------------------------------------------------- bool File_Hevc::Header_Parser_QuickSearch() { while ( Buffer_Offset+6<=Buffer_Size && Buffer[Buffer_Offset ]==0x00 && Buffer[Buffer_Offset+1]==0x00 && (Buffer[Buffer_Offset+2]==0x01 || (Buffer[Buffer_Offset+2]==0x00 && Buffer[Buffer_Offset+3]==0x01))) { //Getting start_code int8u nal_unit_type; if (Buffer[Buffer_Offset+2]==0x00) nal_unit_type=(CC1(Buffer+Buffer_Offset+4)&0x7E)>>1; else nal_unit_type=(CC1(Buffer+Buffer_Offset+3)&0x7E)>>1; //Searching start if (Streams[nal_unit_type].Searching_Payload) return true; //Synchronizing Buffer_Offset+=4; Synched=false; if (!Synchronize()) { UnSynched_IsNotJunk=true; return false; } if (Buffer_Offset+6>Buffer_Size) { UnSynched_IsNotJunk=true; return false; } } Trusted_IsNot("HEVC, Synchronisation lost"); return Synchronize(); } //--------------------------------------------------------------------------- void File_Hevc::Data_Parse() { //Specific case if (Element_Code==(int64u)-1) { VPS_SPS_PPS(); return; } if (nuh_layer_id) { //Skip_XX(Element_Size, "(Extension)"); //return; } //Trailing zeroes int64u Element_Size_SaveBeforeZeroes=Element_Size; if (Element_Size) { while (Element_Size && Buffer[Buffer_Offset+(size_t)Element_Size-1]==0) Element_Size--; } //Searching emulation_prevention_three_byte int8u* Buffer_3Bytes=NULL; const int8u* Save_Buffer=Buffer; int64u Save_File_Offset=File_Offset; size_t Save_Buffer_Offset=Buffer_Offset; int64u Save_Element_Size=Element_Size; size_t Element_Offset_3Bytes=(size_t)Element_Offset; std::vector ThreeByte_List; while (Element_Offset_3Bytes+3<=Element_Size) { if (CC3(Buffer+Buffer_Offset+(size_t)Element_Offset_3Bytes)==0x000003) ThreeByte_List.push_back(Element_Offset_3Bytes+2); Element_Offset_3Bytes+=2; while(Element_Offset_3Bytes=Element_Size || Buffer[Buffer_Offset+(size_t)Element_Offset_3Bytes-1]==0x00) Element_Offset_3Bytes--; } if (!ThreeByte_List.empty()) { //We must change the buffer for keeping out Element_Size=Save_Element_Size-ThreeByte_List.size(); File_Offset+=Buffer_Offset; Buffer_Offset=0; Buffer_3Bytes=new int8u[(size_t)Element_Size]; for (size_t Pos=0; Pos<=ThreeByte_List.size(); Pos++) { size_t Pos0=(Pos==ThreeByte_List.size())?(size_t)Save_Element_Size:(ThreeByte_List[Pos]); size_t Pos1=(Pos==0)?0:(ThreeByte_List[Pos-1]+1); size_t Buffer_3bytes_Begin=Pos1-Pos; size_t Save_Buffer_Begin =Pos1; size_t Size= Pos0-Pos1; std::memcpy(Buffer_3Bytes+Buffer_3bytes_Begin, Save_Buffer+Save_Buffer_Offset+Save_Buffer_Begin, Size); } Buffer=Buffer_3Bytes; } //Parsing switch (Element_Code) { case 0 : case 1 : case 2 : case 3 : case 4: case 5: case 6: case 7: case 8: case 9: case 16 : case 17 : case 18 : case 19 : case 20 : case 21 : slice_segment_layer(); break; case 32 : video_parameter_set(); break; case 33 : seq_parameter_set(); break; case 34 : pic_parameter_set(); break; case 35 : access_unit_delimiter(); break; case 36 : end_of_seq(); break; case 37 : end_of_bitstream(); break; case 38 : filler_data(); break; case 39 : case 40 : sei(); break; default : Skip_XX(Element_Size-Element_Offset, "Data"); if (Element_Code>=48) Trusted_IsNot("Unspecified"); } if (!ThreeByte_List.empty()) { //We must change the buffer for keeping out Element_Size=Save_Element_Size; File_Offset=Save_File_Offset; Buffer_Offset=Save_Buffer_Offset; delete[] Buffer; Buffer=Save_Buffer; Buffer_3Bytes=NULL; //Same as Buffer... Element_Offset+=ThreeByte_List.size(); } #if MEDIAINFO_DEMUX if (Demux_Transcode_Iso14496_15_to_AnnexB) { if (Element_Code==32) { std::vector::iterator Data_Item=video_parameter_sets.begin(); if (Data_Item!=video_parameter_sets.end() && (*Data_Item)) { delete[] (*Data_Item)->AnnexB_Buffer; (*Data_Item)->AnnexB_Buffer_Size=(size_t)(Element_Size+5); (*Data_Item)->AnnexB_Buffer=new int8u[(*Data_Item)->AnnexB_Buffer_Size]; (*Data_Item)->AnnexB_Buffer[0]=0x00; (*Data_Item)->AnnexB_Buffer[1]=0x00; (*Data_Item)->AnnexB_Buffer[2]=0x01; (*Data_Item)->AnnexB_Buffer[3]=Buffer[Buffer_Offset-2]; (*Data_Item)->AnnexB_Buffer[4]=Buffer[Buffer_Offset-1]; std::memcpy((*Data_Item)->AnnexB_Buffer+5, Buffer+Buffer_Offset, (size_t)Element_Size); } } if (Element_Code==33) { std::vector::iterator Data_Item=seq_parameter_sets.begin(); if (Data_Item!=seq_parameter_sets.end() && (*Data_Item)) { delete[] (*Data_Item)->AnnexB_Buffer; (*Data_Item)->AnnexB_Buffer_Size=(size_t)(Element_Size+5); (*Data_Item)->AnnexB_Buffer=new int8u[(*Data_Item)->AnnexB_Buffer_Size]; (*Data_Item)->AnnexB_Buffer[0]=0x00; (*Data_Item)->AnnexB_Buffer[1]=0x00; (*Data_Item)->AnnexB_Buffer[2]=0x01; (*Data_Item)->AnnexB_Buffer[3]=Buffer[Buffer_Offset-2]; (*Data_Item)->AnnexB_Buffer[4]=Buffer[Buffer_Offset-1]; std::memcpy((*Data_Item)->AnnexB_Buffer+5, Buffer+Buffer_Offset, (size_t)Element_Size); } } if (Element_Code==34) { std::vector::iterator Data_Item=pic_parameter_sets.begin(); if (Data_Item!=pic_parameter_sets.end() && (*Data_Item)) { delete[] (*Data_Item)->AnnexB_Buffer; (*Data_Item)->AnnexB_Buffer_Size=(size_t)(Element_Size+5); (*Data_Item)->AnnexB_Buffer=new int8u[(*Data_Item)->AnnexB_Buffer_Size]; (*Data_Item)->AnnexB_Buffer[0]=0x00; (*Data_Item)->AnnexB_Buffer[1]=0x00; (*Data_Item)->AnnexB_Buffer[2]=0x01; (*Data_Item)->AnnexB_Buffer[3]=Buffer[Buffer_Offset-2]; (*Data_Item)->AnnexB_Buffer[4]=Buffer[Buffer_Offset-1]; std::memcpy((*Data_Item)->AnnexB_Buffer+5, Buffer+Buffer_Offset, (size_t)Element_Size); } } } #endif //MEDIAINFO_DEMUX //Trailing zeroes Element_Size=Element_Size_SaveBeforeZeroes; } //*************************************************************************** // Elements //*************************************************************************** //--------------------------------------------------------------------------- // Packets void File_Hevc::slice_segment_layer() { #if MEDIAINFO_TRACE Element_Name("slice_segment_layer"); switch (Element_Code) { case 0 : case 1 : break; case 2 : case 3 : Element_Info("TSA"); break; case 4: case 5: Element_Info("STSA"); break; case 6: case 7: Element_Info("RADL"); break; case 8: case 9: Element_Info("RASL"); break; case 16 : case 17 : case 18 : Element_Info("BLA"); break; case 19 : case 20 : Element_Info("IDR"); break; case 21 : Element_Info("CRA"); break; default: ; } #endif //MEDIAINFO_TRACE //Parsing RapPicFlag=Element_Code>=16 && Element_Code<=23; BS_Begin(); slice_segment_header(); BS_End(); Skip_XX(Element_Size-Element_Offset, "(ToDo)"); FILLING_BEGIN(); if (slice_pic_parameter_set_id==(int32u)-1) return; //Count of I-Frames if (first_slice_segment_in_pic_flag && (Element_Code==19 || Element_Code==20)) IFrame_Count++; if (first_slice_segment_in_pic_flag) { //Frame_Count if (Frame_Count_NotParsedIncluded<16 && TC_Current.IsSet()) { TimeCode TC_Previous(Retrieve_Const(Stream_Video, 0, Video_TimeCode_FirstFrame).To_UTF8(), TC_Current.GetFramesMax()); if (!TC_Previous.IsSet() || TC_Current=RiskCalculationD) // Check if we trust or not the sync { Reject("HEVC"); return; } Accept("HEVC"); } if (!Status[IsFilled]) { if (IFrame_Count>=8) Frame_Count_Valid=Frame_Count; //We have enough frames if (Frame_Count>=Frame_Count_Valid) { Fill("HEVC"); if (!IsSub && Config->ParseSpeed<1.0) Finish("HEVC"); } } } FILLING_END(); } //--------------------------------------------------------------------------- void File_Hevc::video_parameter_sets_creating_data(int8u vps_video_parameter_set_id, const vector& profile_tier_level_info_layers, int8u vps_max_sub_layers_minus1, const vector& view_id_val) { //Creating Data if (vps_video_parameter_set_id >= video_parameter_sets.size()) video_parameter_sets.resize(vps_video_parameter_set_id + 1); std::vector::iterator Data_Item = video_parameter_sets.begin() + vps_video_parameter_set_id; delete *Data_Item; *Data_Item = new video_parameter_set_struct( profile_tier_level_info_layers, vps_max_sub_layers_minus1, view_id_val ); //NextCode NextCode_Clear(); NextCode_Add(33); //Autorisation of other streams Streams[33].Searching_Payload = true; //seq_parameter_set Streams[36].Searching_Payload = true; //end_of_seq Streams[37].Searching_Payload = true; //end_of_bitstream Streams[38].Searching_Payload = true; //filler_data } //--------------------------------------------------------------------------- // Packet "32" void File_Hevc::video_parameter_set() { Element_Name("video_parameter_set"); //Parsing vector ps; int32u vps_num_layer_sets_minus1; int8u vps_video_parameter_set_id, vps_max_sub_layers_minus1, vps_max_layers_minus1, vps_max_layer_id; bool vps_base_layer_internal_flag, vps_temporal_id_nesting_flag, vps_sub_layer_ordering_info_present_flag; BS_Begin(); Get_S1 (4, vps_video_parameter_set_id, "vps_video_parameter_set_id"); if (MustParse_VPS_SPS_PPS_FromFlv) { BS_End(); Skip_XX(Element_Size-Element_Offset, "Data"); //Creating Data video_parameter_sets_creating_data(vps_video_parameter_set_id, {}, 0, {}); //TODO: check which code is intended here return; } Get_SB ( vps_base_layer_internal_flag, "vps_base_layer_internal_flag"); Skip_SB( "vps_base_layer_available_flag"); Get_S1 (6, vps_max_layers_minus1, "vps_max_layers_minus1"); if (vps_max_layers_minus1==63) { Param_Info1("(Not supported)"); RiskCalculationN++; RiskCalculationD++; BS_End(); return; } Get_S1 (3, vps_max_sub_layers_minus1, "vps_max_sub_layers_minus1"); if (vps_max_sub_layers_minus1>6) { Trusted_IsNot("vps_max_sub_layers_minus1 not valid"); RiskCalculationN++; RiskCalculationD++; BS_End(); return; //Problem, not valid } Get_SB ( vps_temporal_id_nesting_flag, "vps_temporal_id_nesting_flag"); //if (vps_max_sub_layers_minus1==0 && !vps_temporal_id_nesting_flag) //{ // Trusted_IsNot("vps_temporal_id_nesting_flag not valid"); // BS_End(); // return; //Problem, not valid //} Skip_S2(16, "vps_reserved_0xffff_16bits"); ps.resize(1); profile_tier_level(ps[0], true, vps_max_sub_layers_minus1); Get_SB ( vps_sub_layer_ordering_info_present_flag, "vps_sub_layer_ordering_info_present_flag"); for (int32u SubLayerPos=(vps_sub_layer_ordering_info_present_flag?0:vps_max_sub_layers_minus1); SubLayerPos<=vps_max_sub_layers_minus1; SubLayerPos++) { Element_Begin1("SubLayer"); Skip_UE( "vps_max_dec_pic_buffering_minus1"); Skip_UE( "vps_max_num_reorder_pics"); Skip_UE( "vps_max_latency_increase_plus1"); Element_End0(); } Get_S1 ( 6, vps_max_layer_id, "vps_max_layer_id"); Get_UE ( vps_num_layer_sets_minus1, "vps_num_layer_sets_minus1"); if (vps_num_layer_sets_minus1>=1024) { Trusted_IsNot("vps_num_layer_sets_minus1 not valid"); RiskCalculationN++; RiskCalculationD++; BS_End(); return; //Problem, not valid } for (int32u LayerSetPos=1; LayerSetPos<=vps_num_layer_sets_minus1; LayerSetPos++) for (int8u LayerId=0; LayerId<=vps_max_layer_id; LayerId++) Skip_SB( "layer_id_included_flag"); TEST_SB_SKIP( "vps_timing_info_present_flag"); int32u vps_time_scale, vps_num_hrd_parameters; Skip_S4(32, "vps_num_units_in_tick"); Get_S4 (32, vps_time_scale, "vps_time_scale"); if (vps_time_scale==0) { Trusted_IsNot("vps_time_scale not valid"); RiskCalculationN++; RiskCalculationD++; Element_End0(); BS_End(); return; //Problem, not valid } TEST_SB_SKIP( "vps_poc_proportional_to_timing_flag"); Skip_UE( "vps_num_ticks_poc_diff_one_minus1"); TEST_SB_END(); Get_UE ( vps_num_hrd_parameters, "vps_num_hrd_parameters"); if (vps_num_hrd_parameters>1024) { Trusted_IsNot("vps_num_hrd_parameters not valid"); RiskCalculationN++; RiskCalculationD++; vps_num_hrd_parameters=0; } for (int32u HrdPos=0; HrdPos=1024) Trusted_IsNot("hrd_layer_set_idx not valid"); if (HrdPos) Get_SB (cprms_present_flag, "cprms_present_flag"); else cprms_present_flag=true; hrd_parameters(cprms_present_flag, vps_max_sub_layers_minus1, xxL_Common, NAL, VCL); delete xxL_Common; xxL_Common=NULL; //TODO: keep VPS hrd_parameters delete NAL; NAL=NULL; delete VCL; VCL=NULL; } TEST_SB_END(); vector view_id_val; TESTELSE_SB_SKIP( "vps_extension_flag"); int8u view_id_len; bool splitting_flag, vps_nuh_layer_id_present_flag; for (auto Bits=Data_BS_Remain()%8; Bits--; Bits) Mark_1(); if (vps_max_layers_minus1 && vps_base_layer_internal_flag) { ps.resize(ps.size()+1); profile_tier_level(ps.back(), false, vps_max_sub_layers_minus1); } Get_SB (splitting_flag, "splitting_flag"); int NumScalabilityTypes=0; bool scalability_mask_flag[16]; for (int i=0; i<16; i++) { Get_SB (scalability_mask_flag[i], "scalability_mask_flag"); NumScalabilityTypes+=scalability_mask_flag[i]; } int8u dimension_id_len_minus1[16]; for (int i=0; i<(NumScalabilityTypes-splitting_flag); i++) { Get_S1 (3, dimension_id_len_minus1[i], "dimension_id_len_minus1"); if (dimension_id_len_minus1[i]>=6) { Param_Info1("dimension_id_len_minus1 not valid"); RiskCalculationN++; RiskCalculationD++; BS_End(); return; } } Get_SB (vps_nuh_layer_id_present_flag, "vps_nuh_layer_id_present_flag"); auto MaxLayersMinus1=vps_max_layers_minus1>62?62:vps_max_layers_minus1; int8u dimension_id[64][16]; int8u layer_id_in_nuh[64]; if (!splitting_flag) for (int j=0; j 0) { auto newViewFlag = 1; for (int j = 0; j < i; j++) if (ViewOrderIdx[lId] == ViewOrderIdx[layer_id_in_nuh[j]]) newViewFlag = 0; NumViews += newViewFlag; } } if (view_id_len) { view_id_val.resize(64, -1); for (int i=0; i 1) Get_UE (num_add_layer_sets, "num_add_layer_sets"); else num_add_layer_sets=0; vector NumLayersInIdList; vector > LayerSetLayerIdList; vector > highest_layer_idx_plus1List; highest_layer_idx_plus1List.resize(num_add_layer_sets); for (int i = 0; i < num_add_layer_sets; i++) { highest_layer_idx_plus1List[i].reserve(NumIndependentLayers); highest_layer_idx_plus1List[i].push_back(0); // Unused? for (int j = 1; j < NumIndependentLayers; j++) { int32u highest_layer_idx_plus1; Get_S4 (ceil(log2(NumLayersInTreePartition[j] + 1)), highest_layer_idx_plus1, "highest_layer_idx_plus1"); highest_layer_idx_plus1List[i].push_back(highest_layer_idx_plus1); } } for (int i = 0; i < num_add_layer_sets; i++) { int32u layerNum = 0; auto lsIdx = vps_num_layer_sets_minus1 + 1 + i; for (int8u treeIdx = 1; treeIdx < NumIndependentLayers; treeIdx++) { for (int8u layerCnt = 0; layerCnt < highest_layer_idx_plus1List[i][treeIdx]; layerCnt++) { if (LayerSetLayerIdList.size() <= lsIdx) LayerSetLayerIdList.resize(lsIdx + 1); if (LayerSetLayerIdList[lsIdx].size() <= layerNum) LayerSetLayerIdList[lsIdx].resize(layerNum + 1); LayerSetLayerIdList[lsIdx][layerNum++] = TreePartitionLayerIdList[treeIdx][layerCnt]; } } if (NumLayersInIdList.size() <= lsIdx) NumLayersInIdList.resize(lsIdx + 1); NumLayersInIdList[lsIdx] = layerNum; } TEST_SB_SKIP( "vps_sub_layers_max_minus1_present_flag") for (int i = 0; i <= MaxLayersMinus1; i++) Skip_S1(3, "sub_layers_vps_max_minus1["); TEST_SB_END(); TEST_SB_SKIP( "max_tid_ref_present_flag") for (int i = 0; i <= MaxLayersMinus1; i++) for (int j = i + 1; j <= MaxLayersMinus1; j++) Skip_S1(3, "max_tid_il_ref_pics_plus1["); TEST_SB_END(); Skip_SB( "default_ref_layers_active_flag"); int32u vps_num_profile_tier_level_minus1; Get_UE(vps_num_profile_tier_level_minus1, "vps_num_profile_tier_level_minus1"); for (int i = vps_base_layer_internal_flag ? 2 : 1; i <= vps_num_profile_tier_level_minus1; i++) { bool vps_profile_present_flag; Get_SB(vps_profile_present_flag, "vps_profile_present_flag"); ps.resize(ps.size()+1); profile_tier_level(ps.back(), vps_profile_present_flag, vps_max_sub_layers_minus1); } auto NumLayerSets = vps_num_layer_sets_minus1 + 1 + num_add_layer_sets; int32u num_add_olss; int8u default_output_layer_idc; if (NumLayerSets > 1) { Get_UE (num_add_olss, "num_add_olss"); Get_S1 (2, default_output_layer_idc, "default_output_layer_idc"); } else { num_add_olss = 0; } Skip_BS(Data_BS_Remain(), "(Not parsed)"); TESTELSE_SB_ELSE( "vps_extension_flag"); rbsp_trailing_bits(); TESTELSE_SB_END(); BS_End(); FILLING_BEGIN_PRECISE(); //Creating Data video_parameter_sets_creating_data(vps_video_parameter_set_id, ps, vps_max_sub_layers_minus1, view_id_val); FILLING_END(); } //--------------------------------------------------------------------------- // Packet "33" void File_Hevc::seq_parameter_set() { Element_Name("seq_parameter_set"); //Parsing profile_tier_level_struct p; seq_parameter_set_struct::vui_parameters_struct* vui_parameters_Item=NULL; int32u sps_seq_parameter_set_id, chroma_format_idc, pic_width_in_luma_samples, pic_height_in_luma_samples, bit_depth_luma_minus8, bit_depth_chroma_minus8, log2_max_pic_order_cnt_lsb_minus4, num_short_term_ref_pic_sets; int32u conf_win_left_offset=0, conf_win_right_offset=0, conf_win_top_offset=0, conf_win_bottom_offset=0, sps_max_num_reorder_pics=0; int8u video_parameter_set_id, max_sub_layers_minus1, sps_ext_or_max_sub_layers_minus1; bool separate_colour_plane_flag=false, sps_sub_layer_ordering_info_present_flag; BS_Begin(); Get_S1 (4, video_parameter_set_id, "sps_video_parameter_set_id"); std::vector::iterator video_parameter_set_Item; if (video_parameter_set_id >= video_parameter_sets.size() || (*(video_parameter_set_Item = video_parameter_sets.begin() + video_parameter_set_id)) == NULL) { //Not yet present Skip_BS(Data_BS_Remain(), "Data (video_parameter_set is missing)"); BS_End(); RiskCalculationN++; RiskCalculationD++; return; } if (nuh_layer_id) { const auto vps_max_sub_layers_minus1 = (*video_parameter_set_Item)->vps_max_sub_layers_minus1; Get_S1 (3, sps_ext_or_max_sub_layers_minus1, "sps_ext_or_max_sub_layers_minus1"); max_sub_layers_minus1=sps_ext_or_max_sub_layers_minus1 == 7 ? vps_max_sub_layers_minus1 : sps_ext_or_max_sub_layers_minus1; } else { sps_ext_or_max_sub_layers_minus1=0; Get_S1 (3, max_sub_layers_minus1, "sps_max_sub_layers_minus1"); } auto MultiLayerExtSpsFlag=(nuh_layer_id && sps_ext_or_max_sub_layers_minus1==7); if (MultiLayerExtSpsFlag) { p.profile_space=-1; p.tier_flag=true; p.profile_idc=-1; p.level_idc=-1; } else { Skip_SB( "sps_temporal_id_nesting_flag"); profile_tier_level(p, true, max_sub_layers_minus1); } Get_UE ( sps_seq_parameter_set_id, "sps_seq_parameter_set_id"); if (MustParse_VPS_SPS_PPS_FromFlv) { BS_End(); Skip_XX(Element_Size-Element_Offset, "Data"); //Creating Data if (sps_seq_parameter_set_id>=seq_parameter_sets.size()) seq_parameter_sets.resize(sps_seq_parameter_set_id+1); std::vector::iterator Data_Item=seq_parameter_sets.begin()+sps_seq_parameter_set_id; delete *Data_Item; *Data_Item=new seq_parameter_set_struct( 0, NULL, //TODO: check which code is intended here profile_tier_level_struct().Clear(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); //NextCode NextCode_Clear(); NextCode_Add(34); //Autorisation of other streams Streams[34].Searching_Payload=true; //pic_parameter_set return; } if (MultiLayerExtSpsFlag) { TEST_SB_SKIP( "update_rep_format_flag"); Skip_S1(1, "sps_rep_format_idx"); TEST_SB_END(); chroma_format_idc=-1; pic_width_in_luma_samples=-1; pic_height_in_luma_samples=-1; bit_depth_luma_minus8=-1; bit_depth_chroma_minus8=-1; } else { Get_UE ( chroma_format_idc, "chroma_format_idc"); Param_Info1(Hevc_chroma_format_idc((int8u)chroma_format_idc)); if (chroma_format_idc>=4) { Trusted_IsNot("chroma_format_idc not valid"); RiskCalculationN++; RiskCalculationD++; BS_End(); return; //Problem, not valid } if (chroma_format_idc==3) Get_SB (separate_colour_plane_flag, "separate_colour_plane_flag"); Get_UE ( pic_width_in_luma_samples, "pic_width_in_luma_samples"); Get_UE ( pic_height_in_luma_samples, "pic_height_in_luma_samples"); TEST_SB_SKIP( "conformance_window_flag"); Get_UE (conf_win_left_offset, "conf_win_left_offset"); Get_UE (conf_win_right_offset, "conf_win_right_offset"); Get_UE (conf_win_top_offset, "conf_win_top_offset"); Get_UE (conf_win_bottom_offset, "conf_win_bottom_offset"); TEST_SB_END(); Get_UE ( bit_depth_luma_minus8, "bit_depth_luma_minus8"); if (bit_depth_luma_minus8>6) { Trusted_IsNot("bit_depth_luma_minus8 not valid"); RiskCalculationN++; RiskCalculationD++; return; //Problem, not valid } Get_UE ( bit_depth_chroma_minus8, "bit_depth_chroma_minus8"); if (bit_depth_chroma_minus8>6) { Trusted_IsNot("bit_depth_chroma_minus8 not valid"); RiskCalculationN++; RiskCalculationD++; return; //Problem, not valid } } Get_UE ( log2_max_pic_order_cnt_lsb_minus4, "log2_max_pic_order_cnt_lsb_minus4"); if (log2_max_pic_order_cnt_lsb_minus4>12) { Trusted_IsNot("log2_max_pic_order_cnt_lsb_minus4 not valid"); RiskCalculationN++; RiskCalculationD++; return; //Problem, not valid } if (!MultiLayerExtSpsFlag) { Get_SB ( sps_sub_layer_ordering_info_present_flag, "sps_sub_layer_ordering_info_present_flag"); for (int32u SubLayerPos = (sps_sub_layer_ordering_info_present_flag ? 0 : max_sub_layers_minus1); SubLayerPos <= max_sub_layers_minus1; SubLayerPos++) { Element_Begin1("SubLayer"); Skip_UE( "sps_max_dec_pic_buffering_minus1"); Get_UE (sps_max_num_reorder_pics, "sps_max_num_reorder_pics"); Skip_UE( "sps_max_latency_increase_plus1"); Element_End0(); } } Skip_UE( "log2_min_luma_coding_block_size_minus3"); Skip_UE( "log2_diff_max_min_luma_coding_block_size"); Skip_UE( "log2_min_transform_block_size_minus2"); Skip_UE( "log2_diff_max_min_transform_block_size"); Skip_UE( "max_transform_hierarchy_depth_inter"); Skip_UE( "max_transform_hierarchy_depth_intra"); TEST_SB_SKIP( "scaling_list_enabled_flag"); bool sps_infer_scaling_list_flag = false; if (MultiLayerExtSpsFlag) Get_SB (sps_infer_scaling_list_flag, "sps_infer_scaling_list_flag"); if (sps_infer_scaling_list_flag) Skip_S1 (6, "sps_scaling_list_ref_layer_id"); else { TEST_SB_SKIP( "sps_scaling_list_data_present_flag"); scaling_list_data(); TEST_SB_END(); } TEST_SB_END(); Skip_SB( "amp_enabled_flag"); Skip_SB( "sample_adaptive_offset_enabled_flag"); TEST_SB_SKIP( "pcm_enabled_flag"); Element_Begin1("pcm"); Skip_S1(4, "pcm_sample_bit_depth_luma_minus1"); Skip_S1(4, "pcm_sample_bit_depth_chroma_minus1"); Skip_UE( "log2_min_pcm_luma_coding_block_size_minus3"); Skip_UE( "log2_diff_max_min_pcm_luma_coding_block_size"); Skip_SB( "pcm_loop_filter_disabled_flag"); Element_End0(); TEST_SB_END(); Get_UE ( num_short_term_ref_pic_sets, "num_short_term_ref_pic_sets"); if (num_short_term_ref_pic_sets>64) { BS_End(); Trusted_IsNot("num_short_term_ref_pic_sets not valid"); RiskCalculationN++; RiskCalculationD++; return; //Problem, not valid } short_term_ref_pic_sets((int8u)num_short_term_ref_pic_sets); TEST_SB_SKIP( "long_term_ref_pics_present_flag"); Element_Begin1("long_term_ref_pics"); int32u num_long_term_ref_pics_sps; Get_UE (num_long_term_ref_pics_sps, "num_long_term_ref_pics_sps"); for (int32u long_term_ref_pics_sps_pos=0; long_term_ref_pics_sps_pos=seq_parameter_sets.size()) seq_parameter_sets.resize(sps_seq_parameter_set_id+1); std::vector::iterator Data_Item=seq_parameter_sets.begin()+sps_seq_parameter_set_id; if (!MustParse_VPS_SPS_PPS_FromLhvc || !*Data_Item) { delete *Data_Item; *Data_Item=new seq_parameter_set_struct( nuh_layer_id, vui_parameters_Item, p, pic_width_in_luma_samples, pic_height_in_luma_samples, conf_win_left_offset, conf_win_right_offset, conf_win_top_offset, conf_win_bottom_offset, (int8u)video_parameter_set_id, (int8u)chroma_format_idc, separate_colour_plane_flag, (int8u)log2_max_pic_order_cnt_lsb_minus4, (int8u)bit_depth_luma_minus8, (int8u)bit_depth_chroma_minus8, (int8u)sps_max_num_reorder_pics ); } //NextCode NextCode_Clear(); NextCode_Add(34); //Autorisation of other streams Streams[34].Searching_Payload=true; //pic_parameter_set //Computing values (for speed) size_t MaxNumber=(int32u)std::pow(2.0, (int)((*Data_Item)->log2_max_pic_order_cnt_lsb_minus4 + 4)); // TODO /* switch (Data_Item_New->pic_order_cnt_type) { case 0 : MaxNumber=Data_Item_New->MaxPicOrderCntLsb; break; case 1 : case 2 : MaxNumber=Data_Item_New->MaxFrameNum*2; break; default: MaxNumber = 0; } */ if (MaxNumber>TemporalReferences_Reserved) { TemporalReferences.resize(4*MaxNumber); TemporalReferences_Reserved=MaxNumber; } FILLING_ELSE(); delete vui_parameters_Item; //vui_parameters_Item=NULL; FILLING_END(); } //--------------------------------------------------------------------------- // Packet "34" void File_Hevc::pic_parameter_set() { Element_Name("pic_parameter_set"); //Parsing int32u pps_pic_parameter_set_id, pps_seq_parameter_set_id, num_ref_idx_l0_default_active_minus1, num_ref_idx_l1_default_active_minus1; int8u num_extra_slice_header_bits; bool tiles_enabled_flag, dependent_slice_segments_enabled_flag; BS_Begin(); Get_UE ( pps_pic_parameter_set_id, "pps_pic_parameter_set_id"); if (pps_pic_parameter_set_id>=64) { Trusted_IsNot("pic_parameter_set_id not valid"); BS_End(); RiskCalculationN++; RiskCalculationD++; return; //Problem, not valid } Get_UE ( pps_seq_parameter_set_id, "pps_seq_parameter_set_id"); if (pps_seq_parameter_set_id>=16) { Trusted_IsNot("seq_parameter_set_id not valid"); BS_End(); RiskCalculationN++; RiskCalculationD++; return; //Problem, not valid } //std::vector::iterator seq_parameter_set_Item; if (pps_seq_parameter_set_id>=seq_parameter_sets.size() || (*(seq_parameter_sets.begin()+pps_seq_parameter_set_id))==NULL) //(seq_parameter_set_Item=seq_parameter_sets.begin()+pps_seq_parameter_set_id) not usd for the moment { //Not yet present Skip_BS(Data_BS_Remain(), "Data (seq_parameter_set is missing)"); BS_End(); RiskCalculationN++; RiskCalculationD++; return; } if (MustParse_VPS_SPS_PPS_FromFlv) { BS_End(); Skip_XX(Element_Size-Element_Offset, "Data"); //Filling if (pps_pic_parameter_set_id>=pic_parameter_sets.size()) pic_parameter_sets.resize(pps_pic_parameter_set_id+1); std::vector::iterator pic_parameter_sets_Item=pic_parameter_sets.begin()+pps_pic_parameter_set_id; delete *pic_parameter_sets_Item; *pic_parameter_sets_Item=new pic_parameter_set_struct( 0, 0, 0, 0, false ); //NextCode NextCode_Clear(); //Autorisation of other streams Streams[ 0].Searching_Payload=true; //slice_segment_layer Streams[ 1].Searching_Payload=true; //slice_segment_layer Streams[ 2].Searching_Payload=true; //slice_segment_layer Streams[ 3].Searching_Payload=true; //slice_segment_layer Streams[ 4].Searching_Payload=true; //slice_layer Streams[ 5].Searching_Payload=true; //slice_layer Streams[ 6].Searching_Payload=true; //slice_layer Streams[ 7].Searching_Payload=true; //slice_layer Streams[ 8].Searching_Payload=true; //slice_layer Streams[ 9].Searching_Payload=true; //slice_layer Streams[16].Searching_Payload=true; //slice_segment_layer Streams[17].Searching_Payload=true; //slice_segment_layer Streams[18].Searching_Payload=true; //slice_segment_layer Streams[19].Searching_Payload=true; //slice_segment_layer Streams[20].Searching_Payload=true; //slice_segment_layer Streams[21].Searching_Payload=true; //slice_segment_layer return; } Get_SB ( dependent_slice_segments_enabled_flag, "dependent_slice_segments_enabled_flag"); Skip_SB( "output_flag_present_flag"); Get_S1 (3, num_extra_slice_header_bits, "num_extra_slice_header_bits"); Skip_SB( "sign_data_hiding_flag"); Skip_SB( "cabac_init_present_flag"); Get_UE ( num_ref_idx_l0_default_active_minus1, "num_ref_idx_l0_default_active_minus1"); Get_UE ( num_ref_idx_l1_default_active_minus1, "num_ref_idx_l1_default_active_minus1"); Skip_SE( "init_qp_minus26"); Skip_SB( "constrained_intra_pred_flag"); Skip_SB( "transform_skip_enabled_flag"); TEST_SB_SKIP( "cu_qp_delta_enabled_flag"); Skip_UE( "diff_cu_qp_delta_depth"); TEST_SB_END(); Skip_SE( "pps_cb_qp_offset"); Skip_SE( "pps_cr_qp_offset"); Skip_SB( "pps_slice_chroma_qp_offsets_present_flag"); Skip_SB( "weighted_pred_flag"); Skip_SB( "weighted_bipred_flag"); Skip_SB( "transquant_bypass_enable_flag"); Get_SB ( tiles_enabled_flag, "tiles_enabled_flag"); Skip_SB( "entropy_coding_sync_enabled_flag"); if (tiles_enabled_flag) { Element_Begin1("tiles"); int32u num_tile_columns_minus1, num_tile_rows_minus1; bool uniform_spacing_flag; Get_UE ( num_tile_columns_minus1, "num_tile_columns_minus1"); Get_UE ( num_tile_rows_minus1, "num_tile_rows_minus1"); Get_SB ( uniform_spacing_flag, "uniform_spacing_flag"); if (!uniform_spacing_flag) { for (int32u tile_pos=0; tile_pos=pic_parameter_sets.size()) pic_parameter_sets.resize(pps_pic_parameter_set_id+1); std::vector::iterator pic_parameter_sets_Item=pic_parameter_sets.begin()+pps_pic_parameter_set_id; if (!MustParse_VPS_SPS_PPS_FromLhvc || !*pic_parameter_sets_Item) { delete *pic_parameter_sets_Item; *pic_parameter_sets_Item = new pic_parameter_set_struct( (int8u)pps_seq_parameter_set_id, (int8u)num_ref_idx_l0_default_active_minus1, (int8u)num_ref_idx_l1_default_active_minus1, num_extra_slice_header_bits, dependent_slice_segments_enabled_flag ); } //Autorisation of other streams //if (!seq_parameter_sets.empty()) //{ // for (int8u Pos=0x01; Pos<=0x06; Pos++) // { // Streams[Pos].Searching_Payload=true; //Coded slice... // if (Streams[0x08].ShouldDuplicate) // Streams[Pos].ShouldDuplicate=true; // } //} //NextCode NextCode_Clear(); //Autorisation of other streams Streams[ 0].Searching_Payload=true; //slice_segment_layer Streams[ 1].Searching_Payload=true; //slice_segment_layer Streams[ 2].Searching_Payload=true; //slice_segment_layer Streams[ 3].Searching_Payload=true; //slice_segment_layer Streams[ 4].Searching_Payload=true; //slice_layer Streams[ 5].Searching_Payload=true; //slice_layer Streams[ 6].Searching_Payload=true; //slice_layer Streams[ 7].Searching_Payload=true; //slice_layer Streams[ 8].Searching_Payload=true; //slice_layer Streams[ 9].Searching_Payload=true; //slice_layer Streams[16].Searching_Payload=true; //slice_segment_layer Streams[17].Searching_Payload=true; //slice_segment_layer Streams[18].Searching_Payload=true; //slice_segment_layer Streams[19].Searching_Payload=true; //slice_segment_layer Streams[20].Searching_Payload=true; //slice_segment_layer Streams[21].Searching_Payload=true; //slice_segment_layer FILLING_END(); } //--------------------------------------------------------------------------- // Packet "35" void File_Hevc::access_unit_delimiter() { Element_Name("access_unit_delimiter"); //Parsing BS_Begin(); Info_S1( 3, pic_type, "pic_type"); Param_Info1(Hevc_pic_type[pic_type]); Mark_1(); BS_End(); FILLING_BEGIN_PRECISE(); FILLING_ELSE(); RiskCalculationN++; FILLING_END(); RiskCalculationD++; } //--------------------------------------------------------------------------- // Packet "36" void File_Hevc::end_of_seq() { Element_Name("end_of_seq"); } //--------------------------------------------------------------------------- // Packet "37" void File_Hevc::end_of_bitstream() { Element_Name("end_of_bitstream"); } //--------------------------------------------------------------------------- // Packet "38" void File_Hevc::filler_data() { Element_Name("filler_data"); //Parsing Skip_XX(Element_Size, "ff_bytes"); } //--------------------------------------------------------------------------- // Packet "39" or "40 void File_Hevc::sei() { Element_Name("sei"); //Parsing int32u seq_parameter_set_id=(int32u)-1; while(Element_Offset+1Element_Size) { Buffer_Buggy=Buffer; Buffer_Offset_Buggy=Buffer_Offset; Element_Size_Buggy=Element_Size; Element_Size=Element_Offset+payloadSize; Buffer=new int8u[(size_t)Element_Size]; Buffer_Offset=0; memcpy((void*)Buffer, Buffer_Buggy+Buffer_Offset, (size_t)Element_Size_Buggy); memset((void*)(Buffer+(size_t)Element_Size_Buggy), 0x00, (size_t)(Element_Size-Element_Size_Buggy)); //Last 0x00 bytes are discarded, we recreate them } else Buffer_Buggy=NULL; int64u Element_Offset_Save=Element_Offset+payloadSize; if (Element_Offset_Save>Element_Size) { Trusted_IsNot("Wrong size"); Skip_XX(Element_Size-Element_Offset, "unknown"); return; } int64u Element_Size_Save=Element_Size; Element_Size=Element_Offset_Save; switch (payloadType) { case 0 : sei_message_buffering_period(seq_parameter_set_id, payloadSize); break; case 1 : sei_message_pic_timing(seq_parameter_set_id, payloadSize); break; case 4 : sei_message_user_data_registered_itu_t_t35(); break; case 5 : sei_message_user_data_unregistered(payloadSize); break; case 6 : sei_message_recovery_point(); break; //case 32 : sei_message_mainconcept(payloadSize); break; case 129 : sei_message_active_parameter_sets(); break; case 132 : sei_message_decoded_picture_hash(payloadSize); break; case 136 : sei_time_code(); break; case 137 : sei_message_mastering_display_colour_volume(); break; case 144 : sei_message_light_level(); break; case 147 : sei_alternative_transfer_characteristics(); break; case 176 : three_dimensional_reference_displays_info(payloadSize); break; default : Element_Info1("unknown"); Skip_XX(payloadSize, "data"); } Element_Offset=Element_Offset_Save; //Positionning in the right place. Element_Size=Element_Size_Save; //Positionning in the right place. //Manage buggy files not having final bit stop if (Buffer_Buggy) { delete[] Buffer; Buffer=Buffer_Buggy; Buffer_Offset=Buffer_Offset_Buggy; Element_Size=Element_Size_Buggy; } } //--------------------------------------------------------------------------- // SEI - 0 void File_Hevc::sei_message_buffering_period(int32u &seq_parameter_set_id, int32u payloadSize) { Element_Info1("buffering_period"); //Parsing if (Element_Offset==Element_Size) return; //Nothing to do BS_Begin(); Get_UE (seq_parameter_set_id, "seq_parameter_set_id"); std::vector::iterator seq_parameter_set_Item; if (seq_parameter_set_id>=seq_parameter_sets.size() || (*(seq_parameter_set_Item=seq_parameter_sets.begin()+seq_parameter_set_id))==NULL) { //Not yet present Skip_BS(Data_BS_Remain(), "Data (seq_parameter_set is missing)"); BS_End(); RiskCalculationN++; RiskCalculationD++; return; } bool sub_pic_hrd_params_present_flag=false; //Default bool irap_cpb_params_present_flag=((*seq_parameter_set_Item)->vui_parameters && (*seq_parameter_set_Item)->vui_parameters->xxL_Common)?(*seq_parameter_set_Item)->vui_parameters->xxL_Common->sub_pic_hrd_params_present_flag:false; if (!sub_pic_hrd_params_present_flag) Get_SB (irap_cpb_params_present_flag, "irap_cpb_params_present_flag"); int8u au_cpb_removal_delay_length_minus1=((*seq_parameter_set_Item)->vui_parameters && (*seq_parameter_set_Item)->vui_parameters->xxL_Common)?(*seq_parameter_set_Item)->vui_parameters->xxL_Common->au_cpb_removal_delay_length_minus1:23; int8u dpb_output_delay_length_minus1=((*seq_parameter_set_Item)->vui_parameters && (*seq_parameter_set_Item)->vui_parameters->xxL_Common)?(*seq_parameter_set_Item)->vui_parameters->xxL_Common->dpb_output_delay_length_minus1:23; if (irap_cpb_params_present_flag) { Skip_S4(au_cpb_removal_delay_length_minus1+1, "cpb_delay_offset"); Skip_S4(dpb_output_delay_length_minus1+1, "dpb_delay_offset"); } Skip_SB( "concatenation_flag"); Skip_S4(au_cpb_removal_delay_length_minus1+1, "au_cpb_removal_delay_delta_minus1"); if ((*seq_parameter_set_Item)->NalHrdBpPresentFlag()) sei_message_buffering_period_xxl((*seq_parameter_set_Item)->vui_parameters?(*seq_parameter_set_Item)->vui_parameters->xxL_Common:NULL, irap_cpb_params_present_flag, (*seq_parameter_set_Item)->vui_parameters->NAL); if ((*seq_parameter_set_Item)->VclHrdBpPresentFlag()) sei_message_buffering_period_xxl((*seq_parameter_set_Item)->vui_parameters?(*seq_parameter_set_Item)->vui_parameters->xxL_Common:NULL, irap_cpb_params_present_flag, (*seq_parameter_set_Item)->vui_parameters->VCL); BS_End(); } void File_Hevc::sei_message_buffering_period_xxl(seq_parameter_set_struct::vui_parameters_struct::xxl_common* xxL_Common, bool irap_cpb_params_present_flag, seq_parameter_set_struct::vui_parameters_struct::xxl* xxl) { if (xxL_Common==NULL || xxl==NULL) { //Problem? Skip_BS(Data_BS_Remain(), "Problem?"); return; } for (int32u SchedSelIdx=0; SchedSelIdxSchedSel.size(); SchedSelIdx++) { //Get_S4 (xxl->SchedSel[SchedSelIdx].initial_cpb_removal_delay_length_minus1+1, xxl->SchedSel[SchedSelIdx].initial_cpb_removal_delay, "initial_cpb_removal_delay"); Param_Info2(xxl->SchedSel[SchedSelIdx].initial_cpb_removal_delay/90, " ms"); //Get_S4 (xxl->SchedSel[SchedSelIdx].initial_cpb_removal_delay_length_minus1+1, xxl->SchedSel[SchedSelIdx].initial_cpb_removal_delay_offset, "initial_cpb_removal_delay_offset"); Param_Info2(xxl->SchedSel[SchedSelIdx].initial_cpb_removal_delay_offset/90, " ms"); Info_S4 (xxL_Common->initial_cpb_removal_delay_length_minus1+1, initial_cpb_removal_delay, "initial_cpb_removal_delay"); Param_Info2(initial_cpb_removal_delay/90, " ms"); Info_S4 (xxL_Common->initial_cpb_removal_delay_length_minus1+1, initial_cpb_removal_delay_offset, "initial_cpb_removal_delay_offset"); Param_Info2(initial_cpb_removal_delay_offset/90, " ms"); if (xxL_Common->sub_pic_hrd_params_present_flag || irap_cpb_params_present_flag) { Info_S4 (xxL_Common->initial_cpb_removal_delay_length_minus1+1, initial_alt_cpb_removal_delay, "initial_alt_cpb_removal_delay"); Param_Info2(initial_alt_cpb_removal_delay/90, " ms"); Info_S4 (xxL_Common->initial_cpb_removal_delay_length_minus1+1, initial_alt_cpb_removal_delay_offset, "initial_alt_cpb_removal_delay_offset"); Param_Info2(initial_alt_cpb_removal_delay_offset/90, " ms"); } } } //--------------------------------------------------------------------------- // SEI - 1 void File_Hevc::sei_message_pic_timing(int32u &seq_parameter_set_id, int32u payloadSize) { Element_Info1("pic_timing"); //Testing if we can parsing it now. TODO: handle case seq_parameter_set_id is unknown (buffering of message, decoding in slice parsing) if (seq_parameter_set_id==(int32u)-1 && seq_parameter_sets.size()==1) seq_parameter_set_id=0; std::vector::iterator seq_parameter_set_Item; if (seq_parameter_set_id>=seq_parameter_sets.size() || (*(seq_parameter_set_Item=seq_parameter_sets.begin()+seq_parameter_set_id))==NULL) { //Not yet present Skip_BS(Data_BS_Remain(), "Data (seq_parameter_set is missing)"); return; } //Parsing BS_Begin(); if ((*seq_parameter_set_Item)->vui_parameters?(*seq_parameter_set_Item)->vui_parameters->frame_field_info_present_flag:((*seq_parameter_set_Item)->profile_tier_level_info.general_progressive_source_flag && (*seq_parameter_set_Item)->profile_tier_level_info.general_interlaced_source_flag)) { Skip_S1(4, "pic_struct"); Skip_S1(2, "source_scan_type"); Skip_SB( "duplicate_flag"); } if ((*seq_parameter_set_Item)->CpbDpbDelaysPresentFlag()) { int8u au_cpb_removal_delay_length_minus1=(*seq_parameter_set_Item)->vui_parameters->xxL_Common->au_cpb_removal_delay_length_minus1; int8u dpb_output_delay_length_minus1=(*seq_parameter_set_Item)->vui_parameters->xxL_Common->dpb_output_delay_length_minus1; bool sub_pic_hrd_params_present_flag=(*seq_parameter_set_Item)->vui_parameters->xxL_Common->sub_pic_hrd_params_present_flag; Skip_S4(au_cpb_removal_delay_length_minus1+1, "au_cpb_removal_delay_minus1"); Skip_S4(dpb_output_delay_length_minus1+1, "pic_dpb_output_delay"); if (sub_pic_hrd_params_present_flag) { int8u dpb_output_delay_du_length_minus1=(*seq_parameter_set_Item)->vui_parameters->xxL_Common->dpb_output_delay_du_length_minus1; Skip_S4(dpb_output_delay_du_length_minus1+1, "pic_dpb_output_du_delay"); } } BS_End(); } //--------------------------------------------------------------------------- // SEI - 4 void File_Hevc::sei_message_user_data_registered_itu_t_t35() { Element_Info1("user_data_registered_itu_t_t35"); int8u itu_t_t35_country_code; Get_B1(itu_t_t35_country_code, "itu_t_t35_country_code"); switch (itu_t_t35_country_code) { case 0xB5: sei_message_user_data_registered_itu_t_t35_B5(); break; // USA case 0x26: sei_message_user_data_registered_itu_t_t35_26(); break; // China } } //--------------------------------------------------------------------------- // SEI - 4 - USA void File_Hevc::sei_message_user_data_registered_itu_t_t35_B5() { int16u itu_t_t35_terminal_provider_code; Get_B2 (itu_t_t35_terminal_provider_code, "itu_t_t35_terminal_provider_code"); switch (itu_t_t35_terminal_provider_code) { case 0x0031: sei_message_user_data_registered_itu_t_t35_B5_0031(); break; case 0x003A: sei_message_user_data_registered_itu_t_t35_B5_003A(); break; case 0x003C: sei_message_user_data_registered_itu_t_t35_B5_003C(); break; } } //--------------------------------------------------------------------------- // SEI - 4 - USA - 0031 void File_Hevc::sei_message_user_data_registered_itu_t_t35_B5_0031() { int32u Identifier; Peek_B4(Identifier); switch (Identifier) { case 0x44544731 : sei_message_user_data_registered_itu_t_t35_B5_0031_DTG1(); return; case 0x47413934 : sei_message_user_data_registered_itu_t_t35_B5_0031_GA94(); return; default : if (Element_Size-Element_Offset) Skip_XX(Element_Size-Element_Offset, "Unknown"); } } //--------------------------------------------------------------------------- // SEI - 4 - USA - 0031 - DTG1 void File_Hevc::sei_message_user_data_registered_itu_t_t35_B5_0031_DTG1() { Element_Info1("Active Format Description"); //Parsing Skip_C4( "afd_identifier"); if (Element_Offsetvui_parameters && seq_parameter_set_Item->vui_parameters->aspect_ratio_info_present_flag) { //TODO: avoid duplicated code int32u Width = seq_parameter_set_Item->pic_width_in_luma_samples; int32u Height= seq_parameter_set_Item->pic_height_in_luma_samples; int8u chromaArrayType = seq_parameter_set_Item->ChromaArrayType(); if (chromaArrayType >= 4) chromaArrayType = 0; int32u CropUnitX=Hevc_SubWidthC [chromaArrayType]; int32u CropUnitY=Hevc_SubHeightC[chromaArrayType]; Width -=(seq_parameter_set_Item->conf_win_left_offset+seq_parameter_set_Item->conf_win_right_offset)*CropUnitX; Height-=(seq_parameter_set_Item->conf_win_top_offset +seq_parameter_set_Item->conf_win_bottom_offset)*CropUnitY; if (Height) { float64 PixelAspectRatio = 1; if (seq_parameter_set_Item->vui_parameters->aspect_ratio_idcvui_parameters->aspect_ratio_idc]; else if (seq_parameter_set_Item->vui_parameters->aspect_ratio_idc == 0xFF && seq_parameter_set_Item->vui_parameters->sar_height) PixelAspectRatio = ((float64) seq_parameter_set_Item->vui_parameters->sar_width) / seq_parameter_set_Item->vui_parameters->sar_height; auto DAR=Width*PixelAspectRatio/Height; if (DAR>=4.0/3.0*0.95 && DAR<4.0/3.0*1.05) DTG1_Parser.aspect_ratio_FromContainer=0; //4/3 if (DAR>=16.0/9.0*0.95 && DAR<16.0/9.0*1.05) DTG1_Parser.aspect_ratio_FromContainer=1; //16/9 } break; } } Open_Buffer_Init(&DTG1_Parser); DTG1_Parser.Format=File_AfdBarData::Format_A53_4_DTG1; Open_Buffer_Continue(&DTG1_Parser, Buffer+Buffer_Offset+(size_t)Element_Offset, Element_Size-Element_Offset); Merge(DTG1_Parser, Stream_Video, 0, 0); Element_Offset=Element_Size; } } //--------------------------------------------------------------------------- // SEI - 4 - USA - 0031 - GA94 void File_Hevc::sei_message_user_data_registered_itu_t_t35_B5_0031_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: sei_message_user_data_registered_itu_t_t35_B5_0031_GA94_03(); break; case 0x09: sei_message_user_data_registered_itu_t_t35_B5_0031_GA94_09(); break; default: Skip_XX(Element_Size - Element_Offset, "GA94_reserved_user_data"); } } //--------------------------------------------------------------------------- // SEI - 4 - USA - 0031 - GA94 - 03 void File_Hevc::sei_message_user_data_registered_itu_t_t35_B5_0031_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 delete TemporalReferences_DelayedElement; TemporalReferences_DelayedElement=new temporal_reference(); TemporalReferences_DelayedElement->GA94_03=new buffer_data(Buffer+Buffer_Offset+(size_t)Element_Offset,(size_t)(Element_Size-Element_Offset)); //Parsing Skip_XX(Element_Size-Element_Offset, "CC data"); #else //defined(MEDIAINFO_DTVCCTRANSPORT_YES) Skip_XX(Element_Size-Element_Offset, "DTVCC Transport data"); #endif //defined(MEDIAINFO_DTVCCTRANSPORT_YES) } void File_Hevc::sei_message_user_data_registered_itu_t_t35_B5_0031_GA94_03_Delayed(int32u seq_parameter_set_id) { // Skipping missing frames if (TemporalReferences_Max-TemporalReferences_Min>(size_t)(4*(seq_parameter_sets[seq_parameter_set_id]->sps_max_num_reorder_pics+3))) // max_num_ref_frames ref frame maximum { size_t TemporalReferences_Min_New=TemporalReferences_Max-4*(seq_parameter_sets[seq_parameter_set_id]->sps_max_num_reorder_pics+3); while (TemporalReferences_Min_New>TemporalReferences_Min && TemporalReferences[TemporalReferences_Min_New-1]) TemporalReferences_Min_New--; TemporalReferences_Min=TemporalReferences_Min_New; while (TemporalReferences[TemporalReferences_Min]==NULL) { TemporalReferences_Min++; if (TemporalReferences_Min>=TemporalReferences.size()) return; } } // Parsing captions while (TemporalReferences[TemporalReferences_Min] && TemporalReferences_Min+2*seq_parameter_sets[seq_parameter_set_id]->sps_max_num_reorder_picsFormat=File_DtvccTransport::Format_A53_4_GA94_03; } if (((File_DtvccTransport*)GA94_03_Parser)->AspectRatio==0) { float64 PixelAspectRatio=1; std::vector::iterator seq_parameter_set_Item=seq_parameter_sets.begin(); for (; seq_parameter_set_Item!=seq_parameter_sets.end(); ++seq_parameter_set_Item) if ((*seq_parameter_set_Item)) break; if (seq_parameter_set_Item!=seq_parameter_sets.end()) { if (((*seq_parameter_set_Item)->vui_parameters) && ((*seq_parameter_set_Item)->vui_parameters->aspect_ratio_info_present_flag)) { if ((*seq_parameter_set_Item)->vui_parameters->aspect_ratio_idcvui_parameters->aspect_ratio_idc]; else if ((*seq_parameter_set_Item)->vui_parameters->aspect_ratio_idc==0xFF && (*seq_parameter_set_Item)->vui_parameters->sar_height) PixelAspectRatio=((float64)(*seq_parameter_set_Item)->vui_parameters->sar_width)/(*seq_parameter_set_Item)->vui_parameters->sar_height; } const int32u Width =(*seq_parameter_set_Item)->pic_width_in_luma_samples; const int32u Height=(*seq_parameter_set_Item)->pic_height_in_luma_samples; if(Height) ((File_DtvccTransport*)GA94_03_Parser)->AspectRatio=Width*PixelAspectRatio/Height; } } if (GA94_03_Parser->PTS_DTS_Needed) { GA94_03_Parser->FrameInfo.PCR=FrameInfo.PCR; GA94_03_Parser->FrameInfo.PTS=FrameInfo.PTS; GA94_03_Parser->FrameInfo.DTS=FrameInfo.DTS; } #if MEDIAINFO_DEMUX if (TemporalReferences[TemporalReferences_Min]->GA94_03) { int8u Demux_Level_Save=Demux_Level; Demux_Level=8; //Ancillary Demux(TemporalReferences[TemporalReferences_Min]->GA94_03->Data, TemporalReferences[TemporalReferences_Min]->GA94_03->Size, ContentType_MainStream); Demux_Level=Demux_Level_Save; } Element_Code=Element_Code_Old; #endif //MEDIAINFO_DEMUX if (TemporalReferences[TemporalReferences_Min]->GA94_03) { #if defined(MEDIAINFO_EIA608_YES) || defined(MEDIAINFO_EIA708_YES) GA94_03_Parser->ServiceDescriptors=ServiceDescriptors; #endif Open_Buffer_Continue(GA94_03_Parser, TemporalReferences[TemporalReferences_Min]->GA94_03->Data, TemporalReferences[TemporalReferences_Min]->GA94_03->Size); } Element_End0(); #endif //defined(MEDIAINFO_DTVCCTRANSPORT_YES) //TemporalReferences_Min+=((seq_parameter_sets[seq_parameter_set_id]->frame_mbs_only_flag | !TemporalReferences[TemporalReferences_Min]->IsField)?2:1); TemporalReferences_Min++; } } //--------------------------------------------------------------------------- // SEI - 4 - USA - 0031 - GA94 - 09 - SMPTE ST 2094-10 static const char* Smpte209410_BlockNames[]= { nullptr, "Content Range", "Trim Pass", nullptr, nullptr, "Active Area", }; static const auto Smpte209410_BlockNames_Size=sizeof(Smpte209410_BlockNames)/sizeof(decltype(*Smpte209410_BlockNames)); void File_Hevc::sei_message_user_data_registered_itu_t_t35_B5_0031_GA94_09() { Element_Info1("SMPTE ST 2094-10"); int32u app_identifier, app_version; bool metadata_refresh_flag; vector ext_block_level_List; BS_Begin(); Get_UE(app_identifier, "app_identifier"); if (app_identifier!=1) return; Get_UE (app_version, "app_version"); if (!app_version) { Get_SB(metadata_refresh_flag, "metadata_refresh_flag"); if (metadata_refresh_flag) { int32u num_ext_blocks; Get_UE (num_ext_blocks, "num_ext_blocks"); if (num_ext_blocks) { auto Align=Data_BS_Remain()%8; if (Align) Skip_BS(Align, "dm_alignment_zero_bits"); for (int32u i=0; iData_BS_Remain()) { Element_End0(); Trusted_IsNot("Coherency"); break; } ext_block_length*=8; if (ext_block_length>Data_BS_Remain()) { Element_End0(); Trusted_IsNot("Coherency"); break; } auto End=Data_BS_Remain()-ext_block_length; ext_block_level_List.push_back(ext_block_level); switch (ext_block_level) { case 1: Skip_S2(12, "min_PQ"); Skip_S2(12, "max_PQ"); Skip_S2(12, "avg_PQ"); break; case 2: Skip_S2(12, "target_max_PQ"); Skip_S2(12, "trim_slope"); Skip_S2(12, "trim_offset"); Skip_S2(12, "trim_power"); Skip_S2(12, "trim_chroma_weight"); Skip_S2(12, "trim_saturation_gain"); Skip_S1( 3, "ms_weight"); break; case 3: Skip_S2(12, "min_PQ_offset"); Skip_S2(12, "max_PQ_offset"); Skip_S2(12, "avg_PQ_offset"); break; case 4: Skip_S2(12, "TF_PQ_mean"); Skip_S2(12, "TF_PQ_stdev"); break; case 5: Skip_S2(13, "active_area_left_offset"); Skip_S2(13, "active_area_right_offset"); Skip_S2(13, "active_area_top_offset"); Skip_S2(13, "active_area_bottom_offset"); break; } if (Data_BS_Remain()>End) { auto Align=Data_BS_Remain()-End; if (Align) Skip_BS(Align, Align>=8?"(Unknown)":"dm_alignment_zero_bits"); } Element_End0(); } } } auto Align=Data_BS_Remain()%8; if (Align) Skip_BS(Align, Align>=8?"(Unknown)":"dm_alignment_zero_bits"); BS_End(); } auto& HDR_Format=HDR[Video_HDR_Format][HdrFormat_SmpteSt209410]; if (HDR_Format.empty()) { HDR_Format=__T("SMPTE ST 2094-10"); FILLING_BEGIN(); HDR[Video_HDR_Format_Version][HdrFormat_SmpteSt209410].From_Number(app_version); FILLING_END(); } if (!Trusted_Get()) { Fill(Stream_Video, 0, "ConformanceErrors", 1, 10, true); Fill(Stream_Video, 0, "ConformanceErrors SMPTE_ST_2049_CVT", 1, 10, true); Fill(Stream_Video, 0, "ConformanceErrors SMPTE_ST_2049_CVT Coherency", "Bitstream parsing ran out of data to read before the end of the syntax was reached, most probably the bitstream is malformed", Unlimited, true, true); } } //--------------------------------------------------------------------------- // SEI - 4 - USA - 003A void File_Hevc::sei_message_user_data_registered_itu_t_t35_B5_003A() { int8u itu_t_t35_terminal_provider_oriented_code; Get_B1 (itu_t_t35_terminal_provider_oriented_code, "itu_t_t35_terminal_provider_oriented_code"); switch (itu_t_t35_terminal_provider_oriented_code) { case 0x00: sei_message_user_data_registered_itu_t_t35_B5_003A_00(); break; case 0x02: sei_message_user_data_registered_itu_t_t35_B5_003A_02(); break; } } //--------------------------------------------------------------------------- // SEI - 4 - USA - 003A - ETSI 103-433-1 void File_Hevc::sei_message_user_data_registered_itu_t_t35_B5_003A_00() { Element_Info1("SL-HDR message"); BS_Begin(); int8u sl_hdr_mode_value_minus1, sl_hdr_spec_major_version_idc, sl_hdr_spec_minor_version_idc; bool sl_hdr_cancel_flag; Get_S1 (4, sl_hdr_mode_value_minus1, "sl_hdr_mode_value_minus1"); Get_S1 (4, sl_hdr_spec_major_version_idc, "sl_hdr_spec_major_version_idc"); Get_S1 (7, sl_hdr_spec_minor_version_idc, "sl_hdr_spec_minor_version_idc"); Get_SB (sl_hdr_cancel_flag, "sl_hdr_cancel_flag"); int8u sl_hdr_payload_mode; int8u k_coefficient_value[3]; if (!sl_hdr_cancel_flag) { mastering_metadata_2086 Meta; bool coded_picture_info_present_flag, target_picture_info_present_flag, src_mdcv_info_present_flag; Skip_SB( "sl_hdr_persistence_flag"); Get_SB (coded_picture_info_present_flag, "coded_picture_info_present_flag"); Get_SB (target_picture_info_present_flag, "target_picture_info_present_flag"); Get_SB (src_mdcv_info_present_flag, "src_mdcv_info_present_flag"); Skip_SB( "sl_hdr_extension_present_flag"); Get_S1 (3, sl_hdr_payload_mode, "sl_hdr_payload_mode"); BS_End(); if (coded_picture_info_present_flag) { Skip_B1( "coded_picture_primaries"); Skip_B2( "coded_picture_max_luminance"); Skip_B2( "coded_picture_min_luminance"); } if (target_picture_info_present_flag) { Skip_B1( "target_picture_primaries"); Skip_B2( "target_picture_max_luminance"); Skip_B2( "target_picture_min_luminance"); } if (src_mdcv_info_present_flag) { int16u max, min; for (int8u i = 0; i < 3; i++) { Get_B2 (Meta.Primaries[i*2 ], "src_mdcv_primaries_x"); Get_B2 (Meta.Primaries[i*2+1], "src_mdcv_primaries_y"); } Get_B2 (Meta.Primaries[3*2 ], "src_mdcv_ref_white_x"); Get_B2 (Meta.Primaries[3*2+1], "src_mdcv_ref_white_y"); Get_B2 (max, "src_mdcv_max_mastering_luminance"); Get_B2 (min, "src_mdcv_min_mastering_luminance"); Meta.Luminance[0]=min; Meta.Luminance[1]=((int32u)max)*10000; } for (int8u i = 0; i < 4; i++) Skip_B2( "matrix_coefficient_value"); for (int8u i = 0; i < 2; i++) Skip_B2( "chroma_to_luma_injection"); for (int8u i = 0; i < 3; i++) Get_B1 (k_coefficient_value[i], "k_coefficient_value"); FILLING_BEGIN() auto& HDR_Format=HDR[Video_HDR_Format][HdrFormat_EtsiTs103433]; if (HDR_Format.empty()) { HDR_Format=__T("SL-HDR")+Ztring().From_Number(sl_hdr_mode_value_minus1+1); HDR[Video_HDR_Format_Version][HdrFormat_EtsiTs103433]=Ztring().From_Number(sl_hdr_spec_major_version_idc)+__T('.')+Ztring().From_Number(sl_hdr_spec_minor_version_idc); Get_MasteringDisplayColorVolume(HDR[Video_MasteringDisplay_ColorPrimaries][HdrFormat_EtsiTs103433], HDR[Video_MasteringDisplay_Luminance][HdrFormat_EtsiTs103433], Meta); auto& HDR_Format_Settings=HDR[Video_HDR_Format_Settings][HdrFormat_EtsiTs103433]; if (sl_hdr_payload_mode<2) HDR_Format_Settings=sl_hdr_payload_mode?__T("Table-based"):__T("Parameter-based"); else HDR_Format_Settings=__T("Payload Mode ") + Ztring().From_Number(sl_hdr_payload_mode); if (!sl_hdr_mode_value_minus1) HDR_Format_Settings+=k_coefficient_value[0]==0 && k_coefficient_value[1]==0 && k_coefficient_value[2]==0?__T(", non-constant"):__T(", constant"); EtsiTS103433 = __T("SL-HDR") + Ztring().From_Number(sl_hdr_mode_value_minus1 + 1); if (!sl_hdr_mode_value_minus1) EtsiTS103433 += k_coefficient_value[0] == 0 && k_coefficient_value[1] == 0 && k_coefficient_value[2] == 0 ? __T(" NCL") : __T(" CL"); EtsiTS103433 += __T(" specVersion=") + Ztring().From_Number(sl_hdr_spec_major_version_idc) + __T(".") + Ztring().From_Number(sl_hdr_spec_minor_version_idc); EtsiTS103433 += __T(" payloadMode=") + Ztring().From_Number(sl_hdr_payload_mode); } FILLING_END(); } else BS_End(); } //--------------------------------------------------------------------------- // SEI - 4 - USA - 003A - ETSI 103-433 void File_Hevc::sei_message_user_data_registered_itu_t_t35_B5_003A_02() { Element_Info1("SL-HDR information"); int8u ts_103_433_spec_version; BS_Begin(); Get_S1 (4, ts_103_433_spec_version, "ts_103_433_spec_version"); if (ts_103_433_spec_version==0) { Skip_S1 (4, "ts_103_433_payload_mode"); } else if (ts_103_433_spec_version==1) { Skip_S1 (3, "sl_hdr_mode_support"); } else Skip_S1 (Data_BS_Remain(), "Unknown"); BS_End(); } //--------------------------------------------------------------------------- // SEI - 4 - USA - 003C void File_Hevc::sei_message_user_data_registered_itu_t_t35_B5_003C() { int16u itu_t_t35_terminal_provider_oriented_code; Get_B2 (itu_t_t35_terminal_provider_oriented_code, "itu_t_t35_terminal_provider_oriented_code"); switch (itu_t_t35_terminal_provider_oriented_code) { case 0x0001: sei_message_user_data_registered_itu_t_t35_B5_003C_0001(); break; } } //--------------------------------------------------------------------------- // SEI - 4 - USA - 003C - 0001 void File_Hevc::sei_message_user_data_registered_itu_t_t35_B5_003C_0001() { int8u application_identifier; Get_B1 (application_identifier, "application_identifier"); switch (application_identifier) { case 0x04: sei_message_user_data_registered_itu_t_t35_B5_003C_0001_04(); break; } } //--------------------------------------------------------------------------- // SEI - 4 - USA - 003C - 0001 - SMPTE ST 2094-40 (HDR10+) void File_Hevc::sei_message_user_data_registered_itu_t_t35_B5_003C_0001_04() { Element_Info1("SMPTE ST 2094 App 4"); int8u application_version; bool IsHDRplus=false, tone_mapping_flag; Get_B1 (application_version, "application_version"); if (application_version==1) { int32u targeted_system_display_maximum_luminance, maxscl[4], distribution_maxrgb_percentiles[16]; int16u fraction_bright_pixels; int8u num_distribution_maxrgb_percentiles, distribution_maxrgb_percentages[16], num_windows, num_bezier_curve_anchors; bool targeted_system_display_actual_peak_luminance_flag, mastering_display_actual_peak_luminance_flag, color_saturation_mapping_flag; BS_Begin(); Get_S1 ( 2, num_windows, "num_windows"); for (int8u w=1; w100 && distribution_maxrgb_percentages[2]!=0xFF) || (!tone_mapping_flag && targeted_system_display_maximum_luminance) || (tone_mapping_flag && num_bezier_curve_anchors>9) || color_saturation_mapping_flag) IsHDRplus=false; for(int8u i=0; i<4; i++) if (maxscl[i]>100000) IsHDRplus=false; if (IsHDRplus) for(int8u i=0; i<9; i++) { static const int8u distribution_maxrgb_percentages_List[9]={1, 5, 10, 25, 50, 75, 90, 95, 99}; if (distribution_maxrgb_percentages[i]!=distribution_maxrgb_percentages_List[i]) IsHDRplus=false; if (distribution_maxrgb_percentiles[i]>100000) IsHDRplus=false; } FILLING_END(); } FILLING_BEGIN(); auto& HDR_Format=HDR[Video_HDR_Format][HdrFormat_SmpteSt209440]; if (HDR_Format.empty()) { HDR_Format=__T("SMPTE ST 2094 App 4"); HDR[Video_HDR_Format_Version][HdrFormat_SmpteSt209440].From_Number(application_version); if (IsHDRplus) HDR[Video_HDR_Format_Compatibility][HdrFormat_SmpteSt209440]=tone_mapping_flag?__T("HDR10+ Profile B"):__T("HDR10+ Profile A"); } FILLING_END(); } //--------------------------------------------------------------------------- // SEI - 4 - China void File_Hevc::sei_message_user_data_registered_itu_t_t35_26() { int16u itu_t_t35_terminal_provider_code; Get_B2 (itu_t_t35_terminal_provider_code, "itu_t_t35_terminal_provider_code"); //HDR Vivid terminal provide code 0x0004, terminal provide oriented code 0x0005 , 0x0005 indicates HDR Vivid version 1 switch (itu_t_t35_terminal_provider_code) { case 0x0004: sei_message_user_data_registered_itu_t_t35_26_0004(); break; } } //--------------------------------------------------------------------------- // SEI - 4 - China similar to sei_message_user_data_registered_itu_t_t35_B5_003C() void File_Hevc::sei_message_user_data_registered_itu_t_t35_26_0004() { int16u itu_t_t35_terminal_provider_oriented_code; Get_B2 (itu_t_t35_terminal_provider_oriented_code, "itu_t_t35_terminal_provider_oriented_code"); //HDR Vivid terminal provide code 0x0004, terminal provide oriented code 0x0005 switch (itu_t_t35_terminal_provider_oriented_code) { case 0x0005: sei_message_user_data_registered_itu_t_t35_26_0004_0005(); break; } } //--------------------------------------------------------------------------- // SEI - 4 - China - 0004 void File_Hevc::sei_message_user_data_registered_itu_t_t35_26_0004_0005() { //Parsing int16u targeted_system_display_maximum_luminance_Max=0; int8u system_start_code; bool color_saturation_mapping_flag; Get_B1(system_start_code, "system_start_code"); if (system_start_code!=0x01) { Skip_XX(Element_Size, "Unknown"); return; } BS_Begin(); //int8u num_windows=1; //for (int8u w=0; w='0' && option[0]<='9') && option.find("fps=")!=0 && option.find("bitdepth=")!=0) //Ignoring redundant information e.g. width, height, frame rate, bit depth { if (!Encoded_Library_Settings.empty()) Encoded_Library_Settings+=__T(" / "); Encoded_Library_Settings+=Ztring().From_UTF8(option.c_str()); } } Element_End0(); } else { string Value; Get_String(Data_Pos-Data_Pos_Before, Value, "data"); //Saving if (Loop==0) { //Cleaning a little the value while (!Value.empty() && Value[0]<0x30) Value.erase(Value.begin()); while (!Value.empty() && Value[Value.size()-1]<0x30) Value.erase(Value.end()-1); size_t Value_Pos=Value.find(__T(' ')); if (Value_Pos!=string::npos) Value.resize(Value_Pos); Encoded_Library.From_UTF8(Value.c_str()); } if (Loop==1 && Encoded_Library.find(__T("x265"))==0) { size_t Value_Pos=Value.find(" 8bpp"); if (Value_Pos!=string::npos) Value.resize(Value_Pos); Encoded_Library+=__T(" - "); Encoded_Library+=Ztring().From_UTF8(Value.c_str()); } } Data_Pos_Before=Data_Pos; if (Data_Pos_Before+3<=Data.size()) { Skip_UTF8(3, "separator"); Data_Pos_Before+=3; } Loop++; } while (Data_Pos_Before!=Data.size()); //Encoded_Library if (Encoded_Library.find(__T("x265 - "))==0) { Encoded_Library_Name=__T("x265"); Encoded_Library_Version=Encoded_Library.SubString(__T("x265 - "), Ztring()); } else Encoded_Library_Name=Encoded_Library; } //--------------------------------------------------------------------------- // SEI - 6 void File_Hevc::sei_message_recovery_point() { Element_Info1("recovery_point"); //Parsing BS_Begin(); Skip_SE( "recovery_poc_cnt"); Skip_SB( "exact_match_flag"); Skip_SB( "broken_link_flag"); BS_End(); } //--------------------------------------------------------------------------- void File_Hevc::sei_message_active_parameter_sets() { Element_Info1("active_parameter_sets"); //Parsing int32u num_sps_ids_minus1; BS_Begin(); Skip_S1(4, "active_video_parameter_set_id"); Skip_SB( "self_contained_cvs_flag"); Skip_SB( "no_parameter_set_update_flag"); Get_UE ( num_sps_ids_minus1, "num_sps_ids_minus1"); for (int32u i=0; i<=num_sps_ids_minus1; ++i) { Skip_UE( "active_seq_parameter_set_id"); } BS_End(); } //--------------------------------------------------------------------------- void File_Hevc::sei_time_code() { Element_Info1("time_code"); //Parsing int8u num_clock_ts; BS_Begin(); Get_S1 (2, num_clock_ts, "num_clock_ts"); for (int32u i=0; i1 && counting_type!=4) { n_frames=0; FrameMax=0; //Unsupported type } else if (!seq_parameter_sets.empty() && seq_parameter_sets[0] && seq_parameter_sets[0]->vui_parameters && seq_parameter_sets[0]->vui_parameters->time_scale && seq_parameter_sets[0]->vui_parameters->num_units_in_tick) //TODO: get the exact seq FrameMax=(int32u)(float64_int64s((float64)seq_parameter_sets[0]->vui_parameters->time_scale/seq_parameter_sets[0]->vui_parameters->num_units_in_tick)-1); else if (n_frames>99) FrameMax=n_frames; else FrameMax=99; TC_Current=TimeCode(hours_value, minutes_value, seconds_value, n_frames, FrameMax, TimeCode::DropFrame(counting_type==4)); Element_Info1(TC_Current.ToString()); } FILLING_END(); } Element_End0(); } BS_End(); } //--------------------------------------------------------------------------- void File_Hevc::sei_message_decoded_picture_hash(int32u payloadSize) { Element_Info1("decoded_picture_hash"); //Parsing int8u hash_type; Get_B1 (hash_type, "hash_type"); for (int8u cIdx=0; cIdx<(chroma_format_idc?3:1); cIdx++) switch (hash_type) { case 0 : // md5 Skip_XX(16, "md5"); break; case 1 : // crc Skip_XX( 2, "crc"); break; case 2 : // checksum Skip_XX( 4, "checksum"); break; default : // Skip_XX((Element_Size-1)/(chroma_format_idc?1:3), "unknown"); break; } } //--------------------------------------------------------------------------- void File_Hevc::sei_message_mastering_display_colour_volume() { Element_Info1("mastering_display_colour_volume"); auto& HDR_Format=HDR[Video_HDR_Format][HdrFormat_SmpteSt2086]; if (HDR_Format.empty()) { HDR_Format=__T("SMPTE ST 2086"); HDR[Video_HDR_Format_Compatibility][HdrFormat_SmpteSt2086]="HDR10"; } Get_MasteringDisplayColorVolume(HDR[Video_MasteringDisplay_ColorPrimaries][HdrFormat_SmpteSt2086], HDR[Video_MasteringDisplay_Luminance][HdrFormat_SmpteSt2086]); } //--------------------------------------------------------------------------- void File_Hevc::sei_message_light_level() { Element_Info1("light_level"); //Parsing Get_LightLevel(maximum_content_light_level, maximum_frame_average_light_level); } //--------------------------------------------------------------------------- void File_Hevc::sei_alternative_transfer_characteristics() { Element_Info1("alternative_transfer_characteristics"); //Parsing Get_B1(preferred_transfer_characteristics, "preferred_transfer_characteristics"); Param_Info1(Mpegv_transfer_characteristics(preferred_transfer_characteristics)); } //--------------------------------------------------------------------------- void File_Hevc::three_dimensional_reference_displays_info(int32u payloadSize) { Element_Info1("three_dimensional_reference_displays_info"); //Parsing BS_Begin(); auto End=Data_BS_Remain()-payloadSize*8; int32u prec_ref_display_width, num_ref_displays_minus1; int32u left_view_id0, right_view_id0; bool ref_viewing_distance_flag; Get_UE (prec_ref_display_width, "prec_ref_display_width"); if (prec_ref_display_width>=32) { Trusted_IsNot("prec_ref_display_width out of range"); BS_End(); return; } TEST_SB_GET (ref_viewing_distance_flag, "ref_viewing_distance_flag"); Skip_UE( "prec_ref_viewing_dist"); TEST_SB_END(); Get_UE (num_ref_displays_minus1, "num_ref_displays_minus1"); if (num_ref_displays_minus1>=32) { Trusted_IsNot("num_ref_displays_minus1 out of range"); BS_End(); return; } for (int32u i=0; i<=num_ref_displays_minus1; i++) { Element_Begin1("ref_display"); int32u left_view_id, right_view_id; int8u exponent_ref_display_width; Get_UE (left_view_id, "left_view_id"); Get_UE (right_view_id, "right_view_id"); if (!i) { left_view_id0=left_view_id; right_view_id0=right_view_id; } Get_S1 (6, exponent_ref_display_width, "exponent_ref_display_width"); if (exponent_ref_display_width>=63) { if (exponent_ref_display_width>63) Trusted_IsNot("exponent_ref_display_width out of range"); else Param_Info1("(Not supported)"); BS_End(); return; } int8u refDispWidthBits; if (exponent_ref_display_width) { auto temp=exponent_ref_display_width+prec_ref_display_width; if (temp>31) refDispWidthBits=(int8u)(temp-31); else refDispWidthBits=0; } else refDispWidthBits=(prec_ref_display_width==31); if (refDispWidthBits) Skip_BS(refDispWidthBits, "mantissa_ref_display_width"); if (ref_viewing_distance_flag) { int8u exponent_ref_viewing_distance; Get_S1 (6, exponent_ref_viewing_distance, "exponent_ref_viewing_distance"); if (exponent_ref_viewing_distance>=63) { if (exponent_ref_viewing_distance>63) Trusted_IsNot("exponent_ref_viewing_distance out of range"); else Param_Info1("(Not supported)"); BS_End(); return; } int8u refViewDistBits; if (exponent_ref_viewing_distance) { auto temp=exponent_ref_viewing_distance+prec_ref_display_width; if (temp>31) refViewDistBits=(int8u)(temp-31); else refViewDistBits=0; } else refViewDistBits=(exponent_ref_viewing_distance==31); if (refViewDistBits) Skip_BS(refViewDistBits, "mantissa_ref_viewing_distance"); } TEST_SB_SKIP( "additional_shift_present_flag"); Skip_S2(10, "num_sample_shift_plus512"); TEST_SB_END(); Element_End0(); } TEST_SB_SKIP( "three_dimensional_reference_displays_extension_flag"); Skip_BS(Data_BS_Remain()-End, "(Not parsed)"); TEST_SB_END(); BS_End(); FILLING_BEGIN_PRECISE(); /* if (!video_parameter_sets.empty()) { const auto& view_id_val=(*video_parameter_sets.begin())->view_id_val; if (left_view_id0==view_id_val[0] && right_view_id0==view_id_val[1]) Fill(Stream_Video, 0, Video_MultiView_Order, "L R"); if (left_view_id0==view_id_val[1] && right_view_id0==view_id_val[0]) Fill(Stream_Video, 0, Video_MultiView_Order, "R L"); } */ FILLING_END(); } //*************************************************************************** // Sub-elements //*************************************************************************** //--------------------------------------------------------------------------- void File_Hevc::slice_segment_header() { Element_Begin1("slice_segment_header"); //Parsing bool dependent_slice_segment_flag=false; Get_SB ( first_slice_segment_in_pic_flag, "first_slice_segment_in_pic_flag"); if (RapPicFlag) Skip_SB( "no_output_of_prior_pics_flag"); Get_UE ( slice_pic_parameter_set_id, "slice_pic_parameter_set_id"); std::vector::iterator pic_parameter_set_Item; if (slice_pic_parameter_set_id>=pic_parameter_sets.size() || (*(pic_parameter_set_Item=pic_parameter_sets.begin()+slice_pic_parameter_set_id))==NULL) { //Not yet present RiskCalculationN++; RiskCalculationD++; Skip_BS(Data_BS_Remain(), "Data (pic_parameter_set is missing)"); Element_End0(); slice_pic_parameter_set_id=(int32u)-1; slice_type=(int32u)-1; return; } if (!first_slice_segment_in_pic_flag) { if (!MustParse_VPS_SPS_PPS_FromFlv && (*pic_parameter_set_Item)->dependent_slice_segments_enabled_flag) Get_SB (dependent_slice_segment_flag, "dependent_slice_segment_flag"); //Skip_BS(Ceil( Log2( PicSizeInCtbsY ) ), "slice_segment_address"); Skip_BS(Data_BS_Remain(), "(ToDo)"); Element_End0(); slice_type=(int32u)-1; return; } if (!dependent_slice_segment_flag) { if (!MustParse_VPS_SPS_PPS_FromFlv) Skip_S1((*pic_parameter_set_Item)->num_extra_slice_header_bits, "slice_reserved_flags"); Get_UE (slice_type, "slice_type"); Param_Info1(Hevc_slice_type(slice_type)); } //TODO... Skip_BS(Data_BS_Remain(), "(ToDo)"); Element_End0(); #if MEDIAINFO_EVENTS if (first_slice_segment_in_pic_flag) { switch(Element_Code) { case 19 : case 20 : // This is an IDR frame case 21 : case 22 : case 23 : TemporalReferences_Offset=TemporalReferences_Max+1; pic_order_cnt_DTS_Ref=FrameInfo.DTS; if (Config->Config_PerPackage && Element_Code==0x05) // First slice of an IDR frame { // IDR Config->Config_PerPackage->FrameForAlignment(this, true); Config->Config_PerPackage->IsClosedGOP(this); } } } #endif //MEDIAINFO_EVENTS //Saving some info std::vector::iterator seq_parameter_set_Item; if ((*pic_parameter_set_Item)->seq_parameter_set_id>=seq_parameter_sets.size() || (*(seq_parameter_set_Item=seq_parameter_sets.begin()+(*pic_parameter_set_Item)->seq_parameter_set_id))==NULL || (*seq_parameter_set_Item)->vui_parameters==NULL) return; float FrameRate=0; if ((*seq_parameter_set_Item)->vui_parameters->time_scale && (*seq_parameter_set_Item)->vui_parameters->num_units_in_tick) FrameRate=(float64)(*seq_parameter_set_Item)->vui_parameters->time_scale/(*seq_parameter_set_Item)->vui_parameters->num_units_in_tick; else FrameRate=0; if (first_slice_segment_in_pic_flag && pic_order_cnt_DTS_Ref!=(int64u)-1 && FrameInfo.PTS!=(int64u)-1 && FrameRate && TemporalReferences_Reserved) { int64s pic_order_cnt=float64_int64s(int64s(FrameInfo.PTS-pic_order_cnt_DTS_Ref)*FrameRate/1000000000); if (pic_order_cnt>=TemporalReferences.size()/4 || pic_order_cnt<=-((int64s)TemporalReferences.size()/4)) pic_order_cnt_DTS_Ref=(int64u)-1; // Incoherency in DTS? Disabling compute by DTS, TODO: more generic test (all formats) } if (first_slice_segment_in_pic_flag && pic_order_cnt_DTS_Ref!=(int64u)-1 && FrameInfo.PTS!=(int64u)-1 && FrameRate && TemporalReferences_Reserved) { //Frame order detection int64s pic_order_cnt=float64_int64s(int64s(FrameInfo.PTS-pic_order_cnt_DTS_Ref)*FrameRate/1000000000); if (pic_order_cnt=4*TemporalReferences_Reserved || Base>=4*TemporalReferences_Reserved || ToInsert+TemporalReferences_Max>=4*TemporalReferences_Reserved || TemporalReferences_Max>=4*TemporalReferences_Reserved || TemporalReferences_Max-Base>=4*TemporalReferences_Reserved) { Trusted_IsNot("Problem in temporal references"); return; } Element_Info1(__T("Offset of ")+Ztring::ToZtring(ToInsert)); TemporalReferences.insert(TemporalReferences.begin()+Base, ToInsert, NULL); TemporalReferences_Offset+=ToInsert; TemporalReferences_Offset_pic_order_cnt_lsb_Last += ToInsert; TemporalReferences_Max+=ToInsert; TemporalReferences_pic_order_cnt_Min=pic_order_cnt; } else if (TemporalReferences_Min>(size_t)(TemporalReferences_Offset+pic_order_cnt)) TemporalReferences_Min=(size_t)(TemporalReferences_Offset+pic_order_cnt); } if (pic_order_cnt<0 && TemporalReferences_Offset<(size_t)(-pic_order_cnt)) //Found in playreadyEncryptedBlowUp.ts without encryption test { Trusted_IsNot("Problem in temporal references"); return; } if ((size_t)(TemporalReferences_Offset+pic_order_cnt)>=3*TemporalReferences_Reserved) { size_t Offset=TemporalReferences_Max-TemporalReferences_Offset; if (Offset%2) Offset++; if (Offset>=TemporalReferences_Reserved && pic_order_cnt>=(int64s)TemporalReferences_Reserved) { TemporalReferences_Offset+=TemporalReferences_Reserved; pic_order_cnt-=TemporalReferences_Reserved; TemporalReferences_pic_order_cnt_Min-=TemporalReferences_Reserved/2; } while (TemporalReferences_Offset+pic_order_cnt>=3*TemporalReferences_Reserved) { for (size_t Pos=0; Posslice_type]; */ delete TemporalReferences[Pos]; TemporalReferences[Pos]=NULL; } /* else if (!PictureTypes_PreviousFrames.empty()) //Only if stream already started { if ((Pos%2)==0) PictureTypes_PreviousFrames+=' '; } */ } /* if (PictureTypes_PreviousFrames.size()>=8*TemporalReferences.size()) PictureTypes_PreviousFrames.erase(PictureTypes_PreviousFrames.begin(), PictureTypes_PreviousFrames.begin()+PictureTypes_PreviousFrames.size()-TemporalReferences.size()); */ TemporalReferences.erase(TemporalReferences.begin(), TemporalReferences.begin()+TemporalReferences_Reserved); TemporalReferences.resize(4*TemporalReferences_Reserved); if (TemporalReferences_Reservedpic_order_cnt_type == 2 && TemporalReferences_Offset_pic_order_cnt_lsb_Lastframe_mbs_only_flag?2:1); if (TemporalReferences_Min>TemporalReferences_Offset_pic_order_cnt_lsb_Last) TemporalReferences_Min=TemporalReferences_Offset_pic_order_cnt_lsb_Last; if (TemporalReferences_DelayedElement) { delete TemporalReferences[TemporalReferences_Offset_pic_order_cnt_lsb_Last]; TemporalReferences[TemporalReferences_Offset_pic_order_cnt_lsb_Last]=TemporalReferences_DelayedElement; } if (TemporalReferences[TemporalReferences_Offset_pic_order_cnt_lsb_Last]==NULL) TemporalReferences[TemporalReferences_Offset_pic_order_cnt_lsb_Last]=new temporal_reference(); /* TemporalReferences[TemporalReferences_Offset_pic_order_cnt_lsb_Last]->frame_num=frame_num; TemporalReferences[TemporalReferences_Offset_pic_order_cnt_lsb_Last]->slice_type=(int8u)slice_type; TemporalReferences[TemporalReferences_Offset_pic_order_cnt_lsb_Last]->IsTop=!bottom_field_flag; TemporalReferences[TemporalReferences_Offset_pic_order_cnt_lsb_Last]->IsField=field_pic_flag; */ if (TemporalReferences_DelayedElement) { TemporalReferences_DelayedElement=NULL; sei_message_user_data_registered_itu_t_t35_B5_0031_GA94_03_Delayed((*pic_parameter_set_Item)->seq_parameter_set_id); } } } //--------------------------------------------------------------------------- void File_Hevc::profile_tier_level(profile_tier_level_struct& p, bool profilePresentFlag, int8u maxNumSubLayersMinus1) { Element_Begin1("profile_tier_level"); //Parsing std::vectorsub_layer_profile_present_flags, sub_layer_level_present_flags; if (profilePresentFlag) { Get_S1 (2, p.profile_space, "general_profile_space"); Get_SB ( p.tier_flag, "general_tier_flag"); Get_S1 (5, p.profile_idc, "general_profile_idc"); Param_Info1(Hevc_profile_idc(p.profile_idc)); Element_Begin1("general_profile_compatibility_flags"); for (int8u profile_pos=0; profile_pos<32; profile_pos++) if (profile_pos==p.profile_idc) { bool general_profile_compatibility_flag; Get_SB ( general_profile_compatibility_flag, "general_profile_compatibility_flag"); //if (!general_profile_compatibility_flag && !profile_space) //found some files without this flag, ignoring the test for the moment (not really important) // Trusted_IsNot("general_profile_compatibility_flag not valid"); } else Skip_SB( "general_profile_compatibility_flag"); Element_End0(); Element_Begin1("general_profile_compatibility_flags"); Get_SB ( p.general_progressive_source_flag, "general_progressive_source_flag"); Get_SB ( p.general_interlaced_source_flag, "general_interlaced_source_flag"); Skip_SB( "general_non_packed_constraint_flag"); Get_SB ( p.general_frame_only_constraint_flag, "general_frame_only_constraint_flag"); Get_SB ( p.general_max_12bit_constraint_flag, "general_max_12bit_constraint_flag"); Get_SB ( p.general_max_10bit_constraint_flag, "general_max_10bit_constraint_flag"); Get_SB ( p.general_max_8bit_constraint_flag, "general_max_8bit_constraint_flag"); Skip_SB( "general_max_422chroma_constraint_flag"); Skip_SB( "general_max_420chroma_constraint_flag"); Skip_SB( "general_max_monochrome_constraint_flag"); Skip_SB( "general_intra_constraint_flag"); Skip_SB( "general_one_picture_only_constraint_flag"); Skip_SB( "general_lower_bit_rate_constraint_flag"); Get_SB ( p.general_max_14bit_constraint_flag, "general_max_14bit_constraint_flag"); for (int8u constraint_pos=0; constraint_pos<33; constraint_pos++) Skip_SB( "general_reserved"); Skip_SB( "general_inbld_flag"); Element_End0(); } Get_S1 (8, p.level_idc, "general_level_idc"); for (int32u SubLayerPos=0; SubLayerPosstRpsIdx) { Skip_BS(Data_BS_Remain(), "(Problem)"); Element_End0(); Element_End0(); return; } Get_SB ( delta_rps_sign, "delta_rps_sign"); Get_UE ( abs_delta_rps_minus1, "abs_delta_rps_minus1"); int32u num_pics_new=0; for(int32u pic_pos=0 ; pic_pos<=num_pics; pic_pos++) { TESTELSE_SB_SKIP( "used_by_curr_pic_flag"); num_pics_new++; TESTELSE_SB_ELSE( "used_by_curr_pic_flag"); bool use_delta_flag; Get_SB (use_delta_flag, "use_delta_flag"); if (use_delta_flag) num_pics_new++; TESTELSE_SB_END(); } num_pics=num_pics_new; } else { int32u num_negative_pics, num_positive_pics; Get_UE (num_negative_pics, "num_negative_pics"); Get_UE (num_positive_pics, "num_positive_pics"); num_pics=num_negative_pics+num_positive_pics; for (int32u i=0; i31) { Trusted_IsNot("cpb_cnt_minus1 too high"); cpb_cnt_minus1=0; return; } } if (nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag) xxL_Common=new seq_parameter_set_struct::vui_parameters_struct::xxl_common( sub_pic_hrd_params_present_flag, du_cpb_removal_delay_increment_length_minus1, dpb_output_delay_du_length_minus1, initial_cpb_removal_delay_length_minus1, au_cpb_removal_delay_length_minus1, dpb_output_delay_length_minus1 ); if (nal_hrd_parameters_present_flag) sub_layer_hrd_parameters(xxL_Common, bit_rate_scale, cpb_size_scale, cpb_cnt_minus1, NAL); //TODO: save HRD per NumSubLayer if (vcl_hrd_parameters_present_flag) sub_layer_hrd_parameters(xxL_Common, bit_rate_scale, cpb_size_scale, cpb_cnt_minus1, VCL); //TODO: save HRD per NumSubLayer } } //--------------------------------------------------------------------------- void File_Hevc::sub_layer_hrd_parameters(seq_parameter_set_struct::vui_parameters_struct::xxl_common* xxL_Common, int8u bit_rate_scale, int8u cpb_size_scale, int32u cpb_cnt_minus1, seq_parameter_set_struct::vui_parameters_struct::xxl* &hrd_parameters_Item_) { //Parsing vector SchedSel; SchedSel.reserve(cpb_cnt_minus1 + 1); for (int8u SchedSelIdx = 0; SchedSelIdx <= cpb_cnt_minus1; ++SchedSelIdx) { Element_Begin1("ShedSel"); int64u bit_rate_value, cpb_size_value; int32u bit_rate_value_minus1, cpb_size_value_minus1; bool cbr_flag; Get_UE (bit_rate_value_minus1, "bit_rate_value_minus1"); bit_rate_value = (int64u)((bit_rate_value_minus1 + 1)*pow(2.0, 6 + bit_rate_scale)); Param_Info2(bit_rate_value, " bps"); Get_UE (cpb_size_value_minus1, "cpb_size_value_minus1"); cpb_size_value = (int64u)((cpb_size_value_minus1 + 1)*pow(2.0, 4 + cpb_size_scale)); Param_Info2(cpb_size_value, " bits"); if (xxL_Common->sub_pic_hrd_params_present_flag) { Skip_UE( "cpb_size_du_value_minus1"); Skip_UE( "bit_rate_du_value_minus1"); } Get_SB (cbr_flag, "cbr_flag"); Element_End0(); FILLING_BEGIN(); SchedSel.push_back(seq_parameter_set_struct::vui_parameters_struct::xxl::xxl_data( bit_rate_value, cpb_size_value, cbr_flag )); FILLING_END(); } //Validity test if (!Element_IsOK() || (SchedSel.size() == 1 && SchedSel[0].bit_rate_value == 64)) { return; //We do not trust this kind of data } //Filling hrd_parameters_Item_=new seq_parameter_set_struct::vui_parameters_struct::xxl( SchedSel ); } //--------------------------------------------------------------------------- void File_Hevc::scaling_list_data() { for(int8u sizeId=0; sizeId<4; sizeId++) for (int8u matrixId = 0; matrixId<((sizeId == 3) ? 2 : 6); matrixId++) { bool scaling_list_pred_mode_flag; Get_SB (scaling_list_pred_mode_flag, "scaling_list_pred_mode_flag"); if(!scaling_list_pred_mode_flag) Skip_UE( "scaling_list_pred_matrix_id_delta"); else { //nextCoef = 8 size_t coefNum=std::min(64, (1<<(4+(sizeId<<1)))); if( sizeId > 1 ) { Skip_SE( "scaling_list_dc_coef_minus8"); //[ sizeId ? 2 ][ matrixId ] se(p) //nextCoef = scaling_list_dc_coef_minus8[ sizeId ? 2 ][ matrixId ] + 8 } for(size_t i=0; i=5 && Buffer[Buffer_Offset ]==0x01 && Buffer[Buffer_Offset+1]==0x00 && Buffer[Buffer_Offset+2]==0x00 && Buffer[Buffer_Offset+3]==0x00 && Buffer[Buffer_Offset+4]==0xFF) //Trying to detect old proposal of the form of Matroska implementation return VPS_SPS_PPS_FromMatroska(); MustParse_VPS_SPS_PPS_FromMatroska=false; MustParse_VPS_SPS_PPS_FromFlv=false; } //Parsing int64u general_constraint_indicator_flags; int32u general_profile_compatibility_flags; int8u configurationVersion; int8u chromaFormat, bitDepthLumaMinus8, bitDepthChromaMinus8; int8u general_profile_space, general_profile_idc, general_level_idc; int8u numOfArrays, constantFrameRate, numTemporalLayers; bool general_tier_flag, temporalIdNested; Get_B1 (configurationVersion, "configurationVersion"); if (!MustParse_VPS_SPS_PPS_FromLhvc) { BS_Begin(); Get_S1 (2, general_profile_space, "general_profile_space"); Get_SB ( general_tier_flag, "general_tier_flag"); Get_S1 (5, general_profile_idc, "general_profile_idc"); Param_Info1(Hevc_profile_idc(general_profile_idc)); BS_End(); Get_B4 (general_profile_compatibility_flags, "general_profile_compatibility_flags"); Get_B6 (general_constraint_indicator_flags, "general_constraint_indicator_flags"); Get_B1 (general_level_idc, "general_level_idc"); } BS_Begin(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Skip_S2(12, "min_spatial_segmentation_idc"); BS_End(); BS_Begin(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Skip_S1(2, "parallelismType"); BS_End(); if (!MustParse_VPS_SPS_PPS_FromLhvc) { BS_Begin(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Get_S1 (2, chromaFormat, "chromaFormat"); BS_End(); BS_Begin(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Get_S1 (3, bitDepthLumaMinus8, "bitDepthLumaMinus8"); BS_End(); BS_Begin(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Mark_1_NoTrustError(); Get_S1 (3, bitDepthChromaMinus8, "bitDepthChromaMinus8"); BS_End(); Skip_B2( "avgFrameRate"); } BS_Begin(); Get_S1 (2, constantFrameRate, "constantFrameRate"); Get_S1 (3, numTemporalLayers, "numTemporalLayers"); Get_SB ( temporalIdNested, "temporalIdNested"); Get_S1 (2, lengthSizeMinusOne, "lengthSizeMinusOne"); BS_End(); Get_B1 (numOfArrays, "numOfArrays"); for (size_t ArrayPos=0; ArrayPosElement_Size) { Trusted_IsNot("Size is wrong"); break; //There is an error } //Header int8u nal_unit_type, nuh_temporal_id_plus1; BS_Begin(); Mark_0 (); Get_S1 (6, nal_unit_type, "nal_unit_type"); Get_S1 (6, nuh_layer_id, "nuh_layer_id"); Get_S1 (3, nuh_temporal_id_plus1, "nuh_temporal_id_plus1"); if (nuh_temporal_id_plus1==0) Trusted_IsNot("nuh_temporal_id_plus1 is invalid"); BS_End(); //Data int64u Element_Offset_Save=Element_Offset; int64u Element_Size_Save=Element_Size; Buffer_Offset+=(size_t)Element_Offset_Save; Element_Offset=0; Element_Size=nalUnitLength-2; Element_Code=nal_unit_type; Data_Parse(); Buffer_Offset-=(size_t)Element_Offset_Save; Element_Offset=Element_Offset_Save+nalUnitLength-2; Element_Size=Element_Size_Save; Element_End0(); } Element_End0(); } MustParse_VPS_SPS_PPS=false; FILLING_BEGIN_PRECISE(); Accept("HEVC"); FILLING_ELSE(); Frame_Count_NotParsedIncluded--; RanOutOfData("HEVC"); Frame_Count_NotParsedIncluded++; FILLING_END(); } //--------------------------------------------------------------------------- void File_Hevc::VPS_SPS_PPS_FromMatroska() { //Parsing int8u Profile, Level, vid_parameter_set_count, seq_parameter_set_count, pic_parameter_set_count; if (SizedBlocks) Skip_B1( "Version"); Get_B1 (Profile, "Profile"); Skip_B1( "Compatible profile"); Get_B1 (Level, "Level"); BS_Begin(); Skip_S1(6, "Reserved"); Get_S1 (2, lengthSizeMinusOne, "Size of NALU length minus 1"); Skip_S1(3, "Reserved"); Get_S1 (5, vid_parameter_set_count, MustParse_VPS_SPS_PPS_FromFlv?"vid_parameter_set+seq_parameter_set count":"vid_parameter_set count"); BS_End(); for (int8u Pos=0; PosElement_Size) { Trusted_IsNot("Size is wrong"); break; //There is an error } //Header int8u nal_unit_type, nuh_temporal_id_plus1; BS_Begin(); Mark_0 (); Get_S1 (6, nal_unit_type, "nal_unit_type"); Get_S1 (6, nuh_layer_id, "nuh_layer_id"); Get_S1 (3, nuh_temporal_id_plus1, "nuh_temporal_id_plus1"); if (nuh_temporal_id_plus1==0) Trusted_IsNot("nuh_temporal_id_plus1 is invalid"); BS_End(); //Data int64u Element_Offset_Save=Element_Offset; int64u Element_Size_Save=Element_Size; Buffer_Offset+=(size_t)Element_Offset_Save; Element_Offset=0; Element_Size=nalUnitLength-2; Element_Code=nal_unit_type; Data_Parse(); Buffer_Offset-=(size_t)Element_Offset_Save; Element_Offset=Element_Offset_Save+nalUnitLength-2; Element_Size=Element_Size_Save; Element_End0(); } if (MustParse_VPS_SPS_PPS_FromFlv) seq_parameter_set_count=0; else { BS_Begin(); Skip_S1(3, "Reserved"); Get_S1 (5, seq_parameter_set_count, "seq_parameter_set count"); BS_End(); } for (int8u Pos=0; PosElement_Size) { Trusted_IsNot("Size is wrong"); break; //There is an error } //Header int8u nal_unit_type, nuh_temporal_id_plus1; BS_Begin(); Mark_0 (); Get_S1 (6, nal_unit_type, "nal_unit_type"); Get_S1 (6, nuh_layer_id, "nuh_layer_id"); Get_S1 (3, nuh_temporal_id_plus1, "nuh_temporal_id_plus1"); if (nuh_temporal_id_plus1==0) Trusted_IsNot("nuh_temporal_id_plus1 is invalid"); BS_End(); //Data int64u Element_Offset_Save=Element_Offset; int64u Element_Size_Save=Element_Size; Buffer_Offset+=(size_t)Element_Offset_Save; Element_Offset=0; Element_Size=nalUnitLength-2; Element_Code=nal_unit_type; Data_Parse(); Buffer_Offset-=(size_t)Element_Offset_Save; Element_Offset=Element_Offset_Save+nalUnitLength-2; Element_Size=Element_Size_Save; Element_End0(); } Get_B1 (pic_parameter_set_count, "pic_parameter_set count"); for (int8u Pos=0; PosElement_Size) { Trusted_IsNot("Size is wrong"); break; //There is an error } //Header int8u nal_unit_type, nuh_temporal_id_plus1; BS_Begin(); Mark_0 (); Get_S1 (6, nal_unit_type, "nal_unit_type"); Get_S1 (6, nuh_layer_id, "nuh_layer_id"); Get_S1 (3, nuh_temporal_id_plus1, "nuh_temporal_id_plus1"); if (nuh_temporal_id_plus1==0) Trusted_IsNot("nuh_temporal_id_plus1 is invalid"); BS_End(); //Data int64u Element_Offset_Save=Element_Offset; int64u Element_Size_Save=Element_Size; Buffer_Offset+=(size_t)Element_Offset_Save; Element_Offset=0; Element_Size=nalUnitLength-2; Element_Code=nal_unit_type; Data_Parse(); Buffer_Offset-=(size_t)Element_Offset_Save; Element_Offset=Element_Offset_Save+nalUnitLength-2; Element_Size=Element_Size_Save; Element_End0(); } if (Element_Offset8) IsRisky=1+Remain/80; //there is lot of unexpected content, not normal, so highly risky (risk weight based on remaining content size) else { int8u RealValue; const int8u ExpectedValue=1<<(Remain-1); Peek_S1(Remain, RealValue); if (RealValue==ExpectedValue) { // Conform to specs IsRisky=0; Mark_1(); while (Data_BS_Remain()) Mark_0(); } else IsRisky=1; //there is some unexpected content, not normal, so highly risky } if (IsRisky) { Skip_BS(Remain, "Unknown"); RiskCalculationN+=IsRisky; RiskCalculationD+=IsRisky; } else RiskCalculationD++; } } //NameSpace #endif //MEDIAINFO_HEVC_YES