Fixed some seeking issues

Original commit message from CVS:
Fixed some seeking issues
This commit is contained in:
Owen Fraser-Green 2005-08-22 07:33:00 +00:00
parent bf941f80d5
commit 79f743bf47
3 changed files with 55 additions and 28 deletions

View file

@ -1,3 +1,9 @@
2005-08-22 Owen Fraser-Green <owen@discobabe.net>
* gst/realmedia/rmdemux.c:
(gst_rmdemux_perform_seek, gst_rmdemux_parse_packet):
Seeking improvements.
2005-08-19 Wim Taymans <wim@fluendo.com> 2005-08-19 Wim Taymans <wim@fluendo.com>
* gst/udp/gstmultiudpsink.c: (gst_multiudpsink_class_init): * gst/udp/gstmultiudpsink.c: (gst_multiudpsink_class_init):

2
common

@ -1 +1 @@
Subproject commit 8ff526a316f9b576e727b8e32cba0a53cdec07a6 Subproject commit aa2a757c587d91069a230d8e656481c3c364ccc6

View file

@ -49,6 +49,7 @@ struct _GstRMDemuxStream
GstRMDemuxIndex *index; GstRMDemuxIndex *index;
int index_length; int index_length;
double frame_rate; double frame_rate;
guint32 seek_offset;
guint16 width; guint16 width;
guint16 height; guint16 height;
@ -255,14 +256,14 @@ GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
GstRMDemux *rmdemux = GST_RMDEMUX (GST_PAD_PARENT (pad)); GstRMDemux *rmdemux = GST_RMDEMUX (GST_PAD_PARENT (pad));
GST_LOG_OBJECT (rmdemux, "handling event");
switch (GST_EVENT_TYPE (event)) { switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_NEWSEGMENT: case GST_EVENT_NEWSEGMENT:
GST_DEBUG_OBJECT (rmdemux, "newsegment event"); GST_LOG_OBJECT (rmdemux, "Event on sink: NEWSEGMENT");
gst_event_unref (event); gst_event_unref (event);
break; break;
default: default:
GST_LOG_OBJECT (rmdemux, "Event on sink: type=%d",
GST_EVENT_TYPE (event));
ret = gst_pad_event_default (rmdemux->sinkpad, event); ret = gst_pad_event_default (rmdemux->sinkpad, event);
break; break;
} }
@ -288,6 +289,7 @@ gst_rmdemux_src_event (GstPad * pad, GstEvent * event)
GstSeekType cur_type, stop_type; GstSeekType cur_type, stop_type;
gint64 cur, stop; gint64 cur, stop;
GST_LOG_OBJECT (rmdemux, "Event on src: SEEK");
/* can't seek if we are not seekable, FIXME could pass the /* can't seek if we are not seekable, FIXME could pass the
* seek query upstream after converting it to bytes using * seek query upstream after converting it to bytes using
* the average bitrate of the stream. */ * the average bitrate of the stream. */
@ -328,6 +330,7 @@ gst_rmdemux_src_event (GstPad * pad, GstEvent * event)
break; break;
} }
default: default:
GST_LOG_OBJECT (rmdemux, "Event on src: type=%d", GST_EVENT_TYPE (event));
ret = gst_pad_event_default (rmdemux->sinkpad, event); ret = gst_pad_event_default (rmdemux->sinkpad, event);
break; break;
} }
@ -378,27 +381,32 @@ gst_rmdemux_perform_seek (GstRMDemux * rmdemux, gboolean flush)
int i, n; int i, n;
rmdemux->offset = 0; rmdemux->offset = 0;
GstClockTime tmp_time = 0; GstClockTime tmp_time = rmdemux->segment_stop;
/* Find the last offset which occurs after the seek time */ /* Find the last offset which occurs before the seek time */
for (n = 0; n < rmdemux->n_streams; n++) { for (n = 0; n < rmdemux->n_streams; n++) {
GstRMDemuxStream *stream; GstRMDemuxStream *stream;
stream = rmdemux->streams[n]; stream = rmdemux->streams[n];
for (i = 0; i < stream->index_length; i++) { for (i = stream->index_length - 1; i >= 0; i--) {
if (stream->index[i].timestamp > rmdemux->segment_start) { if (stream->index[i].timestamp < rmdemux->segment_start) {
if (stream->index[i].offset > rmdemux->offset) { /* Set the seek_offset for the stream so we don't bother parsing it
rmdemux->offset = stream->index[i].offset; * until we've passed that point */
stream->seek_offset = stream->index[i].offset;
if (tmp_time > stream->index[i].timestamp) {
tmp_time = stream->index[i].timestamp; tmp_time = stream->index[i].timestamp;
rmdemux->offset = stream->index[i].offset;
GST_DEBUG_OBJECT (rmdemux,
"We're looking for %" GST_TIME_FORMAT
" and we found that stream %d has the latest index at %"
GST_TIME_FORMAT, GST_TIME_ARGS (rmdemux->segment_start), n,
GST_TIME_ARGS (tmp_time));
} }
break; break;
} }
} }
} }
GST_DEBUG_OBJECT (rmdemux, "seek offset to %" GST_TIME_FORMAT " at 0x%x",
GST_TIME_ARGS (tmp_time), rmdemux->offset);
} }
/* now we have a new position, prepare for streaming again */ /* now we have a new position, prepare for streaming again */
@ -417,6 +425,9 @@ gst_rmdemux_perform_seek (GstRMDemux * rmdemux, gboolean flush)
GST_FORMAT_TIME, (gint64) rmdemux->segment_start, GST_FORMAT_TIME, (gint64) rmdemux->segment_start,
(gint64) rmdemux->segment_stop, 0); (gint64) rmdemux->segment_stop, 0);
GST_DEBUG_OBJECT (rmdemux,
"sending NEWSEGMENT event to all src pads with segment_start= %"
GST_TIME_FORMAT, GST_TIME_ARGS (rmdemux->segment_start));
gst_rmdemux_send_event (rmdemux, event); gst_rmdemux_send_event (rmdemux, event);
/* notify start of new segment */ /* notify start of new segment */
@ -826,6 +837,7 @@ gst_rmdemux_chain (GstPad * pad, GstBuffer * buffer)
gst_element_no_more_pads (GST_ELEMENT (rmdemux)); gst_element_no_more_pads (GST_ELEMENT (rmdemux));
rmdemux->have_pads = TRUE; rmdemux->have_pads = TRUE;
GST_LOG_OBJECT (rmdemux, "no more pads.");
gst_rmdemux_send_event (rmdemux, gst_rmdemux_send_event (rmdemux,
gst_event_new_newsegment (1.0, GST_FORMAT_TIME, (gint64) 0, gst_event_new_newsegment (1.0, GST_FORMAT_TIME, (gint64) 0,
(gint64) - 1, 0)); (gint64) - 1, 0));
@ -945,6 +957,8 @@ gst_rmdemux_send_event (GstRMDemux * rmdemux, GstEvent * event)
stream = rmdemux->streams[i]; stream = rmdemux->streams[i];
GST_DEBUG_OBJECT (rmdemux, "Pushing event to stream %d", i);
gst_event_ref (event); gst_event_ref (event);
gst_pad_push_event (stream->pad, event); gst_pad_push_event (stream->pad, event);
} }
@ -1200,7 +1214,7 @@ gst_rmdemux_parse_prop (GstRMDemux * rmdemux, const void *data, int length)
GST_LOG_OBJECT (rmdemux, "number of packets: %d", rmdemux->num_packets); GST_LOG_OBJECT (rmdemux, "number of packets: %d", rmdemux->num_packets);
GST_LOG_OBJECT (rmdemux, "duration: %d", RMDEMUX_GUINT32_GET (data + 20)); GST_LOG_OBJECT (rmdemux, "duration: %d", RMDEMUX_GUINT32_GET (data + 20));
rmdemux->duration = RMDEMUX_GUINT32_GET (data + 20) * GST_SECOND / 1000; rmdemux->duration = RMDEMUX_GUINT32_GET (data + 20) * GST_MSECOND;
GST_LOG_OBJECT (rmdemux, "preroll: %d", RMDEMUX_GUINT32_GET (data + 24)); GST_LOG_OBJECT (rmdemux, "preroll: %d", RMDEMUX_GUINT32_GET (data + 24));
rmdemux->index_offset = RMDEMUX_GUINT32_GET (data + 28); rmdemux->index_offset = RMDEMUX_GUINT32_GET (data + 28);
@ -1228,6 +1242,7 @@ gst_rmdemux_parse_mdpr (GstRMDemux * rmdemux, const void *data, int length)
stream->id = RMDEMUX_GUINT16_GET (data); stream->id = RMDEMUX_GUINT16_GET (data);
stream->index = NULL; stream->index = NULL;
stream->seek_offset = 0;
GST_LOG_OBJECT (rmdemux, "stream_number=%d", stream->id); GST_LOG_OBJECT (rmdemux, "stream_number=%d", stream->id);
offset = 30; offset = 30;
@ -1393,9 +1408,8 @@ gst_rmdemux_parse_indx (GstRMDemux * rmdemux, const void *data, int length)
index[i].timestamp = RMDEMUX_GUINT32_GET (data + offset + 2) * GST_MSECOND; index[i].timestamp = RMDEMUX_GUINT32_GET (data + offset + 2) * GST_MSECOND;
index[i].offset = RMDEMUX_GUINT32_GET (data + offset + 6); index[i].offset = RMDEMUX_GUINT32_GET (data + offset + 6);
GST_DEBUG_OBJECT (rmdemux, "Index found for timestamp=%f at offset=%x", GST_DEBUG_OBJECT (rmdemux, "Index found for timestamp=%f (at offset=%x)",
(float) index[i].timestamp / 1000.0, index[i].offset); (float) index[i].timestamp / GST_SECOND, index[i].offset);
offset += 14; offset += 14;
} }
@ -1446,6 +1460,7 @@ gst_rmdemux_parse_packet (GstRMDemux * rmdemux, const void *data,
stream = gst_rmdemux_get_stream_by_id (rmdemux, id); stream = gst_rmdemux_get_stream_by_id (rmdemux, id);
if (rmdemux->offset >= stream->seek_offset) {
if (gst_pad_alloc_buffer (stream->pad, GST_BUFFER_OFFSET_NONE, if (gst_pad_alloc_buffer (stream->pad, GST_BUFFER_OFFSET_NONE,
packet_size, stream->caps, &buffer) != GST_FLOW_OK) { packet_size, stream->caps, &buffer) != GST_FLOW_OK) {
GST_WARNING_OBJECT (rmdemux, "failed to alloc src buffer for stream %d", GST_WARNING_OBJECT (rmdemux, "failed to alloc src buffer for stream %d",
@ -1454,10 +1469,16 @@ gst_rmdemux_parse_packet (GstRMDemux * rmdemux, const void *data,
} }
memcpy (GST_BUFFER_DATA (buffer), (guint8 *) data, packet_size); memcpy (GST_BUFFER_DATA (buffer), (guint8 *) data, packet_size);
GST_BUFFER_TIMESTAMP (buffer) = GST_SECOND * timestamp / 1000; GST_BUFFER_TIMESTAMP (buffer) = GST_MSECOND * timestamp;
if (stream && stream->pad && GST_PAD_IS_USABLE (stream->pad)) { if (stream && stream->pad && GST_PAD_IS_USABLE (stream->pad)) {
GST_DEBUG_OBJECT (rmdemux, "Pushing buffer of size %d to pad", packet_size); GST_DEBUG_OBJECT (rmdemux, "Pushing buffer of size %d to pad",
packet_size);
gst_pad_push (stream->pad, buffer); gst_pad_push (stream->pad, buffer);
} }
} else {
GST_DEBUG_OBJECT (rmdemux,
"Stream %d is skipping: seek_offset=%d, offset=%d", stream->id,
stream->seek_offset, rmdemux->offset);
}
} }