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-17 08:29:06.093769370 -0400
@@ -664,22 +664,32 @@ gst_v4l2_buffer_pool_qbuf (GstV4l2Buffer
   }
 
   index = meta->vbuffer.index;
-  meta->vbuffer.bytesused = gst_buffer_get_size (buf);
+  meta->vbuffer.bytesused = 0;
 
   GST_LOG_OBJECT (pool,
-      "enqueue buffer %p, index:%d, queued:%d, flags:%08x used:%d",
+      "enqueue buffer %p, index:%d, queued:%d, flags:%08x mem:%p used:%d",
       buf, index, pool->num_queued, meta->vbuffer.flags,
-      meta->vbuffer.bytesused);
+      meta->mem, meta->vbuffer.bytesused);
 
-  if (pool->buffers[index] != NULL)
-    goto already_queued;
+  if (pool->buffers[index] != NULL) {
+      goto already_queued;
+  }
 
-  GST_LOG_OBJECT (pool, "doing QBUF");
-  if (v4l2_ioctl (pool->video_fd, VIDIOC_QBUF, &meta->vbuffer) < 0)
-    goto queue_failed;
+  GST_V4L2_BUFFER_POOL_LOCK (pool);
+  /* 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++;
+  GST_V4L2_BUFFER_POOL_UNLOCK (pool);
+
+  GST_LOG_OBJECT (pool, "doing QBUF");
+
+  if (v4l2_ioctl (pool->video_fd, VIDIOC_QBUF, &meta->vbuffer) < 0)
+    goto queue_failed;
 
   return GST_FLOW_OK;
 
@@ -705,6 +715,7 @@ gst_v4l2_buffer_pool_dqbuf (GstV4l2Buffe
   struct v4l2_buffer vbuffer;
   GstV4l2Object *obj = pool->obj;
   GstClockTime timestamp;
+  GstV4l2Meta *meta;
 
   if ((res = gst_v4l2_object_poll (obj)) != GST_FLOW_OK)
     goto poll_error;
@@ -719,15 +730,19 @@ gst_v4l2_buffer_pool_dqbuf (GstV4l2Buffe
     vbuffer.memory = V4L2_MEMORY_MMAP;
 
   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) {
     goto error;
+  }
 
+  GST_V4L2_BUFFER_POOL_LOCK (pool);
   /* 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;
@@ -735,10 +750,13 @@ gst_v4l2_buffer_pool_dqbuf (GstV4l2Buffe
 
   timestamp = GST_TIMEVAL_TO_TIME (vbuffer.timestamp);
 
+  meta = GST_V4L2_META_GET (outbuf);
+  g_assert (meta != NULL);
+
   GST_LOG_OBJECT (pool,
-      "dequeued buffer %p seq:%d (ix=%d), used %d, flags %08x, ts %"
+      "dequeued buffer %p seq:%d (ix=%d), mem %p used %d, flags %08x, ts %"
       GST_TIME_FORMAT ", pool-queued=%d, buffer=%p", outbuf, vbuffer.sequence,
-      vbuffer.index, vbuffer.bytesused, vbuffer.flags,
+      vbuffer.index, meta->mem, vbuffer.bytesused, vbuffer.flags,
       GST_TIME_ARGS (timestamp), pool->num_queued, outbuf);
 
   /* set top/bottom field first if v4l2_buffer has the information */
@@ -750,12 +768,17 @@ gst_v4l2_buffer_pool_dqbuf (GstV4l2Buffe
   }
 
   /* this can change at every frame, esp. with jpeg */
-  if (obj->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
-    gst_buffer_resize (outbuf, 0, vbuffer.bytesused);
+  if (obj->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+      gst_buffer_replace_memory (outbuf, 0,
+        gst_memory_new_wrapped (GST_MEMORY_FLAG_NO_SHARE,
+            meta->mem, vbuffer.bytesused, 0, vbuffer.bytesused, NULL,
+            NULL));
+  }
 
   GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
 
   *buffer = outbuf;
+  GST_V4L2_BUFFER_POOL_UNLOCK (pool);
 
   return GST_FLOW_OK;
 
@@ -867,8 +890,8 @@ gst_v4l2_buffer_pool_acquire_buffer (Gst
             }
 #endif
 
-            /* copy the memory */
-            copy = gst_buffer_copy (*buffer);
+            /* copy the buffer with memory, but not the meta data */
+            copy = gst_buffer_copy_region (*buffer, GST_BUFFER_COPY_MEMORY, 0, -1);
             GST_LOG_OBJECT (pool, "copy buffer %p->%p", *buffer, copy);
 
             /* and requeue so that we can continue capturing */
@@ -977,7 +1000,10 @@ gst_v4l2_buffer_pool_release_buffer (Gst
                 index);
 
             /* reset to the full length, in case it was changed */
-            gst_buffer_resize (buffer, 0, meta->vbuffer.length);
+            gst_buffer_replace_memory (buffer, 0,
+                gst_memory_new_wrapped (GST_MEMORY_FLAG_NO_SHARE,
+                    meta->mem, meta->vbuffer.length, 0, meta->vbuffer.length, NULL,
+                    NULL));
 
             /* playback, put the buffer back in the queue to refill later. */
             GST_BUFFER_POOL_CLASS (parent_class)->release_buffer (bpool,
@@ -1025,6 +1051,7 @@ gst_v4l2_buffer_pool_finalize (GObject *
 static void
 gst_v4l2_buffer_pool_init (GstV4l2BufferPool * pool)
 {
+  g_mutex_init(&pool->lock);
 }
 
 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 17:41:46.776571883 -0400
@@ -32,7 +32,7 @@ typedef struct _GstV4l2BufferPoolClass G
 typedef struct _GstV4l2Meta GstV4l2Meta;
 
 #include "gstv4l2object.h"
-//#include "v4l2_calls.h"
+#include <gst/glib-compat-private.h>
 
 GST_DEBUG_CATEGORY_EXTERN (v4l2buffer_debug);
 
@@ -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__ */
