diff --git a/gst/isomp4/atomsrecovery.c b/gst/isomp4/atomsrecovery.c index 5462713e71..8d060fb068 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; - read = fread (data, 1, 4096, mdatrf->file); + readsize = MIN (MAX_CHUNK_SIZE, remaining); + + 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 2d9382d16a..f044c9b9fc 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 80b22ebcb9..f5d2b91dc4 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),