From 4e500d7f9344a8676c5f636e96ca379e6972f9e7 Mon Sep 17 00:00:00 2001 From: cjee21 <77721854+cjee21@users.noreply.github.com> Date: Sun, 14 Sep 2025 04:20:18 +0800 Subject: [PATCH 1/2] AV1/HEVC: Parse Dolby Vision RPU and EL --- Source/MediaInfo/File__Analyze.h | 25 + Source/MediaInfo/File__Analyze_MinimizeSize.h | 25 + Source/MediaInfo/File__Analyze_Streams.cpp | 624 ++++++++++++++++++ Source/MediaInfo/Video/File_Av1.cpp | 209 ++++++ Source/MediaInfo/Video/File_Av1.h | 3 + Source/MediaInfo/Video/File_Hevc.cpp | 111 ++++ Source/MediaInfo/Video/File_Hevc.h | 3 + 7 files changed, 1000 insertions(+) diff --git a/Source/MediaInfo/File__Analyze.h b/Source/MediaInfo/File__Analyze.h index f9c47d83f5..d4a5616c85 100644 --- a/Source/MediaInfo/File__Analyze.h +++ b/Source/MediaInfo/File__Analyze.h @@ -932,6 +932,31 @@ public : #if defined(MEDIAINFO_MPEGPS_YES) || defined(MEDIAINFO_MPEGTS_YES) || defined(MEDIAINFO_MPEG4_YES) || defined(MEDIAINFO_MK_YES) void dvcC(bool has_dependency_pid=false, std::map* Infos=NULL); #endif + #if defined(MEDIAINFO_HEVC_YES) || defined(MEDIAINFO_AV1_YES) + struct DV_RPU { + int8u vdr_rpu_profile{}; + int32u bl_bit_depth{}; + int32u el_bit_depth{}; + int32u vdr_bit_depth{}; + bool BL_video_full_range_flag{}; + int8u isMEL{}; + float CMv{}; + int16u active_area_left_offset{}; + int16u active_area_right_offset{}; + int16u active_area_top_offset{}; + int16u active_area_bottom_offset{}; + int16u max_display_mastering_luminance{}; + int16u min_display_mastering_luminance{}; + int16u max_content_light_level{}; + int16u max_frame_average_light_level{}; + bool L11_present{}; + int8u content_type{}; + int8u white_point{}; + bool reference_mode{}; + }; + // Must be in bitstream before calling this function. + void Get_DolbyVision_ReferenceProcessingUnit(DV_RPU& data); + #endif //*************************************************************************** // Unknown diff --git a/Source/MediaInfo/File__Analyze_MinimizeSize.h b/Source/MediaInfo/File__Analyze_MinimizeSize.h index 2ba6b3287f..f923e6794e 100644 --- a/Source/MediaInfo/File__Analyze_MinimizeSize.h +++ b/Source/MediaInfo/File__Analyze_MinimizeSize.h @@ -800,6 +800,31 @@ public : #if defined(MEDIAINFO_MPEGPS_YES) || defined(MEDIAINFO_MPEGTS_YES) || defined(MEDIAINFO_MPEG4_YES) || defined(MEDIAINFO_MK_YES) void dvcC(bool has_dependency_pid=false, std::map* Infos=NULL); #endif + #if defined(MEDIAINFO_HEVC_YES) || defined(MEDIAINFO_AV1_YES) + struct DV_RPU { + int8u vdr_rpu_profile{}; + int32u bl_bit_depth{}; + int32u el_bit_depth{}; + int32u vdr_bit_depth{}; + bool BL_video_full_range_flag{}; + int8u isMEL{}; + float CMv{}; + int16u active_area_left_offset{}; + int16u active_area_right_offset{}; + int16u active_area_top_offset{}; + int16u active_area_bottom_offset{}; + int16u max_display_mastering_luminance{}; + int16u min_display_mastering_luminance{}; + int16u max_content_light_level{}; + int16u max_frame_average_light_level{}; + bool L11_present{}; + int8u content_type{}; + int8u white_point{}; + bool reference_mode{}; + }; + // Must be in bitstream before calling this function. + void Get_DolbyVision_ReferenceProcessingUnit(DV_RPU& data); + #endif //*************************************************************************** // Unknown diff --git a/Source/MediaInfo/File__Analyze_Streams.cpp b/Source/MediaInfo/File__Analyze_Streams.cpp index 14cccca65a..9e612818c0 100644 --- a/Source/MediaInfo/File__Analyze_Streams.cpp +++ b/Source/MediaInfo/File__Analyze_Streams.cpp @@ -963,6 +963,630 @@ void File__Analyze::dvcC(bool has_dependency_pid, std::map* } #endif +//--------------------------------------------------------------------------- +#if defined(MEDIAINFO_HEVC_YES) || defined(MEDIAINFO_AV1_YES) + +const char* DV_content_type(int8u content_type) +{ + switch (content_type) { + case 0 : return "Default"; + case 1 : return "Movies"; + case 2 : return "Game"; + case 3 : return "Sport"; + case 4 : return "User Generated Content"; + default : return ""; + } +} + +const char* DV_white_point(int8u white_point) +{ + switch (white_point) { + case 0: return "6504K, D65"; + case 1: return "6879K"; + case 2: return "7254K"; + case 3: return "7629K"; + case 4: return "8004K"; + case 5: return "8379K"; + case 6: return "8754K"; + case 7: return "9129K"; + case 8: return "9504K, D93"; + case 9: return "9879K"; + case 10: return "10254K"; + case 11: return "10629K"; + case 12: return "11004K"; + case 13: return "11379K"; + case 14: return "11754K"; + case 15: return "12129K"; + default: return ""; + } +} + +// CRC Table for CRC-32/MPEG-2 +// Polynomial - 0x04C11DB7 +static const int32u CRC_32_MPEG_2_Table[256] = +{ + 0x00000000, 0x04C11DB7, 0x09823B6E, 0x0D4326D9, 0x130476DC, 0x17C56B6B, 0x1A864DB2, 0x1E475005, + 0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6, 0x2B4BCB61, 0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD, + 0x4C11DB70, 0x48D0C6C7, 0x4593E01E, 0x4152FDA9, 0x5F15ADAC, 0x5BD4B01B, 0x569796C2, 0x52568B75, + 0x6A1936C8, 0x6ED82B7F, 0x639B0DA6, 0x675A1011, 0x791D4014, 0x7DDC5DA3, 0x709F7B7A, 0x745E66CD, + 0x9823B6E0, 0x9CE2AB57, 0x91A18D8E, 0x95609039, 0x8B27C03C, 0x8FE6DD8B, 0x82A5FB52, 0x8664E6E5, + 0xBE2B5B58, 0xBAEA46EF, 0xB7A96036, 0xB3687D81, 0xAD2F2D84, 0xA9EE3033, 0xA4AD16EA, 0xA06C0B5D, + 0xD4326D90, 0xD0F37027, 0xDDB056FE, 0xD9714B49, 0xC7361B4C, 0xC3F706FB, 0xCEB42022, 0xCA753D95, + 0xF23A8028, 0xF6FB9D9F, 0xFBB8BB46, 0xFF79A6F1, 0xE13EF6F4, 0xE5FFEB43, 0xE8BCCD9A, 0xEC7DD02D, + 0x34867077, 0x30476DC0, 0x3D044B19, 0x39C556AE, 0x278206AB, 0x23431B1C, 0x2E003DC5, 0x2AC12072, + 0x128E9DCF, 0x164F8078, 0x1B0CA6A1, 0x1FCDBB16, 0x018AEB13, 0x054BF6A4, 0x0808D07D, 0x0CC9CDCA, + 0x7897AB07, 0x7C56B6B0, 0x71159069, 0x75D48DDE, 0x6B93DDDB, 0x6F52C06C, 0x6211E6B5, 0x66D0FB02, + 0x5E9F46BF, 0x5A5E5B08, 0x571D7DD1, 0x53DC6066, 0x4D9B3063, 0x495A2DD4, 0x44190B0D, 0x40D816BA, + 0xACA5C697, 0xA864DB20, 0xA527FDF9, 0xA1E6E04E, 0xBFA1B04B, 0xBB60ADFC, 0xB6238B25, 0xB2E29692, + 0x8AAD2B2F, 0x8E6C3698, 0x832F1041, 0x87EE0DF6, 0x99A95DF3, 0x9D684044, 0x902B669D, 0x94EA7B2A, + 0xE0B41DE7, 0xE4750050, 0xE9362689, 0xEDF73B3E, 0xF3B06B3B, 0xF771768C, 0xFA325055, 0xFEF34DE2, + 0xC6BCF05F, 0xC27DEDE8, 0xCF3ECB31, 0xCBFFD686, 0xD5B88683, 0xD1799B34, 0xDC3ABDED, 0xD8FBA05A, + 0x690CE0EE, 0x6DCDFD59, 0x608EDB80, 0x644FC637, 0x7A089632, 0x7EC98B85, 0x738AAD5C, 0x774BB0EB, + 0x4F040D56, 0x4BC510E1, 0x46863638, 0x42472B8F, 0x5C007B8A, 0x58C1663D, 0x558240E4, 0x51435D53, + 0x251D3B9E, 0x21DC2629, 0x2C9F00F0, 0x285E1D47, 0x36194D42, 0x32D850F5, 0x3F9B762C, 0x3B5A6B9B, + 0x0315D626, 0x07D4CB91, 0x0A97ED48, 0x0E56F0FF, 0x1011A0FA, 0x14D0BD4D, 0x19939B94, 0x1D528623, + 0xF12F560E, 0xF5EE4BB9, 0xF8AD6D60, 0xFC6C70D7, 0xE22B20D2, 0xE6EA3D65, 0xEBA91BBC, 0xEF68060B, + 0xD727BBB6, 0xD3E6A601, 0xDEA580D8, 0xDA649D6F, 0xC423CD6A, 0xC0E2D0DD, 0xCDA1F604, 0xC960EBB3, + 0xBD3E8D7E, 0xB9FF90C9, 0xB4BCB610, 0xB07DABA7, 0xAE3AFBA2, 0xAAFBE615, 0xA7B8C0CC, 0xA379DD7B, + 0x9B3660C6, 0x9FF77D71, 0x92B45BA8, 0x9675461F, 0x8832161A, 0x8CF30BAD, 0x81B02D74, 0x857130C3, + 0x5D8A9099, 0x594B8D2E, 0x5408ABF7, 0x50C9B640, 0x4E8EE645, 0x4A4FFBF2, 0x470CDD2B, 0x43CDC09C, + 0x7B827D21, 0x7F436096, 0x7200464F, 0x76C15BF8, 0x68860BFD, 0x6C47164A, 0x61043093, 0x65C52D24, + 0x119B4BE9, 0x155A565E, 0x18197087, 0x1CD86D30, 0x029F3D35, 0x065E2082, 0x0B1D065B, 0x0FDC1BEC, + 0x3793A651, 0x3352BBE6, 0x3E119D3F, 0x3AD08088, 0x2497D08D, 0x2056CD3A, 0x2D15EBE3, 0x29D4F654, + 0xC5A92679, 0xC1683BCE, 0xCC2B1D17, 0xC8EA00A0, 0xD6AD50A5, 0xD26C4D12, 0xDF2F6BCB, 0xDBEE767C, + 0xE3A1CBC1, 0xE760D676, 0xEA23F0AF, 0xEEE2ED18, 0xF0A5BD1D, 0xF464A0AA, 0xF9278673, 0xFDE69BC4, + 0x89B8FD09, 0x8D79E0BE, 0x803AC667, 0x84FBDBD0, 0x9ABC8BD5, 0x9E7D9662, 0x933EB0BB, 0x97FFAD0C, + 0xAFB010B1, 0xAB710D06, 0xA6322BDF, 0xA2F33668, 0xBCB4666D, 0xB8757BDA, 0xB5365D03, 0xB1F740B4 +}; + +// CRC32 check for Dolby Vision Rererence Processing Unit (RPU) +// Supports non-byte aligned RPU +// Uses CRC-32/MPEG-2 +// Polynomial - 0x04C11DB7 +// Init - 0xFFFFFFFF +// RefIn - false +// RefOut - false +// XorOut - 0x00000000 +// Check - 0x0376E6E7 +static bool DV_CRC32_Check(const int8u* Buffer, int64u BufferOffsetBegin, size_t RemainingBitsBegin, size_t RemainingBitsEnd) +{ + const int8u* CRC_32_Buffer = Buffer + BufferOffsetBegin; + const int32u CRC_Poly{ 0x04C11DB7 }; + int32u CRC_32 = 0xFFFFFFFF; + + const auto first_bits = RemainingBitsBegin & 7; + + for (int8u c = 0; c < first_bits; ++c) { + CRC_32 ^= ((CRC_32_Buffer[0] >> (first_bits - 1 - c)) & 1) << 31; + if (CRC_32 & 0x80000000) + CRC_32 = (CRC_32 << 1) ^ CRC_Poly; + else + CRC_32 <<= 1; + } + + const auto aligned_size = (RemainingBitsBegin - RemainingBitsEnd) + ((8 - first_bits) & 7); + const auto num_bytes = aligned_size / 8; + + for (size_t c = (first_bits != 0); c < num_bytes; ++c) { + CRC_32 = (CRC_32 << 8) ^ CRC_32_MPEG_2_Table[(CRC_32 >> 24) ^ CRC_32_Buffer[c]]; + } + + for (int8u c = 0; c < (aligned_size & 7); ++c) { + CRC_32 ^= ((CRC_32_Buffer[num_bytes] >> (7 - c)) & 1) << 31; + if (CRC_32 & 0x80000000) + CRC_32 = (CRC_32 << 1) ^ CRC_Poly; + else + CRC_32 <<= 1; + } + + return (CRC_32 != 0); +} + +// Must be in bitstream before calling this function. +void File__Analyze::Get_DolbyVision_ReferenceProcessingUnit(DV_RPU& data) +{ + using std::to_string; + + #define UNSUPPORTED() \ + BS_End(); \ + Skip_XX(Element_Size - Element_Offset, "Data"); \ + Trusted_IsNot("Unsupported"); \ + return; + + //Parsing + Element_Begin1("rpu_data"); + auto OffsetBegin{ Element_Offset + BS->Offset_Get() }; + auto RemainingBitsBegin{ Data_BS_Remain() }; + + // EDR RPU header + Element_Begin1("rpu_data_header"); + int8u rpu_type; + int16u rpu_format; + Get_S1 ( 6, rpu_type, "rpu_type"); + Get_S2 (11, rpu_format, "rpu_format"); + if (rpu_type != 2) { + UNSUPPORTED(); + } + // if (rpu_type == 2) { + // EDR RPU frame header + int32u coefficient_log2_denom, bl_bit_depth_minus8, el_bit_depth_minus8, vdr_bit_depth_minus8; + int8u vdr_rpu_profile, dm_compression, coefficient_data_type; + bool BL_video_full_range_flag, el_spatial_resampling_filter_flag, disable_residual_flag; + Get_S1 ( 4, vdr_rpu_profile, "vdr_rpu_profile"); + Skip_S1( 4, "vdr_rpu_level"); + TESTELSE_SB_SKIP( "vdr_seq_info_present_flag"); + // EDR RPU sequence header + Skip_SB( "chroma_resampling_explicit_filter_flag"); + Get_S1 (2, coefficient_data_type, "coefficient_data_type"); + switch (coefficient_data_type) { + case 0: //COEFF_FIXED + Get_UE(coefficient_log2_denom, "coefficient_log2_denom"); + break; + case 1: //COEFF_FLOAT + break; + } + Skip_S1(2, "vdr_rpu_normalized_idc"); + Get_SB (BL_video_full_range_flag, "BL_video_full_range_flag"); + if ((rpu_format & 0x700) == 0) { + // sequence header + Get_UE (bl_bit_depth_minus8, "BL_bit_depth_minus8"); + Get_UE (el_bit_depth_minus8, "EL_bit_depth_minus8"); + Get_UE (vdr_bit_depth_minus8, "vdr_bit_depth_minus8"); + Skip_SB( "spatial_resampling_filter_flag"); + Get_S1 (3, dm_compression, "dm_compression"); + Get_SB (el_spatial_resampling_filter_flag, "el_spatial_resampling_filter_flag"); + Get_SB (disable_residual_flag, "disable_residual_flag"); + } + else { + UNSUPPORTED(); + } + TESTELSE_SB_ELSE( "vdr_seq_info_present"); + UNSUPPORTED(); + TESTELSE_SB_END(); + bool use_prev_vdr_rpu_flag, vdr_dm_metadata_present_flag; + int8u isMEL{ 0xFF }; + Get_SB (vdr_dm_metadata_present_flag, "vdr_dm_metadata_present_flag"); + Get_SB (use_prev_vdr_rpu_flag, "use_prev_vdr_rpu_flag"); + if (use_prev_vdr_rpu_flag) { + Skip_UE( "prev_vdr_rpu_id"); + } + else { + int32u num_pivots_minus_2[3]{}; + Skip_UE( "vdr_rpu_id"); + Skip_UE( "mapping_color_space"); + Skip_UE( "mapping_chroma_format_idc"); + // pivot points for BL three components + for (int8u cmp = 0; cmp < 3; ++cmp) { + Get_UE(num_pivots_minus_2[cmp], ("num_pivots_minus_2[" + to_string(cmp) + "]").c_str()); + for (int32u pivot_idx = 0; pivot_idx < num_pivots_minus_2[cmp] + 2; ++pivot_idx) { + Skip_BS(static_cast(bl_bit_depth_minus8) + 8, ("pred_pivot_value[" + to_string(cmp) + "][" + to_string(pivot_idx) + "]").c_str()); + } + } + auto use_nlq{ (rpu_format & 0x700) == 0 && !disable_residual_flag }; + int8u nlq_method_idc; + if (use_nlq) { + // vl.x architecture EL specific + Get_S1(3, nlq_method_idc, "nlq_method_idc"); + Skip_BS(static_cast(bl_bit_depth_minus8) + 8, "nlq_pred_pivot_value[0]"); + Skip_BS(static_cast(bl_bit_depth_minus8) + 8, "nlq_pred_pivot_value[1]"); + } + Skip_UE( "num_x_partitions_minus1"); + Skip_UE( "num_y_partitions_minus1"); + // } + Element_End0(); // rpu_data_header / EDR RPU header + + // if (rpu_type == 2) { + // EDR RPU data + Element_Begin1("vdr_rpu_data_payload"); + Element_Begin1("rpu_data_mapping"); + for (int8u cmp = 0; cmp < 3; ++cmp) { + for (int32u pivot_idx = 0; pivot_idx < num_pivots_minus_2[cmp] + 1; ++pivot_idx) { + Element_Begin1("rpu_data_mapping_param"); + int32u mapping_idc; + Get_UE(mapping_idc, ("mapping_idc[" + to_string(cmp) + "][" + to_string(pivot_idx) + "]").c_str()); + switch (mapping_idc) { + case 0: //MAPPING_POLYNOMIAL + { + // Polynomial coefficients + int32u poly_order_minus1; + bool linear_interp_flag{}; + Get_UE(poly_order_minus1, ("poly_order_minus1[" + to_string(cmp) + "][" + to_string(pivot_idx) + "]").c_str()); + if (poly_order_minus1 == 0) + Get_SB(linear_interp_flag, ("linear_interp_flag[" + to_string(cmp) + "][" + to_string(pivot_idx) + "]").c_str()); + if (poly_order_minus1 == 0 && linear_interp_flag) { + // Linear interpolation + if (coefficient_data_type == 0) { + Skip_UE( ("pred_linear_interp_value_int[" + to_string(cmp) + "][" + to_string(pivot_idx) + "]").c_str()); + Skip_BS(coefficient_log2_denom, ("pred_linear_interp_value[" + to_string(cmp) + "][" + to_string(pivot_idx) + "]").c_str()); + } + else + Skip_S4(32, ("pred_linear_interp_value[" + to_string(cmp) + "][" + to_string(pivot_idx) + "]").c_str()); + if (pivot_idx == num_pivots_minus_2[cmp]) { + if (coefficient_data_type == 0) { + Skip_UE( ("pred_linear_interp_value_int[" + to_string(cmp) + "][" + to_string(pivot_idx + 1) + "]").c_str()); + Skip_BS(coefficient_log2_denom, ("pred_linear_interp_value[" + to_string(cmp) + "][" + to_string(pivot_idx + 1) + "]").c_str()); + } + else + Skip_S4(32, ("pred_linear_interp_value[" + to_string(cmp) + "][" + to_string(pivot_idx + 1) + "]").c_str()); + } + } + else { + // Non-linear + // the i-th order + for (int32u i = 0; i <= poly_order_minus1 + 1; ++i) { + if (coefficient_data_type == 0) { + Skip_SE( ("poly_coef_int[" + to_string(cmp) + "][" + to_string(pivot_idx) + "][" + to_string(i) + "]").c_str()); + Skip_BS(coefficient_log2_denom, ("poly_coef[" + to_string(cmp) + "][" + to_string(pivot_idx) + "][" + to_string(i) + "]").c_str()); + } + else + Skip_S4(32, ("poly_coef[" + to_string(cmp) + "][" + to_string(pivot_idx) + "][" + to_string(i) + "]").c_str()); + } + } + break; + } + case 1: //MAPPING_MMR + { + // MR coefficients + int8u mmr_order_minus1; + Get_S1(2, mmr_order_minus1, ("mmr_order_minus1[" + to_string(cmp) + "][" + to_string(pivot_idx) + "]").c_str()); + if (coefficient_data_type == 0) { + Skip_SE( ("mmr_constant_int[" + to_string(cmp) + "][" + to_string(pivot_idx) + "]").c_str()); + Skip_BS(coefficient_log2_denom, ("mmr_constant[" + to_string(cmp) + "][" + to_string(pivot_idx) + "]").c_str()); + } + else + Skip_S4(32, ("mmr_constant[" + to_string(cmp) + "][" + to_string(pivot_idx) + "]").c_str()); + // the i-th order + for (int8u i = 1; i <= mmr_order_minus1 + 1; ++i) { + // the j-th coefficients + for (int8u j = 0; j < 7; ++j) { + if (coefficient_data_type == 0) { + Skip_SE( ("mmr_coef_int[" + to_string(cmp) + "][" + to_string(pivot_idx) + "][" + to_string(i) + "][" + to_string(j) + "]").c_str()); + Skip_BS(coefficient_log2_denom, ("mmr_coef[" + to_string(cmp) + "][" + to_string(pivot_idx) + "][" + to_string(i) + "][" + to_string(j) + "]").c_str()); + } + else + Skip_S4(32, ("mmr_coef[" + to_string(cmp) + "][" + to_string(pivot_idx) + "][" + to_string(i) + "][" + to_string(j) + "]").c_str()); + } + } + break; + } + } + Element_End0(); // rpu_data_mapping_param + } + } + Element_End0(); // rpu_data_mapping + if (use_nlq) { + Element_Begin1("rpu_data_nlq"); + isMEL = 1; + // nlq_num_pivots_minus2 == 0 so no pivot_idx loop + for (int8u cmp = 0; cmp < 3; ++cmp) { + // Nonlinear Quantization Parameters + Element_Begin1("rpu_data_nlq_param"); + int16u nlq_offset; + int32u vdr_in_max_int, vdr_in_max, linear_deadzone_slope_int, linear_deadzone_slope, linear_deadzone_threshold_int, linear_deadzone_threshold; + Get_S2(static_cast(el_bit_depth_minus8 + 8), nlq_offset, ("nlq_offset[0][" + to_string(cmp) + "]").c_str()); + if (coefficient_data_type == 0) { + Get_UE(vdr_in_max_int, ("vdr_in_max_int[0][" + to_string(cmp) + "]").c_str()); + Get_S4(coefficient_log2_denom, vdr_in_max, ("vdr_in_max[0][" + to_string(cmp) + "]").c_str()); + } + else + Get_S4(32, vdr_in_max, ("vdr_in_max[0][" + to_string(cmp) + "]").c_str()); + switch (nlq_method_idc) { + case 0: //NLQ_LINEAR_DZ + // Linear dead zone coefficients + if (coefficient_data_type == 0) { + Get_UE(linear_deadzone_slope_int, ("linear_deadzone_slope_int[0][" + to_string(cmp) + "]").c_str()); + Get_S4(coefficient_log2_denom, linear_deadzone_slope, ("linear_deadzone_slope[0][" + to_string(cmp) + "]").c_str()); + } + else + Get_S4(32, linear_deadzone_slope, ("linear_deadzone_slope[0][" + to_string(cmp) + "]").c_str()); + if (coefficient_data_type == 0) { + Get_UE(linear_deadzone_threshold_int, ("linear_deadzone_threshold_int[0][" + to_string(cmp) + "]").c_str()); + Get_S4(coefficient_log2_denom, linear_deadzone_threshold, ("linear_deadzone_threshold[0][" + to_string(cmp) + "]").c_str()); + } + else + Get_S4(32, vdr_in_max, ("linear_deadzone_threshold[0][" + to_string(cmp) + "]").c_str()); + break; + } + if ((nlq_offset | vdr_in_max | linear_deadzone_slope_int | linear_deadzone_slope | linear_deadzone_threshold_int | linear_deadzone_threshold) != 0 || vdr_in_max_int != 1) + isMEL = 0; + Element_End0(); // rpu_data_nlq_param + } + Element_End0(); // rpu_data_nlq + } + + } + // } + Element_End0(); // vdr_rpu_data_payload + + // Display Management + bool L11_present{}, reference_mode_flag{}; + float CMv{}; + int8u content_type{}, white_point{}; + int16u active_area_left_offset{}, active_area_right_offset{}, active_area_top_offset{}, active_area_bottom_offset{}, max_display_mastering_luminance{}, min_display_mastering_luminance{}, max_content_light_level{}, max_frame_average_light_level{}; + if (vdr_dm_metadata_present_flag) { + Element_Begin1("vdr_dm_data_payload"); + Skip_UE( "affected_dm_metadata_id"); + Skip_UE( "current_dm_metadata_id"); + Skip_UE( "scene_refresh_flag"); + if (dm_compression) { + UNSUPPORTED(); + } + for (int8u i = 0; i < 9; ++i) { + Skip_S2(16, ("YCCtoRGB_coef" + to_string(i)).c_str()); + } + for (int8u i = 0; i < 3; ++i) { + Skip_S4(32, ("YCCtoRGB_offset" + to_string(i)).c_str()); + } + for (int8u i = 0; i < 9; ++i) { + Skip_S2(16, ("RGBtoLMS_coef" + to_string(i)).c_str()); + } + Skip_S2(16, "signal_eotf"); + Skip_S2(16, "signal_eotf_param0"); + Skip_S2(16, "signal_eotf_param1"); + Skip_S4(32, "signal_eotf_param2"); + Skip_S1( 5, "signal_bit_depth"); + Skip_S1( 2, "signal_color_space"); + Skip_S1( 2, "signal_chroma_format"); + Skip_S1( 2, "signal_full_range_flag"); + Skip_S2(12, "source_min_PQ"); + Skip_S2(12, "source_max_PQ"); + Skip_S2(10, "source_diagonal"); + + // Extension blocks + // ---------------------------------------------------------------------------------------- + + // Content Mapping v2.9 (CMv2.9) + int32u num_ext_blocks; + Get_UE(num_ext_blocks, "num_ext_blocks"); + if (num_ext_blocks) { + CMv = 2.9f; + auto RemainingBitsEnd = Data_BS_Remain(); + auto size = RemainingBitsBegin - RemainingBitsEnd; + Skip_BS((8 - (size & 7)) & 7, "dm_alignment_zero_bit"); + for (int32u i = 0; i < num_ext_blocks; ++i) { + Element_Begin1("ext_metadata_block"); + int32u ext_block_length; + int8u ext_block_level; + Get_UE(ext_block_length, "ext_block_length"); + Get_S1(8, ext_block_level, "ext_block_level"); + Element_Begin1("ext_block_payload"); + size_t ext_block_len_bits{ static_cast(ext_block_length) * 8 }; + size_t ext_block_use_bits{ 0 }; + switch (ext_block_level) { + case 1: // ANALYSIS METADATA (DYNAMIC) + Skip_S2(12, "min_PQ"); + Skip_S2(12, "max_PQ"); + Skip_S2(12, "avg_PQ"); + ext_block_use_bits += 36; + break; + case 2: // PER-TARGET TRIM METADATA (DYNAMIC) + 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_S2(13, "ms_weight"); + ext_block_use_bits += 85; + break; + case 4: + Skip_S2(12, "anchor_pq"); + Skip_S2(12, "anchor_power"); + ext_block_use_bits += 24; + break; + case 5: // PER-SHOT ASPECT RATIO (DYNAMIC) + Get_S2(13, active_area_left_offset, "active_area_left_offset"); + Get_S2(13, active_area_right_offset, "active_area_right_offset"); + Get_S2(13, active_area_top_offset, "active_area_top_offset"); + Get_S2(13, active_area_bottom_offset, "active_area_bottom_offset"); + ext_block_use_bits += 52; + break; + case 6: // OPTIONAL HDR10 METADATA (STATIC) + Get_S2(16, max_display_mastering_luminance, "max_display_mastering_luminance"); + Get_S2(16, min_display_mastering_luminance, "min_display_mastering_luminance"); + Get_S2(16, max_content_light_level, "max_content_light_level"); + Get_S2(16, max_frame_average_light_level, "max_frame_average_light_level"); + ext_block_use_bits += 64; + break; + case 255: + Skip_S1(8, "dm_run_mode"); + Skip_S1(8, "dm_run_version"); + Skip_S1(8, "dm_debug0"); + Skip_S1(8, "dm_debug1"); + Skip_S1(8, "dm_debug2"); + Skip_S1(8, "dm_debug3"); + ext_block_use_bits += 48; + break; + default: + Skip_BS(ext_block_len_bits, "(Unknown)"); + ext_block_use_bits += ext_block_len_bits; + break; + } + Skip_BS(ext_block_len_bits - ext_block_use_bits, "ext_dm_alignment_zero_bit"); + Element_End0(); // ext_block_payload + Element_End0(); // ext_metadata_block + } + } + + // Content Mapping v4.0 (CMv4.0) + if (Data_BS_Remain() >= 56) { + int32u num_ext_blocks2; + Get_UE(num_ext_blocks2, "num_ext_blocks"); + if (num_ext_blocks2) { + CMv = 4.0; + auto RemainingBitsEnd = Data_BS_Remain(); + auto size = RemainingBitsBegin - RemainingBitsEnd; + Skip_BS((8 - (size & 7)) & 7, "dm_alignment_zero_bit"); + for (int32u i = 0; i < num_ext_blocks2; ++i) { + Element_Begin1("ext_metadata_block"); + int32u ext_block_length; + int8u ext_block_level; + Get_UE(ext_block_length, "ext_block_length"); + Get_S1(8, ext_block_level, "ext_block_level"); + Element_Begin1("ext_block_payload"); + size_t ext_block_len_bits{ static_cast(ext_block_length) * 8 }; + size_t ext_block_use_bits{ 0 }; + switch (ext_block_level) { + case 3: // OFFSETS TO L1 (DYNAMIC) + Skip_S2(12, "min_pq_offset"); + Skip_S2(12, "max_pq_offset"); + Skip_S2(12, "avg_pq_offset"); + ext_block_use_bits += 36; + break; + case 8: // PER-TARGET TRIM METADATA (DYNAMIC) + Skip_S1( 8, "target_display_index"); + 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_S2(12, "ms_weight"); + ext_block_use_bits += 80; + if (ext_block_length > 10) { + Skip_S2(12, "target_mid_contrast"); + ext_block_use_bits += 12; + } + if (ext_block_length > 12) { + Skip_S2(12, "clip_trim"); + ext_block_use_bits += 12; + } + if (ext_block_length > 13) { + for (int8u i = 0; i < 6; ++i) { + Skip_S1(8, ("saturation_vector_field" + to_string(i)).c_str()); + } + ext_block_use_bits += 48; + } + if (ext_block_length > 19) { + for (int8u i = 0; i < 6; ++i) { + Skip_S1(8, ("hue_vector_field" + to_string(i)).c_str()); + } + ext_block_use_bits += 48; + } + break; + case 9: // PER-SHOT SOURCE CONTENT PRIMARIES (DYNAMIC) + Skip_S1(8, "source_primary_index"); + ext_block_use_bits += 8; + if (ext_block_length > 1) { + Skip_S2(16, "source_primary_red_x"); + Skip_S2(16, "source_primary_red_y"); + Skip_S2(16, "source_primary_green_x"); + Skip_S2(16, "source_primary_green_y"); + Skip_S2(16, "source_primary_blue_x"); + Skip_S2(16, "source_primary_blue_y"); + Skip_S2(16, "source_primary_white_x"); + Skip_S2(16, "source_primary_white_y"); + ext_block_use_bits += 128; + } + break; + case 10: + Skip_S1( 8, "target_display_index"); + Skip_S2(12, "target_max_pq"); + Skip_S2(12, "target_min_pq"); + Skip_S1( 8, "target_primary_index"); + ext_block_use_bits += 40; + if (ext_block_length > 5) { + Skip_S2(16, "target_primary_red_x"); + Skip_S2(16, "target_primary_red_y"); + Skip_S2(16, "target_primary_green_x"); + Skip_S2(16, "target_primary_green_y"); + Skip_S2(16, "target_primary_blue_x"); + Skip_S2(16, "target_primary_blue_y"); + Skip_S2(16, "target_primary_white_x"); + Skip_S2(16, "target_primary_white_y"); + ext_block_use_bits += 128; + } + break; + case 11: + { // Automatic Picture/Playback Optimization (APO) / Dolby Vision IQ - Content Type Metadata (L11) + L11_present = true; + Skip_S1(4, "reserved"); + Get_S1 (4, content_type, "content_type"); Param_Info1(DV_content_type(content_type)); + Skip_S1(3, "reserved"); + Get_SB (reference_mode_flag, "reference_mode_flag"); + Get_S1 (4, white_point, "white_point"); Param_Info1(DV_white_point(white_point)); + Skip_S2(16, "(Unknown)"); // Motion control metadata + ext_block_use_bits += 32; + break; + } + case 15: + { // Consumer look metadata, Precision Rendering/Detail + Skip_BS(ext_block_len_bits, "(Unknown)"); + ext_block_use_bits += ext_block_len_bits; + break; + } + case 16: + { // Local tone mapping metadata + Skip_BS(ext_block_len_bits, "(Unknown)"); + ext_block_use_bits += ext_block_len_bits; + break; + } + case 17: + { // Up mapping metadata + Skip_BS(ext_block_len_bits, "(Unknown)"); + ext_block_use_bits += ext_block_len_bits; + break; + } + case 254: // CM version + Skip_S1(8, "dm_mode"); + Skip_S1(8, "dm_version_index"); + ext_block_use_bits += 16; + break; + default: + Skip_BS(ext_block_len_bits, "(Unknown)"); + ext_block_use_bits += ext_block_len_bits; + break; + } + Skip_BS(ext_block_len_bits - ext_block_use_bits, "ext_dm_alignment_zero_bit"); + Element_End0(); // ext_block_payload + Element_End0(); // ext_metadata_block + } + } + } + Element_End0(); // vdr_dm_data_payload + } + + auto RemainingBitsEnd = Data_BS_Remain(); + auto size = RemainingBitsBegin - RemainingBitsEnd; + Skip_BS((8 - (size & 7)) & 7, "rpu_alignment_zero_bit"); + Skip_S4(32, "rpu_data_crc32"); + auto CRC32_Check = DV_CRC32_Check(Buffer, Buffer_Offset + OffsetBegin, RemainingBitsBegin, Data_BS_Remain()); + Param_Info1(CRC32_Check ? "NOK" : "OK"); + Element_End0(); // rpu_data + + Element_Begin1("rbsp_trailing_bits"); + Mark_1(); // rbsp_stop_one_bit + for (int8u i = 0; i < 7; ++i) Mark_0(); // rbsp_alignment_zero_bit + Element_End0(); // rbsp_trailing_bits + + #undef UNSUPPORTED + + FILLING_BEGIN(); + if (CRC32_Check) + return; + data.vdr_rpu_profile = vdr_rpu_profile; + data.bl_bit_depth = bl_bit_depth_minus8 + 8; + data.el_bit_depth = el_bit_depth_minus8 + 8; + data.vdr_bit_depth = vdr_bit_depth_minus8 + 8; + data.BL_video_full_range_flag = BL_video_full_range_flag; + data.isMEL = isMEL; + data.CMv = CMv; + data.active_area_left_offset = active_area_left_offset; + data.active_area_right_offset = active_area_right_offset; + data.active_area_top_offset = active_area_top_offset; + data.active_area_bottom_offset = active_area_bottom_offset; + data.max_display_mastering_luminance = max_display_mastering_luminance; + data.min_display_mastering_luminance = min_display_mastering_luminance; + data.max_content_light_level = max_content_light_level; + data.max_frame_average_light_level = max_frame_average_light_level; + data.L11_present = L11_present; + data.content_type = content_type; + data.white_point = white_point; + data.reference_mode = reference_mode_flag; + FILLING_END(); +} + +#endif // defined(MEDIAINFO_HEVC_YES) || defined(MEDIAINFO_AV1_YES) + //--------------------------------------------------------------------------- #if defined(MEDIAINFO_AV1_YES) || defined(MEDIAINFO_AVC_YES) || defined(MEDIAINFO_HEVC_YES) || defined(MEDIAINFO_MPEG4_YES) void File__Analyze::Get_LightLevel(Ztring &MaxCLL, Ztring &MaxFALL, int32u Divisor) diff --git a/Source/MediaInfo/Video/File_Av1.cpp b/Source/MediaInfo/Video/File_Av1.cpp index b297d93d1a..ef8ac3a34a 100644 --- a/Source/MediaInfo/Video/File_Av1.cpp +++ b/Source/MediaInfo/Video/File_Av1.cpp @@ -768,11 +768,220 @@ void File_Av1::metadata_itu_t_t35_B5() switch (itu_t_t35_terminal_provider_code) { + case 0x003B: Param_Info1("Dolby Laboratories, Inc."); metadata_itu_t_t35_B5_003B(); break; case 0x003C: Param_Info1("Samsung Electronics America"); metadata_itu_t_t35_B5_003C(); break; case 0x5890: Param_Info1("AOMedia"); metadata_itu_t_t35_B5_5890(); break; } } +//--------------------------------------------------------------------------- +void File_Av1::metadata_itu_t_t35_B5_003B() +{ + int32u itu_t_t35_terminal_provider_oriented_code; + Get_B4(itu_t_t35_terminal_provider_oriented_code, "itu_t_t35_terminal_provider_oriented_code"); + + switch (itu_t_t35_terminal_provider_oriented_code) + { + case 0x00000800: metadata_itu_t_t35_B5_003B_00000800(); break; + } + +} + +//--------------------------------------------------------------------------- +void File_Av1::metadata_itu_t_t35_B5_003B_00000800() +{ + Element_Info1("Extensible Metadata Delivery Format (EMDF)"); + + auto Get_V4{ [this](int8u Bits, int32u& Info, const char* Name) + { + Info = 0; + + #if MEDIAINFO_TRACE + int8u Count = 0; + #endif //MEDIAINFO_TRACE + for (;;) + { + Info += BS->Get4(Bits); + #if MEDIAINFO_TRACE + Count += Bits; + #endif //MEDIAINFO_TRACE + if (!BS->GetB()) + break; + Info <<= Bits; + Info += (1 << Bits); + } + #if MEDIAINFO_TRACE + if (Trace_Activated) + { + Param(Name, Info, Count); + Param_Info(__T("(") + Ztring::ToZtring(Count) + __T(" bits)")); + } + #endif //MEDIAINFO_TRACE + } + }; + + auto Skip_V4{ [&](int8u Bits, const char* Name) { + int32u Info; + Get_V4(Bits, Info, Name); + } + }; + + BS_Begin(); + size_t Start = Data_BS_Remain(); + int32u version, key_id; + Element_Begin1("emdf_container"); + Get_S4 (2, version, "emdf_version"); + if (version == 3) + { + int32u add; + Get_V4(2, add, "emdf_version addition"); + version += add; + } + if (version) + { + Skip_BS(Data_BS_Remain(), "(Unparsed emdf_container data)"); + Element_End0(); + return; + } + + Get_S4 (3, key_id, "key_id"); + if (key_id == 7) + { + int32u add; + Get_V4 (3, add, "key_id addition"); + key_id += add; + } + Param_Info1C(key_id == 0x6, "Ignore protection bits"); + + int32u emdf_payload_id = 0; + + for(;;) + { + Element_Begin1("emdf_payload"); + Get_S4 (5, emdf_payload_id, "emdf_payload_id"); + if (emdf_payload_id==0x1F) + { + int32u add; + Get_V4 (5, add, "emdf_payload_id addition"); + emdf_payload_id += add; + } + + if (emdf_payload_id == 256) + Element_Info1("Dolby Vision Reference Processing Unit (RPU)"); + if (emdf_payload_id == 0x00) + { + Element_End0(); + break; + } + + Element_Begin1("emdf_payload_config"); + + bool smploffste = false; + Get_SB (smploffste, "smploffste"); + if (smploffste) + { + Skip_S2(11, "smploffst"); + Skip_SB( "reserved"); + } + + TEST_SB_SKIP( "duratione"); + Skip_V4(11, "duration"); + TEST_SB_END(); + TEST_SB_SKIP( "groupide"); + Skip_V4(2, "groupid"); + TEST_SB_END(); + TEST_SB_SKIP( "codecdatae"); + Skip_S1(8, "reserved"); + TEST_SB_END(); + + bool discard_unknown_payload = false; + Get_SB(discard_unknown_payload, "discard_unknown_payload"); + if (!discard_unknown_payload) + { + bool payload_frame_aligned = false; + if (!smploffste) + { + Get_SB (payload_frame_aligned, "payload_frame_aligned"); + if (payload_frame_aligned) + { + Skip_SB( "create_duplicate"); + Skip_SB( "remove_duplicate"); + } + } + + if (smploffste || payload_frame_aligned) + { + Skip_S1(5, "priority"); + Skip_S1(2, "proc_allowed"); + } + } + + Element_End0(); // emdf_payload_config + + int32u emdf_payload_size = 0; + Get_V4 (8, emdf_payload_size, "emdf_payload_size"); + size_t emdf_payload_End = Data_BS_Remain() - static_cast(emdf_payload_size) * 8; + + Element_Begin1("emdf_payload_bytes"); + switch (emdf_payload_id) + { + case 256: Get_DolbyVision_ReferenceProcessingUnit(DV_RPU_data); break; + default : Skip_BS(static_cast(emdf_payload_size) * 8, "(Unknown)"); break; + } + size_t RemainginBits=Data_BS_Remain(); + if (RemainginBits>=emdf_payload_End) + { + if (RemainginBits>emdf_payload_End) + Skip_BS(RemainginBits-emdf_payload_End, "(Unparsed bits)"); + } + else + { + //There is a problem, too many bits were consumed by the parser. //TODO: prevent the parser to consume more bits than count of bits in this element + if (Data_BS_Remain()) + Skip_BS(Data_BS_Remain(), "(Problem during emdf_payload parsing)"); + else + Skip_BS(Data_BS_Remain(), "(Problem during emdf_payload parsing, going to end directly)"); + Element_End0(); + Element_End0(); + break; + } + Element_End0(); // emdf_payload_bytes + + Element_End0(); // emdf_payload + } + + Element_Begin1("emdf_protection"); + + int8u len_primary = 0, len_second = 0; + Get_S1(2, len_primary, "protection_length_primary"); + Get_S1(2, len_second, "protection_length_secondary"); + + switch (len_primary) + { + //case 0: break; //protection_length_primary coherency was already tested in sync layer + case 1: len_primary = 8; break; + case 2: len_primary = 32; break; + case 3: len_primary = 128; break; + default:; //Cannot append, read only 2 bits + }; + switch (len_second) + { + case 0: len_second = 0; break; + case 1: len_second = 8; break; + case 2: len_second = 32; break; + case 3: len_second = 128; break; + default:; //Cannot append, read only 2 bits + }; + Skip_BS(len_primary, "protection_bits_primary"); + if (len_second) + Skip_BS(len_second, "protection_bits_secondary"); + + Element_End0(); // emdf_protection + + Element_End0(); // emdf_container + BS_End(); +} + //--------------------------------------------------------------------------- void File_Av1::metadata_itu_t_t35_B5_003C() { diff --git a/Source/MediaInfo/Video/File_Av1.h b/Source/MediaInfo/Video/File_Av1.h index 19e7fd774d..aa2b0b13f6 100644 --- a/Source/MediaInfo/Video/File_Av1.h +++ b/Source/MediaInfo/Video/File_Av1.h @@ -63,6 +63,8 @@ private : void metadata_hdr_mdcv(); void metadata_itu_t_t35(); void metadata_itu_t_t35_B5(); + void metadata_itu_t_t35_B5_003B(); + void metadata_itu_t_t35_B5_003B_00000800(); void metadata_itu_t_t35_B5_003C(); void metadata_itu_t_t35_B5_003C_0001(); void metadata_itu_t_t35_B5_003C_0001_04(); @@ -91,6 +93,7 @@ private : typedef std::map hdr; hdr HDR; std::set scalability_structure_seen; + DV_RPU DV_RPU_data; //Helpers std::string GOP_Detect(std::string PictureTypes); diff --git a/Source/MediaInfo/Video/File_Hevc.cpp b/Source/MediaInfo/Video/File_Hevc.cpp index bed76176bf..87cd975ddf 100644 --- a/Source/MediaInfo/Video/File_Hevc.cpp +++ b/Source/MediaInfo/Video/File_Hevc.cpp @@ -1344,6 +1344,8 @@ void File_Hevc::Data_Parse() case 39 : case 40 : sei(); break; + case 62 : Dolby_Vision_reference_processing_unit(); break; + case 63 : Dolby_Vision_enhancement_layer(); break; default : Skip_XX(Element_Size-Element_Offset, "Data"); if (Element_Code>=48) @@ -3761,6 +3763,115 @@ void File_Hevc::three_dimensional_reference_displays_info(int32u payloadSize) FILLING_END(); } +//--------------------------------------------------------------------------- +// Packet "62" +void File_Hevc::Dolby_Vision_reference_processing_unit() +{ + int8u nal_prefix; + Peek_B1(nal_prefix); + if (nal_prefix != 25) { + Skip_XX(Element_Size - Element_Offset, "Data"); + Trusted_IsNot("Unspecified"); + return; + } + + Element_Name("Dolby Vision Reference Processing Unit (RPU)"); + + //Parsing + Skip_B1( "nal_prefix"); + BS_Begin(); + Get_DolbyVision_ReferenceProcessingUnit(DV_RPU_data); + BS_End(); +} + +//--------------------------------------------------------------------------- +// Packet "63" +void File_Hevc::Dolby_Vision_enhancement_layer() +{ +#if MEDIAINFO_TRACE + + Element_Name("Dolby Vision Enhancement Layer (EL)"); + + Element_Begin0(); + Element_Begin1("Header"); + int8u nal_unit_type; + BS_Begin(); + Mark_0(); + Get_S1 (6, nal_unit_type, "nal_unit_type"); + Skip_S1(6, "nuh_layer_id"); + Skip_S1(3, "nuh_temporal_id_plus1"); + BS_End(); + Element_End0(); + + 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: + Element_Name("slice_segment_layer"); break; + case 32: Element_Name("video_parameter_set"); break; + case 33: Element_Name("seq_parameter_set"); break; + case 34: Element_Name("pic_parameter_set"); break; + case 35: + { + Element_Name("access_unit_delimiter"); + BS_Begin(); + Info_S1(3, pic_type, "pic_type"); Param_Info1(Hevc_pic_type[pic_type]); + Mark_1(); + BS_End(); + break; + } + case 36: Element_Name("end_of_seq"); break; + case 37: Element_Name("end_of_bitstream"); break; + case 38: Element_Name("filler_data"); break; + case 39: + case 40: + { + Element_Name("sei"); + Element_Begin1("sei message header"); + int8u payload_type_byte; + Get_B1 (payload_type_byte, "payload_type_byte"); + Skip_B1( "payload_size_byte"); + Element_End0(); + switch (payload_type_byte) + { + case 0: Element_Info1("buffering_period"); break; + case 1: Element_Info1("pic_timing"); break; + case 4: Element_Info1("user_data_registered_itu_t_t35"); break; + case 5: Element_Info1("user_data_unregistered"); break; + case 6: Element_Info1("recovery_point"); break; + case 129: Element_Info1("active_parameter_sets"); break; + case 132: Element_Info1("decoded_picture_hash"); break; + case 136: Element_Info1("time_code"); break; + case 137: Element_Info1("mastering_display_colour_volume"); break; + case 144: Element_Info1("light_level"); break; + case 147: Element_Info1("transfer_characteristics"); break; + case 148: Element_Info1("viewing_environment"); break; + case 176: Element_Info1("three_dimensional_reference_displays_info"); break; + default : Element_Info1(Ztring().From_CC1(payload_type_byte)); break; + } + break; + } + default: Element_Name(Ztring().From_CC1(nal_unit_type)); break; + } + Skip_XX(Element_Size - Element_Offset, "Data"); + Element_End0(); + +#endif // MEDIAINFO_TRACE +} + //*************************************************************************** // Sub-elements //*************************************************************************** diff --git a/Source/MediaInfo/Video/File_Hevc.h b/Source/MediaInfo/Video/File_Hevc.h index e2477f90d6..e690225cb4 100644 --- a/Source/MediaInfo/Video/File_Hevc.h +++ b/Source/MediaInfo/Video/File_Hevc.h @@ -412,6 +412,8 @@ private : void sei_alternative_transfer_characteristics(); void sei_ambient_viewing_environment(); void three_dimensional_reference_displays_info(int32u payloadSize); + void Dolby_Vision_reference_processing_unit(); + void Dolby_Vision_enhancement_layer(); //Packets - SubElements void slice_segment_header(); @@ -515,6 +517,7 @@ private : }; typedef std::map hdr; hdr HDR; + DV_RPU DV_RPU_data; Ztring EtsiTS103433; int32u chroma_format_idc{}; int32u slice_pic_parameter_set_id{}; From 4ccf4b8284df9343b16f02f1b8419d547f2fdb40 Mon Sep 17 00:00:00 2001 From: cjee21 <77721854+cjee21@users.noreply.github.com> Date: Sun, 8 Feb 2026 14:35:34 +0800 Subject: [PATCH 2/2] Fix warnings in HEVC & Analyze_Streams --- Source/MediaInfo/File__Analyze_Streams.cpp | 22 +++++++++++----------- Source/MediaInfo/Video/File_Hevc.cpp | 18 +++++++++--------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Source/MediaInfo/File__Analyze_Streams.cpp b/Source/MediaInfo/File__Analyze_Streams.cpp index 9e612818c0..43bc5b2586 100644 --- a/Source/MediaInfo/File__Analyze_Streams.cpp +++ b/Source/MediaInfo/File__Analyze_Streams.cpp @@ -161,13 +161,13 @@ namespace MediaInfoLib //--------------------------------------------------------------------------- static const float digit_to_precision[] = { - 0.5, - 0.05, - 0.005, - 0.0005, - 0.00005, - 0.000005, - 0.0000005, + 0.5f, + 0.05f, + 0.005f, + 0.0005f, + 0.00005f, + 0.000005f, + 0.0000005f, }; const size_t digit_to_precision_Size = sizeof(digit_to_precision) / sizeof(*digit_to_precision); bool Location_Compare(const string& Current, const string& CompareTo, bool& Replace) @@ -688,8 +688,8 @@ void File__Analyze::Get_MasteringDisplayColorVolume(Ztring &MasteringDisplay_Col if (Meta.Luminance[0]!=(int32u)-1 && Meta.Luminance[1]!=(int32u)-1) { - float32 Luminance_Min_Ratio=FromAV1?16384:10000; // 18.14 fixed-point, MPEG values are x10000 - float32 Luminance_Max_Ratio=FromAV1?256:10000; // 24.8 fixed-point, MPEG values are x10000 + float32 Luminance_Min_Ratio=static_cast(FromAV1?16384:10000); // 18.14 fixed-point, MPEG values are x10000 + float32 Luminance_Max_Ratio=static_cast(FromAV1?256:10000); // 24.8 fixed-point, MPEG values are x10000 MasteringDisplay_Luminance= __T("min: ")+Ztring::ToZtring(((float64)Meta.Luminance[0])/Luminance_Min_Ratio, 4) +__T(" cd/m2, max: ")+Ztring::ToZtring(((float64)Meta.Luminance[1])/Luminance_Max_Ratio, ((float64)Meta.Luminance[1]/Luminance_Max_Ratio-Meta.Luminance[1]/Luminance_Max_Ratio==0)?0:4) +__T(" cd/m2"); @@ -1600,9 +1600,9 @@ void File__Analyze::Get_LightLevel(Ztring &MaxCLL, Ztring &MaxFALL, int32u Divis auto Decimals=to_string(Divisor).size()-1; if (maximum_content_light_level) - MaxCLL=Ztring::ToZtring(((float32)maximum_content_light_level)/Divisor, Decimals); + MaxCLL=Ztring::ToZtring(((float32)maximum_content_light_level)/Divisor, (int8u)Decimals); if (maximum_frame_average_light_level) - MaxFALL=Ztring::ToZtring(((float32)maximum_frame_average_light_level)/Divisor, Decimals); + MaxFALL=Ztring::ToZtring(((float32)maximum_frame_average_light_level)/Divisor, (int8u)Decimals); } else { diff --git a/Source/MediaInfo/Video/File_Hevc.cpp b/Source/MediaInfo/Video/File_Hevc.cpp index 87cd975ddf..d686ec9538 100644 --- a/Source/MediaInfo/Video/File_Hevc.cpp +++ b/Source/MediaInfo/Video/File_Hevc.cpp @@ -1153,7 +1153,7 @@ void File_Hevc::Header_Parse() if (Buffer_Offset_Temp+3<=Buffer_Offset+Size) { SizedBlocks_FileThenStream=File_Offset+Buffer_Offset+Size; - Size=Buffer_Offset_Temp-(Buffer_Offset+Element_Offset); + Size=static_cast(Buffer_Offset_Temp-(Buffer_Offset+Element_Offset)); } Header_Fill_Size(Element_Offset+Size); @@ -1823,18 +1823,18 @@ void File_Hevc::video_parameter_set() 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++) + for (int32u 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"); + Get_S4 ((int8u)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++) + for (int32u i = 0; i < num_add_layer_sets; i++) { int32u layerNum = 0; auto lsIdx = vps_num_layer_sets_minus1 + 1 + i; @@ -1865,7 +1865,7 @@ void File_Hevc::video_parameter_set() 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++) + for (int32u 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"); @@ -3152,7 +3152,7 @@ void File_Hevc::sei_message_user_data_registered_itu_t_t35_B5_003A_02() Skip_S1 (3, "sl_hdr_mode_support"); } else - Skip_S1 (Data_BS_Remain(), "Unknown"); + Skip_BS (Data_BS_Remain(), "Unknown"); BS_End(); } @@ -3949,13 +3949,13 @@ void File_Hevc::slice_segment_header() 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; + FrameRate=(float)((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)) + if (pic_order_cnt>= ((int64s)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) @@ -4787,7 +4787,7 @@ void File_Hevc::rbsp_trailing_bits() { int8u RealValue; const int8u ExpectedValue=1<<(Remain-1); - Peek_S1(Remain, RealValue); + Peek_S1((int8u)Remain, RealValue); if (RealValue==ExpectedValue) { // Conform to specs