diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/v4l2/v4l2src_calls.c | 49 |
1 files changed, 31 insertions, 18 deletions
diff --git a/sys/v4l2/v4l2src_calls.c b/sys/v4l2/v4l2src_calls.c index f17667d9..79d4aa7f 100644 --- a/sys/v4l2/v4l2src_calls.c +++ b/sys/v4l2/v4l2src_calls.c @@ -432,31 +432,44 @@ gst_v4l2src_free_buffer (GstBuffer * buffer) gboolean gst_v4l2src_capture_deinit (GstV4l2Src * v4l2src) { - gint i, dequeue = 0; + gint i; + gboolean try_reinit = FALSE; GST_DEBUG_OBJECT (v4l2src, "deinitting capture system"); GST_V4L2_CHECK_OPEN (GST_V4L2ELEMENT (v4l2src)); GST_V4L2_CHECK_ACTIVE (GST_V4L2ELEMENT (v4l2src)); - /* free the buffers */ - for (i = 0; i < v4l2src->breq.count; i++) { - if (gst_atomic_int_dec_and_test (&v4l2src->pool->buffers[i].refcount)) - dequeue++; - } - for (i = 0; i < dequeue; i++) { - struct v4l2_buffer buffer; - - buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - if (ioctl (GST_V4L2ELEMENT (v4l2src)->video_fd, VIDIOC_DQBUF, &buffer) < 0) - GST_WARNING_OBJECT (v4l2src, - "Could not dequeue buffer on uninitialization"); - } - if (gst_atomic_int_dec_and_test (&v4l2src->pool->refcount)) { - /* we're last thing that used all this */ - gst_v4l2src_buffer_pool_free (v4l2src->pool, FALSE); + if (v4l2src->pool) { + /* free the buffers */ + for (i = 0; i < v4l2src->breq.count; i++) { + if (gst_atomic_int_dec_and_test (&v4l2src->pool->buffers[i].refcount)) { + if (ioctl (GST_V4L2ELEMENT (v4l2src)->video_fd, VIDIOC_DQBUF, + &v4l2src->pool->buffers[i].buffer) < 0) + GST_WARNING_OBJECT (v4l2src, + "Could not dequeue buffer on uninitialization: %s - will try reinit instead", + g_strerror (errno)); + try_reinit = TRUE; + } + } + if (gst_atomic_int_dec_and_test (&v4l2src->pool->refcount)) { + /* we're last thing that used all this */ + gst_v4l2src_buffer_pool_free (v4l2src->pool, FALSE); + } + v4l2src->pool = NULL; + /* This is our second try to get the buffers dequeued. + * Since buffers are normally dequeued automatically when capturing is + * stopped, but may be enqueued before capturing has started, you get + * a problem when you abort before capturing started but have enqueued + * the buffers. We avoid that by starting/stopping capturing once so + * they get auto-dequeued. + */ + if (try_reinit) { + if (!gst_v4l2src_capture_start (v4l2src) || + !gst_v4l2src_capture_stop (v4l2src)) + return FALSE; + } } - v4l2src->pool = NULL; GST_V4L2_SET_INACTIVE (GST_V4L2ELEMENT (v4l2src)); return TRUE; |