atomsrecovery: expect more atom types at the headers
authorThiago Santos <thiagossantos@gmail.com>
Sat, 11 Mar 2017 20:27:28 +0000 (12:27 -0800)
committerThiago Santos <thiagossantos@gmail.com>
Wed, 15 Mar 2017 03:27:48 +0000 (20:27 -0700)
Skip more atoms at the header until it finds the 'mdat' to continue the
moov recovery

https://bugzilla.gnome.org/show_bug.cgi?id=771478

gst/isomp4/atomsrecovery.c

index b21ee9c..e3f4621 100644 (file)
@@ -339,11 +339,58 @@ mdat_recov_file_parse_mdat_start (MdatRecovFile * mdatrf)
   return fourcc == FOURCC_mdat;
 }
 
+static gboolean
+mdat_recov_file_find_mdat (FILE * file, GError ** err)
+{
+  guint32 fourcc = 0, size = 0;
+  gboolean failure = FALSE;
+  while (fourcc != FOURCC_mdat && !failure) {
+    if (!read_atom_header (file, &fourcc, &size)) {
+      goto parse_error;
+    }
+    switch (fourcc) {
+        /* skip these atoms */
+      case FOURCC_ftyp:
+      case FOURCC_free:
+      case FOURCC_udta:
+        if (fseek (file, size - 8, SEEK_CUR) != 0) {
+          goto file_seek_error;
+        }
+        break;
+      case FOURCC_mdat:
+        break;
+      default:
+        GST_ERROR ("Unexpected atom in headers %" GST_FOURCC_FORMAT,
+            GST_FOURCC_ARGS (fourcc));
+        failure = TRUE;
+        break;
+    }
+  }
+
+  if (!failure) {
+    /* Reverse to mdat start */
+    if (fseek (file, -8, SEEK_CUR) != 0)
+      goto file_seek_error;
+  }
+
+  return !failure;
+
+parse_error:
+  g_set_error (err, ATOMS_RECOV_QUARK, ATOMS_RECOV_ERR_FILE,
+      "Failed to parse atom");
+  return FALSE;
+
+file_seek_error:
+  g_set_error (err, ATOMS_RECOV_QUARK, ATOMS_RECOV_ERR_FILE,
+      "Failed to seek to start of the file");
+  return FALSE;
+
+}
+
 MdatRecovFile *
 mdat_recov_file_create (FILE * file, gboolean datafile, GError ** err)
 {
   MdatRecovFile *mrf = g_new0 (MdatRecovFile, 1);
-  guint32 fourcc, size;
 
   g_return_val_if_fail (file != NULL, NULL);
 
@@ -370,24 +417,9 @@ mdat_recov_file_create (FILE * file, gboolean datafile, GError ** err)
     return mrf;
   }
 
-  if (!read_atom_header (file, &fourcc, &size)) {
-    goto parse_error;
-  }
-  if (fourcc != FOURCC_ftyp) {
-    /* this could be a prefix atom, let's skip it and try again */
-    if (fseek (file, size - 8, SEEK_CUR) != 0) {
-      goto file_seek_error;
-    }
-    if (!read_atom_header (file, &fourcc, &size)) {
-      goto parse_error;
-    }
-  }
-
-  if (fourcc != FOURCC_ftyp) {
-    goto parse_error;
+  if (!mdat_recov_file_find_mdat (file, err)) {
+    goto fail;
   }
-  if (fseek (file, size - 8, SEEK_CUR) != 0)
-    goto file_seek_error;
 
   /* we don't parse this if we have a tmpdatafile */
   if (!mdat_recov_file_parse_mdat_start (mrf)) {
@@ -398,11 +430,6 @@ mdat_recov_file_create (FILE * file, gboolean datafile, GError ** err)
 
   return mrf;
 
-parse_error:
-  g_set_error (err, ATOMS_RECOV_QUARK, ATOMS_RECOV_ERR_FILE,
-      "Failed to parse atom");
-  goto fail;
-
 file_seek_error:
   g_set_error (err, ATOMS_RECOV_QUARK, ATOMS_RECOV_ERR_FILE,
       "Failed to seek to start of the file");