static void gst_qt_moov_recover_run (void *data) { FILE *moovrec = NULL; FILE *mdatinput = NULL; FILE *output = NULL; MdatRecovFile *mdat_recov = NULL; MoovRecovFile *moov_recov = NULL; GstQTMoovRecover *qtmr = GST_QT_MOOV_RECOVER_CAST (data); GError *err = NULL; GST_LOG_OBJECT (qtmr, "Starting task"); GST_DEBUG_OBJECT (qtmr, "Validating properties"); GST_OBJECT_LOCK (qtmr); /* validate properties */ if (qtmr->broken_input == NULL) { GST_OBJECT_UNLOCK (qtmr); GST_ELEMENT_ERROR (qtmr, RESOURCE, SETTINGS, ("Please set broken-input property"), (NULL)); goto end; } if (qtmr->recovery_input == NULL) { GST_OBJECT_UNLOCK (qtmr); GST_ELEMENT_ERROR (qtmr, RESOURCE, SETTINGS, ("Please set recovery-input property"), (NULL)); goto end; } if (qtmr->fixed_output == NULL) { GST_OBJECT_UNLOCK (qtmr); GST_ELEMENT_ERROR (qtmr, RESOURCE, SETTINGS, ("Please set fixed-output property"), (NULL)); goto end; } GST_DEBUG_OBJECT (qtmr, "Opening input/output files"); /* open files */ moovrec = g_fopen (qtmr->recovery_input, "rb"); if (moovrec == NULL) { GST_OBJECT_UNLOCK (qtmr); GST_ELEMENT_ERROR (qtmr, RESOURCE, OPEN_READ, ("Failed to open recovery-input file"), (NULL)); goto end; } mdatinput = g_fopen (qtmr->broken_input, "rb"); if (mdatinput == NULL) { GST_OBJECT_UNLOCK (qtmr); GST_ELEMENT_ERROR (qtmr, RESOURCE, OPEN_READ, ("Failed to open broken-input file"), (NULL)); goto end; } output = g_fopen (qtmr->fixed_output, "wb+"); if (output == NULL) { GST_OBJECT_UNLOCK (qtmr); GST_ELEMENT_ERROR (qtmr, RESOURCE, OPEN_READ_WRITE, ("Failed to open fixed-output file"), (NULL)); goto end; } GST_OBJECT_UNLOCK (qtmr); GST_DEBUG_OBJECT (qtmr, "Parsing input files"); /* now create our structures */ mdat_recov = mdat_recov_file_create (mdatinput, qtmr->faststart_mode, &err); mdatinput = NULL; if (mdat_recov == NULL) { GST_ELEMENT_ERROR (qtmr, RESOURCE, FAILED, ("Broken file could not be parsed correctly"), (NULL)); goto end; } moov_recov = moov_recov_file_create (moovrec, &err); moovrec = NULL; if (moov_recov == NULL) { GST_ELEMENT_ERROR (qtmr, RESOURCE, FAILED, ("Recovery file could not be parsed correctly"), (NULL)); goto end; } /* now parse the buffers data from moovrec */ if (!moov_recov_parse_buffers (moov_recov, mdat_recov, &err)) { goto end; } GST_DEBUG_OBJECT (qtmr, "Writing fixed file to output"); if (!moov_recov_write_file (moov_recov, mdat_recov, output, &err)) { goto end; } /* here means success */ GST_DEBUG_OBJECT (qtmr, "Finished successfully, posting EOS"); gst_element_post_message (GST_ELEMENT_CAST (qtmr), gst_message_new_eos (GST_OBJECT_CAST (qtmr))); end: GST_LOG_OBJECT (qtmr, "Finalizing task"); if (err) { GST_ELEMENT_ERROR (qtmr, RESOURCE, FAILED, ("%s", err->message), (NULL)); g_error_free (err); } if (moov_recov) moov_recov_file_free (moov_recov); if (moovrec) fclose (moovrec); if (mdat_recov) mdat_recov_file_free (mdat_recov); if (mdatinput) fclose (mdatinput); if (output) fclose (output); GST_LOG_OBJECT (qtmr, "Leaving task"); gst_task_stop (qtmr->task); }
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); mrf->file = file; mrf->rawfile = datafile; /* get the file/data length */ if (fseek (file, 0, SEEK_END) != 0) goto file_length_error; /* still needs to deduce the mdat header and ftyp size */ mrf->data_size = ftell (file); if (mrf->data_size == -1L) goto file_length_error; if (fseek (file, 0, SEEK_SET) != 0) goto file_seek_error; if (datafile) { /* this file contains no atoms, only raw data to be placed on the mdat * this happens when faststart mode is used */ mrf->mdat_start = 0; mrf->mdat_header_size = 16; mrf->mdat_size = 16; 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 (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)) { g_set_error (err, ATOMS_RECOV_QUARK, ATOMS_RECOV_ERR_PARSING, "Error while parsing mdat atom"); goto fail; } 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"); goto fail; file_length_error: g_set_error (err, ATOMS_RECOV_QUARK, ATOMS_RECOV_ERR_FILE, "Failed to determine file size"); goto fail; fail: mdat_recov_file_free (mrf); return NULL; }