Binary files gst-plugins-good-0.10.16.orig/sys/v4l2/.libs/libgstvideo4linux2.so and gst-plugins-good-0.10.16/sys/v4l2/.libs/libgstvideo4linux2.so differ
Binary files gst-plugins-good-0.10.16.orig/sys/v4l2/.libs/libgstvideo4linux2.soT and gst-plugins-good-0.10.16/sys/v4l2/.libs/libgstvideo4linux2.soT differ
Only in gst-plugins-good-0.10.16/sys/v4l2: gstv4l2_calls.c.rej
diff -rup -x '*.o' -x '*.lo' -x Makefile -x Makefile.in -x '*.la' -x '*.a' gst-plugins-good-0.10.16.orig/sys/v4l2/gstv4l2bufferpool.c gst-plugins-good-0.10.16/sys/v4l2/gstv4l2bufferpool.c
--- gst-plugins-good-0.10.16.orig/sys/v4l2/gstv4l2bufferpool.c	2010-03-01 18:11:38.000000000 +0100
+++ gst-plugins-good-0.10.16/sys/v4l2/gstv4l2bufferpool.c	2010-03-04 17:13:54.000000000 +0100
@@ -51,19 +51,20 @@ static void
 gst_v4l2_buffer_finalize (GstV4l2Buffer * buffer)
 {
   GstV4l2BufferPool *pool;
+  struct v4l2_buffer *vbuffer;
   gboolean resuscitated = FALSE;
   gint index;
 
   pool = buffer->pool;
-
-  index = buffer->vbuffer.index;
+  index = buffer->index;
+  vbuffer = &pool->vbuffers[index];
 
   GST_LOG_OBJECT (pool->v4l2elem, "finalizing buffer %p %d", buffer, index);
 
   GST_V4L2_BUFFER_POOL_LOCK (pool);
   if (pool->running) {
     if (pool->requeuebuf) {
-      if (!gst_v4l2_buffer_pool_qbuf (pool, buffer)) {
+      if (!gst_v4l2_buffer_pool_qbuf (pool, buffer->index)) {
         GST_WARNING ("could not requeue buffer %p %d", buffer, index);
       } else {
         resuscitated = TRUE;
@@ -85,7 +86,7 @@ gst_v4l2_buffer_finalize (GstV4l2Buffer 
     GST_LOG_OBJECT (pool->v4l2elem, "reviving buffer %p, %d", buffer, index);
     gst_buffer_ref (GST_BUFFER (buffer));
     GST_BUFFER_SIZE (buffer) = 0;
-    pool->buffers[index] = buffer;
+    pool->buffers[index] = GST_BUFFER(buffer);
   }
 
   GST_V4L2_BUFFER_POOL_UNLOCK (pool);
@@ -94,7 +95,7 @@ gst_v4l2_buffer_finalize (GstV4l2Buffer 
     GST_LOG_OBJECT (pool->v4l2elem, "buffer %p not recovered, unmapping",
         buffer);
     gst_mini_object_unref (GST_MINI_OBJECT (pool));
-    v4l2_munmap ((void *) GST_BUFFER_DATA (buffer), buffer->vbuffer.length);
+    v4l2_munmap ((void *) GST_BUFFER_DATA (buffer), vbuffer->length);
 
     GST_MINI_OBJECT_CLASS (v4l2buffer_parent_class)->finalize (GST_MINI_OBJECT
         (buffer));
@@ -136,54 +137,70 @@ gst_v4l2_buffer_get_type (void)
   return _gst_v4l2_buffer_type;
 }
 
-static GstV4l2Buffer *
-gst_v4l2_buffer_new (GstV4l2BufferPool * pool, guint index, GstCaps * caps)
+static struct v4l2_buffer *
+gst_v4l2_buffer_pool_prepare_vbuffer (GstV4l2BufferPool * pool, guint index)
+{
+  struct v4l2_buffer *vbuffer;
+
+  vbuffer = &pool->vbuffers[index];
+  vbuffer->type = pool->type;
+  vbuffer->index = index;
+  vbuffer->memory = pool->memory;
+
+  GST_LOG ("creating buffer %u, in pool %p", index, pool);
+
+  return vbuffer;
+}
+
+static void
+gst_v4l2_buffer_pool_log_vbuffer (GstV4l2BufferPool * pool, struct v4l2_buffer * vbuffer)
+{
+  GST_LOG_OBJECT (pool->v4l2elem, "  index:     %u", vbuffer->index);
+  GST_LOG_OBJECT (pool->v4l2elem, "  type:      %d", vbuffer->type);
+  GST_LOG_OBJECT (pool->v4l2elem, "  bytesused: %u", vbuffer->bytesused);
+  GST_LOG_OBJECT (pool->v4l2elem, "  flags:     0x%08x", vbuffer->flags);
+  GST_LOG_OBJECT (pool->v4l2elem, "  field:     %d", vbuffer->field);
+  GST_LOG_OBJECT (pool->v4l2elem, "  memory:    %d", vbuffer->memory);
+  if (vbuffer->memory == V4L2_MEMORY_MMAP)
+    GST_LOG_OBJECT (pool->v4l2elem, "  mmap offset:  %u", vbuffer->m.offset);
+  else if (vbuffer->memory == V4L2_MEMORY_USERPTR)
+    GST_LOG_OBJECT (pool->v4l2elem, "  user address: 0x%08lx", vbuffer->m.userptr);
+  GST_LOG_OBJECT (pool->v4l2elem, "  length:    %u", vbuffer->length);
+  GST_LOG_OBJECT (pool->v4l2elem, "  input:     %u", vbuffer->input);
+
+}
+
+static GstBuffer *
+gst_v4l2_buffer_new_mmap (GstV4l2BufferPool * pool, guint index, GstCaps * caps)
 {
+  struct v4l2_buffer *vbuffer = gst_v4l2_buffer_pool_prepare_vbuffer (pool, index);
   GstV4l2Buffer *ret;
   guint8 *data;
 
   ret = (GstV4l2Buffer *) gst_mini_object_new (GST_TYPE_V4L2_BUFFER);
 
-  GST_LOG_OBJECT (pool->v4l2elem, "creating buffer %u, %p in pool %p", index,
-      ret, pool);
-
   ret->pool =
       (GstV4l2BufferPool *) gst_mini_object_ref (GST_MINI_OBJECT (pool));
+  ret->index = index;
 
-  ret->vbuffer.index = index;
-  ret->vbuffer.type = pool->type;
-  ret->vbuffer.memory = V4L2_MEMORY_MMAP;
-
-  if (v4l2_ioctl (pool->video_fd, VIDIOC_QUERYBUF, &ret->vbuffer) < 0)
+  if (v4l2_ioctl (pool->video_fd, VIDIOC_QUERYBUF, vbuffer) < 0)
     goto querybuf_failed;
 
-  GST_LOG_OBJECT (pool->v4l2elem, "  index:     %u", ret->vbuffer.index);
-  GST_LOG_OBJECT (pool->v4l2elem, "  type:      %d", ret->vbuffer.type);
-  GST_LOG_OBJECT (pool->v4l2elem, "  bytesused: %u", ret->vbuffer.bytesused);
-  GST_LOG_OBJECT (pool->v4l2elem, "  flags:     %08x", ret->vbuffer.flags);
-  GST_LOG_OBJECT (pool->v4l2elem, "  field:     %d", ret->vbuffer.field);
-  GST_LOG_OBJECT (pool->v4l2elem, "  memory:    %d", ret->vbuffer.memory);
-  if (ret->vbuffer.memory == V4L2_MEMORY_MMAP)
-    GST_LOG_OBJECT (pool->v4l2elem, "  MMAP offset:  %u",
-        ret->vbuffer.m.offset);
-  GST_LOG_OBJECT (pool->v4l2elem, "  length:    %u", ret->vbuffer.length);
-  GST_LOG_OBJECT (pool->v4l2elem, "  input:     %u", ret->vbuffer.input);
-
-  data = (guint8 *) v4l2_mmap (0, ret->vbuffer.length,
-      PROT_READ | PROT_WRITE, MAP_SHARED, pool->video_fd,
-      ret->vbuffer.m.offset);
-
+  data = (guint8 *) v4l2_mmap (0, vbuffer->length, PROT_READ | PROT_WRITE,
+      MAP_SHARED, pool->video_fd, vbuffer->m.offset);
   if (data == MAP_FAILED)
     goto mmap_failed;
 
+  gst_v4l2_buffer_pool_log_vbuffer (pool, vbuffer);
+
   GST_BUFFER_DATA (ret) = data;
-  GST_BUFFER_SIZE (ret) = ret->vbuffer.length;
+  GST_BUFFER_SIZE (ret) = vbuffer->length;
 
   GST_BUFFER_FLAG_SET (ret, GST_BUFFER_FLAG_READONLY);
 
   gst_buffer_set_caps (GST_BUFFER (ret), caps);
 
-  return ret;
+  return GST_BUFFER (ret);
 
   /* ERRORS */
 querybuf_failed:
@@ -206,6 +223,34 @@ mmap_failed:
   }
 }
 
+static GstBuffer *
+gst_v4l2_buffer_new_pad_alloc (GstV4l2BufferPool * pool, GstV4l2Src * v4l2src, guint index, GstCaps * caps)
+{
+  struct v4l2_buffer *vbuffer = gst_v4l2_buffer_pool_prepare_vbuffer (pool, index);
+  GstBuffer *buf = NULL;
+  GstFlowReturn flow_ret;
+
+  vbuffer->length = v4l2src->frame_byte_size;
+
+  flow_ret = gst_pad_alloc_buffer_and_set_caps (GST_BASE_SRC_PAD (v4l2src),
+    0LL, vbuffer->length, caps, &buf);
+  if (flow_ret != GST_FLOW_OK)
+    goto pad_alloc_failed;
+
+  vbuffer->m.userptr = (unsigned int) GST_BUFFER_DATA (buf);
+
+  gst_v4l2_buffer_pool_log_vbuffer (pool, vbuffer);
+
+  return buf;
+
+  /* ERRORS */
+pad_alloc_failed:
+  {
+    GST_WARNING ("Failed to pad_alloc_buffer: %s",
+      gst_flow_get_name (flow_ret));
+    return NULL;
+  }
+}
 
 /*
  * GstV4l2BufferPool:
@@ -229,7 +274,10 @@ gst_v4l2_buffer_pool_finalize (GstV4l2Bu
     g_free (pool->buffers);
     pool->buffers = NULL;
   }
-
+  if (pool->vbuffers) {
+    g_free (pool->vbuffers);
+    pool->vbuffers = NULL;
+  }
   GST_MINI_OBJECT_CLASS (buffer_pool_parent_class)->finalize (GST_MINI_OBJECT
       (pool));
 }
@@ -296,13 +344,36 @@ get_v4l2_object (GstElement * v4l2elem)
 }
 
 
+static gint
+gst_v4l2_buffer_pool_probe_memory_type (GstV4l2BufferPool * pool,
+  struct v4l2_requestbuffers * breq, gint num_buffers, enum v4l2_memory memory)
+{
+  gint ioret;
+  memset (breq, 0, sizeof (struct v4l2_requestbuffers));
+  breq->count = num_buffers;
+  breq->type = pool->type;
+  breq->memory = memory;
+
+  ioret = v4l2_ioctl (get_v4l2_object(pool->v4l2elem)->video_fd, VIDIOC_REQBUFS, breq);
+
+  if (ioret < 0) {
+    GST_DEBUG_OBJECT (pool->v4l2elem,
+        "VIDIOC_REQBUFS(V4L2_MEMORY_USERPTR) for %d buffers failed %d:%s",
+        num_buffers, errno, g_strerror (errno));
+  } else {
+    GST_LOG_OBJECT (pool->v4l2elem, " count:  %u", breq->count);
+  }
+  GST_LOG_OBJECT (pool->v4l2elem, " type:   %d", breq->type);
+  GST_LOG_OBJECT (pool->v4l2elem, " memory: %d", breq->memory);
+
+  return ioret;
+}
 
 /**
  * Construct a new buffer pool
  *
  * @v4l2elem  the v4l2 element (src or sink) that owns this pool
  * @fd   the video device file descriptor
- * @num_buffers  the requested number of buffers in the pool
  * @caps  the caps to set on the buffer
  * @requeuebuf  if <code>TRUE</code>, and if the pool is still in the
  *   <code>running</code> state, a buffer with no remaining references
@@ -317,52 +388,68 @@ gst_v4l2_buffer_pool_new (GstElement * v
   GstV4l2BufferPool *pool;
   gint n;
   struct v4l2_requestbuffers breq;
+  GstV4l2Src *v4l2src = NULL;
+  gboolean use_mmap = TRUE;
+
+  if (GST_IS_V4L2SRC (v4l2elem)) {
+    v4l2src = GST_V4L2SRC (v4l2elem);
+  }
 
   pool = (GstV4l2BufferPool *) gst_mini_object_new (GST_TYPE_V4L2_BUFFER_POOL);
 
   pool->video_fd = v4l2_dup (fd);
   if (pool->video_fd < 0)
     goto dup_failed;
+  pool->v4l2elem = v4l2elem;
+  pool->type = type;
 
-
-  /* first, lets request buffers, and see how many we can get: */
-  GST_DEBUG_OBJECT (v4l2elem, "STREAMING, requesting %d MMAP buffers",
-      num_buffers);
-
-  memset (&breq, 0, sizeof (struct v4l2_requestbuffers));
-  breq.type = type;
-  breq.count = num_buffers;
-  breq.memory = V4L2_MEMORY_MMAP;
-
-  if (v4l2_ioctl (fd, VIDIOC_REQBUFS, &breq) < 0)
-    goto reqbufs_failed;
-
-  GST_LOG_OBJECT (v4l2elem, " count:  %u", breq.count);
-  GST_LOG_OBJECT (v4l2elem, " type:   %d", breq.type);
-  GST_LOG_OBJECT (v4l2elem, " memory: %d", breq.memory);
-
+  GST_DEBUG_OBJECT (v4l2elem, "STREAMING, requesting %d buffers", num_buffers);
+  if (v4l2src) {
+    /* negotiate memory mapping or user pointer i/o */
+    if (gst_v4l2_buffer_pool_probe_memory_type (pool, &breq, num_buffers,
+        V4L2_MEMORY_USERPTR) < 0) {
+      if (gst_v4l2_buffer_pool_probe_memory_type (pool, &breq, num_buffers,
+          V4L2_MEMORY_MMAP) < 0) {
+        goto reqbufs_failed;
+      } else {
+        GST_INFO_OBJECT (v4l2elem, "allocate buffers via mmap");
+        use_mmap = TRUE;
+      }
+    } else {
+      GST_INFO_OBJECT (v4l2elem, "allocate buffers via pad_alloc");
+      use_mmap = FALSE;
+    }
+    v4l2src->use_mmap = use_mmap;
+  } else {
+    if (gst_v4l2_buffer_pool_probe_memory_type (pool, &breq, num_buffers,
+        V4L2_MEMORY_MMAP) < 0) {
+      goto reqbufs_failed;
+    }
+  }
   if (breq.count < GST_V4L2_MIN_BUFFERS)
     goto no_buffers;
 
   if (num_buffers != breq.count) {
-    GST_WARNING_OBJECT (v4l2elem, "using %u buffers instead", breq.count);
+    GST_WARNING_OBJECT (v4l2src, "using %u buffers instead", breq.count);
     num_buffers = breq.count;
   }
-
-  pool->v4l2elem = v4l2elem;
+  pool->memory = breq.memory;
   pool->requeuebuf = requeuebuf;
-  pool->type = type;
   pool->buffer_count = num_buffers;
-  pool->buffers = g_new0 (GstV4l2Buffer *, num_buffers);
+  pool->buffers = g_new0 (GstBuffer *, num_buffers);
+  pool->vbuffers = g_new0 (struct v4l2_buffer, num_buffers);
   pool->avail_buffers = g_async_queue_new ();
 
   /* now, map the buffers: */
   for (n = 0; n < num_buffers; n++) {
-    pool->buffers[n] = gst_v4l2_buffer_new (pool, n, caps);
+    pool->buffers[n] = use_mmap ? 
+        gst_v4l2_buffer_new_mmap (pool, n, caps) :
+        gst_v4l2_buffer_new_pad_alloc (pool, v4l2src, n, caps);
     if (!pool->buffers[n])
       goto buffer_new_failed;
     pool->num_live_buffers++;
-    g_async_queue_push (pool->avail_buffers, pool->buffers[n]);
+    if (use_mmap)
+      g_async_queue_push (pool->avail_buffers, GST_V4L2_BUFFER(pool->buffers[n]));
   }
 
   return pool;
@@ -453,7 +540,7 @@ gst_v4l2_buffer_pool_get (GstV4l2BufferP
   GstV4l2Buffer *buf = g_async_queue_try_pop (pool->avail_buffers);
 
   if (buf)
-    GST_BUFFER_SIZE (buf) = buf->vbuffer.length;
+    GST_BUFFER_SIZE (buf) = pool->vbuffers[buf->index].length;
 
   pool->running = TRUE;
 
@@ -465,14 +552,15 @@ gst_v4l2_buffer_pool_get (GstV4l2BufferP
  * Queue a buffer to the driver
  *
  * @pool   the "this" object
- * @buf    the buffer to queue
+ * @index  the index of the buffer to queue
  */
 gboolean
-gst_v4l2_buffer_pool_qbuf (GstV4l2BufferPool * pool, GstV4l2Buffer * buf)
+gst_v4l2_buffer_pool_qbuf (GstV4l2BufferPool * pool, gint index)
 {
-  GST_LOG_OBJECT (pool->v4l2elem, "enqueue pool buffer %d", buf->vbuffer.index);
+  struct v4l2_buffer *vbuffer = &pool->vbuffers[index];
+  GST_LOG_OBJECT (pool->v4l2elem, "enqueue pool buffer %d", index);
 
-  if (v4l2_ioctl (pool->video_fd, VIDIOC_QBUF, &buf->vbuffer) < 0)
+  if (v4l2_ioctl (pool->video_fd, VIDIOC_QBUF, vbuffer) < 0)
     return FALSE;
 
   pool->num_live_buffers--;
@@ -489,16 +577,16 @@ gst_v4l2_buffer_pool_qbuf (GstV4l2Buffer
  *
  * @pool   the "this" object
  */
-GstV4l2Buffer *
+GstBuffer *
 gst_v4l2_buffer_pool_dqbuf (GstV4l2BufferPool * pool)
 {
   GstV4l2Object *v4l2object = get_v4l2_object (pool->v4l2elem);
-  GstV4l2Buffer *pool_buffer;
+  GstBuffer *pool_buffer;
   struct v4l2_buffer buffer;
 
   memset (&buffer, 0x00, sizeof (buffer));
   buffer.type = pool->type;
-  buffer.memory = V4L2_MEMORY_MMAP;
+  buffer.memory = pool->memory;
 
 
   if (v4l2_ioctl (pool->video_fd, VIDIOC_DQBUF, &buffer) >= 0) {
@@ -520,14 +608,22 @@ gst_v4l2_buffer_pool_dqbuf (GstV4l2Buffe
     }
 
     GST_LOG_OBJECT (pool->v4l2elem,
-        "grabbed frame %d (ix=%d), flags %08x, pool-ct=%d, buffer=%p",
+        "grabbed frame %d (ix=%d), flags %08x, pool-ct=%d, buffer=%p (refct=%d)",
         buffer.sequence, buffer.index, buffer.flags, pool->num_live_buffers,
-        pool_buffer);
+        pool_buffer, GST_MINI_OBJECT_REFCOUNT(pool_buffer));
 
     pool->num_live_buffers++;
     GST_DEBUG_OBJECT (pool->v4l2elem, "num_live_buffers++: %d",
         pool->num_live_buffers);
 
+    /* USERPTR buffers don't use our finalize function, so we can't revive them
+     * there.  Therefore, add a ref here so we can recycle them in _update().
+     * FIXME this is suboptimal since that makes the buffer non-writable, thereby
+     * disabling in-place transformations.
+     */
+    if (pool->memory == V4L2_MEMORY_USERPTR)
+      gst_buffer_ref (pool_buffer);
+
     GST_V4L2_BUFFER_POOL_UNLOCK (pool);
 
     /* this can change at every frame, esp. with jpeg */
@@ -589,6 +685,42 @@ gst_v4l2_buffer_pool_dqbuf (GstV4l2Buffe
 }
 
 /**
+ * gst_v4l2_buffer_pool_update:
+ * Scans the pool for buffers that can be requeued (i.e. that are
+ * not queued yet and that are writable), and requeues them.
+ */
+gboolean
+gst_v4l2_buffer_pool_update (GstV4l2BufferPool * pool)
+{
+  gint n;
+  struct v4l2_buffer qbuffer = {0,};
+  struct v4l2_buffer *vbuffer;
+
+  g_mutex_lock (pool->lock);
+
+  for (n = 0; n < pool->buffer_count; n++) {
+    vbuffer = &pool->vbuffers[n];
+
+    qbuffer.type = pool->type;
+    qbuffer.memory = pool->memory;
+    qbuffer.index = n;
+    if (v4l2_ioctl (pool->video_fd, VIDIOC_QUERYBUF, &qbuffer) >= 0) {
+      if (((qbuffer.flags & V4L2_BUF_FLAG_QUEUED) == 0) &&
+          gst_buffer_is_writable (pool->buffers[n])) {
+        if (!gst_v4l2_buffer_pool_qbuf (pool, n)) {
+          GST_WARNING_OBJECT (pool->v4l2elem, "could not requeue buffer %p vbuffer %p at index %d",
+            pool->buffers[n], vbuffer, n);
+        }
+      }
+    }
+  }
+
+  g_mutex_unlock (pool->lock);
+
+  return TRUE;
+}
+
+/**
  * gst_v4l2_buffer_pool_available_buffers:
  * Returns the number of buffers available to the driver, ie. buffers that
  * have been QBUF'd but not yet DQBUF'd.
Only in gst-plugins-good-0.10.16/sys/v4l2: gstv4l2bufferpool.c.orig
Only in gst-plugins-good-0.10.16/sys/v4l2: gstv4l2bufferpool.c~
diff -rup -x '*.o' -x '*.lo' -x Makefile -x Makefile.in -x '*.la' -x '*.a' gst-plugins-good-0.10.16.orig/sys/v4l2/gstv4l2bufferpool.h gst-plugins-good-0.10.16/sys/v4l2/gstv4l2bufferpool.h
--- gst-plugins-good-0.10.16.orig/sys/v4l2/gstv4l2bufferpool.h	2010-03-01 18:11:40.000000000 +0100
+++ gst-plugins-good-0.10.16/sys/v4l2/gstv4l2bufferpool.h	2010-03-02 22:20:04.000000000 +0100
@@ -56,6 +56,7 @@ struct _GstV4l2BufferPool
   GstElement *v4l2elem;      /* the v4l2 src/sink that owns us.. maybe we should be owned by v4l2object? */
   gboolean requeuebuf;       /* if true, unusued buffers are automatically re-QBUF'd */
   enum v4l2_buf_type type;   /* V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_BUF_TYPE_VIDEO_OUTPUT */
+  enum v4l2_memory memory;   /* V4l2_MEMORY_MMAP, V4l2_MEMORY_USERPTR */
 
   GMutex *lock;
   gboolean running;          /* with lock */
@@ -63,13 +64,14 @@ struct _GstV4l2BufferPool
   GAsyncQueue* avail_buffers;/* pool of available buffers, not with the driver and which aren't held outside the bufferpool */
   gint video_fd;             /* a dup(2) of the v4l2object's video_fd */
   guint buffer_count;
-  GstV4l2Buffer **buffers;
+  GstBuffer **buffers;
+  struct v4l2_buffer *vbuffers;
 };
 
 struct _GstV4l2Buffer {
   GstBuffer   buffer;
 
-  struct v4l2_buffer vbuffer;
+  gint index;
 
   /* FIXME: have GstV4l2Src* instead, as this has GstV4l2BufferPool* */
   /* FIXME: do we really want to fix this if GstV4l2Buffer/Pool is shared
@@ -85,9 +87,10 @@ GstV4l2BufferPool *gst_v4l2_buffer_pool_
 
 
 GstV4l2Buffer *gst_v4l2_buffer_pool_get (GstV4l2BufferPool *pool);
-gboolean gst_v4l2_buffer_pool_qbuf (GstV4l2BufferPool *pool, GstV4l2Buffer *buf);
-GstV4l2Buffer *gst_v4l2_buffer_pool_dqbuf (GstV4l2BufferPool *pool);
+gboolean gst_v4l2_buffer_pool_qbuf (GstV4l2BufferPool *pool, gint index);
+GstBuffer *gst_v4l2_buffer_pool_dqbuf (GstV4l2BufferPool *pool);
 
+gboolean gst_v4l2_buffer_pool_update (GstV4l2BufferPool * pool);
 gint gst_v4l2_buffer_pool_available_buffers (GstV4l2BufferPool *pool);
 
 
Only in gst-plugins-good-0.10.16/sys/v4l2: gstv4l2bufferpool.h.orig
Only in gst-plugins-good-0.10.16/sys/v4l2: gstv4l2bufferpool.h.rej
Only in gst-plugins-good-0.10.16/sys/v4l2: gstv4l2bufferpool.h~
diff -rup -x '*.o' -x '*.lo' -x Makefile -x Makefile.in -x '*.la' -x '*.a' gst-plugins-good-0.10.16.orig/sys/v4l2/gstv4l2sink.c gst-plugins-good-0.10.16/sys/v4l2/gstv4l2sink.c
--- gst-plugins-good-0.10.16.orig/sys/v4l2/gstv4l2sink.c	2010-03-01 18:11:38.000000000 +0100
+++ gst-plugins-good-0.10.16/sys/v4l2/gstv4l2sink.c	2010-03-02 17:57:52.000000000 +0100
@@ -683,7 +683,7 @@ gst_v4l2sink_show_frame (GstBaseSink * b
     buf = newbuf;
   }
 
-  if (!gst_v4l2_buffer_pool_qbuf (v4l2sink->pool, GST_V4L2_BUFFER (buf))) {
+  if (!gst_v4l2_buffer_pool_qbuf (v4l2sink->pool, GST_V4L2_BUFFER (buf)->index)) {
     return GST_FLOW_ERROR;
   }
   if (v4l2sink->state == STATE_PENDING_STREAMON) {
@@ -702,15 +702,15 @@ gst_v4l2sink_show_frame (GstBaseSink * b
    * _buffer_alloc():
    */
   if (gst_v4l2_buffer_pool_available_buffers (v4l2sink->pool) > 1) {
-    GstV4l2Buffer *v4l2buf = gst_v4l2_buffer_pool_dqbuf (v4l2sink->pool);
+    GstBuffer *buf = gst_v4l2_buffer_pool_dqbuf (v4l2sink->pool);
 
     /* note: if we get a buf, we don't want to use it directly (because
      * someone else could still hold a ref).. but instead we release our
      * reference to it, and if no one else holds a ref it will be returned
      * to the pool of available buffers..  and if not, we keep looping.
      */
-    if (v4l2buf) {
-      gst_buffer_unref (GST_BUFFER (v4l2buf));
+    if (buf) {
+      gst_buffer_unref (buf);
     }
   }
 
Only in gst-plugins-good-0.10.16/sys/v4l2: gstv4l2sink.c~
diff -rup -x '*.o' -x '*.lo' -x Makefile -x Makefile.in -x '*.la' -x '*.a' gst-plugins-good-0.10.16.orig/sys/v4l2/gstv4l2src.c gst-plugins-good-0.10.16/sys/v4l2/gstv4l2src.c
--- gst-plugins-good-0.10.16.orig/sys/v4l2/gstv4l2src.c	2010-03-01 18:11:38.000000000 +0100
+++ gst-plugins-good-0.10.16/sys/v4l2/gstv4l2src.c	2010-03-02 15:51:21.000000000 +0100
@@ -69,7 +69,12 @@ GST_ELEMENT_DETAILS ("Video (video4linux
 GST_DEBUG_CATEGORY (v4l2src_debug);
 #define GST_CAT_DEFAULT v4l2src_debug
 
-#define PROP_DEF_QUEUE_SIZE         2
+/* queue-size=1 will cause immediate copies to keep something enqueued
+ * queue-size=2 will probably cause every 2nd buffer to be copied
+ * queue-size=3 ensure that src and sink can have a buffer enqueue and one
+ *   buffer is traveling
+ */
+#define PROP_DEF_QUEUE_SIZE         3
 #define PROP_DEF_ALWAYS_COPY        TRUE
 
 #define DEFAULT_PROP_DEVICE   "/dev/video0"
@@ -614,15 +619,15 @@ gst_v4l2src_set_caps (GstBaseSrc * src, 
     /* error already posted */
     return FALSE;
 
+  /* now store the expected output size */
+  v4l2src->frame_byte_size = size;
+
   if (!gst_v4l2src_capture_init (v4l2src, caps))
     return FALSE;
 
   if (!gst_v4l2src_capture_start (v4l2src))
     return FALSE;
 
-  /* now store the expected output size */
-  v4l2src->frame_byte_size = size;
-
   return TRUE;
 }
 
@@ -776,18 +781,19 @@ gst_v4l2src_change_state (GstElement * e
 static GstFlowReturn
 gst_v4l2src_get_read (GstV4l2Src * v4l2src, GstBuffer ** buf)
 {
-  gint amount;
-  gint ret;
-
-  gint buffersize;
-
-  buffersize = v4l2src->frame_byte_size;
+  GstBuffer *temp;
+  gint poll_ret;
+  GstFlowReturn ret;
+  gint size;
 
-  *buf = gst_buffer_new_and_alloc (buffersize);
+  ret = gst_pad_alloc_buffer(GST_BASE_SRC_PAD(v4l2src), 0LL, v4l2src->frame_byte_size,
+      NULL, &temp);
+  if (ret != GST_FLOW_OK)
+    goto done;
 
   do {
-    ret = gst_poll_wait (v4l2src->v4l2object->poll, GST_CLOCK_TIME_NONE);
-    if (G_UNLIKELY (ret < 0)) {
+    poll_ret = gst_poll_wait (v4l2src->v4l2object->poll, GST_CLOCK_TIME_NONE);
+    if (G_UNLIKELY (poll_ret < 0)) {
       if (errno == EBUSY)
         goto stopped;
       if (errno == ENXIO) {
@@ -799,12 +805,11 @@ gst_v4l2src_get_read (GstV4l2Src * v4l2s
           goto select_error;
       }
     }
-    amount =
-        v4l2_read (v4l2src->v4l2object->video_fd, GST_BUFFER_DATA (*buf),
-        buffersize);
-    if (amount == buffersize) {
+    size = v4l2_read (v4l2src->v4l2object->video_fd, GST_BUFFER_DATA (temp),
+        v4l2src->frame_byte_size);
+    if (size == v4l2src->frame_byte_size) {
       break;
-    } else if (amount == -1) {
+    } else if (size == -1) {
       if (errno == EAGAIN || errno == EINTR) {
         continue;
       } else
@@ -816,8 +821,9 @@ gst_v4l2src_get_read (GstV4l2Src * v4l2s
   } while (TRUE);
 
   /* we set the buffer metadata in gst_v4l2src_create() */
-
-  return GST_FLOW_OK;
+  *buf = temp;
+done:
+  return ret;
 
   /* ERRORS */
 select_error:
@@ -835,8 +841,9 @@ read_error:
   {
     GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ,
         (_("Error reading %d bytes from device '%s'."),
-            buffersize, v4l2src->v4l2object->videodev), GST_ERROR_SYSTEM);
-    gst_buffer_unref (*buf);
+            v4l2src->frame_byte_size, v4l2src->v4l2object->videodev),
+        GST_ERROR_SYSTEM);
+    gst_buffer_unref (temp);
     return GST_FLOW_ERROR;
   }
 }
@@ -890,7 +897,7 @@ gst_v4l2src_create (GstPushSrc * src, Gs
   GstV4l2Src *v4l2src = GST_V4L2SRC (src);
   GstFlowReturn ret;
 
-  if (v4l2src->use_mmap) {
+  if (v4l2src->use_streaming) {
     ret = gst_v4l2src_get_mmap (v4l2src, buf);
   } else {
     ret = gst_v4l2src_get_read (v4l2src, buf);
Only in gst-plugins-good-0.10.16/sys/v4l2: gstv4l2src.c.orig
Only in gst-plugins-good-0.10.16/sys/v4l2: gstv4l2src.c.rej~
Only in gst-plugins-good-0.10.16/sys/v4l2: gstv4l2src.c~
diff -rup -x '*.o' -x '*.lo' -x Makefile -x Makefile.in -x '*.la' -x '*.a' gst-plugins-good-0.10.16.orig/sys/v4l2/gstv4l2src.h gst-plugins-good-0.10.16/sys/v4l2/gstv4l2src.h
--- gst-plugins-good-0.10.16.orig/sys/v4l2/gstv4l2src.h	2010-03-01 18:11:38.000000000 +0100
+++ gst-plugins-good-0.10.16/sys/v4l2/gstv4l2src.h	2010-03-02 15:29:48.000000000 +0100
@@ -67,6 +67,7 @@ struct _GstV4l2Src
   GstV4l2BufferPool *pool;
 
   guint32 num_buffers;
+  gboolean use_streaming;
   gboolean use_mmap;
   guint32 frame_byte_size;
 
Only in gst-plugins-good-0.10.16/sys/v4l2: gstv4l2src.h.orig
Only in gst-plugins-good-0.10.16/sys/v4l2: gstv4l2src.h.rej
diff -rup -x '*.o' -x '*.lo' -x Makefile -x Makefile.in -x '*.la' -x '*.a' gst-plugins-good-0.10.16.orig/sys/v4l2/v4l2src_calls.c gst-plugins-good-0.10.16/sys/v4l2/v4l2src_calls.c
--- gst-plugins-good-0.10.16.orig/sys/v4l2/v4l2src_calls.c	2010-03-01 18:11:38.000000000 +0100
+++ gst-plugins-good-0.10.16/sys/v4l2/v4l2src_calls.c	2010-03-02 22:22:10.000000000 +0100
@@ -68,9 +68,13 @@ gst_v4l2src_buffer_pool_activate (GstV4l
 {
   GstV4l2Buffer *buf;
 
-  while ((buf = gst_v4l2_buffer_pool_get (pool)) != NULL)
-    if (!gst_v4l2_buffer_pool_qbuf (pool, buf))
-      goto queue_failed;
+  if (pool->memory == V4L2_MEMORY_MMAP) {
+    while ((buf = gst_v4l2_buffer_pool_get (pool)) != NULL)
+      if (!gst_v4l2_buffer_pool_qbuf (pool, buf->index))
+        goto queue_failed;
+  } else {
+    return gst_v4l2_buffer_pool_update (pool);
+  }
 
   return TRUE;
 
@@ -81,7 +85,7 @@ queue_failed:
         (_("Could not enqueue buffers in device '%s'."),
             v4l2src->v4l2object->videodev),
         ("enqueing buffer %d/%d failed: %s",
-            buf->vbuffer.index, v4l2src->num_buffers, g_strerror (errno)));
+            buf->index, v4l2src->num_buffers, g_strerror (errno)));
     return FALSE;
   }
 }
@@ -107,6 +111,11 @@ gst_v4l2src_grab_frame (GstV4l2Src * v4l
 
   GST_DEBUG_OBJECT (v4l2src, "grab frame");
 
+  if (v4l2src->pool->memory == V4L2_MEMORY_USERPTR) {
+    /* requeue buffers that are writable again */
+    gst_v4l2_buffer_pool_update (v4l2src->pool);
+  }
+
   for (;;) {
     if (v4l2object->can_poll_device) {
       ret = gst_poll_wait (v4l2object->poll, GST_CLOCK_TIME_NONE);
@@ -125,7 +134,7 @@ gst_v4l2src_grab_frame (GstV4l2Src * v4l
       GST_DEBUG_OBJECT (v4l2src, "poll done");
     }
 
-    pool_buffer = GST_BUFFER (gst_v4l2_buffer_pool_dqbuf (pool));
+    pool_buffer = gst_v4l2_buffer_pool_dqbuf (pool);
     if (pool_buffer)
       break;
 
@@ -291,8 +300,8 @@ gst_v4l2src_capture_init (GstV4l2Src * v
                 v4l2src->num_buffers, caps, TRUE, V4L2_BUF_TYPE_VIDEO_CAPTURE)))
       goto buffer_pool_new_failed;
 
-    GST_INFO_OBJECT (v4l2src, "capturing buffers via mmap()");
-    v4l2src->use_mmap = TRUE;
+    GST_INFO_OBJECT (v4l2src, "capturing buffers via streaming");
+    v4l2src->use_streaming = TRUE;
 
     if (v4l2src->num_buffers != v4l2src->pool->buffer_count) {
       v4l2src->num_buffers = v4l2src->pool->buffer_count;
@@ -301,7 +310,7 @@ gst_v4l2src_capture_init (GstV4l2Src * v
 
   } else if (v4l2src->v4l2object->vcap.capabilities & V4L2_CAP_READWRITE) {
     GST_INFO_OBJECT (v4l2src, "capturing buffers via read()");
-    v4l2src->use_mmap = FALSE;
+    v4l2src->use_streaming = FALSE;
     v4l2src->pool = NULL;
   } else {
     goto no_supported_capture_method;
@@ -344,7 +353,7 @@ gst_v4l2src_capture_start (GstV4l2Src * 
 
   v4l2src->quit = FALSE;
 
-  if (v4l2src->use_mmap) {
+  if (v4l2src->use_streaming) {
     if (!gst_v4l2src_buffer_pool_activate (v4l2src->pool, v4l2src)) {
       return FALSE;
     }
@@ -376,7 +385,7 @@ gst_v4l2src_capture_stop (GstV4l2Src * v
     goto done;
   }
 
-  if (v4l2src->use_mmap) {
+  if (v4l2src->use_streaming) {
     /* we actually need to sync on all queued buffers but not
      * on the non-queued ones */
     if (!gst_v4l2_object_stop_streaming (v4l2src->v4l2object)) {
Only in gst-plugins-good-0.10.16/sys/v4l2: v4l2src_calls.c.orig
Only in gst-plugins-good-0.10.16/sys/v4l2: v4l2src_calls.c.rej
Only in gst-plugins-good-0.10.16/sys/v4l2: v4l2src_calls.c~
