From e88bb1aee5ebdf3cda3dc59817588a6ad8eecb8f Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Wed, 15 Aug 2007 17:59:22 +0000 Subject: [PATCH] Don't remove SPS and PPS NALUs from AVC/h.264 streams. --- ChangeLog | 5 +++++ src/common/mpeg4_common.cpp | 40 +++++++++++++++++++++++++++++-------- src/common/mpeg4_common.h | 4 ++++ tests/results.txt | 6 +++--- 4 files changed, 44 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 79aa8406b..1a0de9d7c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2007-08-15 Moritz Bunkus + + * mkvmerge: bug fix: SPS and PPS NALUs are no longer removed from + AVC/h.264 streams. Hopefully a fix for bug 231. + 2007-07-19 Moritz Bunkus * mkvmerge: enhancement: Fixed SSA/ASS detection for files diff --git a/src/common/mpeg4_common.cpp b/src/common/mpeg4_common.cpp index 37b01a4c2..de721db10 100644 --- a/src/common/mpeg4_common.cpp +++ b/src/common/mpeg4_common.cpp @@ -695,6 +695,8 @@ mpeg4::p10::parse_sps(memory_cptr &buffer, buffer = mcptr_newsps; buffer->set_size(w.get_bit_position() / 8); + sps.checksum = calc_adler32(buffer->get(), buffer->get_size()); + return true; } @@ -715,6 +717,8 @@ mpeg4::p10::parse_pps(memory_cptr &buffer, r.skip_bits(1); // entropy_coding_mode_flag pps.pic_order_present = r.get_bit(); + pps.checksum = calc_adler32(buffer->get(), buffer->get_size()); + return true; } catch (...) { return false; @@ -1223,41 +1227,61 @@ mpeg4::p10::avc_es_parser_c::handle_slice_nalu(memory_cptr &nalu) { void mpeg4::p10::avc_es_parser_c::handle_sps_nalu(memory_cptr &nalu) { sps_info_t sps_info; - vector::iterator i; + int i; nalu_to_rbsp(nalu); if (!parse_sps(nalu, sps_info, m_keep_ar_info)) return; rbsp_to_nalu(nalu); - mxforeach(i, m_sps_info_list) - if (i->id == sps_info.id) + for (i = 0; m_sps_info_list.size() > i; ++i) + if (m_sps_info_list[i].id == sps_info.id) break; - if (m_sps_info_list.end() == i) { + + if (m_sps_info_list.size() == i) { m_sps_list.push_back(nalu); m_sps_info_list.push_back(sps_info); m_avcc_changed = true; + + } else if (m_sps_info_list[i].checksum != sps_info.checksum) { + mxverb(2, "mpeg4::p10: SPS ID %04x changed; checksum old %04x new %04x\n", sps_info.id, m_sps_info_list[i].checksum, sps_info.checksum); + + m_sps_info_list[i] = sps_info; + m_sps_list[i] = nalu; + m_avcc_changed = true; } + + m_extra_data.push_back(create_nalu_with_size(nalu)); } void mpeg4::p10::avc_es_parser_c::handle_pps_nalu(memory_cptr &nalu) { pps_info_t pps_info; - vector::iterator i; + int i; nalu_to_rbsp(nalu); if (!parse_pps(nalu, pps_info)) return; rbsp_to_nalu(nalu); - mxforeach(i, m_pps_info_list) - if (i->id == pps_info.id) + for (i = 0; m_pps_info_list.size() > i; ++i) + if (m_pps_info_list[i].id == pps_info.id) break; - if (m_pps_info_list.end() == i) { + + if (m_pps_info_list.size() == i) { m_pps_list.push_back(nalu); m_pps_info_list.push_back(pps_info); m_avcc_changed = true; + + } else if (m_pps_info_list[i].checksum != pps_info.checksum) { + mxverb(2, "mpeg4::p10: PPS ID %04x changed; checksum old %04x new %04x\n", pps_info.id, m_pps_info_list[i].checksum, pps_info.checksum); + + m_pps_info_list[i] = pps_info; + m_pps_list[i] = nalu; + m_avcc_changed = true; } + + m_extra_data.push_back(create_nalu_with_size(nalu)); } void diff --git a/src/common/mpeg4_common.h b/src/common/mpeg4_common.h index e1ed4b588..2c4105a89 100644 --- a/src/common/mpeg4_common.h +++ b/src/common/mpeg4_common.h @@ -218,6 +218,8 @@ namespace mpeg4 { unsigned crop_left, crop_top, crop_right, crop_bottom; unsigned width, height; + uint32_t checksum; + sps_info_t() { memset(this, 0, sizeof(*this)); } @@ -229,6 +231,8 @@ namespace mpeg4 { bool pic_order_present; + uint32_t checksum; + pps_info_t() { memset(this, 0, sizeof(*this)); } diff --git a/tests/results.txt b/tests/results.txt index 000148f24..71782480b 100644 --- a/tests/results.txt +++ b/tests/results.txt @@ -72,9 +72,9 @@ T_222stereo_mode:22eebd6bda7d848379044be8d9d8f440-38a1988c087c40e6e52025bb974f2c T_223ra_cook_keyframes:9586107c7cf22c7fe4e3a3513f8da68d:passed:20061228-150947 T_224dts:af6388e169eb68cfb5e3ce3af8b39da3-844ad568698bde5b3b778632f355aab8:passed:20070206-174735 T_225dts_in_wav:8bc50d56c1bc7031284c963b0c00389c-7438d3051d05d983d1cf740902a1b913:passed:20070206-174726 -T_226h264:9e28bc123b7eed1a3884843d852c37a4:passed:20070208-103558 -T_227h264_with_garbage:728d3bbf0de07225130ba4d4b1eb176d:passed:20070208-103656 -T_228h264_no_idr_slices:fe4cd3110b305aeba4d4ee1c80737651:passed:20070426-103130 +T_226h264:d2599cdc7b3aa46f2b00c5ef49f948d2:passed:20070208-103558 +T_227h264_with_garbage:a390685806a6282bbf68593329728557:passed:20070208-103656 +T_228h264_no_idr_slices:80c935a51e96facf6a4232df8c647cfa:passed:20070426-103130 T_229rav3_in_rm:afe8fabeb8f8d74f29a5116b731c3262:passed:20070619-220659 T_230h264_nalu_size_len_change:7778979ff769e9c85cd052ea1731beb0-abf88626e2ae80e8711b3bce9ba2ed2e:passed:20070622-103843 T_231X_ac3_header_removal:6ca341797c5f93e273c8502f4d6f4fba:passed:20070623-111240