diff -rupN gst-plugins-good-1.1.3/sys/v4l2/gstv4l2bufferpool.c gst-plugins-good-1.1.3.new/sys/v4l2/gstv4l2bufferpool.c
--- gst-plugins-good-1.1.3/sys/v4l2/gstv4l2bufferpool.c	2013-07-08 10:27:16.000000000 -0400
+++ gst-plugins-good-1.1.3.new/sys/v4l2/gstv4l2bufferpool.c	2013-08-16 12:31:59.914854891 -0400
@@ -671,16 +671,29 @@ gst_v4l2_buffer_pool_qbuf (GstV4l2Buffer
       buf, index, pool->num_queued, meta->vbuffer.flags,
       meta->vbuffer.bytesused);
 
-  if (pool->buffers[index] != NULL)
-    goto already_queued;
+  GST_V4L2_BUFFER_POOL_LOCK (pool);
+  if (pool->buffers[index] != NULL) {
+      GST_V4L2_BUFFER_POOL_UNLOCK (pool);
+      goto already_queued;
+  }
 
   GST_LOG_OBJECT (pool, "doing QBUF");
-  if (v4l2_ioctl (pool->video_fd, VIDIOC_QBUF, &meta->vbuffer) < 0)
-    goto queue_failed;
+
+  /* Memory may have been replaced in GstBuffer so put it back using meta cookie */
+  gst_buffer_replace_memory (buf, 0,
+    gst_memory_new_wrapped (GST_MEMORY_FLAG_NO_SHARE,
+        meta->mem, meta->vbuffer.length, 0, meta->vbuffer.length, NULL,
+        NULL));
 
   pool->buffers[index] = buf;
   pool->num_queued++;
 
+  if (v4l2_ioctl (pool->video_fd, VIDIOC_QBUF, &meta->vbuffer) < 0) {
+    GST_V4L2_BUFFER_POOL_UNLOCK (pool);
+    goto queue_failed;
+  }
+  GST_V4L2_BUFFER_POOL_UNLOCK (pool);
+
   return GST_FLOW_OK;
 
   /* ERRORS */
@@ -718,16 +731,21 @@ gst_v4l2_buffer_pool_dqbuf (GstV4l2Buffe
 #endif
     vbuffer.memory = V4L2_MEMORY_MMAP;
 
+  GST_V4L2_BUFFER_POOL_LOCK (pool);
   GST_LOG_OBJECT (pool, "doing DQBUF");
-  if (v4l2_ioctl (pool->video_fd, VIDIOC_DQBUF, &vbuffer) < 0)
+  if (v4l2_ioctl (pool->video_fd, VIDIOC_DQBUF, &vbuffer) < 0) {
+    GST_V4L2_BUFFER_POOL_UNLOCK (pool);
     goto error;
+  }
 
   /* get our GstBuffer with that index from the pool, if the buffer was
    * outstanding we have a serious problem.
    */
   outbuf = pool->buffers[vbuffer.index];
-  if (outbuf == NULL)
+  if (outbuf == NULL) {
+    GST_V4L2_BUFFER_POOL_UNLOCK (pool);
     goto no_buffer;
+  }
 
   /* mark the buffer outstanding */
   pool->buffers[vbuffer.index] = NULL;
@@ -756,6 +774,7 @@ gst_v4l2_buffer_pool_dqbuf (GstV4l2Buffe
   GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
 
   *buffer = outbuf;
+  GST_V4L2_BUFFER_POOL_UNLOCK (pool);
 
   return GST_FLOW_OK;
 
@@ -1009,6 +1028,9 @@ gst_v4l2_buffer_pool_finalize (GObject *
 {
   GstV4l2BufferPool *pool = GST_V4L2_BUFFER_POOL (object);
 
+  g_mutex_free (pool->lock);
+  pool->lock = NULL;
+
   gst_v4l2_buffer_pool_free_buffers (pool);
 
   if (pool->video_fd >= 0)
@@ -1025,6 +1047,7 @@ gst_v4l2_buffer_pool_finalize (GObject *
 static void
 gst_v4l2_buffer_pool_init (GstV4l2BufferPool * pool)
 {
+  pool->lock = g_mutex_new ();
 }
 
 static void
diff -rupN gst-plugins-good-1.1.3/sys/v4l2/gstv4l2bufferpool.h gst-plugins-good-1.1.3.new/sys/v4l2/gstv4l2bufferpool.h
--- gst-plugins-good-1.1.3/sys/v4l2/gstv4l2bufferpool.h	2013-05-03 05:18:04.000000000 -0400
+++ gst-plugins-good-1.1.3.new/sys/v4l2/gstv4l2bufferpool.h	2013-08-16 11:30:22.850686582 -0400
@@ -65,6 +65,7 @@ struct _GstV4l2BufferPool
   gboolean streaming;
 
   GstBuffer **buffers;
+  GMutex *lock;
 };
 
 struct _GstV4l2BufferPoolClass
@@ -90,6 +91,9 @@ GstBufferPool *     gst_v4l2_buffer_pool
 
 GstFlowReturn       gst_v4l2_buffer_pool_process (GstV4l2BufferPool * bpool, GstBuffer * buf);
 
+#define GST_V4L2_BUFFER_POOL_LOCK(pool)     g_mutex_lock ((pool)->lock)
+#define GST_V4L2_BUFFER_POOL_UNLOCK(pool)   g_mutex_unlock ((pool)->lock)
+
 G_END_DECLS
 
 #endif /*__GST_V4L2_BUFFER_POOL_H__ */
