typefindfunctions: Consider the number and types of atoms found in a row for suggesti...
authorSebastian Dröge <sebastian@centricular.com>
Tue, 19 Jan 2021 08:23:12 +0000 (10:23 +0200)
committerSebastian Dröge <sebastian@centricular.com>
Sun, 31 Jan 2021 09:53:43 +0000 (11:53 +0200)
If there are 3 or more known atoms in a row, it's likely that this is
actually MOV/MP4 even if we don't find any other known atoms. If 5 or
more are found then this is most certainly MOV/MP4 and we can return.

Also if a moov and mdat atom is found, this is definitely a MOV/MP4 file
and can be used as such, independent of anything else following the
mdat.

Fixes typefinding of various MOV files that have no `ftyp` atom but
otherwise a valid file structure followed by some garbage.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/1013>

gst/typefind/gsttypefindfunctions.c

index 7635e4d..491a665 100644 (file)
@@ -3383,6 +3383,8 @@ qt_type_find (GstTypeFind * tf, gpointer unused)
 {
   const guint8 *data;
   guint tip = 0;
+  guint atoms_in_a_row = 0;
+  gboolean have_moov = FALSE, have_mdat = FALSE;
   guint64 offset = 0;
   guint64 size;
   const gchar *variant = NULL;
@@ -3435,6 +3437,17 @@ qt_type_find (GstTypeFind * tf, gpointer unused)
       } else {
         tip = GST_TYPE_FIND_NEARLY_CERTAIN;
       }
+
+      if (STRNCMP (&data[4], "moov", 4) == 0)
+        have_moov = TRUE;
+      if (STRNCMP (&data[4], "mdat", 4) == 0)
+        have_mdat = TRUE;
+
+      atoms_in_a_row += 1;
+      if ((have_moov && have_mdat) || atoms_in_a_row >= 5) {
+        tip = GST_TYPE_FIND_MAXIMUM;
+        break;
+      }
     }
     /* other box/atom types, apparently quicktime specific */
     else if (STRNCMP (&data[4], "pnot", 4) == 0 ||
@@ -3444,7 +3457,10 @@ qt_type_find (GstTypeFind * tf, gpointer unused)
       tip = GST_TYPE_FIND_MAXIMUM;
       break;
     } else {
-      tip = 0;
+      if (atoms_in_a_row >= 3)
+        tip = GST_TYPE_FIND_LIKELY;
+      else
+        tip = 0;
       break;
     }