mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-25 01:30:38 +00:00
v4l2: Split flush in start/stop_streaming
This allow calling start streaming later for capture device. Currently it breaks in dmabuf-import because downstream is holding a buffer that will only be released after stream-start. https://bugzilla.gnome.org/show_bug.cgi?id=730207
This commit is contained in:
parent
c1792de95e
commit
a4b5811d22
4 changed files with 62 additions and 26 deletions
|
@ -1690,29 +1690,38 @@ start_failed:
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_v4l2_buffer_pool_flush:
|
* gst_v4l2_buffer_pool_stop_streaming:
|
||||||
* @bpool: a #GstBufferPool
|
* @bpool: a #GstBufferPool
|
||||||
*
|
*
|
||||||
* First, set obj->poll to be flushing
|
* First, set obj->poll to be flushing
|
||||||
* Call STREAMOFF to clear QUEUED flag on every driver buffers.
|
* Call STREAMOFF to clear QUEUED flag on every driver buffers.
|
||||||
* Then release all buffers that are in pool->buffers array.
|
* Then release all buffers that are in pool->buffers array.
|
||||||
* Finally call STREAMON if CAPTURE type
|
|
||||||
* The caller is responsible to unset flushing on obj->pool
|
|
||||||
*
|
*
|
||||||
* Returns: TRUE on success.
|
* Returns: TRUE on success.
|
||||||
*/
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
gst_v4l2_buffer_pool_flush (GstV4l2BufferPool * pool)
|
gst_v4l2_buffer_pool_stop_streaming (GstV4l2BufferPool * pool)
|
||||||
{
|
{
|
||||||
GstV4l2Object *obj = pool->obj;
|
GST_DEBUG_OBJECT (pool, "stop streaming");
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (pool, "flush");
|
if (!stop_streaming (pool))
|
||||||
|
goto stop_failed;
|
||||||
|
|
||||||
stop_streaming (pool);
|
return TRUE;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
stop_failed:
|
||||||
|
{
|
||||||
|
GST_ERROR_OBJECT (pool, "failed to stop streaming");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_v4l2_buffer_pool_start_streaming (GstV4l2BufferPool * pool)
|
||||||
|
{
|
||||||
|
GST_DEBUG_OBJECT (pool, "start straming");
|
||||||
|
|
||||||
/* we can start capturing now, we wait for the playback
|
|
||||||
* case until we queued the first buffer */
|
|
||||||
if (!V4L2_TYPE_IS_OUTPUT (obj->type))
|
|
||||||
if (!start_streaming (pool))
|
if (!start_streaming (pool))
|
||||||
goto start_failed;
|
goto start_failed;
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,8 @@ GstBufferPool * gst_v4l2_buffer_pool_new (GstV4l2Object *obj, GstCaps *c
|
||||||
|
|
||||||
GstFlowReturn gst_v4l2_buffer_pool_process (GstV4l2BufferPool * bpool, GstBuffer ** buf);
|
GstFlowReturn gst_v4l2_buffer_pool_process (GstV4l2BufferPool * bpool, GstBuffer ** buf);
|
||||||
|
|
||||||
gboolean gst_v4l2_buffer_pool_flush (GstV4l2BufferPool * pool);
|
gboolean gst_v4l2_buffer_pool_stop_streaming (GstV4l2BufferPool * pool);
|
||||||
|
gboolean gst_v4l2_buffer_pool_start_streaming (GstV4l2BufferPool * pool);
|
||||||
|
|
||||||
void gst_v4l2_buffer_pool_set_other_pool (GstV4l2BufferPool * pool,
|
void gst_v4l2_buffer_pool_set_other_pool (GstV4l2BufferPool * pool,
|
||||||
GstBufferPool * other_pool);
|
GstBufferPool * other_pool);
|
||||||
|
|
|
@ -530,6 +530,11 @@ static gboolean
|
||||||
gst_v4l2_transform_sink_event (GstBaseTransform * trans, GstEvent * event)
|
gst_v4l2_transform_sink_event (GstBaseTransform * trans, GstEvent * event)
|
||||||
{
|
{
|
||||||
GstV4l2Transform *self = GST_V4L2_TRANSFORM (trans);
|
GstV4l2Transform *self = GST_V4L2_TRANSFORM (trans);
|
||||||
|
gboolean ret;
|
||||||
|
|
||||||
|
/* Nothing to flush in passthrough */
|
||||||
|
if (gst_base_transform_is_passthrough (trans))
|
||||||
|
return GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (trans, event);
|
||||||
|
|
||||||
switch (GST_EVENT_TYPE (event)) {
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
case GST_EVENT_FLUSH_START:
|
case GST_EVENT_FLUSH_START:
|
||||||
|
@ -539,19 +544,38 @@ gst_v4l2_transform_sink_event (GstBaseTransform * trans, GstEvent * event)
|
||||||
break;
|
break;
|
||||||
case GST_EVENT_FLUSH_STOP:
|
case GST_EVENT_FLUSH_STOP:
|
||||||
GST_DEBUG_OBJECT (self, "flush stop");
|
GST_DEBUG_OBJECT (self, "flush stop");
|
||||||
if (self->v4l2output->pool)
|
|
||||||
gst_v4l2_buffer_pool_flush (GST_V4L2_BUFFER_POOL (self->v4l2output->
|
if (self->v4l2output->pool) {
|
||||||
pool));
|
gst_v4l2_buffer_pool_stop_streaming (GST_V4L2_BUFFER_POOL
|
||||||
if (self->v4l2capture->pool)
|
(self->v4l2output->pool));
|
||||||
gst_v4l2_buffer_pool_flush (GST_V4L2_BUFFER_POOL (self->v4l2capture->
|
gst_v4l2_buffer_pool_start_streaming (GST_V4L2_BUFFER_POOL
|
||||||
pool));
|
(self->v4l2capture->pool));
|
||||||
gst_v4l2_object_unlock_stop (self->v4l2output);
|
gst_v4l2_object_unlock_stop (self->v4l2output);
|
||||||
gst_v4l2_object_unlock_stop (self->v4l2capture);
|
}
|
||||||
|
if (self->v4l2capture->pool)
|
||||||
|
gst_v4l2_buffer_pool_stop_streaming (GST_V4L2_BUFFER_POOL
|
||||||
|
(self->v4l2capture->pool));
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (trans, event);
|
ret = GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (trans, event);
|
||||||
|
|
||||||
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
|
case GST_EVENT_FLUSH_STOP:
|
||||||
|
/* Buffer should be back now */
|
||||||
|
if (self->v4l2capture->pool) {
|
||||||
|
gst_v4l2_buffer_pool_start_streaming (GST_V4L2_BUFFER_POOL
|
||||||
|
(self->v4l2capture->pool));
|
||||||
|
gst_v4l2_object_unlock_stop (self->v4l2capture);
|
||||||
|
}
|
||||||
|
GST_DEBUG_OBJECT (self, "flush stop done");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstStateChangeReturn
|
static GstStateChangeReturn
|
||||||
|
|
|
@ -277,13 +277,12 @@ gst_v4l2_video_dec_flush (GstVideoDecoder * decoder)
|
||||||
self->output_flow = GST_FLOW_OK;
|
self->output_flow = GST_FLOW_OK;
|
||||||
|
|
||||||
if (self->v4l2output->pool)
|
if (self->v4l2output->pool)
|
||||||
gst_v4l2_buffer_pool_flush (GST_V4L2_BUFFER_POOL (self->v4l2output->pool));
|
gst_v4l2_buffer_pool_stop_streaming (GST_V4L2_BUFFER_POOL
|
||||||
|
(self->v4l2output->pool));
|
||||||
|
|
||||||
if (self->v4l2capture->pool)
|
if (self->v4l2capture->pool)
|
||||||
gst_v4l2_buffer_pool_flush (GST_V4L2_BUFFER_POOL (self->v4l2capture->pool));
|
gst_v4l2_buffer_pool_stop_streaming (GST_V4L2_BUFFER_POOL
|
||||||
|
(self->v4l2capture->pool));
|
||||||
/* Output will remain flushing until new frame comes in */
|
|
||||||
gst_v4l2_object_unlock_stop (self->v4l2capture);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -525,7 +524,10 @@ gst_v4l2_video_dec_handle_frame (GstVideoDecoder * decoder,
|
||||||
GST_DEBUG_OBJECT (self, "Starting decoding thread");
|
GST_DEBUG_OBJECT (self, "Starting decoding thread");
|
||||||
|
|
||||||
/* Enable processing input */
|
/* Enable processing input */
|
||||||
|
gst_v4l2_buffer_pool_start_streaming (GST_V4L2_BUFFER_POOL
|
||||||
|
(self->v4l2capture->pool));
|
||||||
gst_v4l2_object_unlock_stop (self->v4l2output);
|
gst_v4l2_object_unlock_stop (self->v4l2output);
|
||||||
|
gst_v4l2_object_unlock_stop (self->v4l2capture);
|
||||||
|
|
||||||
/* Start the processing task, when it quits, the task will disable input
|
/* Start the processing task, when it quits, the task will disable input
|
||||||
* processing to unlock input if draining, or prevent potential block */
|
* processing to unlock input if draining, or prevent potential block */
|
||||||
|
|
Loading…
Reference in a new issue