[Bug 764637] qtdemux: Ensure stream duration by using stts box

GStreamer (GNOME Bugzilla) bugzilla at gnome.org
Wed Apr 13 13:29:41 UTC 2016


https://bugzilla.gnome.org/show_bug.cgi?id=764637

Seungha Yang <sh.yang at lge.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
 Attachment #325860|none                        |rejected
             status|                            |
 Attachment #325860|0                           |1
        is obsolete|                            |

--- Comment #7 from Seungha Yang <sh.yang at lge.com> ---
Comment on attachment 325860
  --> https://bugzilla.gnome.org/attachment.cgi?id=325860
qtdemux: Ensure stream duration by using stts box

>From 4f3184343e7e7a7842c8aa9c7ccab24336251c1e Mon Sep 17 00:00:00 2001
>From: Seungha Yang <sh.yang at lge.com>
>Date: Wed, 13 Apr 2016 22:18:15 +0900
>Subject: [PATCH] qtdemux: Ensure stream duration by using stts box
>
>Some files have incorrect stream duration value in mdhd box
>So, we need to double check the stream duration.
>
>https://bugzilla.gnome.org/show_bug.cgi?id=764637
>---
> gst/isomp4/qtdemux.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 68 insertions(+)
>
>diff --git a/gst/isomp4/qtdemux.c b/gst/isomp4/qtdemux.c
>index c4aa9c5..1925a44 100644
>--- a/gst/isomp4/qtdemux.c
>+++ b/gst/isomp4/qtdemux.c
>@@ -362,6 +362,9 @@ struct _QtDemuxStream
>   guint32 stts_sample_index;
>   guint64 stts_time;
>   guint32 stts_duration;
>+  guint64 stts_total_duration;  /* To ensure stream duration. non-zero value
>+                                 * means we need to use this value for updating
>+                                 * stream duration */
>   /* stss */
>   gboolean stss_present;
>   guint32 n_sample_syncs;
>@@ -7185,6 +7188,12 @@ gst_qtdemux_configure_protected_caps (GstQTDemux * qtdemux,
> static gboolean
> gst_qtdemux_configure_stream (GstQTDemux * qtdemux, QtDemuxStream * stream)
> {
>+  if (stream->stts_total_duration) {
>+    /* if stts_total_duration has non-zero value, update duration using it */
>+    check_update_duration (qtdemux, QTSTREAMTIME_TO_GSTTIME (stream,
>+            stream->stts_total_duration));
>+  }
>+
>   if (stream->subtype == FOURCC_vide) {
>     /* fps is calculated base on the duration of the average framerate since
>      * qt does not have a fixed framerate. */
>@@ -7595,6 +7604,58 @@ flow_failed:
>   }
> }
> 
>+/* Check and compare duration of @stream with file duration.
>+ * If stream duration is needed to update using each stts sample data,
>+ * stts_total_duration will be set to non-zero value.
>+ * To use this function, byte_reader position of stts should be located at
>+ * the first entry of stts entry table.
>+ */
>+static void
>+qtdemux_ensure_stream_duration (GstQTDemux * qtdemux, QtDemuxStream * stream)
>+{
>+  GstClockTime demux_dur, stream_dur, diff;
>+  gint i;
>+  guint byte_pos;
>+  guint32 samples;
>+  guint32 duration;
>+
>+  stream->stts_total_duration = 0;
>+
>+  /* we can't believe stts data of fragmented format  */
>+  if (qtdemux->fragmented)
>+    return;
>+
>+  demux_dur = QTTIME_TO_GSTTIME (qtdemux, qtdemux->duration);
>+  stream_dur = QTSTREAMTIME_TO_GSTTIME (stream, stream->duration);
>+
>+  if (demux_dur == GST_CLOCK_TIME_NONE || stream_dur == GST_CLOCK_TIME_NONE)
>+    return;
>+
>+  diff = (demux_dur > stream_dur) ?
>+      (demux_dur - stream_dur) : (stream_dur - demux_dur);
>+
>+  /* If difference is over 1 second, need to double check stream duration */
>+  if (diff > GST_SECOND) {
>+    GST_DEBUG_OBJECT (qtdemux, "duration difference %" GST_TIME_FORMAT
>+        " = (demux duration %" GST_TIME_FORMAT " - stream duration %"
>+        GST_TIME_FORMAT ")", GST_TIME_ARGS (diff), GST_TIME_ARGS (demux_dur),
>+        GST_TIME_ARGS (stream_dur));
>+
>+    /* store position of byte_reader */
>+    byte_pos = gst_byte_reader_get_pos (&stream->stts);
>+
>+    for (i = 0; i < stream->n_sample_times; i++) {
>+      samples = gst_byte_reader_get_uint32_be_unchecked (&stream->stts);
>+      duration = gst_byte_reader_get_uint32_be_unchecked (&stream->stts);
>+
>+      stream->stts_total_duration += (guint64) (samples * duration);
>+    }
>+
>+    /* roll back byte_reader position to stored position */
>+    gst_byte_reader_set_pos (&stream->stts, byte_pos);
>+  }
>+}
>+
> /* initialise bytereaders for stbl sub-atoms */
> static gboolean
> qtdemux_stbl_init (GstQTDemux * qtdemux, QtDemuxStream * stream, GNode * stbl)
>@@ -7624,6 +7685,13 @@ qtdemux_stbl_init (GstQTDemux * qtdemux, QtDemuxStream * stream, GNode * stbl)
>       goto corrupt_file;
>   }
> 
>+  /* Some corrupted files have incorrect stream duration info in mdhd box
>+   * If there is difference between file duration (in mvhd) and
>+   * stream duration (in mdhd), it's the clue that this file maybe corrupted.
>+   * In that case, we need to ensure actual stream duration by using stts.
>+   */
>+  qtdemux_ensure_stream_duration (qtdemux, stream);
>+
>   /* sync sample atom */
>   stream->stps_present = FALSE;
>   if ((stream->stss_present =
>-- 
>1.9.1
>

-- 
You are receiving this mail because:
You are the QA Contact for the bug.
You are the assignee for the bug.


More information about the gstreamer-bugs mailing list