mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-02 04:22:27 +00:00
gst/base/gstbasesrc.c: Fix seeking.
Original commit message from CVS: * gst/base/gstbasesrc.c: (gst_base_src_init), (gst_base_src_do_seek), (gst_base_src_loop), (gst_base_src_start): Fix seeking.
This commit is contained in:
parent
5cce351ef3
commit
5b63b6489e
3 changed files with 118 additions and 66 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2005-10-21 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
|
* gst/base/gstbasesrc.c: (gst_base_src_init),
|
||||||
|
(gst_base_src_do_seek), (gst_base_src_loop), (gst_base_src_start):
|
||||||
|
Fix seeking.
|
||||||
|
|
||||||
2005-10-21 Wim Taymans <wim@fluendo.com>
|
2005-10-21 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
* docs/design/part-segments.txt:
|
* docs/design/part-segments.txt:
|
||||||
|
|
|
@ -211,6 +211,7 @@ gst_base_src_init (GstBaseSrc * basesrc, gpointer g_class)
|
||||||
GST_DEBUG_OBJECT (basesrc, "adding src pad");
|
GST_DEBUG_OBJECT (basesrc, "adding src pad");
|
||||||
gst_element_add_pad (GST_ELEMENT (basesrc), pad);
|
gst_element_add_pad (GST_ELEMENT (basesrc), pad);
|
||||||
|
|
||||||
|
basesrc->segment_loop = FALSE;
|
||||||
basesrc->segment_start = -1;
|
basesrc->segment_start = -1;
|
||||||
basesrc->segment_end = -1;
|
basesrc->segment_end = -1;
|
||||||
basesrc->need_newsegment = TRUE;
|
basesrc->need_newsegment = TRUE;
|
||||||
|
@ -424,6 +425,8 @@ gst_base_src_do_seek (GstBaseSrc * src, GstEvent * event)
|
||||||
GstSeekFlags flags;
|
GstSeekFlags flags;
|
||||||
GstSeekType cur_type, stop_type;
|
GstSeekType cur_type, stop_type;
|
||||||
gint64 cur, stop;
|
gint64 cur, stop;
|
||||||
|
gboolean flush;
|
||||||
|
gboolean update_stop = TRUE, update_start = TRUE;
|
||||||
|
|
||||||
gst_event_parse_seek (event, &rate, &format, &flags,
|
gst_event_parse_seek (event, &rate, &format, &flags,
|
||||||
&cur_type, &cur, &stop_type, &stop);
|
&cur_type, &cur, &stop_type, &stop);
|
||||||
|
@ -433,13 +436,18 @@ gst_base_src_do_seek (GstBaseSrc * src, GstEvent * event)
|
||||||
format = GST_FORMAT_BYTES;
|
format = GST_FORMAT_BYTES;
|
||||||
/* we can only seek bytes */
|
/* we can only seek bytes */
|
||||||
if (format != GST_FORMAT_BYTES)
|
if (format != GST_FORMAT_BYTES)
|
||||||
return FALSE;
|
goto unsupported_seek;
|
||||||
|
|
||||||
|
flush = flags & GST_SEEK_FLAG_FLUSH;
|
||||||
|
|
||||||
/* get seek positions */
|
/* get seek positions */
|
||||||
src->segment_loop = flags & GST_SEEK_FLAG_SEGMENT;
|
src->segment_loop = (flags & GST_SEEK_FLAG_SEGMENT) != 0;
|
||||||
|
|
||||||
/* send flush start */
|
/* send flush start */
|
||||||
gst_pad_push_event (src->srcpad, gst_event_new_flush_start ());
|
if (flush)
|
||||||
|
gst_pad_push_event (src->srcpad, gst_event_new_flush_start ());
|
||||||
|
else
|
||||||
|
gst_pad_pause_task (src->srcpad);
|
||||||
|
|
||||||
/* unblock streaming thread */
|
/* unblock streaming thread */
|
||||||
gst_base_src_unlock (src);
|
gst_base_src_unlock (src);
|
||||||
|
@ -447,52 +455,49 @@ gst_base_src_do_seek (GstBaseSrc * src, GstEvent * event)
|
||||||
/* grab streaming lock */
|
/* grab streaming lock */
|
||||||
GST_STREAM_LOCK (src->srcpad);
|
GST_STREAM_LOCK (src->srcpad);
|
||||||
|
|
||||||
/* send flush stop */
|
|
||||||
gst_pad_push_event (src->srcpad, gst_event_new_flush_stop ());
|
|
||||||
|
|
||||||
/* perform the seek */
|
/* perform the seek */
|
||||||
switch (cur_type) {
|
switch (cur_type) {
|
||||||
case GST_SEEK_TYPE_NONE:
|
case GST_SEEK_TYPE_NONE:
|
||||||
|
/* no update to segment */
|
||||||
|
cur = src->segment_start;
|
||||||
|
update_start = FALSE;
|
||||||
break;
|
break;
|
||||||
case GST_SEEK_TYPE_SET:
|
case GST_SEEK_TYPE_SET:
|
||||||
if (cur < 0)
|
/* cur hold desired position */
|
||||||
goto error;
|
|
||||||
src->offset = MIN (cur, src->size);
|
|
||||||
src->segment_start = src->offset;
|
|
||||||
break;
|
break;
|
||||||
case GST_SEEK_TYPE_CUR:
|
case GST_SEEK_TYPE_CUR:
|
||||||
src->offset = CLAMP (src->offset + cur, 0, src->size);
|
/* add cur to currently configure segment */
|
||||||
src->segment_start = src->offset;
|
cur = src->segment_start + cur;
|
||||||
break;
|
break;
|
||||||
case GST_SEEK_TYPE_END:
|
case GST_SEEK_TYPE_END:
|
||||||
if (cur > 0)
|
/* add cur to total length */
|
||||||
goto error;
|
cur = src->size + cur;
|
||||||
src->offset = MAX (0, src->size + cur);
|
|
||||||
src->segment_start = src->offset;
|
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
goto error;
|
|
||||||
}
|
}
|
||||||
|
/* bring in sane range */
|
||||||
|
cur = CLAMP (cur, 0, src->size);
|
||||||
|
|
||||||
switch (stop_type) {
|
switch (stop_type) {
|
||||||
case GST_SEEK_TYPE_NONE:
|
case GST_SEEK_TYPE_NONE:
|
||||||
|
stop = src->segment_end;
|
||||||
|
update_stop = FALSE;
|
||||||
break;
|
break;
|
||||||
case GST_SEEK_TYPE_SET:
|
case GST_SEEK_TYPE_SET:
|
||||||
if (stop < 0)
|
|
||||||
goto error;
|
|
||||||
src->segment_end = MIN (stop, src->size);
|
|
||||||
break;
|
break;
|
||||||
case GST_SEEK_TYPE_CUR:
|
case GST_SEEK_TYPE_CUR:
|
||||||
src->segment_end = CLAMP (src->segment_end + stop, 0, src->size);
|
stop = src->segment_end + stop;
|
||||||
break;
|
break;
|
||||||
case GST_SEEK_TYPE_END:
|
case GST_SEEK_TYPE_END:
|
||||||
if (stop > 0)
|
stop = src->size + stop;
|
||||||
goto error;
|
|
||||||
src->segment_end = src->size + stop;
|
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
goto error;
|
|
||||||
}
|
}
|
||||||
|
stop = CLAMP (stop, 0, src->size);
|
||||||
|
|
||||||
|
src->segment_start = cur;
|
||||||
|
src->segment_end = stop;
|
||||||
|
|
||||||
|
/* update our offset */
|
||||||
|
src->offset = cur;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (src, "seek pending for segment from %" G_GINT64_FORMAT
|
GST_DEBUG_OBJECT (src, "seek pending for segment from %" G_GINT64_FORMAT
|
||||||
" to %" G_GINT64_FORMAT, src->segment_start, src->segment_end);
|
" to %" G_GINT64_FORMAT, src->segment_start, src->segment_end);
|
||||||
|
@ -500,9 +505,20 @@ gst_base_src_do_seek (GstBaseSrc * src, GstEvent * event)
|
||||||
/* now make sure the newsegment will be send */
|
/* now make sure the newsegment will be send */
|
||||||
src->need_newsegment = TRUE;
|
src->need_newsegment = TRUE;
|
||||||
|
|
||||||
|
if (flush)
|
||||||
|
/* send flush stop */
|
||||||
|
gst_pad_push_event (src->srcpad, gst_event_new_flush_stop ());
|
||||||
|
|
||||||
|
if (src->segment_loop) {
|
||||||
|
gst_element_post_message (GST_ELEMENT (src),
|
||||||
|
gst_message_new_segment_start (GST_OBJECT (src), GST_FORMAT_BYTES,
|
||||||
|
cur));
|
||||||
|
}
|
||||||
|
|
||||||
/* and restart the task */
|
/* and restart the task */
|
||||||
gst_pad_start_task (src->srcpad, (GstTaskFunction) gst_base_src_loop,
|
gst_pad_start_task (src->srcpad, (GstTaskFunction) gst_base_src_loop,
|
||||||
src->srcpad);
|
src->srcpad);
|
||||||
|
|
||||||
GST_STREAM_UNLOCK (src->srcpad);
|
GST_STREAM_UNLOCK (src->srcpad);
|
||||||
|
|
||||||
gst_event_unref (event);
|
gst_event_unref (event);
|
||||||
|
@ -510,11 +526,12 @@ gst_base_src_do_seek (GstBaseSrc * src, GstEvent * event)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* ERROR */
|
/* ERROR */
|
||||||
error:
|
unsupported_seek:
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (src, "seek error");
|
GST_DEBUG_OBJECT (src, "invalid format");
|
||||||
GST_STREAM_UNLOCK (src->srcpad);
|
GST_ELEMENT_WARNING (src, STREAM, NOT_IMPLEMENTED,
|
||||||
gst_event_unref (event);
|
("Seek aborted, unsupported format"),
|
||||||
|
("Seek aborted, unsupported format"));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -740,7 +757,12 @@ eos:
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (src, "going to EOS");
|
GST_DEBUG_OBJECT (src, "going to EOS");
|
||||||
gst_pad_pause_task (pad);
|
gst_pad_pause_task (pad);
|
||||||
gst_pad_push_event (pad, gst_event_new_eos ());
|
if (src->segment_loop) {
|
||||||
|
gst_element_post_message (GST_ELEMENT (src),
|
||||||
|
gst_message_new_segment_done (GST_OBJECT (src),
|
||||||
|
GST_FORMAT_BYTES, src->segment_end));
|
||||||
|
} else
|
||||||
|
gst_pad_push_event (pad, gst_event_new_eos ());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pause:
|
pause:
|
||||||
|
@ -938,7 +960,8 @@ gst_base_src_start (GstBaseSrc * basesrc)
|
||||||
|
|
||||||
GST_DEBUG ("size %d %lld", result, basesrc->size);
|
GST_DEBUG ("size %d %lld", result, basesrc->size);
|
||||||
|
|
||||||
/* we always run to the end */
|
/* we always run to the end when starting */
|
||||||
|
basesrc->segment_loop = FALSE;
|
||||||
basesrc->segment_start = 0;
|
basesrc->segment_start = 0;
|
||||||
basesrc->segment_end = basesrc->size;
|
basesrc->segment_end = basesrc->size;
|
||||||
basesrc->need_newsegment = TRUE;
|
basesrc->need_newsegment = TRUE;
|
||||||
|
|
|
@ -211,6 +211,7 @@ gst_base_src_init (GstBaseSrc * basesrc, gpointer g_class)
|
||||||
GST_DEBUG_OBJECT (basesrc, "adding src pad");
|
GST_DEBUG_OBJECT (basesrc, "adding src pad");
|
||||||
gst_element_add_pad (GST_ELEMENT (basesrc), pad);
|
gst_element_add_pad (GST_ELEMENT (basesrc), pad);
|
||||||
|
|
||||||
|
basesrc->segment_loop = FALSE;
|
||||||
basesrc->segment_start = -1;
|
basesrc->segment_start = -1;
|
||||||
basesrc->segment_end = -1;
|
basesrc->segment_end = -1;
|
||||||
basesrc->need_newsegment = TRUE;
|
basesrc->need_newsegment = TRUE;
|
||||||
|
@ -424,6 +425,8 @@ gst_base_src_do_seek (GstBaseSrc * src, GstEvent * event)
|
||||||
GstSeekFlags flags;
|
GstSeekFlags flags;
|
||||||
GstSeekType cur_type, stop_type;
|
GstSeekType cur_type, stop_type;
|
||||||
gint64 cur, stop;
|
gint64 cur, stop;
|
||||||
|
gboolean flush;
|
||||||
|
gboolean update_stop = TRUE, update_start = TRUE;
|
||||||
|
|
||||||
gst_event_parse_seek (event, &rate, &format, &flags,
|
gst_event_parse_seek (event, &rate, &format, &flags,
|
||||||
&cur_type, &cur, &stop_type, &stop);
|
&cur_type, &cur, &stop_type, &stop);
|
||||||
|
@ -433,13 +436,18 @@ gst_base_src_do_seek (GstBaseSrc * src, GstEvent * event)
|
||||||
format = GST_FORMAT_BYTES;
|
format = GST_FORMAT_BYTES;
|
||||||
/* we can only seek bytes */
|
/* we can only seek bytes */
|
||||||
if (format != GST_FORMAT_BYTES)
|
if (format != GST_FORMAT_BYTES)
|
||||||
return FALSE;
|
goto unsupported_seek;
|
||||||
|
|
||||||
|
flush = flags & GST_SEEK_FLAG_FLUSH;
|
||||||
|
|
||||||
/* get seek positions */
|
/* get seek positions */
|
||||||
src->segment_loop = flags & GST_SEEK_FLAG_SEGMENT;
|
src->segment_loop = (flags & GST_SEEK_FLAG_SEGMENT) != 0;
|
||||||
|
|
||||||
/* send flush start */
|
/* send flush start */
|
||||||
gst_pad_push_event (src->srcpad, gst_event_new_flush_start ());
|
if (flush)
|
||||||
|
gst_pad_push_event (src->srcpad, gst_event_new_flush_start ());
|
||||||
|
else
|
||||||
|
gst_pad_pause_task (src->srcpad);
|
||||||
|
|
||||||
/* unblock streaming thread */
|
/* unblock streaming thread */
|
||||||
gst_base_src_unlock (src);
|
gst_base_src_unlock (src);
|
||||||
|
@ -447,52 +455,49 @@ gst_base_src_do_seek (GstBaseSrc * src, GstEvent * event)
|
||||||
/* grab streaming lock */
|
/* grab streaming lock */
|
||||||
GST_STREAM_LOCK (src->srcpad);
|
GST_STREAM_LOCK (src->srcpad);
|
||||||
|
|
||||||
/* send flush stop */
|
|
||||||
gst_pad_push_event (src->srcpad, gst_event_new_flush_stop ());
|
|
||||||
|
|
||||||
/* perform the seek */
|
/* perform the seek */
|
||||||
switch (cur_type) {
|
switch (cur_type) {
|
||||||
case GST_SEEK_TYPE_NONE:
|
case GST_SEEK_TYPE_NONE:
|
||||||
|
/* no update to segment */
|
||||||
|
cur = src->segment_start;
|
||||||
|
update_start = FALSE;
|
||||||
break;
|
break;
|
||||||
case GST_SEEK_TYPE_SET:
|
case GST_SEEK_TYPE_SET:
|
||||||
if (cur < 0)
|
/* cur hold desired position */
|
||||||
goto error;
|
|
||||||
src->offset = MIN (cur, src->size);
|
|
||||||
src->segment_start = src->offset;
|
|
||||||
break;
|
break;
|
||||||
case GST_SEEK_TYPE_CUR:
|
case GST_SEEK_TYPE_CUR:
|
||||||
src->offset = CLAMP (src->offset + cur, 0, src->size);
|
/* add cur to currently configure segment */
|
||||||
src->segment_start = src->offset;
|
cur = src->segment_start + cur;
|
||||||
break;
|
break;
|
||||||
case GST_SEEK_TYPE_END:
|
case GST_SEEK_TYPE_END:
|
||||||
if (cur > 0)
|
/* add cur to total length */
|
||||||
goto error;
|
cur = src->size + cur;
|
||||||
src->offset = MAX (0, src->size + cur);
|
|
||||||
src->segment_start = src->offset;
|
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
goto error;
|
|
||||||
}
|
}
|
||||||
|
/* bring in sane range */
|
||||||
|
cur = CLAMP (cur, 0, src->size);
|
||||||
|
|
||||||
switch (stop_type) {
|
switch (stop_type) {
|
||||||
case GST_SEEK_TYPE_NONE:
|
case GST_SEEK_TYPE_NONE:
|
||||||
|
stop = src->segment_end;
|
||||||
|
update_stop = FALSE;
|
||||||
break;
|
break;
|
||||||
case GST_SEEK_TYPE_SET:
|
case GST_SEEK_TYPE_SET:
|
||||||
if (stop < 0)
|
|
||||||
goto error;
|
|
||||||
src->segment_end = MIN (stop, src->size);
|
|
||||||
break;
|
break;
|
||||||
case GST_SEEK_TYPE_CUR:
|
case GST_SEEK_TYPE_CUR:
|
||||||
src->segment_end = CLAMP (src->segment_end + stop, 0, src->size);
|
stop = src->segment_end + stop;
|
||||||
break;
|
break;
|
||||||
case GST_SEEK_TYPE_END:
|
case GST_SEEK_TYPE_END:
|
||||||
if (stop > 0)
|
stop = src->size + stop;
|
||||||
goto error;
|
|
||||||
src->segment_end = src->size + stop;
|
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
goto error;
|
|
||||||
}
|
}
|
||||||
|
stop = CLAMP (stop, 0, src->size);
|
||||||
|
|
||||||
|
src->segment_start = cur;
|
||||||
|
src->segment_end = stop;
|
||||||
|
|
||||||
|
/* update our offset */
|
||||||
|
src->offset = cur;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (src, "seek pending for segment from %" G_GINT64_FORMAT
|
GST_DEBUG_OBJECT (src, "seek pending for segment from %" G_GINT64_FORMAT
|
||||||
" to %" G_GINT64_FORMAT, src->segment_start, src->segment_end);
|
" to %" G_GINT64_FORMAT, src->segment_start, src->segment_end);
|
||||||
|
@ -500,9 +505,20 @@ gst_base_src_do_seek (GstBaseSrc * src, GstEvent * event)
|
||||||
/* now make sure the newsegment will be send */
|
/* now make sure the newsegment will be send */
|
||||||
src->need_newsegment = TRUE;
|
src->need_newsegment = TRUE;
|
||||||
|
|
||||||
|
if (flush)
|
||||||
|
/* send flush stop */
|
||||||
|
gst_pad_push_event (src->srcpad, gst_event_new_flush_stop ());
|
||||||
|
|
||||||
|
if (src->segment_loop) {
|
||||||
|
gst_element_post_message (GST_ELEMENT (src),
|
||||||
|
gst_message_new_segment_start (GST_OBJECT (src), GST_FORMAT_BYTES,
|
||||||
|
cur));
|
||||||
|
}
|
||||||
|
|
||||||
/* and restart the task */
|
/* and restart the task */
|
||||||
gst_pad_start_task (src->srcpad, (GstTaskFunction) gst_base_src_loop,
|
gst_pad_start_task (src->srcpad, (GstTaskFunction) gst_base_src_loop,
|
||||||
src->srcpad);
|
src->srcpad);
|
||||||
|
|
||||||
GST_STREAM_UNLOCK (src->srcpad);
|
GST_STREAM_UNLOCK (src->srcpad);
|
||||||
|
|
||||||
gst_event_unref (event);
|
gst_event_unref (event);
|
||||||
|
@ -510,11 +526,12 @@ gst_base_src_do_seek (GstBaseSrc * src, GstEvent * event)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* ERROR */
|
/* ERROR */
|
||||||
error:
|
unsupported_seek:
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (src, "seek error");
|
GST_DEBUG_OBJECT (src, "invalid format");
|
||||||
GST_STREAM_UNLOCK (src->srcpad);
|
GST_ELEMENT_WARNING (src, STREAM, NOT_IMPLEMENTED,
|
||||||
gst_event_unref (event);
|
("Seek aborted, unsupported format"),
|
||||||
|
("Seek aborted, unsupported format"));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -740,7 +757,12 @@ eos:
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (src, "going to EOS");
|
GST_DEBUG_OBJECT (src, "going to EOS");
|
||||||
gst_pad_pause_task (pad);
|
gst_pad_pause_task (pad);
|
||||||
gst_pad_push_event (pad, gst_event_new_eos ());
|
if (src->segment_loop) {
|
||||||
|
gst_element_post_message (GST_ELEMENT (src),
|
||||||
|
gst_message_new_segment_done (GST_OBJECT (src),
|
||||||
|
GST_FORMAT_BYTES, src->segment_end));
|
||||||
|
} else
|
||||||
|
gst_pad_push_event (pad, gst_event_new_eos ());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pause:
|
pause:
|
||||||
|
@ -938,7 +960,8 @@ gst_base_src_start (GstBaseSrc * basesrc)
|
||||||
|
|
||||||
GST_DEBUG ("size %d %lld", result, basesrc->size);
|
GST_DEBUG ("size %d %lld", result, basesrc->size);
|
||||||
|
|
||||||
/* we always run to the end */
|
/* we always run to the end when starting */
|
||||||
|
basesrc->segment_loop = FALSE;
|
||||||
basesrc->segment_start = 0;
|
basesrc->segment_start = 0;
|
||||||
basesrc->segment_end = basesrc->size;
|
basesrc->segment_end = basesrc->size;
|
||||||
basesrc->need_newsegment = TRUE;
|
basesrc->need_newsegment = TRUE;
|
||||||
|
|
Loading…
Reference in a new issue