summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorNicolas Dufresne <nicolas.dufresne@collabora.com>2014-05-14 17:18:35 -0400
committerNicolas Dufresne <nicolas.dufresne@collabora.com>2014-05-15 12:21:44 -0400
commita4b5811d22ba401fbcfc4d264034a9ca1d9aca67 (patch)
treedcad0e2289e9f0be523e539f7e21935ed535c795 /sys
parentc1792de95e9a6b28891a53cd953941d30bebf09d (diff)
downloadgstreamer-plugins-good-a4b5811d22ba401fbcfc4d264034a9ca1d9aca67.tar.gz
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
Diffstat (limited to 'sys')
-rw-r--r--sys/v4l2/gstv4l2bufferpool.c33
-rw-r--r--sys/v4l2/gstv4l2bufferpool.h3
-rw-r--r--sys/v4l2/gstv4l2transform.c40
-rw-r--r--sys/v4l2/gstv4l2videodec.c12
4 files changed, 62 insertions, 26 deletions
diff --git a/sys/v4l2/gstv4l2bufferpool.c b/sys/v4l2/gstv4l2bufferpool.c
index 3a067f6ad..0e9065081 100644
--- a/sys/v4l2/gstv4l2bufferpool.c
+++ b/sys/v4l2/gstv4l2bufferpool.c
@@ -1690,31 +1690,40 @@ start_failed:
/**
- * gst_v4l2_buffer_pool_flush:
+ * gst_v4l2_buffer_pool_stop_streaming:
* @bpool: a #GstBufferPool
*
* First, set obj->poll to be flushing
* Call STREAMOFF to clear QUEUED flag on every driver buffers.
* 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.
*/
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;
- /* 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))
- goto start_failed;
+ /* 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");
+
+ if (!start_streaming (pool))
+ goto start_failed;
return TRUE;
diff --git a/sys/v4l2/gstv4l2bufferpool.h b/sys/v4l2/gstv4l2bufferpool.h
index 3a0aeda25..3459637d5 100644
--- a/sys/v4l2/gstv4l2bufferpool.h
+++ b/sys/v4l2/gstv4l2bufferpool.h
@@ -84,7 +84,8 @@ GstBufferPool * gst_v4l2_buffer_pool_new (GstV4l2Object *obj, GstCaps *c
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,
GstBufferPool * other_pool);
diff --git a/sys/v4l2/gstv4l2transform.c b/sys/v4l2/gstv4l2transform.c
index aecd530e9..d0c913986 100644
--- a/sys/v4l2/gstv4l2transform.c
+++ b/sys/v4l2/gstv4l2transform.c
@@ -530,6 +530,11 @@ static gboolean
gst_v4l2_transform_sink_event (GstBaseTransform * trans, GstEvent * event)
{
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)) {
case GST_EVENT_FLUSH_START:
@@ -539,19 +544,38 @@ gst_v4l2_transform_sink_event (GstBaseTransform * trans, GstEvent * event)
break;
case GST_EVENT_FLUSH_STOP:
GST_DEBUG_OBJECT (self, "flush stop");
- if (self->v4l2output->pool)
- gst_v4l2_buffer_pool_flush (GST_V4L2_BUFFER_POOL (self->v4l2output->
- pool));
+
+ if (self->v4l2output->pool) {
+ gst_v4l2_buffer_pool_stop_streaming (GST_V4L2_BUFFER_POOL
+ (self->v4l2output->pool));
+ gst_v4l2_buffer_pool_start_streaming (GST_V4L2_BUFFER_POOL
+ (self->v4l2capture->pool));
+ gst_v4l2_object_unlock_stop (self->v4l2output);
+ }
if (self->v4l2capture->pool)
- gst_v4l2_buffer_pool_flush (GST_V4L2_BUFFER_POOL (self->v4l2capture->
- pool));
- gst_v4l2_object_unlock_stop (self->v4l2output);
- gst_v4l2_object_unlock_stop (self->v4l2capture);
+ gst_v4l2_buffer_pool_stop_streaming (GST_V4L2_BUFFER_POOL
+ (self->v4l2capture->pool));
default:
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
diff --git a/sys/v4l2/gstv4l2videodec.c b/sys/v4l2/gstv4l2videodec.c
index 2b3aa9d83..71481d22a 100644
--- a/sys/v4l2/gstv4l2videodec.c
+++ b/sys/v4l2/gstv4l2videodec.c
@@ -277,13 +277,12 @@ gst_v4l2_video_dec_flush (GstVideoDecoder * decoder)
self->output_flow = GST_FLOW_OK;
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)
- gst_v4l2_buffer_pool_flush (GST_V4L2_BUFFER_POOL (self->v4l2capture->pool));
-
- /* Output will remain flushing until new frame comes in */
- gst_v4l2_object_unlock_stop (self->v4l2capture);
+ gst_v4l2_buffer_pool_stop_streaming (GST_V4L2_BUFFER_POOL
+ (self->v4l2capture->pool));
return TRUE;
}
@@ -525,7 +524,10 @@ gst_v4l2_video_dec_handle_frame (GstVideoDecoder * decoder,
GST_DEBUG_OBJECT (self, "Starting decoding thread");
/* 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->v4l2capture);
/* Start the processing task, when it quits, the task will disable input
* processing to unlock input if draining, or prevent potential block */