From 923b83a48cce999abd10f869dd721880aee19b0f Mon Sep 17 00:00:00 2001 From: Thiago Santos Date: Sat, 8 Jul 2017 22:11:49 -0700 Subject: [PATCH] atomsrecovery: read from mdat only what is on headers It is possible that the mdat has more data than what was stored in the headers file. If we put that to the output the file will have bogus data at the end and some players will complain. https://bugzilla.gnome.org/show_bug.cgi?id=784258 --- gst/isomp4/atomsrecovery.c | 28 +++++++++++++++++++++++----- gst/isomp4/atomsrecovery.h | 2 +- gst/isomp4/gstqtmoovrecover.c | 8 +++++++- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/gst/isomp4/atomsrecovery.c b/gst/isomp4/atomsrecovery.c index 5462713..8d060fb 100644 --- a/gst/isomp4/atomsrecovery.c +++ b/gst/isomp4/atomsrecovery.c @@ -88,6 +88,8 @@ #include "atomsrecovery.h" +#define MAX_CHUNK_SIZE (1024 * 1024) /* 1MB */ + #define ATOMS_RECOV_OUTPUT_WRITE_ERROR(err) \ g_set_error (err, ATOMS_RECOV_QUARK, ATOMS_RECOV_ERR_FILE, \ "Failed to write to output file: %s", g_strerror (errno)) @@ -956,7 +958,7 @@ fail: gboolean moov_recov_write_file (MoovRecovFile * moovrf, MdatRecovFile * mdatrf, - FILE * outf, GError ** err) + FILE * outf, GError ** err, GError ** warn) { guint8 auxdata[16]; guint8 *data = NULL; @@ -969,6 +971,7 @@ moov_recov_write_file (MoovRecovFile * moovrf, MdatRecovFile * mdatrf, guint8 *stbl_children = NULL; guint32 longest_duration = 0; guint16 version; + guint remaining; /* check the version */ if (fseek (moovrf->file, 0, SEEK_SET) != 0) { @@ -1159,12 +1162,16 @@ moov_recov_write_file (MoovRecovFile * moovrf, MdatRecovFile * mdatrf, (mdatrf->rawfile ? 0 : mdatrf->mdat_header_size), SEEK_SET) != 0) goto fail; - data = g_malloc (4096); - while (!feof (mdatrf->file)) { - gint read, write; + remaining = mdatrf->mdat_size - mdatrf->mdat_header_size; + data = g_malloc (MAX_CHUNK_SIZE); + while (!feof (mdatrf->file) && remaining > 0) { + gint read, write, readsize; + + readsize = MIN (MAX_CHUNK_SIZE, remaining); - read = fread (data, 1, 4096, mdatrf->file); + read = fread (data, 1, readsize, mdatrf->file); write = fwrite (data, 1, read, outf); + remaining -= read; if (write != read) { g_set_error (err, ATOMS_RECOV_QUARK, ATOMS_RECOV_ERR_FILE, @@ -1174,6 +1181,17 @@ moov_recov_write_file (MoovRecovFile * moovrf, MdatRecovFile * mdatrf, } g_free (data); + if (remaining) { + g_set_error (warn, ATOMS_RECOV_QUARK, ATOMS_RECOV_ERR_FILE, + "Samples in recovery file were not present on headers." + " Bytes lost: %u", remaining); + } else if (!feof (mdatrf->file)) { + g_set_error (warn, ATOMS_RECOV_QUARK, ATOMS_RECOV_ERR_FILE, + "Samples in headers were not found in data file."); + GST_FIXME ("Rewrite mdat size if we reach this to make the file" + " fully correct"); + } + return TRUE; fail: diff --git a/gst/isomp4/atomsrecovery.h b/gst/isomp4/atomsrecovery.h index 2d9382d..f044c9b 100644 --- a/gst/isomp4/atomsrecovery.h +++ b/gst/isomp4/atomsrecovery.h @@ -157,6 +157,6 @@ gboolean moov_recov_parse_buffers (MoovRecovFile * moovrf, GError ** err); gboolean moov_recov_write_file (MoovRecovFile * moovrf, MdatRecovFile * mdatrf, FILE * outf, - GError ** err); + GError ** err, GError ** warn); #endif /* __ATOMS_RECOVERY_H__ */ diff --git a/gst/isomp4/gstqtmoovrecover.c b/gst/isomp4/gstqtmoovrecover.c index 80b22eb..f5d2b91 100644 --- a/gst/isomp4/gstqtmoovrecover.c +++ b/gst/isomp4/gstqtmoovrecover.c @@ -169,6 +169,7 @@ gst_qt_moov_recover_run (void *data) MoovRecovFile *moov_recov = NULL; GstQTMoovRecover *qtmr = GST_QT_MOOV_RECOVER_CAST (data); GError *err = NULL; + GError *warn = NULL; GST_LOG_OBJECT (qtmr, "Starting task"); @@ -243,10 +244,15 @@ gst_qt_moov_recover_run (void *data) } GST_DEBUG_OBJECT (qtmr, "Writing fixed file to output"); - if (!moov_recov_write_file (moov_recov, mdat_recov, output, &err)) { + if (!moov_recov_write_file (moov_recov, mdat_recov, output, &err, &warn)) { goto end; } + if (warn) { + GST_ELEMENT_WARNING (qtmr, RESOURCE, FAILED, ("%s", warn->message), (NULL)); + g_error_free (warn); + } + /* here means success */ GST_DEBUG_OBJECT (qtmr, "Finished successfully, posting EOS"); gst_element_post_message (GST_ELEMENT_CAST (qtmr), -- 2.7.4