rsvgdec: use input buffer timings if possible
authorVincent Penquerc'h <vincent.penquerch@collabora.co.uk>
Thu, 18 Aug 2011 12:21:18 +0000 (13:21 +0100)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Tue, 23 Aug 2011 08:21:04 +0000 (10:21 +0200)
SVG data may come through multiple buffers, so keep track of the
timestamp of the first buffer, and use it in preference.

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

ext/rsvg/gstrsvgdec.c
ext/rsvg/gstrsvgdec.h

index c0a636216dc359c09c0954b3c912d5754ff018c1..f7cb701aa8695ee25d1456dbdc730f0b936aeba5 100644 (file)
@@ -141,7 +141,7 @@ gst_rsvg_dec_reset (GstRsvgDec * dec)
   dec->width = dec->height = 0;
   dec->fps_n = 0;
   dec->fps_d = 1;
-  dec->timestamp_offset = GST_CLOCK_TIME_NONE;
+  dec->first_timestamp = GST_CLOCK_TIME_NONE;
   dec->frame_count = 0;
 
   gst_segment_init (&dec->segment, GST_FORMAT_UNDEFINED);
@@ -341,11 +341,18 @@ gst_rsvg_dec_chain (GstPad * pad, GstBuffer * buffer)
   guint size;
   gboolean ret = GST_FLOW_OK;
 
-  if (rsvg->timestamp_offset == GST_CLOCK_TIME_NONE) {
+  /* first_timestamp is used slightly differently where a framerate
+     is given or not.
+     If there is a frame rate, it will be used as a base.
+     If there is not, it will be used to keep track of the timestamp
+     of the first buffer, to be used as the timestamp of the output
+     buffer. When a buffer is output, first timestamp will resync to
+     the next buffer's timestamp. */
+  if (rsvg->first_timestamp == GST_CLOCK_TIME_NONE) {
     if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer))
-      rsvg->timestamp_offset = GST_BUFFER_TIMESTAMP (buffer);
-    else
-      rsvg->timestamp_offset = 0;
+      rsvg->first_timestamp = GST_BUFFER_TIMESTAMP (buffer);
+    else if (rsvg->fps_n != 0)
+      rsvg->first_timestamp = 0;
   }
 
   gst_adapter_push (rsvg->adapter, buffer);
@@ -377,15 +384,33 @@ gst_rsvg_dec_chain (GstPad * pad, GstBuffer * buffer)
         break;
 
 
-      if (rsvg->fps_n != 0) {
+      if (rsvg->first_timestamp != GST_CLOCK_TIME_NONE) {
+        GST_BUFFER_TIMESTAMP (outbuf) = rsvg->first_timestamp;
+        GST_BUFFER_DURATION (outbuf) = GST_CLOCK_TIME_NONE;
+        if (GST_BUFFER_DURATION_IS_VALID (buffer)) {
+          GstClockTime end =
+              GST_BUFFER_TIMESTAMP_IS_VALID (buffer) ?
+              GST_BUFFER_TIMESTAMP (buffer) : rsvg->first_timestamp;
+          end += GST_BUFFER_DURATION (buffer);
+          GST_BUFFER_DURATION (outbuf) = end - GST_BUFFER_TIMESTAMP (outbuf);
+        }
+        if (rsvg->fps_n == 0) {
+          rsvg->first_timestamp = GST_CLOCK_TIME_NONE;
+        } else {
+          GST_BUFFER_DURATION (outbuf) =
+              gst_util_uint64_scale (rsvg->frame_count, rsvg->fps_d,
+              rsvg->fps_n * GST_SECOND);
+        }
+      } else if (rsvg->fps_n != 0) {
         GST_BUFFER_TIMESTAMP (outbuf) =
-            rsvg->timestamp_offset + gst_util_uint64_scale (rsvg->frame_count,
+            rsvg->first_timestamp + gst_util_uint64_scale (rsvg->frame_count,
             rsvg->fps_d, rsvg->fps_n * GST_SECOND);
         GST_BUFFER_DURATION (outbuf) =
             gst_util_uint64_scale (rsvg->frame_count, rsvg->fps_d,
             rsvg->fps_n * GST_SECOND);
       } else {
-        GST_BUFFER_TIMESTAMP (outbuf) = 0;
+        GST_BUFFER_TIMESTAMP (outbuf) = rsvg->first_timestamp;
+        GST_BUFFER_DURATION (outbuf) = GST_CLOCK_TIME_NONE;
       }
       rsvg->frame_count++;
 
index 00279922fb46a9d58f9eebc97e460e24fce52078..0d048eeceb445bc8d6110dba0afcb857ae8103f5 100644 (file)
@@ -58,7 +58,7 @@ struct _GstRsvgDec
   GstTagList *pending_tags;
 
   gint fps_n, fps_d;
-  GstClockTime timestamp_offset;
+  GstClockTime first_timestamp;
   guint64 frame_count;
 
   GstSegment segment;