diff --git a/ChangeLog b/ChangeLog index 730b2589b..9387a8161 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2016-01-15 Moritz Bunkus + + * mkvmerge: QuickTime/MP4 reader: fix a division by zero in the + index generation for certain old audio codecs that have certain + header fields (bytes_per_frame, samples_per_packet) set to 0. + 2016-01-13 Moritz Bunkus * mkvinfo: bug fix: global elements (EBML void and CRC-32 diff --git a/src/input/r_qtmp4.cpp b/src/input/r_qtmp4.cpp index 274d98f76..cb1cb9378 100644 --- a/src/input/r_qtmp4.cpp +++ b/src/input/r_qtmp4.cpp @@ -2291,6 +2291,13 @@ qtmp4_demuxer_c::build_index_constant_sample_size_mode() { size_t keyframe_table_idx = 0; size_t keyframe_table_size = keyframe_table.size(); + auto is_audio = 'a' == type; + auto sound_stsd_atom = reinterpret_cast(is_audio && stsd ? stsd->get_buffer() : nullptr); + auto v0_sample_size = sound_stsd_atom ? get_uint16_be(&sound_stsd_atom->v0.sample_size) : 0; + auto v0_audio_version = sound_stsd_atom ? get_uint16_be(&sound_stsd_atom->v0.version) : 0; + auto v1_bytes_per_frame = 1 == v0_audio_version ? get_uint32_be(&sound_stsd_atom->v1.bytes_per_frame) : 0; + auto v1_samples_per_packet = 1 == v0_audio_version ? get_uint32_be(&sound_stsd_atom->v1.samples_per_packet) : 0; + size_t frame_idx; for (frame_idx = 0; frame_idx < chunk_table.size(); ++frame_idx) { uint64_t frame_size; @@ -2301,13 +2308,12 @@ qtmp4_demuxer_c::build_index_constant_sample_size_mode() { } else { frame_size = chunk_table[frame_idx].size; - if ('a' == type) { - auto sound_stsd_atom = reinterpret_cast(stsd->get_buffer()); - if (get_uint16_be(&sound_stsd_atom->v0.version) == 1) { - frame_size *= get_uint32_be(&sound_stsd_atom->v1.bytes_per_frame); - frame_size /= get_uint32_be(&sound_stsd_atom->v1.samples_per_packet); + if (is_audio) { + if ((0 != v1_bytes_per_frame) && (0 != v1_samples_per_packet)) { + frame_size *= v1_bytes_per_frame; + frame_size /= v1_samples_per_packet; } else - frame_size = frame_size * a_channels * get_uint16_be(&sound_stsd_atom->v0.sample_size) / 8; + frame_size = frame_size * a_channels * v0_sample_size / 8; } }