diff --git a/ChangeLog b/ChangeLog index 2639a65db..ee39c8c2e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2015-03-29 Moritz Bunkus + * mkvmerge: bug fix: The calculation of the width and height of + h.265/HEVC video tracks did not take the conformance window + (cropping) into account. Fixes #1152. + * mkvmerge: bug fix: Fixed the value of the DocTypeVersion header field if any of the Matroska elements CodecDelay, DiscardPadding or SeekPreRoll is used. This is the case for Opus tracks. diff --git a/src/common/hevc.cpp b/src/common/hevc.cpp index a0c74a348..0dc3f0098 100644 --- a/src/common/hevc.cpp +++ b/src/common/hevc.cpp @@ -1117,11 +1117,12 @@ parse_sps(memory_cptr &buffer, sps.width = w.copy_unsigned_golomb(r); // pic_width_in_luma_samples sps.height = w.copy_unsigned_golomb(r); // pic_height_in_luma_samples - if (w.copy_bits(1, r) == 1) { - w.copy_unsigned_golomb(r); // conf_win_left_offset - w.copy_unsigned_golomb(r); // conf_win_right_offset - w.copy_unsigned_golomb(r); // conf_win_top_offset - w.copy_unsigned_golomb(r); // conf_win_bottom_offset + sps.conformance_window_flag = w.copy_bits(1, r); + if (sps.conformance_window_flag) { + sps.conf_win_left_offset = w.copy_unsigned_golomb(r); // conf_win_left_offset + sps.conf_win_right_offset = w.copy_unsigned_golomb(r); // conf_win_right_offset + sps.conf_win_top_offset = w.copy_unsigned_golomb(r); // conf_win_top_offset + sps.conf_win_bottom_offset = w.copy_unsigned_golomb(r); // conf_win_bottom_offset } sps.bit_depth_luma_minus8 = w.copy_unsigned_golomb(r); // bit_depth_luma_minus8 @@ -1192,6 +1193,16 @@ parse_sps(memory_cptr &buffer, sps.checksum = mtx::checksum::calculate_as_uint(mtx::checksum::algorithm_e::adler32, *buffer); + // See ITU-T H.265 section 7.4.3.2 for the width/height calculation + // formula. + if (sps.conformance_window_flag) { + auto sub_width_c = ((1 == sps.chroma_format_idc) || (2 == sps.chroma_format_idc)) && (0 == sps.separate_colour_plane_flag) ? 2 : 1; + auto sub_height_c = (1 == sps.chroma_format_idc) && (0 == sps.separate_colour_plane_flag) ? 2 : 1; + + sps.width -= std::min((sub_width_c * sps.conf_win_right_offset) + (sub_width_c * sps.conf_win_left_offset), sps.width); + sps.height -= std::min((sub_height_c * sps.conf_win_bottom_offset) + (sub_height_c * sps.conf_win_top_offset), sps.height); + } + return true; } diff --git a/src/common/hevc.h b/src/common/hevc.h index 0540f6db7..13354b94e 100644 --- a/src/common/hevc.h +++ b/src/common/hevc.h @@ -263,6 +263,9 @@ struct sps_info_t { unsigned int log2_diff_max_min_luma_coding_block_size; unsigned int log2_max_pic_order_cnt_lsb; + bool conformance_window_flag; + unsigned int conf_win_left_offset, conf_win_right_offset, conf_win_top_offset, conf_win_bottom_offset; + // vui: bool vui_present, ar_found; unsigned int par_num, par_den; diff --git a/tests/results.txt b/tests/results.txt index 10c2c5a9e..8ad9e9769 100644 --- a/tests/results.txt +++ b/tests/results.txt @@ -327,9 +327,10 @@ T_478ui_locale_sr_RS:e82297022868c560a80c41513033ef39-2cdbfc8453e871653f2243f91e T_479dts_7_1_channels:4f310bdab1c5d09d045dc7cfa6dfd620-22473473f925932cdbed04adc86bab0c:passed:20150325-221521:0.561800769 T_480dts_express:564af1cf4765e27e054d248ccb214cd6-f4a3abe81bdf0fb40a6ba8c0983e3e0b:passed:20150326-093608:0.611162252 T_481dts_hd_high_resolution:18be2234293a4ca12ecfa0c1648e853e-edb2e77c3a778f2fd0b3fe5db71637c1:passed:20150326-184450:1.647462876 -T_482hevc_no_aspect_ratio_in_sps:6ee3a0bc21ccabde46a8c7af049b120e-3d1417ef349f58a50c768a13b6daf2d4-3f56f42c30cdffd70c4992a1eaeb2332:passed:20150327-125855:0.880932303 +T_482hevc_no_aspect_ratio_in_sps:4bf1bfa9cfa6b463070f6ed5dd246966-3d1417ef349f58a50c768a13b6daf2d4-3f56f42c30cdffd70c4992a1eaeb2332:passed:20150327-125855:0.880932303 T_483select_tracks_by_language:29372d441ceb28c4619b67bb4341ad31+3c1bb1b57f532c27a6e4ee3f5d9490f2+3c1bb1b57f532c27a6e4ee3f5d9490f2+3c1bb1b57f532c27a6e4ee3f5d9490f2+8addc95582a81fae7df19cf954945fe3:passed:20150328-191349:0.156972906 T_484dts_without_core_xll_substream:f562501d11cc5c773bae34670b50d7b4:passed:20150328-221149:0.468020256 T_485dtshd_file_format:577be0cf2bffc155aacd74a7bc2619dd:passed:20150329-085728:1.683480773 T_486m2ts_eac3_with_extension_in_own_packet:265d8436497eb50f49b24805a08cd39a:passed:20150329-193642:0.518299841 T_487matroska_version_and_read_version_with_opus:4+2-4+2-4+2-4+1-4+2-4+1-4+1-4+1:passed:20150329-213811:0.670610463 +T_488hevc_conformance_window_with_cropping:71d84f56384c2d25fe55477766b7604d:passed:20150329-220212:0.705828455 diff --git a/tests/test-488hevc_conformance_window_with_cropping.rb b/tests/test-488hevc_conformance_window_with_cropping.rb new file mode 100755 index 000000000..e64d06d23 --- /dev/null +++ b/tests/test-488hevc_conformance_window_with_cropping.rb @@ -0,0 +1,5 @@ +#!/usr/bin/ruby -w + +# T_488hevc_conformance_window_with_cropping +describe "mkvmerge / HEVC with conformance_window in SPS present and cropping applied" +test_merge "data/h265/hevc_1080_lines_deteced_as_1088.265"