gst/realmedia/rmdemux.*: Keep track of the first timestamp of the stream and add this to the outgoing buffer timestam...

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.
This commit is contained in:
Wim Taymans 2008-08-27 09:47:17 +00:00
parent 34014be4d4
commit 82a84e69e5
3 changed files with 64 additions and 4 deletions

View file

@ -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>

View 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;

View file

@ -113,6 +113,7 @@ struct _GstRMDemux {
GstClockTime cur_timestamp;
/* First timestamp */
GstClockTime base_ts;
GstClockTime first_ts;
int n_chunks;