qtmux: use trun with multiple entries in more cases
authorMatthew Waters <matthew@centricular.com>
Thu, 17 Nov 2022 09:59:35 +0000 (20:59 +1100)
committerMatthew Waters <matthew@centricular.com>
Thu, 17 Nov 2022 10:04:57 +0000 (21:04 +1100)
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>

subprojects/gst-plugins-good/gst/isomp4/atoms.c

index 2e8b444..829d0e5 100644 (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)
-    return FALSE;
+  gsize trun_data_offset_end = trun->data_offset;
+  int i, n;
 
-  /* FIXME: this should be TRUE but currently fails on demuxing */
-  return FALSE;
-}
+  if (data_offset == 0)
+    return TRUE;
 
-static void
-atom_trun_append_samples (AtomTRUN * trun, TRUNSampleEntry * nentry,
-    guint32 nsamples, guint32 delta, guint32 size)
-{
-  trun->sample_count += nsamples;
+  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;
+
+  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));