AVC parser: use 25 FPS instead of bogus timing info values from SPS

Fixes #1946.
This commit is contained in:
Moritz Bunkus 2017-04-17 20:32:45 +02:00
parent 6bed17f55f
commit 5e48f483b0
5 changed files with 29 additions and 4 deletions

View File

@ -52,6 +52,9 @@
* mkvmerge: fixed an endless loop in certain circumstances when splitting by * mkvmerge: fixed an endless loop in certain circumstances when splitting by
`parts` or `parts-frames` and the start of the file is discarded. Fixes `parts` or `parts-frames` and the start of the file is discarded. Fixes
#1944. #1944.
* mkvmerge: AVC/h.264 parser: mkvmerge will now ignore bogus timing
information in the sequence parameter sets (values indicating more than
100000 progressive frames per second). Fixes #1946.
## Build system changes ## Build system changes

View File

@ -265,6 +265,14 @@ mpeg4::p10::timing_info_t::default_duration()
return 1000000000ll * num_units_in_tick / time_scale; return 1000000000ll * num_units_in_tick / time_scale;
} }
bool
mpeg4::p10::timing_info_t::is_valid()
const {
return is_present
&& (0 != num_units_in_tick)
&& (0 != time_scale);
}
void void
mpeg4::p10::sps_info_t::dump() { mpeg4::p10::sps_info_t::dump() {
mxinfo(boost::format("sps_info dump:\n" mxinfo(boost::format("sps_info dump:\n"
@ -327,9 +335,7 @@ mpeg4::p10::sps_info_t::dump() {
bool bool
mpeg4::p10::sps_info_t::timing_info_valid() mpeg4::p10::sps_info_t::timing_info_valid()
const { const {
return timing_info.is_present return timing_info.is_valid();
&& (0 != timing_info.num_units_in_tick)
&& (0 != timing_info.time_scale);
} }
void void
@ -563,6 +569,15 @@ mpeg4::p10::parse_sps(memory_cptr const &buffer,
sps.timing_info.num_units_in_tick = r.get_bits(32); sps.timing_info.num_units_in_tick = r.get_bits(32);
sps.timing_info.time_scale = r.get_bits(32); sps.timing_info.time_scale = r.get_bits(32);
sps.timing_info.fixed_frame_rate = r.get_bit(); sps.timing_info.fixed_frame_rate = r.get_bit();
if ( sps.timing_info.is_valid()
&& (sps.timing_info.default_duration() < 5'000ll)) {
mxdebug_if(s_debug_fix_bistream_timing_info,
boost::format("timing info present && bogus values detected (#units %2% time_scale %3%); defaulting to 25 FPS (default duration 20'000'000)\n")
% sps.timing_info.is_present % sps.timing_info.num_units_in_tick % sps.timing_info.time_scale);
sps.timing_info.num_units_in_tick = 1;
sps.timing_info.time_scale = 50;
}
} }
mxdebug_if(s_debug_fix_bistream_timing_info, mxdebug_if(s_debug_fix_bistream_timing_info,
@ -1307,7 +1322,7 @@ mpeg4::p10::avc_es_parser_c::handle_nalu(memory_cptr const &nalu,
int type = *(nalu->get_buffer()) & 0x1f; int type = *(nalu->get_buffer()) & 0x1f;
mxdebug_if(m_debug_nalu_types, boost::format("NALU type 0x%|1$02x| (%2%) size %3%\n") % type % get_nalu_type_name(type) % nalu->get_size()); mxdebug_if(m_debug_nalu_types, boost::format("NALU type 0x%|1$02x| (%2%) at %3% size %4%\n") % type % get_nalu_type_name(type) % nalu_pos % nalu->get_size());
switch (type) { switch (type) {
case NALU_TYPE_SEQ_PARAM: case NALU_TYPE_SEQ_PARAM:

View File

@ -56,6 +56,7 @@ struct timing_info_t {
bool is_present, fixed_frame_rate; bool is_present, fixed_frame_rate;
int64_t default_duration() const; int64_t default_duration() const;
bool is_valid() const;
}; };
struct sps_info_t { struct sps_info_t {

View File

@ -440,3 +440,4 @@ T_591hevc_wrong_number_of_parameter_sets:cc0ff46884d832c3b7234136f963bc39:passed
T_592mpeg_ts_aac_wrong_track_parameters_detected:25116993128e73fe9251dc7161ae8030:passed:20170412-225238:0.044257474 T_592mpeg_ts_aac_wrong_track_parameters_detected:25116993128e73fe9251dc7161ae8030:passed:20170412-225238:0.044257474
T_593flac_with_picture_metadata:c5779b653e274bbb49d3ddf0a274c63c-c58da16285f056972ce09e617e0bd19e-998802dac83743b286c37a681742f296-7cda56d8aceb15753fc915338f1c0fbb-0e4d2b364f8e535d64286ea154948709:passed:20170415-182414:0.302331784 T_593flac_with_picture_metadata:c5779b653e274bbb49d3ddf0a274c63c-c58da16285f056972ce09e617e0bd19e-998802dac83743b286c37a681742f296-7cda56d8aceb15753fc915338f1c0fbb-0e4d2b364f8e535d64286ea154948709:passed:20170415-182414:0.302331784
T_594hevc_split_parts_discarding_start_endless_loop:9728cf3f10e0c0aa187f4f7f55a4b7b6:passed:20170416-073513:0.635225717 T_594hevc_split_parts_discarding_start_endless_loop:9728cf3f10e0c0aa187f4f7f55a4b7b6:passed:20170416-073513:0.635225717
T_595h264_bogus_timing_info:78c27e10b35f3bfea09d8c005dead342:passed:20170417-200233:0.368456672

View File

@ -0,0 +1,5 @@
#!/usr/bin/ruby -w
# T_595h264_bogus_timing_info
describe "mkvmerge / h.264 files created by x264 with bogus timing information values"
test_merge "data/h264/bogus_timing_info.h264"