qtmux: use trun with multiple entries in more cases

The only case where we definitely need to write a new trun is when the
data_offset value does not match the end of the list of entries.
Needing multiple trun atoms is required when interleaving multiple
streams together.

All other cases can be covered by adding more entries to the existing
trun atom.

Fixes playback of fragemented mp4 in ffplay and chrome.

Using e.g. mp4mux fragment-duration=1000 fragment-mode=dash-or-mss
and
mp4mux fragment-duration=1000 fragment-mode=first-moov-then-finalise

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3426>
This commit is contained in:
Matthew Waters 2022-11-17 20:59:35 +11:00
parent 416446b25c
commit 8e355d23a1

View file

@ -4825,30 +4825,23 @@ atom_trun_set_offset (AtomTRUN * trun, gint32 offset)
}
static gboolean
atom_trun_can_append_samples_to_entry (AtomTRUN * trun,
TRUNSampleEntry * nentry, guint32 nsamples, guint32 delta, guint32 size,
guint32 flags, gint32 data_offset, gint64 pts_offset)
atom_trun_can_append (AtomTRUN * trun, gint32 data_offset)
{
if (pts_offset != 0)
return FALSE;
if (nentry->sample_flags != flags)
return FALSE;
if (trun->data_offset + nentry->sample_size != data_offset)
return FALSE;
if (nentry->sample_size != size)
return FALSE;
if (nentry->sample_duration != delta)
gsize trun_data_offset_end = trun->data_offset;
int i, n;
if (data_offset == 0)
return TRUE;
n = atom_array_get_len (&trun->entries);
for (i = 0; i < n; i++) {
TRUNSampleEntry *entry = &atom_array_index (&trun->entries, i);
trun_data_offset_end += entry->sample_size;
}
if (trun_data_offset_end != data_offset)
return FALSE;
/* FIXME: this should be TRUE but currently fails on demuxing */
return FALSE;
}
static void
atom_trun_append_samples (AtomTRUN * trun, TRUNSampleEntry * nentry,
guint32 nsamples, guint32 delta, guint32 size)
{
trun->sample_count += nsamples;
return TRUE;
}
static void
@ -4919,7 +4912,6 @@ atom_traf_add_samples (AtomTRAF * traf, guint32 nsamples,
{
GList *l = NULL;
AtomTRUN *prev_trun, *trun = NULL;
TRUNSampleEntry *nentry = NULL;
guint32 flags;
/* 0x10000 is sample-is-difference-sample flag
@ -4928,16 +4920,9 @@ atom_traf_add_samples (AtomTRAF * traf, guint32 nsamples,
if (traf->truns) {
trun = g_list_last (traf->truns)->data;
nentry =
&atom_array_index (&trun->entries,
atom_array_get_len (&trun->entries) - 1);
if (!atom_trun_can_append_samples_to_entry (trun, nentry, nsamples, delta,
size, flags, data_offset, pts_offset)) {
/* if we can't add to the previous trun, write a new one */
if (!atom_trun_can_append (trun, data_offset))
trun = NULL;
nentry = NULL;
}
}
prev_trun = trun;
@ -4986,11 +4971,7 @@ atom_traf_add_samples (AtomTRAF * traf, guint32 nsamples,
}
}
if (prev_trun == trun) {
atom_trun_append_samples (trun, nentry, nsamples, delta, size);
} else {
atom_trun_add_samples (trun, nsamples, delta, size, flags, pts_offset);
}
atom_trun_add_samples (trun, nsamples, delta, size, flags, pts_offset);
if (traf->sdtps)
atom_sdtp_add_samples (traf->sdtps->data, 0x10 | ((flags & 0xff) >> 4));