mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-09-28 14:52:24 +00:00
libs/gst/base/gstbasesrc.c: Don't update the last_stop position in do_seek, that's the position we did a seek to.
Original commit message from CVS: * libs/gst/base/gstbasesrc.c: (gst_base_src_default_do_seek), (gst_base_src_loop): Don't update the last_stop position in do_seek, that's the position we did a seek to. Read backwards when we have a negative rate. * tests/check/elements/filesrc.c: (event_func), (wait_eos), (setup_filesrc), (cleanup_filesrc), (GST_START_TEST), (filesrc_suite): Add check for reverse reading.
This commit is contained in:
parent
91a59d5af5
commit
f473d72719
3 changed files with 132 additions and 18 deletions
13
ChangeLog
13
ChangeLog
|
@ -1,3 +1,16 @@
|
||||||
|
2008-01-07 Wim Taymans <wim.taymans@collabora.co.uk>
|
||||||
|
|
||||||
|
* libs/gst/base/gstbasesrc.c: (gst_base_src_default_do_seek),
|
||||||
|
(gst_base_src_loop):
|
||||||
|
Don't update the last_stop position in do_seek, that's the position we
|
||||||
|
did a seek to.
|
||||||
|
Read backwards when we have a negative rate.
|
||||||
|
|
||||||
|
* tests/check/elements/filesrc.c: (event_func), (wait_eos),
|
||||||
|
(setup_filesrc), (cleanup_filesrc), (GST_START_TEST),
|
||||||
|
(filesrc_suite):
|
||||||
|
Add check for reverse reading.
|
||||||
|
|
||||||
2008-01-07 Tim-Philipp Müller <tim at centricular dot net>
|
2008-01-07 Tim-Philipp Müller <tim at centricular dot net>
|
||||||
|
|
||||||
Patch by: Alexis Ballier <aballier at gentoo org>
|
Patch by: Alexis Ballier <aballier at gentoo org>
|
||||||
|
|
|
@ -895,11 +895,9 @@ gst_base_src_default_do_seek (GstBaseSrc * src, GstSegment * segment)
|
||||||
|
|
||||||
/* update our offset if the start/stop position was updated */
|
/* update our offset if the start/stop position was updated */
|
||||||
if (segment->format == GST_FORMAT_BYTES) {
|
if (segment->format == GST_FORMAT_BYTES) {
|
||||||
segment->last_stop = segment->start;
|
|
||||||
segment->time = segment->start;
|
segment->time = segment->start;
|
||||||
} else if (segment->start == 0) {
|
} else if (segment->start == 0) {
|
||||||
/* seek to start, we can implement a default for this. */
|
/* seek to start, we can implement a default for this. */
|
||||||
segment->last_stop = 0;
|
|
||||||
segment->time = 0;
|
segment->time = 0;
|
||||||
res = TRUE;
|
res = TRUE;
|
||||||
} else
|
} else
|
||||||
|
@ -1973,6 +1971,7 @@ gst_base_src_loop (GstPad * pad)
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
gint64 position;
|
gint64 position;
|
||||||
gboolean eos;
|
gboolean eos;
|
||||||
|
gulong blocksize;
|
||||||
|
|
||||||
eos = FALSE;
|
eos = FALSE;
|
||||||
|
|
||||||
|
@ -1988,13 +1987,26 @@ gst_base_src_loop (GstPad * pad)
|
||||||
|
|
||||||
src->priv->last_sent_eos = FALSE;
|
src->priv->last_sent_eos = FALSE;
|
||||||
|
|
||||||
|
blocksize = src->blocksize;
|
||||||
|
|
||||||
/* if we operate in bytes, we can calculate an offset */
|
/* if we operate in bytes, we can calculate an offset */
|
||||||
if (src->segment.format == GST_FORMAT_BYTES)
|
if (src->segment.format == GST_FORMAT_BYTES) {
|
||||||
position = src->segment.last_stop;
|
position = src->segment.last_stop;
|
||||||
else
|
/* for negative rates, start with subtracting the blocksize */
|
||||||
|
if (src->segment.rate < 0.0) {
|
||||||
|
/* we cannot go below segment.start */
|
||||||
|
if (position > src->segment.start + blocksize)
|
||||||
|
position -= blocksize;
|
||||||
|
else {
|
||||||
|
/* last block, remainder up to segment.start */
|
||||||
|
blocksize = position - src->segment.start;
|
||||||
|
position = src->segment.start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
position = -1;
|
position = -1;
|
||||||
|
|
||||||
ret = gst_base_src_get_range (src, position, src->blocksize, &buf);
|
ret = gst_base_src_get_range (src, position, blocksize, &buf);
|
||||||
if (G_UNLIKELY (ret != GST_FLOW_OK)) {
|
if (G_UNLIKELY (ret != GST_FLOW_OK)) {
|
||||||
GST_INFO_OBJECT (src, "pausing after gst_base_src_get_range() = %s",
|
GST_INFO_OBJECT (src, "pausing after gst_base_src_get_range() = %s",
|
||||||
gst_flow_get_name (ret));
|
gst_flow_get_name (ret));
|
||||||
|
@ -2018,8 +2030,14 @@ gst_base_src_loop (GstPad * pad)
|
||||||
/* figure out the new position */
|
/* figure out the new position */
|
||||||
switch (src->segment.format) {
|
switch (src->segment.format) {
|
||||||
case GST_FORMAT_BYTES:
|
case GST_FORMAT_BYTES:
|
||||||
position += GST_BUFFER_SIZE (buf);
|
{
|
||||||
|
guint bufsize = GST_BUFFER_SIZE (buf);
|
||||||
|
|
||||||
|
/* we subtracted above for negative rates */
|
||||||
|
if (src->segment.rate >= 0.0)
|
||||||
|
position += bufsize;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case GST_FORMAT_TIME:
|
case GST_FORMAT_TIME:
|
||||||
{
|
{
|
||||||
GstClockTime start, duration;
|
GstClockTime start, duration;
|
||||||
|
@ -2032,23 +2050,44 @@ gst_base_src_loop (GstPad * pad)
|
||||||
else
|
else
|
||||||
position = src->segment.last_stop;
|
position = src->segment.last_stop;
|
||||||
|
|
||||||
if (GST_CLOCK_TIME_IS_VALID (duration))
|
if (GST_CLOCK_TIME_IS_VALID (duration)) {
|
||||||
position += duration;
|
if (src->segment.rate >= 0.0)
|
||||||
|
position += duration;
|
||||||
|
else if (position > duration)
|
||||||
|
position -= duration;
|
||||||
|
else
|
||||||
|
position = 0;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GST_FORMAT_DEFAULT:
|
case GST_FORMAT_DEFAULT:
|
||||||
position = GST_BUFFER_OFFSET_END (buf);
|
if (src->segment.rate >= 0.0)
|
||||||
|
position = GST_BUFFER_OFFSET_END (buf);
|
||||||
|
else
|
||||||
|
position = GST_BUFFER_OFFSET (buf);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
position = -1;
|
position = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (position != -1) {
|
if (position != -1) {
|
||||||
if (src->segment.stop != -1) {
|
if (src->segment.rate >= 0.0) {
|
||||||
if (position >= src->segment.stop) {
|
/* positive rate, check if we reached the stop */
|
||||||
eos = TRUE;
|
if (src->segment.stop != -1) {
|
||||||
position = src->segment.stop;
|
if (position >= src->segment.stop) {
|
||||||
|
eos = TRUE;
|
||||||
|
position = src->segment.stop;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
/* negative rate, check if we reached the start. start is always set to
|
||||||
|
* something different from -1 */
|
||||||
|
if (position <= src->segment.start) {
|
||||||
|
eos = TRUE;
|
||||||
|
position = src->segment.start;
|
||||||
|
}
|
||||||
|
/* when going reverse, all buffers are DISCONT */
|
||||||
|
src->priv->discont = TRUE;
|
||||||
}
|
}
|
||||||
gst_segment_set_last_stop (&src->segment, src->segment.format, position);
|
gst_segment_set_last_stop (&src->segment, src->segment.format, position);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,9 +25,11 @@
|
||||||
|
|
||||||
#include <gst/check/gstcheck.h>
|
#include <gst/check/gstcheck.h>
|
||||||
|
|
||||||
gboolean have_eos = FALSE;
|
static gboolean have_eos = FALSE;
|
||||||
|
static GCond *eos_cond;
|
||||||
|
static GMutex *event_mutex;
|
||||||
|
|
||||||
GstPad *mysinkpad;
|
static GstPad *mysinkpad;
|
||||||
|
|
||||||
static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
|
static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
GST_PAD_SINK,
|
GST_PAD_SINK,
|
||||||
|
@ -37,14 +39,31 @@ static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
gboolean
|
gboolean
|
||||||
event_func (GstPad * pad, GstEvent * event)
|
event_func (GstPad * pad, GstEvent * event)
|
||||||
{
|
{
|
||||||
|
gboolean res = TRUE;
|
||||||
|
|
||||||
|
g_mutex_lock (event_mutex);
|
||||||
if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
|
if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
|
||||||
have_eos = TRUE;
|
have_eos = TRUE;
|
||||||
gst_event_unref (event);
|
GST_DEBUG ("signal EOS");
|
||||||
return TRUE;
|
g_cond_broadcast (eos_cond);
|
||||||
}
|
}
|
||||||
|
g_mutex_unlock (event_mutex);
|
||||||
|
|
||||||
gst_event_unref (event);
|
gst_event_unref (event);
|
||||||
return FALSE;
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wait_eos (void)
|
||||||
|
{
|
||||||
|
g_mutex_lock (event_mutex);
|
||||||
|
GST_DEBUG ("waiting for EOS");
|
||||||
|
while (!have_eos) {
|
||||||
|
g_cond_wait (eos_cond, event_mutex);
|
||||||
|
}
|
||||||
|
GST_DEBUG ("received EOS");
|
||||||
|
g_mutex_unlock (event_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
GstElement *
|
GstElement *
|
||||||
|
@ -57,6 +76,10 @@ setup_filesrc ()
|
||||||
mysinkpad = gst_check_setup_sink_pad (filesrc, &sinktemplate, NULL);
|
mysinkpad = gst_check_setup_sink_pad (filesrc, &sinktemplate, NULL);
|
||||||
gst_pad_set_event_function (mysinkpad, event_func);
|
gst_pad_set_event_function (mysinkpad, event_func);
|
||||||
gst_pad_set_active (mysinkpad, TRUE);
|
gst_pad_set_active (mysinkpad, TRUE);
|
||||||
|
|
||||||
|
eos_cond = g_cond_new ();
|
||||||
|
event_mutex = g_mutex_new ();
|
||||||
|
|
||||||
return filesrc;
|
return filesrc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,6 +89,9 @@ cleanup_filesrc (GstElement * filesrc)
|
||||||
gst_pad_set_active (mysinkpad, FALSE);
|
gst_pad_set_active (mysinkpad, FALSE);
|
||||||
gst_check_teardown_sink_pad (filesrc);
|
gst_check_teardown_sink_pad (filesrc);
|
||||||
gst_check_teardown_element (filesrc);
|
gst_check_teardown_element (filesrc);
|
||||||
|
|
||||||
|
g_cond_free (eos_cond);
|
||||||
|
g_mutex_free (event_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_START_TEST (test_seeking)
|
GST_START_TEST (test_seeking)
|
||||||
|
@ -101,6 +127,41 @@ GST_START_TEST (test_seeking)
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
|
GST_START_TEST (test_reverse)
|
||||||
|
{
|
||||||
|
GstElement *src;
|
||||||
|
|
||||||
|
#ifndef TESTFILE
|
||||||
|
#error TESTFILE not defined
|
||||||
|
#endif
|
||||||
|
src = setup_filesrc ();
|
||||||
|
|
||||||
|
g_object_set (G_OBJECT (src), "location", TESTFILE, NULL);
|
||||||
|
/* we're going to perform the seek in ready */
|
||||||
|
fail_unless (gst_element_set_state (src,
|
||||||
|
GST_STATE_READY) == GST_STATE_CHANGE_SUCCESS,
|
||||||
|
"could not set to ready");
|
||||||
|
|
||||||
|
/* reverse seek from end to start */
|
||||||
|
gst_element_seek (src, -1.0, GST_FORMAT_BYTES, 0, GST_SEEK_TYPE_SET, 100,
|
||||||
|
GST_SEEK_TYPE_SET, -1);
|
||||||
|
|
||||||
|
fail_unless (gst_element_set_state (src,
|
||||||
|
GST_STATE_PAUSED) == GST_STATE_CHANGE_SUCCESS,
|
||||||
|
"could not set to paused");
|
||||||
|
|
||||||
|
/* wait for EOS */
|
||||||
|
wait_eos ();
|
||||||
|
|
||||||
|
fail_unless (gst_element_set_state (src,
|
||||||
|
GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
|
||||||
|
|
||||||
|
/* cleanup */
|
||||||
|
cleanup_filesrc (src);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
GST_START_TEST (test_pull)
|
GST_START_TEST (test_pull)
|
||||||
{
|
{
|
||||||
GstElement *src;
|
GstElement *src;
|
||||||
|
@ -323,6 +384,7 @@ filesrc_suite (void)
|
||||||
|
|
||||||
suite_add_tcase (s, tc_chain);
|
suite_add_tcase (s, tc_chain);
|
||||||
tcase_add_test (tc_chain, test_seeking);
|
tcase_add_test (tc_chain, test_seeking);
|
||||||
|
tcase_add_test (tc_chain, test_reverse);
|
||||||
tcase_add_test (tc_chain, test_pull);
|
tcase_add_test (tc_chain, test_pull);
|
||||||
tcase_add_test (tc_chain, test_coverage);
|
tcase_add_test (tc_chain, test_coverage);
|
||||||
tcase_add_test (tc_chain, test_uri_interface);
|
tcase_add_test (tc_chain, test_uri_interface);
|
||||||
|
|
Loading…
Reference in a new issue