asfdemux: 0-base timestamps consistently (whether or not streaming)
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Sat, 2 May 2009 14:51:11 +0000 (16:51 +0200)
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Tue, 5 May 2009 20:41:41 +0000 (22:41 +0200)
This also makes timestamps (more) consistent before and after a possible
seek, and moreover makes for reasonable position reporting in live stream
(whose payload timestamps should not be taken for granted).

gst/asfdemux/asfpacket.c
gst/asfdemux/gstasfdemux.c
gst/asfdemux/gstasfdemux.h

index 8b86653..f7972d2 100644 (file)
@@ -129,20 +129,13 @@ gst_asf_payload_queue_for_stream (GstASFDemux * demux, AsfPayload * payload,
     GST_DEBUG_OBJECT (demux, "first ts: %" GST_TIME_FORMAT,
         GST_TIME_ARGS (payload->ts));
     demux->first_ts = payload->ts;
-    if (demux->streaming) {
-      gst_segment_set_seek (&demux->segment, demux->segment.rate,
-          GST_FORMAT_TIME, demux->segment.flags, GST_SEEK_TYPE_SET,
-          demux->first_ts, GST_SEEK_TYPE_NONE, 0, NULL);
-    }
   }
 
   /* make timestamps start from 0 */
-  if (!demux->streaming) {
-    if (demux->first_ts < payload->ts)
-      payload->ts -= demux->first_ts;
-    else
-      payload->ts = 0;
-  }
+  if (demux->first_ts < payload->ts)
+    payload->ts -= demux->first_ts;
+  else
+    payload->ts = 0;
 
   /* remove any incomplete payloads that will never be completed */
   while (stream->payloads->len > 0) {
@@ -190,6 +183,19 @@ gst_asf_payload_queue_for_stream (GstASFDemux * demux, AsfPayload * payload,
     GST_BUFFER_FLAG_SET (payload->buf, GST_BUFFER_FLAG_DISCONT);
   }
 
+  /* remember the first queued timestamp for the segment */
+  if (!GST_CLOCK_TIME_IS_VALID (demux->segment_ts) &&
+      GST_CLOCK_TIME_IS_VALID (payload->ts)) {
+    GST_DEBUG_OBJECT (demux, "segment ts: %" GST_TIME_FORMAT,
+        GST_TIME_ARGS (payload->ts));
+    demux->segment_ts = payload->ts;
+    /* always note, but only determines segment when streaming */
+    if (demux->streaming)
+      gst_segment_set_seek (&demux->segment, demux->segment.rate,
+          GST_FORMAT_TIME, demux->segment.flags, GST_SEEK_TYPE_SET,
+          demux->segment_ts, GST_SEEK_TYPE_NONE, 0, NULL);
+  }
+
   g_array_append_vals (stream->payloads, payload, 1);
 }
 
index 67fed5b..3a92700 100644 (file)
@@ -207,6 +207,7 @@ gst_asf_demux_reset (GstASFDemux * demux)
   demux->num_streams = 0;
   demux->activated_streams = FALSE;
   demux->first_ts = GST_CLOCK_TIME_NONE;
+  demux->segment_ts = GST_CLOCK_TIME_NONE;
   demux->state = GST_ASF_DEMUX_STATE_HEADER;
   demux->seekable = FALSE;
   demux->broadcast = FALSE;
@@ -313,7 +314,7 @@ gst_asf_demux_sink_event (GstPad * pad, GstEvent * event)
 
       /* in either case, clear some state and generate newsegment later on */
       GST_OBJECT_LOCK (demux);
-      demux->first_ts = GST_CLOCK_TIME_NONE;
+      demux->segment_ts = GST_CLOCK_TIME_NONE;
       demux->need_newsegment = TRUE;
       gst_asf_demux_reset_stream_state_after_discont (demux);
       GST_OBJECT_UNLOCK (demux);
@@ -1185,7 +1186,7 @@ gst_asf_demux_push_complete_payloads (GstASFDemux * demux, gboolean force)
   if (demux->need_newsegment) {
 
     /* wait until we had a chance to "lock on" some payload's timestamp */
-    if (!GST_CLOCK_TIME_IS_VALID (demux->first_ts))
+    if (!GST_CLOCK_TIME_IS_VALID (demux->segment_ts))
       return GST_FLOW_OK;
 
     if (demux->segment.stop == GST_CLOCK_TIME_NONE &&
index 37fd413..86a3cfb 100644 (file)
@@ -169,6 +169,7 @@ struct _GstASFDemux {
   GstSegment           segment;          /* configured play segment                 */
 
   gboolean             need_newsegment;  /* do we need to send a new-segment event? */
+  GstClockTime         segment_ts;       /* streaming; timestamp for segment start */
   gboolean             segment_running;  /* if we've started the current segment    */
   gboolean             streaming;        /* TRUE if we are operating chain-based    */
   GstClockTime         latency;