mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-05 06:58:56 +00:00
basesrc: do not send EOS when automatic_eos is FALSE
This commit is contained in:
parent
ae57b1c76d
commit
fee108f7cf
2 changed files with 139 additions and 2 deletions
|
@ -656,6 +656,12 @@ gst_base_src_set_dynamic_size (GstBaseSrc * src, gboolean dynamic)
|
||||||
* that can't return an authoritative size and only know that they're EOS
|
* that can't return an authoritative size and only know that they're EOS
|
||||||
* when trying to read more should set this to %FALSE.
|
* when trying to read more should set this to %FALSE.
|
||||||
*
|
*
|
||||||
|
* When @src operates in %GST_FORMAT_TIME, #GstBaseSrc will send an EOS
|
||||||
|
* when a buffer outside of the currently configured segment is pushed if
|
||||||
|
* @automatic_eos is %TRUE. Since 1.16, if @automatic_eos is %FALSE an
|
||||||
|
* EOS will be pushed only when the #GstBaseSrc.create implementation
|
||||||
|
* returns %GST_FLOW_EOS.
|
||||||
|
*
|
||||||
* Since: 1.4
|
* Since: 1.4
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
|
@ -2931,7 +2937,8 @@ gst_base_src_loop (GstPad * pad)
|
||||||
/* positive rate, check if we reached the stop */
|
/* positive rate, check if we reached the stop */
|
||||||
if (src->segment.stop != -1) {
|
if (src->segment.stop != -1) {
|
||||||
if (position >= src->segment.stop) {
|
if (position >= src->segment.stop) {
|
||||||
eos = TRUE;
|
if (g_atomic_int_get (&src->priv->automatic_eos))
|
||||||
|
eos = TRUE;
|
||||||
position = src->segment.stop;
|
position = src->segment.stop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2939,7 +2946,8 @@ gst_base_src_loop (GstPad * pad)
|
||||||
/* negative rate, check if we reached the start. start is always set to
|
/* negative rate, check if we reached the start. start is always set to
|
||||||
* something different from -1 */
|
* something different from -1 */
|
||||||
if (position <= src->segment.start) {
|
if (position <= src->segment.start) {
|
||||||
eos = TRUE;
|
if (g_atomic_int_get (&src->priv->automatic_eos))
|
||||||
|
eos = TRUE;
|
||||||
position = src->segment.start;
|
position = src->segment.start;
|
||||||
}
|
}
|
||||||
/* when going reverse, all buffers are DISCONT */
|
/* when going reverse, all buffers are DISCONT */
|
||||||
|
|
|
@ -904,6 +904,134 @@ GST_START_TEST (basesrc_create_bufferlist)
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GstBaseSrc parent;
|
||||||
|
GstSegment *segment;
|
||||||
|
gboolean n_output_buffers;
|
||||||
|
} TimeSrc;
|
||||||
|
|
||||||
|
typedef GstBaseSrcClass TimeSrcClass;
|
||||||
|
|
||||||
|
static GType time_src_get_type (void);
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (TimeSrc, time_src, GST_TYPE_BASE_SRC);
|
||||||
|
|
||||||
|
static void
|
||||||
|
time_src_init (TimeSrc * src)
|
||||||
|
{
|
||||||
|
gst_base_src_set_format (GST_BASE_SRC (src), GST_FORMAT_TIME);
|
||||||
|
gst_base_src_set_automatic_eos (GST_BASE_SRC (src), FALSE);
|
||||||
|
src->n_output_buffers = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This test src outputs a compressed format, with a single GOP
|
||||||
|
* starting at PTS 0.
|
||||||
|
*
|
||||||
|
* This means that in reverse playback, we may want to output
|
||||||
|
* buffers outside the segment bounds, and decide when to EOS
|
||||||
|
* from the create function.
|
||||||
|
*/
|
||||||
|
static GstFlowReturn
|
||||||
|
time_src_create (GstBaseSrc * bsrc, guint64 offset, guint size,
|
||||||
|
GstBuffer ** p_buf)
|
||||||
|
{
|
||||||
|
TimeSrc *src = (TimeSrc *) bsrc;
|
||||||
|
|
||||||
|
if (src->segment->position >= src->segment->stop)
|
||||||
|
return GST_FLOW_EOS;
|
||||||
|
|
||||||
|
*p_buf = gst_buffer_new ();
|
||||||
|
GST_BUFFER_PTS (*p_buf) = src->segment->position;
|
||||||
|
GST_BUFFER_DURATION (*p_buf) = GST_SECOND;
|
||||||
|
src->segment->position += GST_SECOND;
|
||||||
|
|
||||||
|
src->n_output_buffers++;
|
||||||
|
|
||||||
|
return GST_FLOW_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
time_src_do_seek (GstBaseSrc * bsrc, GstSegment * segment)
|
||||||
|
{
|
||||||
|
TimeSrc *src = (TimeSrc *) bsrc;
|
||||||
|
fail_unless (segment->format == GST_FORMAT_TIME);
|
||||||
|
|
||||||
|
if (src->segment)
|
||||||
|
gst_segment_free (src->segment);
|
||||||
|
|
||||||
|
src->segment = gst_segment_copy (segment);
|
||||||
|
|
||||||
|
((TimeSrc *) bsrc)->segment->position = 0;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
time_src_is_seekable (GstBaseSrc * bsrc)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
time_src_class_init (TimeSrcClass * klass)
|
||||||
|
{
|
||||||
|
GstBaseSrcClass *gstbasesrc_class = GST_BASE_SRC_CLASS (klass);
|
||||||
|
|
||||||
|
gst_element_class_add_static_pad_template (GST_ELEMENT_CLASS (klass),
|
||||||
|
&src_template);
|
||||||
|
|
||||||
|
gstbasesrc_class->create = time_src_create;
|
||||||
|
gstbasesrc_class->do_seek = time_src_do_seek;
|
||||||
|
gstbasesrc_class->is_seekable = time_src_is_seekable;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_START_TEST (basesrc_time_automatic_eos)
|
||||||
|
{
|
||||||
|
GstElement *src, *sink;
|
||||||
|
GstElement *pipe;
|
||||||
|
GstBus *bus;
|
||||||
|
|
||||||
|
src = g_object_new (time_src_get_type (), NULL);
|
||||||
|
sink = gst_element_factory_make ("fakesink", NULL);
|
||||||
|
|
||||||
|
pipe = gst_pipeline_new (NULL);
|
||||||
|
|
||||||
|
gst_bin_add (GST_BIN (pipe), src);
|
||||||
|
gst_bin_add (GST_BIN (pipe), sink);
|
||||||
|
|
||||||
|
gst_element_link (src, sink);
|
||||||
|
|
||||||
|
gst_element_set_state (pipe, GST_STATE_PAUSED);
|
||||||
|
gst_element_get_state (pipe, NULL, NULL, GST_CLOCK_TIME_NONE);
|
||||||
|
|
||||||
|
gst_element_seek (pipe, -1.0, GST_FORMAT_TIME,
|
||||||
|
GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET,
|
||||||
|
GST_SECOND, GST_SEEK_TYPE_SET, 2 * GST_SECOND);
|
||||||
|
|
||||||
|
gst_element_set_state (pipe, GST_STATE_PLAYING);
|
||||||
|
|
||||||
|
bus = gst_pipeline_get_bus (GST_PIPELINE (pipe));
|
||||||
|
|
||||||
|
gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_EOS);
|
||||||
|
|
||||||
|
gst_element_set_state (pipe, GST_STATE_NULL);
|
||||||
|
|
||||||
|
/* - One preroll buffer
|
||||||
|
* - One (1-second) buffer outside the segment, our "keyframe"
|
||||||
|
* - One buffer inside the segment
|
||||||
|
*/
|
||||||
|
fail_unless_equals_int (((TimeSrc *) src)->n_output_buffers, 3);
|
||||||
|
|
||||||
|
if (((TimeSrc *) src)->segment)
|
||||||
|
gst_segment_free (((TimeSrc *) src)->segment);
|
||||||
|
|
||||||
|
gst_object_unref (bus);
|
||||||
|
gst_object_unref (pipe);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
static Suite *
|
static Suite *
|
||||||
gst_basesrc_suite (void)
|
gst_basesrc_suite (void)
|
||||||
{
|
{
|
||||||
|
@ -920,6 +1048,7 @@ gst_basesrc_suite (void)
|
||||||
tcase_add_test (tc, basesrc_seek_events_rate_update);
|
tcase_add_test (tc, basesrc_seek_events_rate_update);
|
||||||
tcase_add_test (tc, basesrc_seek_on_last_buffer);
|
tcase_add_test (tc, basesrc_seek_on_last_buffer);
|
||||||
tcase_add_test (tc, basesrc_create_bufferlist);
|
tcase_add_test (tc, basesrc_create_bufferlist);
|
||||||
|
tcase_add_test (tc, basesrc_time_automatic_eos);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue