gst/realmedia/rmdemux.*: Keep track of the first timestamp of the stream and add...
authorWim Taymans <wim.taymans@gmail.com>
Wed, 27 Aug 2008 09:47:17 +0000 (09:47 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Wed, 27 Aug 2008 09:47:17 +0000 (09:47 +0000)
Original commit message from CVS:
* gst/realmedia/rmdemux.c: (gst_rmdemux_init),
(find_seek_offset_time), (gst_rmdemux_reset), (gst_rmdemux_chain),
(gst_rmdemux_parse_mdpr), (gst_rmdemux_descramble_cook_audio),
(gst_rmdemux_descramble_dnet_audio),
(gst_rmdemux_parse_video_packet), (gst_rmdemux_parse_audio_packet):
* gst/realmedia/rmdemux.h:
Keep track of the first timestamp of the stream and add this to the
outgoing buffer timestamps so that we can handle live streams.
Set discont flag on the first buffers and after a seek.

ChangeLog
gst/realmedia/rmdemux.c
gst/realmedia/rmdemux.h

index bfdf73b..f55aa90 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2008-08-27  Wim Taymans  <wim.taymans@collabora.co.uk>
+
+       * gst/realmedia/rmdemux.c: (gst_rmdemux_init),
+       (find_seek_offset_time), (gst_rmdemux_reset), (gst_rmdemux_chain),
+       (gst_rmdemux_parse_mdpr), (gst_rmdemux_descramble_cook_audio),
+       (gst_rmdemux_descramble_dnet_audio),
+       (gst_rmdemux_parse_video_packet), (gst_rmdemux_parse_audio_packet):
+       * gst/realmedia/rmdemux.h:
+       Keep track of the first timestamp of the stream and add this to the
+       outgoing buffer timestamps so that we can handle live streams.
+       Set discont flag on the first buffers and after a seek.
+
 === release 0.10.9 ===
 
 2008-08-26  Jan Schmidt <jan.schmidt@sun.com>
index e1bb4f1..bf9b1df 100644 (file)
@@ -58,6 +58,7 @@ struct _GstRMDemuxStream
   int id;
   GstPad *pad;
   GstFlowReturn last_flow;
+  gboolean discont;
   int timescale;
 
   int sample_index;
@@ -264,6 +265,7 @@ gst_rmdemux_init (GstRMDemux * rmdemux)
 
   rmdemux->adapter = gst_adapter_new ();
   rmdemux->first_ts = GST_CLOCK_TIME_NONE;
+  rmdemux->base_ts = GST_CLOCK_TIME_NONE;
   rmdemux->need_newsegment = TRUE;
 }
 
@@ -462,6 +464,7 @@ find_seek_offset_time (GstRMDemux * rmdemux, GstClockTime time)
         break;
       }
     }
+    stream->discont = TRUE;
   }
   return ret;
 }
@@ -717,6 +720,7 @@ gst_rmdemux_reset (GstRMDemux * rmdemux)
 
   gst_segment_init (&rmdemux->segment, GST_FORMAT_UNDEFINED);
   rmdemux->first_ts = GST_CLOCK_TIME_NONE;
+  rmdemux->base_ts = GST_CLOCK_TIME_NONE;
   rmdemux->need_newsegment = TRUE;
 }
 
@@ -971,6 +975,12 @@ gst_rmdemux_chain (GstPad * pad, GstBuffer * buffer)
 
   GstRMDemux *rmdemux = GST_RMDEMUX (GST_PAD_PARENT (pad));
 
