diff options
-rw-r--r-- | gst/isomp4/atomsrecovery.c | 73 |
1 files changed, 50 insertions, 23 deletions
diff --git a/gst/isomp4/atomsrecovery.c b/gst/isomp4/atomsrecovery.c index b21ee9cbe..e3f4621a9 100644 --- a/gst/isomp4/atomsrecovery.c +++ b/gst/isomp4/atomsrecovery.c @@ -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"); |