qtmux: Un-merge the last two stsc entries after serializing

The last entry will most likely get new samples added to it in "robust"
muxing mode, changing the samples_per_chunk and thus making it wrong to
keep the last two entries merged. It will run into an assertion later
when adding a new sample to the chunk.

Thanks to gdiener@cardinalpeak.com for the analysis of the bug and
proposal for a solution.
This commit is contained in:
Sebastian Dröge 2017-06-15 11:50:44 +03:00
parent a82e38d607
commit deb9c62cd9

View file

@ -2221,6 +2221,7 @@ atom_stsc_copy_data (AtomSTSC * stsc, guint8 ** buffer, guint64 * size,
{ {
guint64 original_offset = *offset; guint64 original_offset = *offset;
guint i, len; guint i, len;
gboolean last_entries_merged = FALSE;
if (!atom_full_copy_data (&stsc->header, buffer, size, offset)) { if (!atom_full_copy_data (&stsc->header, buffer, size, offset)) {
return 0; return 0;
@ -2232,6 +2233,7 @@ atom_stsc_copy_data (AtomSTSC * stsc, guint8 ** buffer, guint64 * size,
((atom_array_index (&stsc->entries, len - 1)).samples_per_chunk == ((atom_array_index (&stsc->entries, len - 1)).samples_per_chunk ==
(atom_array_index (&stsc->entries, len - 2)).samples_per_chunk)) { (atom_array_index (&stsc->entries, len - 2)).samples_per_chunk)) {
stsc->entries.len--; stsc->entries.len--;
last_entries_merged = TRUE;
} }
prop_copy_uint32 (atom_array_get_len (&stsc->entries), buffer, size, offset); prop_copy_uint32 (atom_array_get_len (&stsc->entries), buffer, size, offset);
@ -2248,6 +2250,15 @@ atom_stsc_copy_data (AtomSTSC * stsc, guint8 ** buffer, guint64 * size,
} }
atom_write_size (buffer, size, offset, original_offset); atom_write_size (buffer, size, offset, original_offset);
/* Need to add the last entry again as in "robust" muxing mode we will most
* likely add new samples to the last chunk, thus making the
* samples_per_chunk in the last one different to the second to last one,
* and thus making it wrong to keep them merged
*/
if (last_entries_merged)
stsc->entries.len++;
return *offset - original_offset; return *offset - original_offset;
} }