gst/qtdemux/qtdemux.c: Store duration in uint64 too instead of clipping.
authorWim Taymans <wim.taymans@gmail.com>
Mon, 17 Jul 2006 10:25:57 +0000 (10:25 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Mon, 17 Jul 2006 10:25:57 +0000 (10:25 +0000)
Original commit message from CVS:
* gst/qtdemux/qtdemux.c: (gst_qtdemux_perform_seek),
(gst_qtdemux_prepare_current_sample),
(gst_qtdemux_loop_state_movie):
Store duration in uint64 too instead of clipping.
When we do a keyframe seek and the requested time is at the
keyframe, don't seek back to the beginning of the keyframe.
Fixes #347439.

ChangeLog
gst/qtdemux/qtdemux.c

index c4a5281..88a1763 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2006-07-17  Wim Taymans  <wim@fluendo.com>
+
+       * gst/qtdemux/qtdemux.c: (gst_qtdemux_perform_seek),
+       (gst_qtdemux_prepare_current_sample),
+       (gst_qtdemux_loop_state_movie):
+       Store duration in uint64 too instead of clipping.
+       When we do a keyframe seek and the requested time is at the
+       keyframe, don't seek back to the beginning of the keyframe.
+       Fixes #347439.
+
 2006-07-16  Wim Taymans  <wim@fluendo.com>
 
        * ext/faad/gstfaad.c: (gst_faad_setcaps), (gst_faad_sync):
index 291f073..39a8331 100644 (file)
@@ -79,7 +79,7 @@ struct _QtDemuxSample
   guint32 size;
   guint64 offset;
   guint64 timestamp;            /* In GstClockTime */
-  guint32 duration;             /* in GstClockTime */
+  guint64 duration;             /* in GstClockTime */
   gboolean keyframe;            /* TRUE when this packet is a keyframe */
 };
 
@@ -112,7 +112,7 @@ struct _QtDemuxStream
   guint32 n_samples;
   QtDemuxSample *samples;
   gboolean all_keyframe;        /* TRUE when all samples are keyframes (no stss) */
-  guint32 min_duration;         /* duration of dirst sample, used for figuring out
+  guint32 min_duration;         /* duration in timescale of dirst sample, used for figuring out
                                    the framerate, in timescale units */
 
   /* if we use chunks or samples */
@@ -659,7 +659,7 @@ gst_qtdemux_perform_seek (GstQTDemux * qtdemux, GstSegment * segment)
      * and move back to the previous keyframe. */
     for (n = 0; n < qtdemux->n_streams; n++) {
       QtDemuxStream *str;
-      guint32 index;
+      guint32 index, kindex;
       guint32 seg_idx;
       guint64 media_start;
       guint64 media_time;
@@ -686,31 +686,39 @@ gst_qtdemux_perform_seek (GstQTDemux * qtdemux, GstSegment * segment)
       index = gst_qtdemux_find_index (qtdemux, str, media_start);
       GST_DEBUG_OBJECT (qtdemux, "sample for %" GST_TIME_FORMAT " at %u",
           GST_TIME_ARGS (media_start), index);
+
       /* find previous keyframe */
-      index = gst_qtdemux_find_keyframe (qtdemux, str, index);
-      /* get timestamp of keyframe */
-      media_time = str->samples[index].timestamp;
-
-      GST_DEBUG_OBJECT (qtdemux, "keyframe at %u with time %" GST_TIME_FORMAT,
-          index, GST_TIME_ARGS (media_time));
-
-      /* keyframes in the segment get a chance to change the
-       * desired_offset. keyframes out of the segment are
-       * ignored. */
-      if (media_time >= seg->media_start) {
-        guint64 seg_time;
-
-        /* this keyframe is inside the segment, convert back to
-         * segment time */
-        seg_time = (media_time - seg->media_start) + seg->time;
-        if (seg_time < min_offset)
-          min_offset = seg_time;
+      kindex = gst_qtdemux_find_keyframe (qtdemux, str, index);
+
+      GST_DEBUG_OBJECT (qtdemux, "keyframe at %u", kindex);
+
+      /* if the keyframe is at a different position, we need to update the
+       * requiested seek time */
+      if (index != kindex) {
+        index = kindex;
+
+        /* get timestamp of keyframe */
+        media_time = str->samples[kindex].timestamp;
+        GST_DEBUG_OBJECT (qtdemux, "keyframe at %u with time %" GST_TIME_FORMAT,
+            kindex, GST_TIME_ARGS (media_time));
+
+        /* keyframes in the segment get a chance to change the
+         * desired_offset. keyframes out of the segment are
+         * ignored. */
+        if (media_time >= seg->media_start) {
+          guint64 seg_time;
+
+          /* this keyframe is inside the segment, convert back to
+           * segment time */
+          seg_time = (media_time - seg->media_start) + seg->time;
+          if (seg_time < min_offset)
+            min_offset = seg_time;
+        }
       }
     }
-    desired_offset = min_offset;
-
     GST_DEBUG_OBJECT (qtdemux, "keyframe seek, align to %"
         GST_TIME_FORMAT, GST_TIME_ARGS (desired_offset));
+    desired_offset = min_offset;
   }
 
   /* and set all streams to the final position */
@@ -1134,7 +1142,7 @@ gst_qtdemux_activate_segment (GstQTDemux * qtdemux, QtDemuxStream * stream,
 static gboolean
 gst_qtdemux_prepare_current_sample (GstQTDemux * qtdemux,
     QtDemuxStream * stream, guint64 * offset, guint * size, guint64 * timestamp,
-    guint32 * duration, gboolean * keyframe)
+    guint64 * duration, gboolean * keyframe)
 {
   QtDemuxSample *sample;
   guint64 time_position;
@@ -1283,7 +1291,7 @@ gst_qtdemux_loop_state_movie (GstQTDemux * qtdemux)
   guint64 min_time;
   guint64 offset;
   guint64 timestamp;
-  guint32 duration;
+  guint64 duration;
   gboolean keyframe;
   guint size;
   gint index;
@@ -1354,8 +1362,9 @@ gst_qtdemux_loop_state_movie (GstQTDemux * qtdemux)
     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
 
   GST_LOG_OBJECT (qtdemux,
-      "Pushing buffer with time %" GST_TIME_FORMAT " on pad %p",
-      GST_TIME_ARGS (timestamp), stream->pad);
+      "Pushing buffer with time %" GST_TIME_FORMAT ", duration %"
+      GST_TIME_FORMAT " on pad %p", GST_TIME_ARGS (timestamp),
+      GST_TIME_ARGS (duration), stream->pad);
 
   gst_buffer_set_caps (buf, stream->caps);