AVC/h.264 parser: flush queued frames on SPS/PPS changes

Whenever a sequence parameter set or picture parameter set
changes (meaning an SPS with the same ID as an earlier SPS but with
different content is found), all frames queued for order & timestamp
calculation must be flushed. Otherwise frame order calculation will be
based on wrong values for some frames and on correct values for other
frames.

Fixes #2028.
This commit is contained in:
Moritz Bunkus 2017-07-04 20:29:17 +02:00
parent de9f48dbc6
commit def48b2606
4 changed files with 15 additions and 1 deletions

View File

@ -7,6 +7,9 @@
* MKVToolNix GUI: multiplex tool: implemented a workaround for a crash that
could occur during drag & drop if at least one of the columns is
hidden. Fixes #2009.
* mkvmerge: AVC/h.264 parser: fixed wrong frame order & timestamp calculation
in certain situations when SPS (sequence parameter sets) or PPS (picture
parameter sets) change mid-sream. Fixes #2028.
# Version 13.0.0 "The Juggler" 2017-06-25

View File

@ -1197,6 +1197,8 @@ mpeg4::p10::avc_es_parser_c::handle_sps_nalu(memory_cptr const &nalu) {
} else if (m_sps_info_list[i].checksum != sps_info.checksum) {
mxdebug_if(m_debug_sps_pps_changes, boost::format("mpeg4::p10: SPS ID %|1$04x| changed; checksum old %|2$04x| new %|3$04x|\n") % sps_info.id % m_sps_info_list[i].checksum % sps_info.checksum);
cleanup();
m_sps_info_list[i] = sps_info;
m_sps_list[i] = parsed_nalu;
m_avcc_changed = true;
@ -1247,6 +1249,9 @@ mpeg4::p10::avc_es_parser_c::handle_pps_nalu(memory_cptr const &nalu) {
} else if (m_pps_info_list[i].checksum != pps_info.checksum) {
mxdebug_if(m_debug_sps_pps_changes, boost::format("mpeg4::p10: PPS ID %|1$04x| changed; checksum old %|2$04x| new %|3$04x|\n") % pps_info.id % m_pps_info_list[i].checksum % pps_info.checksum);
if (m_pps_info_list[i].sps_id != pps_info.sps_id)
cleanup();
m_pps_info_list[i] = pps_info;
m_pps_list[i] = nalu;
m_avcc_changed = true;

View File

@ -78,7 +78,7 @@ T_228h264_no_idr_slices:320e3ea079952e80e1110c3b1aac2dac:passed:20070426-103130:
T_229rav3_in_rm:3db8200918c4d94c59a1aeb15c0409f1:passed:20070619-220659:0.054850494
T_230h264_nalu_size_len_change:47e6449dbc974aaad4755bcab8f8be3f-993026f0388f0b1e6ea8be8c2ec55b37:passed:20070622-103843:0.273132819
T_231X_ac3_header_removal:6ca341797c5f93e273c8502f4d6f4fba:passed:20070623-111240:0.172661551
T_232h264_changing_sps_pps:943f7ef3ef518ac5cf03829e4748ed49:passed:20070815-211934:4.982966207
T_232h264_changing_sps_pps:bdc21768407975be6275dc3abeb2bcae:passed:20070815-211934:4.982966207
T_233srt_with_coordinates:0de6cfc206a5889a5bd7afc8ddd9bdb8:passed:20070819-203105:0.279280932
T_234avi_aac_codecid_0x706d:5d6ff6aca9c26ed9cf51bb1aaa32b10e:passed:20080223-174500:1.065188599
T_235wav_fmt_chunk_length:4a02ad008c2b504e3b9d702dabccfb4d:passed:20080226-134540:0.199256803
@ -450,3 +450,4 @@ T_601mp4_mpeg2_via_esds:5cadaf9b8dd86a51052182ed341a4bc0:passed:20170618-150319:
T_602vob_with_garbage_at_start:c34788ceb7d96fe4ea073c6227026bea:passed:20170619-185256:0.236132323
T_603mpeg_ps_ac3_not_enough_data_in_first_packet:1+189+128+AC_3/E_AC_3-2+189+129+AC_3/E_AC_3-3+189+130+AC_3/E_AC_3-4+189+131+AC_3/E_AC_3-5+189+132+AC_3/E_AC_3-6+189+133+AC_3/E_AC_3-7+189+134+AC_3/E_AC_3:passed:20170624-092201:0.028142136
T_604append_only_one_video_track_with_codec_private:ec52119afb52345809a1c5c1a43b6fe0:passed:20170624-105837:0.144927484
T_605h264_changing_sps_pps_wrong_frame_order_and_timestamps:1af409bd8266567525c54a0799de44cc:passed:20170704-211727:0.912982996

View File

@ -0,0 +1,5 @@
#!/usr/bin/ruby -w
# T_605h264_changing_sps_pps_wrong_frame_order_and_timestamps
describe "mkvmerge / AVC/h.264 wrong frame order & timestamps due to changing SPS/PPS"
test_merge "data/h264/changing-sps-pps2.h264"