From 3d7b34352552fe70ff8a70bf692ec408b2fbb005 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Wed, 1 Apr 2015 00:58:52 +1100 Subject: [PATCH] isomp4: Update edit list when re-writing moov Correctly update any edit lists each time the moov is recalculated, updating existing table entries if they already exist instead of just adding new ones. --- gst/isomp4/atoms.c | 36 +++++++++++++++++++++++------------- gst/isomp4/atoms.h | 2 +- gst/isomp4/gstqtmux.c | 17 ++++++++++------- 3 files changed, 34 insertions(+), 21 deletions(-) diff --git a/gst/isomp4/atoms.c b/gst/isomp4/atoms.c index a8ca9cdcf0..4ac76703d7 100644 --- a/gst/isomp4/atoms.c +++ b/gst/isomp4/atoms.c @@ -3279,31 +3279,41 @@ atom_tkhd_set_subtitle (AtomTKHD * tkhd, AtomsContext * context, guint32 width, static void -atom_edts_add_entry (AtomEDTS * edts, EditListEntry * entry) +atom_edts_add_entry (AtomEDTS * edts, gint index, EditListEntry * entry) { - edts->elst.entries = g_slist_append (edts->elst.entries, entry); + EditListEntry *e = + (EditListEntry *) g_slist_nth_data (edts->elst.entries, index); + /* Create a new entry if missing (appends to the list if index is larger) */ + if (e == NULL) { + e = g_new (EditListEntry, 1); + edts->elst.entries = g_slist_insert (edts->elst.entries, e, index); + } + + /* Update the entry */ + *e = *entry; } -/* - * Adds a new entry to this trak edits list +/* + * Update an entry in this trak edits list, creating it if needed. + * index is the index of the entry to update, or create if it's past the end. * duration is in the moov's timescale * media_time is the offset in the media time to start from (media's timescale) * rate is a 32 bits fixed-point */ void -atom_trak_add_elst_entry (AtomTRAK * trak, guint32 duration, guint32 media_time, - guint32 rate) +atom_trak_set_elst_entry (AtomTRAK * trak, gint index, + guint32 duration, guint32 media_time, guint32 rate) { - EditListEntry *entry = g_new (EditListEntry, 1); + EditListEntry entry; - entry->duration = duration; - entry->media_time = media_time; - entry->media_rate = rate; + entry.duration = duration; + entry.media_time = media_time; + entry.media_rate = rate; - if (trak->edts == NULL) { + if (trak->edts == NULL) trak->edts = atom_edts_new (); - } - atom_edts_add_entry (trak->edts, entry); + + atom_edts_add_entry (trak->edts, index, &entry); } /* re-negotiation is prevented at top-level, so only 1 entry expected. diff --git a/gst/isomp4/atoms.h b/gst/isomp4/atoms.h index a54838093d..943dfd6ee4 100644 --- a/gst/isomp4/atoms.h +++ b/gst/isomp4/atoms.h @@ -828,7 +828,7 @@ AtomTRAK* atom_trak_new (AtomsContext *context); void atom_trak_add_samples (AtomTRAK * trak, guint32 nsamples, guint32 delta, guint32 size, guint64 chunk_offset, gboolean sync, gint64 pts_offset); -void atom_trak_add_elst_entry (AtomTRAK * trak, guint32 duration, +void atom_trak_set_elst_entry (AtomTRAK * trak, gint index, guint32 duration, guint32 media_time, guint32 rate); guint32 atom_trak_get_timescale (AtomTRAK *trak); guint32 atom_trak_get_id (AtomTRAK * trak); diff --git a/gst/isomp4/gstqtmux.c b/gst/isomp4/gstqtmux.c index d1426b179d..d20ac9b894 100644 --- a/gst/isomp4/gstqtmux.c +++ b/gst/isomp4/gstqtmux.c @@ -249,7 +249,6 @@ enum #define DEFAULT_DTS_METHOD DTS_METHOD_REORDER #endif - static void gst_qt_mux_finalize (GObject * object); static GstStateChangeReturn gst_qt_mux_change_state (GstElement * element, @@ -2110,25 +2109,29 @@ gst_qt_mux_stop_file (GstQTMux * qtmux) first_ts = qtpad->first_ts; } } + GST_DEBUG_OBJECT (qtmux, "Media first ts selected: %" GST_TIME_FORMAT, GST_TIME_ARGS (first_ts)); - /* add EDTSs for late streams */ + /* add/update EDTSs for late streams. configure_moov will have + * set the trak durations above by summing the sample tables */ for (walk = qtmux->collect->data; walk; walk = g_slist_next (walk)) { GstCollectData *cdata = (GstCollectData *) walk->data; GstQTPad *qtpad = (GstQTPad *) cdata; guint32 lateness; guint32 duration; - if (GST_CLOCK_TIME_IS_VALID (qtpad->first_ts) && qtpad->first_ts > first_ts) { + if (GST_CLOCK_TIME_IS_VALID (qtpad->first_ts) + && qtpad->first_ts > first_ts) { GST_DEBUG_OBJECT (qtmux, "Pad %s is a late stream by %" GST_TIME_FORMAT, GST_PAD_NAME (qtpad->collect.pad), GST_TIME_ARGS (qtpad->first_ts - first_ts)); - lateness = gst_util_uint64_scale_round (qtpad->first_ts - first_ts, - timescale, GST_SECOND); + lateness = + gst_util_uint64_scale_round (qtpad->first_ts - first_ts, timescale, + GST_SECOND); duration = qtpad->trak->tkhd.duration; - atom_trak_add_elst_entry (qtpad->trak, lateness, (guint32) - 1, + atom_trak_set_elst_entry (qtpad->trak, 0, lateness, (guint32) - 1, (guint32) (1 * 65536.0)); - atom_trak_add_elst_entry (qtpad->trak, duration, 0, + atom_trak_set_elst_entry (qtpad->trak, 1, duration, 0, (guint32) (1 * 65536.0)); /* need to add the empty time to the trak duration */