+  if (rmdemux->base_ts == -1) {
+    rmdemux->base_ts = GST_BUFFER_TIMESTAMP (buffer);
+    GST_LOG_OBJECT (rmdemux, "base_ts %" GST_TIME_FORMAT,
+        GST_TIME_ARGS (rmdemux->base_ts));
+  }
+
   gst_adapter_push (rmdemux->adapter, buffer);
 
   GST_LOG_OBJECT (rmdemux, "Chaining buffer of size %d",
@@ -1557,6 +1567,7 @@ gst_rmdemux_parse_mdpr (GstRMDemux * rmdemux, const guint8 * data, int length)
   stream->last_ts = -1;
   stream->next_ts = -1;
   stream->last_flow = GST_FLOW_OK;
+  stream->discont = TRUE;
   stream->adapter = gst_adapter_new ();
   GST_LOG_OBJECT (rmdemux, "stream_number=%d", stream->id);
 
@@ -1924,6 +1935,15 @@ gst_rmdemux_descramble_cook_audio (GstRMDemux * rmdemux,
     GstBuffer *subbuf;
 
     subbuf = gst_buffer_create_sub (outbuf, p * packet_size, packet_size);
+
+    GST_LOG_OBJECT (rmdemux, "pushing buffer timestamp %" GST_TIME_FORMAT,
+        GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (subbuf)));
+
+    if (stream->discont) {
+      GST_BUFFER_FLAG_SET (subbuf, GST_BUFFER_FLAG_DISCONT);
+      stream->discont = FALSE;
+    }
+
     gst_buffer_set_caps (subbuf, GST_PAD_CAPS (stream->pad));
     ret = gst_pad_push (stream->pad, subbuf);
     if (ret != GST_FLOW_OK)
@@ -1950,6 +1970,11 @@ gst_rmdemux_descramble_dnet_audio (GstRMDemux * rmdemux,
   g_ptr_array_set_size (stream->subpackets, 0);
 
   buf = gst_rm_utils_descramble_dnet_buffer (buf);
+
+  if (stream->discont) {
+    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
+    stream->discont = FALSE;
+  }
   return gst_pad_push (stream->pad, buf);
 }
 
@@ -2289,13 +2314,24 @@ gst_rmdemux_parse_video_packet (GstRMDemux * rmdemux, GstRMDemuxStream * stream,
       timestamp =
           gst_rmdemux_fix_timestamp (rmdemux, stream, outdata, timestamp);
 
-      if (timestamp > rmdemux->first_ts)
+      if (rmdemux->first_ts != -1 && timestamp > rmdemux->first_ts)
         timestamp -= rmdemux->first_ts;
       else
         timestamp = 0;
 
+      if (rmdemux->base_ts != -1)
+        timestamp += rmdemux->base_ts;
+
       GST_BUFFER_TIMESTAMP (out) = timestamp;
 
+      GST_LOG_OBJECT (rmdemux, "pushing timestamp %" GST_TIME_FORMAT,
+          GST_TIME_ARGS (timestamp));
+
+      if (stream->discont) {
+        GST_BUFFER_FLAG_SET (out, GST_BUFFER_FLAG_DISCONT);
+        stream->discont = FALSE;
+      }
+
       ret = gst_pad_push (stream->pad, out);
       ret = gst_rmdemux_combine_flows (rmdemux, stream, ret);
       if (ret != GST_FLOW_OK)
@@ -2352,19 +2388,30 @@ gst_rmdemux_parse_audio_packet (GstRMDemux * rmdemux, GstRMDemuxStream * stream,
 
   memcpy (GST_BUFFER_DATA (buffer), (guint8 *) data, size);
 
-  if (timestamp > rmdemux->first_ts)
+  if (rmdemux->first_ts != -1 && timestamp > rmdemux->first_ts)
     timestamp -= rmdemux->first_ts;
   else
     timestamp = 0;
 
+  if (rmdemux->base_ts != -1)
+    timestamp += rmdemux->base_ts;
+
   GST_BUFFER_TIMESTAMP (buffer) = timestamp;
 
   if (stream->needs_descrambling) {
+    GST_LOG_OBJECT (rmdemux, "descramble timestamp %" GST_TIME_FORMAT,
+        GST_TIME_ARGS (timestamp));
     ret = gst_rmdemux_handle_scrambled_packet (rmdemux, stream, buffer, key);
   } else {
-    GST_LOG_OBJECT (rmdemux, "Pushing buffer of size %d to pad %s",
-        GST_BUFFER_SIZE (buffer), GST_PAD_NAME (stream->pad));
-
+    GST_LOG_OBJECT (rmdemux,
+        "Pushing buffer of size %d, timestamp %" GST_TIME_FORMAT "to pad %s",
+        GST_BUFFER_SIZE (buffer), GST_TIME_ARGS (timestamp),
+        GST_PAD_NAME (stream->pad));
+
+    if (stream->discont) {
+      GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
+      stream->discont = FALSE;
+    }
     ret = gst_pad_push (stream->pad, buffer);
   }
   return ret;
index f44fb0a..0ca0101 100644 (file)
@@ -113,6 +113,7 @@ struct _GstRMDemux {
   GstClockTime cur_timestamp;
 
   /* First timestamp */
+  GstClockTime base_ts;
   GstClockTime first_ts;
 
   int n_chunks;