QuickTime/MP4 reader: handle sound stsd samples_per_frame == 0

This commit is contained in:
Moritz Bunkus 2016-01-15 23:27:08 +01:00
parent 98fce862fd
commit 82336dc470
2 changed files with 18 additions and 6 deletions

View File

@ -1,3 +1,9 @@
2016-01-15 Moritz Bunkus <moritz@bunkus.org>
* 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 <moritz@bunkus.org> 2016-01-13 Moritz Bunkus <moritz@bunkus.org>
* mkvinfo: bug fix: global elements (EBML void and CRC-32 * mkvinfo: bug fix: global elements (EBML void and CRC-32

View File

@ -2291,6 +2291,13 @@ qtmp4_demuxer_c::build_index_constant_sample_size_mode() {
size_t keyframe_table_idx = 0; size_t keyframe_table_idx = 0;
size_t keyframe_table_size = keyframe_table.size(); size_t keyframe_table_size = keyframe_table.size();
auto is_audio = 'a' == type;
auto sound_stsd_atom = reinterpret_cast<sound_v1_stsd_atom_t *>(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; size_t frame_idx;
for (frame_idx = 0; frame_idx < chunk_table.size(); ++frame_idx) { for (frame_idx = 0; frame_idx < chunk_table.size(); ++frame_idx) {
uint64_t frame_size; uint64_t frame_size;
@ -2301,13 +2308,12 @@ qtmp4_demuxer_c::build_index_constant_sample_size_mode() {
} else { } else {
frame_size = chunk_table[frame_idx].size; frame_size = chunk_table[frame_idx].size;
if ('a' == type) { if (is_audio) {
auto sound_stsd_atom = reinterpret_cast<sound_v1_stsd_atom_t *>(stsd->get_buffer()); if ((0 != v1_bytes_per_frame) && (0 != v1_samples_per_packet)) {
if (get_uint16_be(&sound_stsd_atom->v0.version) == 1) { frame_size *= v1_bytes_per_frame;
frame_size *= get_uint32_be(&sound_stsd_atom->v1.bytes_per_frame); frame_size /= v1_samples_per_packet;
frame_size /= get_uint32_be(&sound_stsd_atom->v1.samples_per_packet);
} else } 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;
} }
} }