summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Otte <otte@gnome.org>2005-07-14 23:13:15 +0000
committerBenjamin Otte <otte@gnome.org>2005-07-14 23:13:15 +0000
commitc5763888f87919647224cc181c05ebade4bee5d9 (patch)
tree6879a58ebe1b9644cd441701ea5df8a551dfe909
parentb744fcb3dbaeb838ab20334ce4bea55852250c87 (diff)
downloadgst-plugins-bad-c5763888f87919647224cc181c05ebade4bee5d9.tar.gz
gst-plugins-bad-c5763888f87919647224cc181c05ebade4bee5d9.tar.bz2
gst-plugins-bad-c5763888f87919647224cc181c05ebade4bee5d9.zip
sys/v4l2/v4l2src_calls.c: try extra hard to discard queued buffers. Fixes reinit breakage for
Original commit message from CVS: * sys/v4l2/v4l2src_calls.c: (gst_v4l2src_capture_deinit): try extra hard to discard queued buffers. Fixes reinit breakage for SAA7134.
-rw-r--r--ChangeLog6
-rw-r--r--sys/v4l2/v4l2src_calls.c49
2 files changed, 37 insertions, 18 deletions
diff --git a/ChangeLog b/ChangeLog
index 4808f015..6e785c38 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2005-07-15 Benjamin Otte <otte@gnome.org>
+
+ * sys/v4l2/v4l2src_calls.c: (gst_v4l2src_capture_deinit):
+ try extra hard to discard queued buffers. Fixes reinit breakage for
+ SAA7134.
+
2005-07-14 Zaheer Abbas Merali <zaheerabbas at merali dot org>
* sys/ximage/ximagesrc.c: (gst_ximagesrc_ximage_get),
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;