aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-multimedia/gstreamer/gst-plugins-good
diff options
context:
space:
mode:
authorNobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>2015-03-25 10:47:45 +0900
committerNobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>2015-03-25 10:47:45 +0900
commit1c35920d85e424b3f65aa6df1dbde689dd6ec007 (patch)
tree58b2cacb3674111aad5a4ded694db0cef5cf55f3 /common/recipes-multimedia/gstreamer/gst-plugins-good
commit BSP v1.8.0
Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
Diffstat (limited to 'common/recipes-multimedia/gstreamer/gst-plugins-good')
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good/0001-sys-v4l2-gstv4l2-fix-the-depth-value-for-RGB32.patch65
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good/0002-Revert-sys-v4l2-gstv4l2-fix-the-depth-value-for-RGB3.patch64
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good/0003-sys-v4l2-gstv4l2-register-uiomux-memory-regions-via-.patch262
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good/0004-sys-v4l2-gstv4l2-release-corresponding-uiomux-handle.patch31
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good/0005-videocrop-correct-coding-style-with-gst-indent.patch104
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good/0006-videocrop-send-a-query-whether-the-rowstride-capabil.patch105
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good/0007-videocrop-set-rowstride-capability.patch59
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good/0008-videocrop-kick-off-the-zero-copy-cropping.patch100
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good/0009-avidemux-set-frame-start-code-to-VC-1-advanced-profi.patch90
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good/0010-videocrop-add-gst_video_crop_get_image_details_from_.patch55
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good/0011-videocrop-change-the-unit-of-rowstride-to-byte.patch36
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good/0012-videocrop-add-tests-to-determine-if-width-and-height.patch39
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good/0013-videocrop-replace-the-processing-to-set-gint-value-t.patch35
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good/0014-videocrop-don-t-set-rowstride-only-when-the-color-sp.patch66
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good/0015-videocrop-fix-wrong-subbuffer-size.patch27
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good/0016-videocrop-support-getting-NV12-image-details.patch84
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good/0017-videocrop-add-NV12-format-caps-template.patch25
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good/0018-videocrop-kick-off-NV12-zero-copy-cropping.patch105
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good/0019-videocrop-send-a-query-by-the-first-invorker-of-quer.patch123
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good/0020-videocrop-set-tile-boundary-offset-in-caps-for-T-L-a.patch44
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good/0021-videocrop-support-cropping-interlaced-images.patch99
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good/0022-videocrop-move-output-buffer-size-calculation-to-tra.patch178
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good/0023-videocrop-skip-the-transforming-caps-process-when-th.patch32
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good/0024-v4l2src-fix-RGB32-colorspace-deinitions.patch69
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good/0025-sys-v4l2-gstv4l2-skip-set-caps-processing-if-the-par.patch86
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good/0026-sys-v4l2-gstv4l2-return-an-error-from-set_caps-if-tr.patch66
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good/0027-videocrop-add-a-new-function-to-determine-if-source-.patch67
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good/0028-videocrop-set-result-of-determing-if-source-images-a.patch35
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good/0029-videocrop-round-down-cropping-parameters-when-the-co.patch193
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good/0030-videocrop-hold-a-lock-to-prevent-from-accessing-crop.patch30
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good/0031-videocrop-fix-a-memory-leak-caused-by-invoking-gst_p.patch39
31 files changed, 2413 insertions, 0 deletions
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good/0001-sys-v4l2-gstv4l2-fix-the-depth-value-for-RGB32.patch b/common/recipes-multimedia/gstreamer/gst-plugins-good/0001-sys-v4l2-gstv4l2-fix-the-depth-value-for-RGB32.patch
new file mode 100644
index 0000000..b6bf9c1
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good/0001-sys-v4l2-gstv4l2-fix-the-depth-value-for-RGB32.patch
@@ -0,0 +1,65 @@
+From f2ceec7fb2e1b7a182eb737216fe3214a743247d Mon Sep 17 00:00:00 2001
+From: Katsuya Matsubara <matsu@igel.co.jp>
+Date: Wed, 14 Mar 2012 21:19:31 +0900
+Subject: [PATCH 01/31] sys/v4l2/gstv4l2: fix the depth value for RGB32
+
+The 'depth' value for RGB32 must be 24 rather than 32.
+This changes conversion code between color format
+representaion in caps and V4L2 definition.
+---
+ sys/v4l2/gstv4l2object.c | 17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+diff --git a/sys/v4l2/gstv4l2object.c b/sys/v4l2/gstv4l2object.c
+index 81d1cb7..2c1bde4 100644
+--- a/sys/v4l2/gstv4l2object.c
++++ b/sys/v4l2/gstv4l2object.c
+@@ -1208,14 +1208,16 @@ gst_v4l2_object_v4l2fourcc_to_structure (guint32 fourcc)
+ b_mask = 0xff0000;
+ break;
+ case V4L2_PIX_FMT_RGB32:
+- bpp = depth = 32;
++ bpp = 32;
++ depth = 24;
+ endianness = G_BIG_ENDIAN;
+ r_mask = 0xff000000;
+ g_mask = 0x00ff0000;
+ b_mask = 0x0000ff00;
+ break;
+ case V4L2_PIX_FMT_BGR32:
+- bpp = depth = 32;
++ bpp = 32;
++ depth = 24;
+ endianness = G_BIG_ENDIAN;
+ r_mask = 0x000000ff;
+ g_mask = 0x0000ff00;
+@@ -1480,9 +1482,10 @@ gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps,
+ #endif
+ }
+ } else if (!strcmp (mimetype, "video/x-raw-rgb")) {
+- gint depth, endianness, r_mask;
++ gint bpp, depth, endianness, r_mask;
+
+ gst_structure_get_int (structure, "depth", &depth);
++ gst_structure_get_int (structure, "bpp", &bpp);
+ gst_structure_get_int (structure, "endianness", &endianness);
+ gst_structure_get_int (structure, "red_mask", &r_mask);
+
+@@ -1499,10 +1502,10 @@ gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps,
+ V4L2_PIX_FMT_RGB565 : V4L2_PIX_FMT_RGB565X;
+ break;
+ case 24:
+- fourcc = (r_mask == 0xFF) ? V4L2_PIX_FMT_BGR24 : V4L2_PIX_FMT_RGB24;
+- break;
+- case 32:
+- fourcc = (r_mask == 0xFF) ? V4L2_PIX_FMT_BGR32 : V4L2_PIX_FMT_RGB32;
++ if (bpp == 24)
++ fourcc = (r_mask == 0xFF) ? V4L2_PIX_FMT_BGR24 : V4L2_PIX_FMT_RGB24;
++ else if (bpp == 32)
++ fourcc = (r_mask == 0xFF) ? V4L2_PIX_FMT_BGR32 : V4L2_PIX_FMT_RGB32;
+ break;
+ }
+ } else if (strcmp (mimetype, "video/x-dv") == 0) {
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good/0002-Revert-sys-v4l2-gstv4l2-fix-the-depth-value-for-RGB3.patch b/common/recipes-multimedia/gstreamer/gst-plugins-good/0002-Revert-sys-v4l2-gstv4l2-fix-the-depth-value-for-RGB3.patch
new file mode 100644
index 0000000..d53ca83
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good/0002-Revert-sys-v4l2-gstv4l2-fix-the-depth-value-for-RGB3.patch
@@ -0,0 +1,64 @@
+From 187c290bc57a65fe6f669a6026bdb36b4c89a2a9 Mon Sep 17 00:00:00 2001
+From: Katsuya Matsubara <matsu@igel.co.jp>
+Date: Thu, 15 Mar 2012 14:53:39 +0900
+Subject: [PATCH 02/31] Revert "sys/v4l2/gstv4l2: fix the depth value for
+ RGB32"
+
+This reverts commit f2ceec7fb2e1b7a182eb737216fe3214a743247d.
+---
+ sys/v4l2/gstv4l2object.c | 17 +++++++----------
+ 1 file changed, 7 insertions(+), 10 deletions(-)
+
+diff --git a/sys/v4l2/gstv4l2object.c b/sys/v4l2/gstv4l2object.c
+index 2c1bde4..81d1cb7 100644
+--- a/sys/v4l2/gstv4l2object.c
++++ b/sys/v4l2/gstv4l2object.c
+@@ -1208,16 +1208,14 @@ gst_v4l2_object_v4l2fourcc_to_structure (guint32 fourcc)
+ b_mask = 0xff0000;
+ break;
+ case V4L2_PIX_FMT_RGB32:
+- bpp = 32;
+- depth = 24;
++ bpp = depth = 32;
+ endianness = G_BIG_ENDIAN;
+ r_mask = 0xff000000;
+ g_mask = 0x00ff0000;
+ b_mask = 0x0000ff00;
+ break;
+ case V4L2_PIX_FMT_BGR32:
+- bpp = 32;
+- depth = 24;
++ bpp = depth = 32;
+ endianness = G_BIG_ENDIAN;
+ r_mask = 0x000000ff;
+ g_mask = 0x0000ff00;
+@@ -1482,10 +1480,9 @@ gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps,
+ #endif
+ }
+ } else if (!strcmp (mimetype, "video/x-raw-rgb")) {
+- gint bpp, depth, endianness, r_mask;
++ gint depth, endianness, r_mask;
+
+ gst_structure_get_int (structure, "depth", &depth);
+- gst_structure_get_int (structure, "bpp", &bpp);
+ gst_structure_get_int (structure, "endianness", &endianness);
+ gst_structure_get_int (structure, "red_mask", &r_mask);
+
+@@ -1502,10 +1499,10 @@ gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps,
+ V4L2_PIX_FMT_RGB565 : V4L2_PIX_FMT_RGB565X;
+ break;
+ case 24:
+- if (bpp == 24)
+- fourcc = (r_mask == 0xFF) ? V4L2_PIX_FMT_BGR24 : V4L2_PIX_FMT_RGB24;
+- else if (bpp == 32)
+- fourcc = (r_mask == 0xFF) ? V4L2_PIX_FMT_BGR32 : V4L2_PIX_FMT_RGB32;
++ fourcc = (r_mask == 0xFF) ? V4L2_PIX_FMT_BGR24 : V4L2_PIX_FMT_RGB24;
++ break;
++ case 32:
++ fourcc = (r_mask == 0xFF) ? V4L2_PIX_FMT_BGR32 : V4L2_PIX_FMT_RGB32;
+ break;
+ }
+ } else if (strcmp (mimetype, "video/x-dv") == 0) {
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good/0003-sys-v4l2-gstv4l2-register-uiomux-memory-regions-via-.patch b/common/recipes-multimedia/gstreamer/gst-plugins-good/0003-sys-v4l2-gstv4l2-register-uiomux-memory-regions-via-.patch
new file mode 100644
index 0000000..cd22317
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good/0003-sys-v4l2-gstv4l2-register-uiomux-memory-regions-via-.patch
@@ -0,0 +1,262 @@
+From c3fe71c65f87b32351e58969becb30102d3ddb05 Mon Sep 17 00:00:00 2001
+From: Katsuya Matsubara <matsu@igel.co.jp>
+Date: Fri, 6 Apr 2012 16:51:08 +0900
+Subject: [PATCH 03/31] sys/v4l2/gstv4l2: register uiomux memory regions via
+ USERPTR
+
+This patch enables to register uiomux memory regions via USERPTR
+for capture buffers. This may reduce memory-copy overhead with
+sharing the buffer between source and sink element.
+---
+ configure.ac | 8 ++++++
+ sys/v4l2/Makefile.am | 2 ++
+ sys/v4l2/gstv4l2bufferpool.c | 55 ++++++++++++++++++++++++++++++++++++++++++
+ sys/v4l2/gstv4l2bufferpool.h | 8 ++++++
+ sys/v4l2/gstv4l2src.c | 15 ++++++++----
+ 5 files changed, 83 insertions(+), 5 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 8a43fda..5bfddfe 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -572,6 +572,14 @@ return 0;
+ AC_DEFINE(GST_V4L2_MISSING_BUFDECL, 1, [struct v4l2_buffer missing])
+ fi
+
++ dnl check for libuiomux
++ PKG_CHECK_MODULES(UIOMUX, uiomux >= 1.6.2, HAVE_UIOMUX="yes", [
++ HAVE_UIOMUX="no"
++ ])
++ if test $HAVE_UIOMUX = "yes"; then
++ AC_DEFINE(HAVE_UIOMUX, 1, [Define if we have libuiomux])
++ fi
++
+ dnl check for XOverlay libraries
+ AG_GST_CHECK_XV
+ fi
+diff --git a/sys/v4l2/Makefile.am b/sys/v4l2/Makefile.am
+index a7a99de..c4b55d2 100644
+--- a/sys/v4l2/Makefile.am
++++ b/sys/v4l2/Makefile.am
+@@ -28,6 +28,7 @@ libgstvideo4linux2_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) \
+ $(GST_BASE_CFLAGS) \
+ $(GST_CONTROLLER_CFLAGS) \
+ $(GST_CFLAGS) \
++ $(UIOMUX_CFLAGS) \
+ $(X_CFLAGS) \
+ $(LIBV4L2_CFLAGS) \
+ $(GUDEV_CFLAGS)
+@@ -42,6 +43,7 @@ libgstvideo4linux2_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) \
+ -lgstvideo-$(GST_MAJORMINOR) \
+ -lgstinterfaces-$(GST_MAJORMINOR) \
+ $(GST_LIBS) \
++ $(UIOMUX_LIBS) \
+ $(xv_libs) \
+ $(LIBV4L2_LIBS) \
+ $(GUDEV_LIBS)
+diff --git a/sys/v4l2/gstv4l2bufferpool.c b/sys/v4l2/gstv4l2bufferpool.c
+index b81c6a4..a2800aa 100644
+--- a/sys/v4l2/gstv4l2bufferpool.c
++++ b/sys/v4l2/gstv4l2bufferpool.c
+@@ -108,7 +108,12 @@ gst_v4l2_buffer_finalize (GstV4l2Buffer * buffer)
+ "buffer %p (data %p, len %u) not recovered, unmapping",
+ buffer, GST_BUFFER_DATA (buffer), buffer->vbuffer.length);
+ gst_mini_object_unref (GST_MINI_OBJECT (pool));
++#if defined(HAVE_UIOMUX)
++ uiomux_free (pool->uiomux, pool->uiores, (void *) GST_BUFFER_DATA (buffer),
++ buffer->vbuffer.length);
++#else
+ v4l2_munmap ((void *) GST_BUFFER_DATA (buffer), buffer->vbuffer.length);
++#endif
+
+ GST_MINI_OBJECT_CLASS (v4l2buffer_parent_class)->finalize (GST_MINI_OBJECT
+ (buffer));
+@@ -166,7 +171,11 @@ gst_v4l2_buffer_new (GstV4l2BufferPool * pool, guint index, GstCaps * caps)
+
+ ret->vbuffer.index = index;
+ ret->vbuffer.type = pool->type;
++#if defined(HAVE_UIOMUX)
++ ret->vbuffer.memory = V4L2_MEMORY_USERPTR;
++#else
+ ret->vbuffer.memory = V4L2_MEMORY_MMAP;
++#endif
+
+ if (v4l2_ioctl (pool->video_fd, VIDIOC_QUERYBUF, &ret->vbuffer) < 0)
+ goto querybuf_failed;
+@@ -183,12 +192,21 @@ gst_v4l2_buffer_new (GstV4l2BufferPool * pool, guint index, GstCaps * caps)
+ GST_LOG_OBJECT (pool->v4l2elem, " length: %u", ret->vbuffer.length);
+ GST_LOG_OBJECT (pool->v4l2elem, " input: %u", ret->vbuffer.input);
+
++#if defined(HAVE_UIOMUX)
++ data = uiomux_malloc (pool->uiomux, pool->uiores, ret->vbuffer.length, 32);
++ if (data == NULL)
++ goto malloc_failed;
++
++ memset (data, 0, ret->vbuffer.length);
++ ret->vbuffer.m.userptr = (unsigned long) data;
++#else
+ data = (guint8 *) v4l2_mmap (0, ret->vbuffer.length,
+ PROT_READ | PROT_WRITE, MAP_SHARED, pool->video_fd,
+ ret->vbuffer.m.offset);
+
+ if (data == MAP_FAILED)
+ goto mmap_failed;
++#endif
+
+ GST_BUFFER_DATA (ret) = data;
+ GST_BUFFER_SIZE (ret) = ret->vbuffer.length;
+@@ -209,6 +227,17 @@ querybuf_failed:
+ errno = errnosave;
+ return NULL;
+ }
++#if defined(HAVE_UIOMUX)
++malloc_failed:
++ {
++ gint errnosave = errno;
++
++ GST_WARNING ("Failed uiomux_malloc: %s", g_strerror (errnosave));
++ gst_buffer_unref (GST_BUFFER (ret));
++ errno = errnosave;
++ return NULL;
++ }
++#else
+ mmap_failed:
+ {
+ gint errnosave = errno;
+@@ -218,6 +247,7 @@ mmap_failed:
+ errno = errnosave;
+ return NULL;
+ }
++#endif /* defined(HAVE_UIOMUX) */
+ }
+
+
+@@ -335,6 +365,9 @@ gst_v4l2_buffer_pool_new (GstElement * v4l2elem, gint fd, gint num_buffers,
+ GstV4l2BufferPool *pool;
+ gint n;
+ struct v4l2_requestbuffers breq;
++#if defined(HAVE_UIOMUX)
++ const char *blocks[2] = { "VIO", NULL };
++#endif
+
+ pool = (GstV4l2BufferPool *) gst_mini_object_new (GST_TYPE_V4L2_BUFFER_POOL);
+
+@@ -342,6 +375,12 @@ gst_v4l2_buffer_pool_new (GstElement * v4l2elem, gint fd, gint num_buffers,
+ if (pool->video_fd < 0)
+ goto dup_failed;
+
++#if defined(HAVE_UIOMUX)
++ pool->uiores = 1 << 0;
++ pool->uiomux = uiomux_open_named (blocks);
++ if (pool->uiomux == NULL)
++ goto uiomux_failed;
++#endif
+
+ /* first, lets request buffers, and see how many we can get: */
+ GST_DEBUG_OBJECT (v4l2elem, "STREAMING, requesting %d MMAP buffers",
+@@ -350,7 +389,11 @@ gst_v4l2_buffer_pool_new (GstElement * v4l2elem, gint fd, gint num_buffers,
+ memset (&breq, 0, sizeof (struct v4l2_requestbuffers));
+ breq.type = type;
+ breq.count = num_buffers;
++#if defined(HAVE_UIOMUX)
++ breq.memory = V4L2_MEMORY_USERPTR;
++#else
+ breq.memory = V4L2_MEMORY_MMAP;
++#endif
+
+ if (v4l2_ioctl (fd, VIDIOC_REQBUFS, &breq) < 0)
+ goto reqbufs_failed;
+@@ -396,6 +439,14 @@ dup_failed:
+
+ return NULL;
+ }
++#if defined(HAVE_UIOMUX)
++uiomux_failed:
++ {
++ GST_ELEMENT_ERROR (v4l2elem, RESOURCE, READ,
++ (_("Failed uiomux_open")), (NULL));
++ return NULL;
++ }
++#endif /* defined(HAVE_UIOMUX) */
+ reqbufs_failed:
+ {
+ GstV4l2Object *v4l2object = get_v4l2_object (v4l2elem);
+@@ -540,7 +591,11 @@ gst_v4l2_buffer_pool_dqbuf (GstV4l2BufferPool * pool)
+
+ memset (&buffer, 0x00, sizeof (buffer));
+ buffer.type = pool->type;
++#if defined(HAVE_UIOMUX)
++ buffer.memory = V4L2_MEMORY_USERPTR;
++#else
+ buffer.memory = V4L2_MEMORY_MMAP;
++#endif
+
+
+ if (v4l2_ioctl (pool->video_fd, VIDIOC_DQBUF, &buffer) >= 0) {
+diff --git a/sys/v4l2/gstv4l2bufferpool.h b/sys/v4l2/gstv4l2bufferpool.h
+index caad9ac..6fb3067 100644
+--- a/sys/v4l2/gstv4l2bufferpool.h
++++ b/sys/v4l2/gstv4l2bufferpool.h
+@@ -27,6 +27,9 @@
+
+ #include <gst/gst.h>
+ #include "v4l2_calls.h"
++#if defined(HAVE_UIOMUX)
++#include "uiomux/uiomux.h"
++#endif
+
+ GST_DEBUG_CATEGORY_EXTERN (v4l2buffer_debug);
+
+@@ -53,6 +56,11 @@ struct _GstV4l2BufferPool
+ {
+ GstMiniObject parent;
+
++#if defined(HAVE_UIOMUX)
++ UIOMux *uiomux; /* uiomux handle */
++ uiomux_resource_t uiores; /* uiomux resource flag */
++#endif /* defined(HAVE_UIOMUX) */
++
+ 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 */
+diff --git a/sys/v4l2/gstv4l2src.c b/sys/v4l2/gstv4l2src.c
+index f8ae09c..d3f9a3c 100644
+--- a/sys/v4l2/gstv4l2src.c
++++ b/sys/v4l2/gstv4l2src.c
+@@ -63,8 +63,13 @@
+ GST_DEBUG_CATEGORY (v4l2src_debug);
+ #define GST_CAT_DEFAULT v4l2src_debug
+
++#if defined(HAVE_UIOMUX)
++#define PROP_DEF_QUEUE_SIZE 4
++#define PROP_DEF_ALWAYS_COPY FALSE
++#else
+ #define PROP_DEF_QUEUE_SIZE 2
+ #define PROP_DEF_ALWAYS_COPY TRUE
++#endif
+ #define PROP_DEF_DECIMATE 1
+
+ #define DEFAULT_PROP_DEVICE "/dev/video0"
+@@ -96,14 +101,14 @@ gst_v4l2src_iface_supported (GstImplementsInterface * iface, GType iface_type)
+
+ #ifdef HAVE_XVIDEO
+ if (!(iface_type == GST_TYPE_TUNER ||
+- iface_type == GST_TYPE_X_OVERLAY ||
+- iface_type == GST_TYPE_COLOR_BALANCE ||
+- iface_type == GST_TYPE_VIDEO_ORIENTATION))
++ iface_type == GST_TYPE_X_OVERLAY ||
++ iface_type == GST_TYPE_COLOR_BALANCE ||
++ iface_type == GST_TYPE_VIDEO_ORIENTATION))
+ return FALSE;
+ #else
+ if (!(iface_type == GST_TYPE_TUNER ||
+- iface_type == GST_TYPE_COLOR_BALANCE ||
+- iface_type == GST_TYPE_VIDEO_ORIENTATION))
++ iface_type == GST_TYPE_COLOR_BALANCE ||
++ iface_type == GST_TYPE_VIDEO_ORIENTATION))
+ return FALSE;
+ #endif
+
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good/0004-sys-v4l2-gstv4l2-release-corresponding-uiomux-handle.patch b/common/recipes-multimedia/gstreamer/gst-plugins-good/0004-sys-v4l2-gstv4l2-release-corresponding-uiomux-handle.patch
new file mode 100644
index 0000000..c1b06b5
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good/0004-sys-v4l2-gstv4l2-release-corresponding-uiomux-handle.patch
@@ -0,0 +1,31 @@
+From c856d711cc54856dac5410aac6bf35330e5f8394 Mon Sep 17 00:00:00 2001
+From: Katsuya Matsubara <matsu@igel.co.jp>
+Date: Mon, 7 May 2012 10:11:38 +0900
+Subject: [PATCH 04/31] sys/v4l2/gstv4l2: release corresponding uiomux handle
+ whenever a buffer pool destroyed
+
+This change could avoid memory leaks and unnecessary file descriptor
+consumption.
+---
+ sys/v4l2/gstv4l2bufferpool.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/sys/v4l2/gstv4l2bufferpool.c b/sys/v4l2/gstv4l2bufferpool.c
+index a2800aa..90ce3b3 100644
+--- a/sys/v4l2/gstv4l2bufferpool.c
++++ b/sys/v4l2/gstv4l2bufferpool.c
+@@ -513,6 +513,11 @@ gst_v4l2_buffer_pool_destroy (GstV4l2BufferPool * pool)
+ gst_buffer_unref (buf);
+ }
+
++#if defined(HAVE_UIOMUX)
++ if (pool->uiomux)
++ uiomux_close (pool->uiomux);
++#endif
++
+ gst_mini_object_unref (GST_MINI_OBJECT (pool));
+ }
+
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good/0005-videocrop-correct-coding-style-with-gst-indent.patch b/common/recipes-multimedia/gstreamer/gst-plugins-good/0005-videocrop-correct-coding-style-with-gst-indent.patch
new file mode 100644
index 0000000..d512ba6
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good/0005-videocrop-correct-coding-style-with-gst-indent.patch
@@ -0,0 +1,104 @@
+From 1cce809f580828df792e35ae76a7a38685eec377 Mon Sep 17 00:00:00 2001
+From: Kazunori Kobayashi <kkobayas@igel.co.jp>
+Date: Tue, 8 May 2012 17:04:13 +0900
+Subject: [PATCH 05/31] videocrop: correct coding style with gst-indent
+
+---
+ gst/videocrop/gstvideocrop.c | 7 +++----
+ gst/videocrop/gstvideocrop.h | 25 +++++++++++--------------
+ 2 files changed, 14 insertions(+), 18 deletions(-)
+
+diff --git a/gst/videocrop/gstvideocrop.c b/gst/videocrop/gstvideocrop.c
+index 04b6e61..1f09f8d 100644
+--- a/gst/videocrop/gstvideocrop.c
++++ b/gst/videocrop/gstvideocrop.c
+@@ -147,8 +147,7 @@ gst_video_crop_base_init (gpointer g_class)
+ "Crops video into a user-defined region",
+ "Tim-Philipp Müller <tim centricular net>");
+
+- gst_element_class_add_static_pad_template (element_class,
+- &sink_template);
++ gst_element_class_add_static_pad_template (element_class, &sink_template);
+ gst_element_class_add_static_pad_template (element_class, &src_template);
+ }
+
+@@ -639,8 +638,8 @@ gst_video_crop_set_caps (GstBaseTransform * trans, GstCaps * incaps,
+ GST_LOG_OBJECT (crop, "incaps = %" GST_PTR_FORMAT ", outcaps = %"
+ GST_PTR_FORMAT, incaps, outcaps);
+
+- if ((crop->crop_left | crop->crop_right | crop->crop_top | crop->
+- crop_bottom) == 0) {
++ if ((crop->crop_left | crop->crop_right | crop->
++ crop_top | crop->crop_bottom) == 0) {
+ GST_LOG_OBJECT (crop, "we are using passthrough");
+ gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (crop), TRUE);
+ } else {
+diff --git a/gst/videocrop/gstvideocrop.h b/gst/videocrop/gstvideocrop.h
+index 477f21b..f05649d 100644
+--- a/gst/videocrop/gstvideocrop.h
++++ b/gst/videocrop/gstvideocrop.h
+@@ -23,7 +23,6 @@
+ #include <gst/base/gstbasetransform.h>
+
+ G_BEGIN_DECLS
+-
+ #define GST_TYPE_VIDEO_CROP \
+ (gst_video_crop_get_type())
+ #define GST_VIDEO_CROP(obj) \
+@@ -34,27 +33,27 @@ G_BEGIN_DECLS
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VIDEO_CROP))
+ #define GST_IS_VIDEO_CROP_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VIDEO_CROP))
+-
+-typedef enum {
+- VIDEO_CROP_PIXEL_FORMAT_PACKED_SIMPLE = 0, /* RGBx, AYUV */
+- VIDEO_CROP_PIXEL_FORMAT_PACKED_COMPLEX, /* UYVY, YVYU */
+- VIDEO_CROP_PIXEL_FORMAT_PLANAR /* I420, YV12 */
++ typedef enum
++{
++ VIDEO_CROP_PIXEL_FORMAT_PACKED_SIMPLE = 0, /* RGBx, AYUV */
++ VIDEO_CROP_PIXEL_FORMAT_PACKED_COMPLEX, /* UYVY, YVYU */
++ VIDEO_CROP_PIXEL_FORMAT_PLANAR /* I420, YV12 */
+ } VideoCropPixelFormat;
+
+ typedef struct _GstVideoCropImageDetails GstVideoCropImageDetails;
+ struct _GstVideoCropImageDetails
+ {
+- /*< private >*/
+- VideoCropPixelFormat packing;
++ /*< private > */
++ VideoCropPixelFormat packing;
+
+ guint width;
+ guint height;
+ guint size;
+
+ /* for packed RGB and YUV */
+- guint stride;
+- guint bytes_per_pixel;
+- guint8 macro_y_off; /* for YUY2, YVYU, UYVY, Y offset within macropixel in bytes */
++ guint stride;
++ guint bytes_per_pixel;
++ guint8 macro_y_off; /* for YUY2, YVYU, UYVY, Y offset within macropixel in bytes */
+
+ /* for planar YUV */
+ guint y_stride, y_off;
+@@ -69,7 +68,7 @@ struct _GstVideoCrop
+ {
+ GstBaseTransform basetransform;
+
+- /*< private >*/
++ /*< private > */
+ gint crop_left;
+ gint crop_right;
+ gint crop_top;
+@@ -87,6 +86,4 @@ struct _GstVideoCropClass
+ GType gst_video_crop_get_type (void);
+
+ G_END_DECLS
+-
+ #endif /* __GST_VIDEO_CROP_H__ */
+-
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good/0006-videocrop-send-a-query-whether-the-rowstride-capabil.patch b/common/recipes-multimedia/gstreamer/gst-plugins-good/0006-videocrop-send-a-query-whether-the-rowstride-capabil.patch
new file mode 100644
index 0000000..7058544
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good/0006-videocrop-send-a-query-whether-the-rowstride-capabil.patch
@@ -0,0 +1,105 @@
+From 39bb299bd638b78fdf8c4054bcc90f9f915d7ff8 Mon Sep 17 00:00:00 2001
+From: Kazunori Kobayashi <kkobayas@igel.co.jp>
+Date: Thu, 10 May 2012 10:46:20 +0900
+Subject: [PATCH 06/31] videocrop: send a query whether the rowstride
+ capability is supported
+
+This patch sends a query which asks downstream plugins whether
+can handle the rowstride capability.
+gst_video_crop_start() can be invoked when the pad is enabled.
+The query is issued by gst_video_crop_start() once at initialization.
+
+This patch is preliminary for the zero-copy cropping.
+---
+ gst/videocrop/gstvideocrop.c | 38 ++++++++++++++++++++++++++++++++++++++
+ gst/videocrop/gstvideocrop.h | 4 ++++
+ 2 files changed, 42 insertions(+)
+
+diff --git a/gst/videocrop/gstvideocrop.c b/gst/videocrop/gstvideocrop.c
+index 1f09f8d..b0c3a68 100644
+--- a/gst/videocrop/gstvideocrop.c
++++ b/gst/videocrop/gstvideocrop.c
+@@ -136,6 +136,7 @@ static gboolean gst_video_crop_set_caps (GstBaseTransform * trans,
+ GstCaps * in_caps, GstCaps * outcaps);
+ static gboolean gst_video_crop_src_event (GstBaseTransform * trans,
+ GstEvent * event);
++static gboolean gst_video_crop_start (GstBaseTransform * trans);
+
+ static void
+ gst_video_crop_base_init (gpointer g_class)
+@@ -228,6 +229,7 @@ gst_video_crop_class_init (GstVideoCropClass * klass)
+ basetransform_class->set_caps = GST_DEBUG_FUNCPTR (gst_video_crop_set_caps);
+ basetransform_class->get_unit_size =
+ GST_DEBUG_FUNCPTR (gst_video_crop_get_unit_size);
++ basetransform_class->start = GST_DEBUG_FUNCPTR (gst_video_crop_start);
+
+ basetransform_class->passthrough_on_same_caps = FALSE;
+ basetransform_class->src_event = GST_DEBUG_FUNCPTR (gst_video_crop_src_event);
+@@ -240,6 +242,10 @@ gst_video_crop_init (GstVideoCrop * vcrop, GstVideoCropClass * klass)
+ vcrop->crop_left = 0;
+ vcrop->crop_top = 0;
+ vcrop->crop_bottom = 0;
++
++ /* register query type for rowstride */
++ vcrop->query_type_stride = gst_query_type_register ("stride-supported",
++ "whether dealing with rowstride as a capability or not");
+ }
+
+ static gboolean
+@@ -669,6 +675,38 @@ cropping_too_much:
+ }
+ }
+
++static gboolean
++gst_video_crop_query_stride_supported (GstVideoCrop * vcrop)
++{
++ gboolean result = FALSE;
++ GstPad *peer = gst_pad_get_peer (GST_BASE_TRANSFORM (vcrop)->srcpad);
++ GstStructure *structure;
++ GstQuery *query;
++
++ structure = gst_structure_empty_new ("GstQueryStrideSupported");
++ gst_structure_set (structure, "stride-supported", G_TYPE_BOOLEAN, FALSE,
++ NULL);
++
++ query = gst_query_new_application (vcrop->query_type_stride, structure);
++ if (gst_pad_query (peer, query))
++ gst_structure_get_boolean (structure, "stride-supported", &result);
++
++ gst_query_unref (query);
++ gst_object_unref (peer);
++
++ return result;
++}
++
++static gboolean
++gst_video_crop_start (GstBaseTransform * trans)
++{
++ GstVideoCrop *vcrop = GST_VIDEO_CROP (trans);
++
++ vcrop->stride_supported = gst_video_crop_query_stride_supported (vcrop);
++
++ return TRUE;
++}
++
+ static void
+ gst_video_crop_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+diff --git a/gst/videocrop/gstvideocrop.h b/gst/videocrop/gstvideocrop.h
+index f05649d..5cfe03e 100644
+--- a/gst/videocrop/gstvideocrop.h
++++ b/gst/videocrop/gstvideocrop.h
+@@ -76,6 +76,10 @@ struct _GstVideoCrop
+
+ GstVideoCropImageDetails in; /* details of input image */
+ GstVideoCropImageDetails out; /* details of output image */
++
++ /* query for rowstride */
++ GstQueryType query_type_stride;
++ gboolean stride_supported;
+ };
+
+ struct _GstVideoCropClass
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good/0007-videocrop-set-rowstride-capability.patch b/common/recipes-multimedia/gstreamer/gst-plugins-good/0007-videocrop-set-rowstride-capability.patch
new file mode 100644
index 0000000..1eef8de
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good/0007-videocrop-set-rowstride-capability.patch
@@ -0,0 +1,59 @@
+From 0d5b9694fc670d489d02018d1e2d83394f299ad5 Mon Sep 17 00:00:00 2001
+From: Kazunori Kobayashi <kkobayas@igel.co.jp>
+Date: Thu, 10 May 2012 11:20:18 +0900
+Subject: [PATCH 07/31] videocrop: set rowstride capability
+
+This patch sets the rowstride capability if downstream plugins
+can handle it.
+
+This patch is preliminary for the zero-copy cropping.
+---
+ gst/videocrop/gstvideocrop.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+diff --git a/gst/videocrop/gstvideocrop.c b/gst/videocrop/gstvideocrop.c
+index b0c3a68..ae7ddaf 100644
+--- a/gst/videocrop/gstvideocrop.c
++++ b/gst/videocrop/gstvideocrop.c
+@@ -585,22 +585,22 @@ gst_video_crop_transform_caps (GstBaseTransform * trans,
+ other_caps = gst_caps_new_empty ();
+
+ for (i = 0; i < gst_caps_get_size (caps); ++i) {
+- const GValue *v;
++ const GValue *in_width, *in_height;
+ GstStructure *structure, *new_structure;
+ GValue w_val = { 0, }, h_val = {
+ 0,};
+
+ structure = gst_caps_get_structure (caps, i);
+
+- v = gst_structure_get_value (structure, "width");
+- if (!gst_video_crop_transform_dimension_value (v, dx, &w_val)) {
++ in_width = gst_structure_get_value (structure, "width");
++ if (!gst_video_crop_transform_dimension_value (in_width, dx, &w_val)) {
+ GST_WARNING_OBJECT (vcrop, "could not tranform width value with dx=%d"
+ ", caps structure=%" GST_PTR_FORMAT, dx, structure);
+ continue;
+ }
+
+- v = gst_structure_get_value (structure, "height");
+- if (!gst_video_crop_transform_dimension_value (v, dy, &h_val)) {
++ in_height = gst_structure_get_value (structure, "height");
++ if (!gst_video_crop_transform_dimension_value (in_height, dy, &h_val)) {
+ g_value_unset (&w_val);
+ GST_WARNING_OBJECT (vcrop, "could not tranform height value with dy=%d"
+ ", caps structure=%" GST_PTR_FORMAT, dy, structure);
+@@ -610,6 +610,10 @@ gst_video_crop_transform_caps (GstBaseTransform * trans,
+ new_structure = gst_structure_copy (structure);
+ gst_structure_set_value (new_structure, "width", &w_val);
+ gst_structure_set_value (new_structure, "height", &h_val);
++
++ /* set rowstride when creating output caps */
++ if (vcrop->stride_supported && (direction == GST_PAD_SINK))
++ gst_structure_set_value (new_structure, "rowstride", in_width);
+ g_value_unset (&w_val);
+ g_value_unset (&h_val);
+ GST_LOG_OBJECT (vcrop, "transformed structure %2d: %" GST_PTR_FORMAT
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good/0008-videocrop-kick-off-the-zero-copy-cropping.patch b/common/recipes-multimedia/gstreamer/gst-plugins-good/0008-videocrop-kick-off-the-zero-copy-cropping.patch
new file mode 100644
index 0000000..1e4734e
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good/0008-videocrop-kick-off-the-zero-copy-cropping.patch
@@ -0,0 +1,100 @@
+From 78f532d7cc31fc7e2980998af97b1260c45ec5e5 Mon Sep 17 00:00:00 2001
+From: Kazunori Kobayashi <kkobayas@igel.co.jp>
+Date: Thu, 10 May 2012 14:55:22 +0900
+Subject: [PATCH 08/31] videocrop: kick off the zero-copy cropping
+
+This patch enables zero-copy buffer cropping by creating a subbuffer
+from an input buffer.
+
+Instead of creating a new buffer, the subbuffer is specified as an
+offset into the input buffer along with an appropriate buffer size.
+
+The cropping functionality of gst_video_crop_transform() (which uses memory
+copying) is bypassed when a subbuffer is defined.
+---
+ gst/videocrop/gstvideocrop.c | 48 ++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 48 insertions(+)
+
+diff --git a/gst/videocrop/gstvideocrop.c b/gst/videocrop/gstvideocrop.c
+index ae7ddaf..cfd548e 100644
+--- a/gst/videocrop/gstvideocrop.c
++++ b/gst/videocrop/gstvideocrop.c
+@@ -137,6 +137,8 @@ static gboolean gst_video_crop_set_caps (GstBaseTransform * trans,
+ static gboolean gst_video_crop_src_event (GstBaseTransform * trans,
+ GstEvent * event);
+ static gboolean gst_video_crop_start (GstBaseTransform * trans);
++static GstFlowReturn gst_video_crop_prepare_output_buffer (GstBaseTransform *
++ trans, GstBuffer * input, gint size, GstCaps * caps, GstBuffer ** buf);
+
+ static void
+ gst_video_crop_base_init (gpointer g_class)
+@@ -230,6 +232,8 @@ gst_video_crop_class_init (GstVideoCropClass * klass)
+ basetransform_class->get_unit_size =
+ GST_DEBUG_FUNCPTR (gst_video_crop_get_unit_size);
+ basetransform_class->start = GST_DEBUG_FUNCPTR (gst_video_crop_start);
++ basetransform_class->prepare_output_buffer =
++ GST_DEBUG_FUNCPTR (gst_video_crop_prepare_output_buffer);
+
+ basetransform_class->passthrough_on_same_caps = FALSE;
+ basetransform_class->src_event = GST_DEBUG_FUNCPTR (gst_video_crop_src_event);
+@@ -484,6 +488,13 @@ gst_video_crop_transform (GstBaseTransform * trans, GstBuffer * inbuf,
+ {
+ GstVideoCrop *vcrop = GST_VIDEO_CROP (trans);
+
++ if (vcrop->stride_supported &&
++ ((vcrop->in.packing == VIDEO_CROP_PIXEL_FORMAT_PACKED_SIMPLE) ||
++ (vcrop->in.packing == VIDEO_CROP_PIXEL_FORMAT_PACKED_COMPLEX))) {
++ GST_LOG_OBJECT (vcrop, "passthrough because of zero-copy cropping");
++ return GST_FLOW_OK;
++ }
++
+ switch (vcrop->in.packing) {
+ case VIDEO_CROP_PIXEL_FORMAT_PACKED_SIMPLE:
+ gst_video_crop_transform_packed_simple (vcrop, inbuf, outbuf);
+@@ -711,6 +722,43 @@ gst_video_crop_start (GstBaseTransform * trans)
+ return TRUE;
+ }
+
++static GstFlowReturn
++gst_video_crop_prepare_output_buffer (GstBaseTransform * trans,
++ GstBuffer * input, gint size, GstCaps * caps, GstBuffer ** buf)
++{
++ GstVideoCrop *vcrop = GST_VIDEO_CROP (trans);
++ guint sub_offset, sub_size;
++
++ if (!vcrop->stride_supported) {
++ GST_LOG_OBJECT
++ (vcrop,
++ "creating subbuffer isn't needed because downstream plugins don't support rowstride");
++ return GST_FLOW_OK;
++ }
++
++ if (vcrop->in.packing == VIDEO_CROP_PIXEL_FORMAT_PACKED_SIMPLE) {
++ sub_offset = (vcrop->crop_top * vcrop->in.stride) +
++ (vcrop->crop_left * vcrop->in.bytes_per_pixel);
++ } else if (vcrop->in.packing == VIDEO_CROP_PIXEL_FORMAT_PACKED_COMPLEX) {
++ sub_offset = (vcrop->crop_top * vcrop->in.stride) +
++ (ROUND_DOWN_2 (vcrop->crop_left) * vcrop->in.bytes_per_pixel);
++ } else {
++ GST_LOG_OBJECT (vcrop,
++ "can't do zero-copy cropping except for packed format");
++ return GST_FLOW_OK;
++ }
++
++ sub_size = vcrop->out.height * vcrop->out.stride;
++ *buf = gst_buffer_create_sub (input, sub_offset, sub_size);
++ if (*buf == NULL) {
++ GST_ERROR_OBJECT (vcrop, "failed to create subbuffer");
++ return GST_FLOW_ERROR;
++ }
++ gst_buffer_set_caps (*buf, caps);
++
++ return GST_FLOW_OK;
++}
++
+ static void
+ gst_video_crop_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good/0009-avidemux-set-frame-start-code-to-VC-1-advanced-profi.patch b/common/recipes-multimedia/gstreamer/gst-plugins-good/0009-avidemux-set-frame-start-code-to-VC-1-advanced-profi.patch
new file mode 100644
index 0000000..180fac3
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good/0009-avidemux-set-frame-start-code-to-VC-1-advanced-profi.patch
@@ -0,0 +1,90 @@
+From a3dc6aa0c57e1fa00efdf0e68d3a4b8645519b9d Mon Sep 17 00:00:00 2001
+From: Kazunori Kobayashi <kkobayas@igel.co.jp>
+Date: Wed, 18 Jul 2012 19:30:34 +0900
+Subject: [PATCH 09/31] avidemux: set frame start code to VC-1 advanced
+ profile stream
+
+VC-1 advanced profile constrains the bitstream format to pair
+the frame data with the frame start code.
+This patch pulls frame data from previous plugin with extra field
+for containing a start code and inserts the start code before the
+frame data if the stream doesn't has the start code.
+---
+ gst/avi/gstavidemux.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 48 insertions(+), 3 deletions(-)
+
+diff --git a/gst/avi/gstavidemux.c b/gst/avi/gstavidemux.c
+index b6c065f..385aa30 100644
+--- a/gst/avi/gstavidemux.c
++++ b/gst/avi/gstavidemux.c
+@@ -4689,6 +4689,10 @@ gst_avi_demux_loop_data (GstAviDemux * avi)
+ guint64 out_offset, out_offset_end;
+ gboolean keyframe;
+ GstAviIndexEntry *entry;
++ guint8 *data;
++ GstStructure *structure;
++ guint32 fourcc;
++ gboolean need_st_code;
+
+ do {
+ stream_num = gst_avi_demux_find_next (avi, avi->segment.rate);
+@@ -4740,12 +4744,53 @@ gst_avi_demux_loop_data (GstAviDemux * avi)
+ G_GUINT64_FORMAT " (0x%" G_GINT64_MODIFIER "x), kf %d", size,
+ stream_num, offset, offset, keyframe);
+
++ structure = gst_caps_get_structure (GST_PAD_CAPS (stream->pad), 0);
++ if (gst_structure_get_fourcc (structure, "format", &fourcc)) {
++ /* set start code for VC-1 advanced profile if fourcc is 'WVC1' */
++ if (fourcc == GST_MAKE_FOURCC ('W', 'V', 'C', '1'))
++ need_st_code = TRUE;
++ else
++ need_st_code = FALSE;
++ } else
++ need_st_code = FALSE;
++
+ /* FIXME, check large chunks and cut them up */
+
+ /* pull in the data */
+- ret = gst_pad_pull_range (avi->sinkpad, offset, size, &buf);
+- if (ret != GST_FLOW_OK)
+- goto pull_failed;
++ if (need_st_code) {
++ if (offset < 4)
++ /* This branch isn't passed through because offset is definitely
++ more than 4 owing to container's header presented before
++ frame data. */
++ goto pull_failed;
++
++ ret = gst_pad_pull_range (avi->sinkpad, offset - 4, size + 4, &buf);
++ if (ret != GST_FLOW_OK)
++ goto pull_failed;
++
++ data = GST_BUFFER_DATA (buf);
++ /* check if this stream has a start code */
++ if (data[4] == 0x00 && data[5] == 0x00 && data[6] == 0x01 &&
++ data[7] == 0x0d) {
++ GstBuffer *sub_buf;
++
++ sub_buf = gst_buffer_create_sub (buf, 4, size);
++ if (sub_buf == NULL)
++ goto pull_failed;
++
++ gst_buffer_unref (buf);
++ buf = sub_buf;
++ } else {
++ data[0] = 0x00;
++ data[1] = 0x00;
++ data[2] = 0x01;
++ data[3] = 0x0d;
++ }
++ } else {
++ ret = gst_pad_pull_range (avi->sinkpad, offset, size, &buf);
++ if (ret != GST_FLOW_OK)
++ goto pull_failed;
++ }
+
+ /* check for short buffers, this is EOS as well */
+ if (GST_BUFFER_SIZE (buf) < size)
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good/0010-videocrop-add-gst_video_crop_get_image_details_from_.patch b/common/recipes-multimedia/gstreamer/gst-plugins-good/0010-videocrop-add-gst_video_crop_get_image_details_from_.patch
new file mode 100644
index 0000000..5d64ac8
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good/0010-videocrop-add-gst_video_crop_get_image_details_from_.patch
@@ -0,0 +1,55 @@
+From 9f24d6c70d56c454a06b6fe41116d046dcc3c9f6 Mon Sep 17 00:00:00 2001
+From: Kazunori Kobayashi <kkobayas@igel.co.jp>
+Date: Tue, 25 Sep 2012 15:51:24 +0900
+Subject: [PATCH 10/31] videocrop: add
+ gst_video_crop_get_image_details_from_structure
+ function
+
+Add an function to allow retrieval of image details from structures instead of
+only from caps.
+---
+ gst/videocrop/gstvideocrop.c | 18 ++++++++++++++----
+ 1 file changed, 14 insertions(+), 4 deletions(-)
+
+diff --git a/gst/videocrop/gstvideocrop.c b/gst/videocrop/gstvideocrop.c
+index cfd548e..80c6d3d 100644
+--- a/gst/videocrop/gstvideocrop.c
++++ b/gst/videocrop/gstvideocrop.c
+@@ -253,13 +253,11 @@ gst_video_crop_init (GstVideoCrop * vcrop, GstVideoCropClass * klass)
+ }
+
+ static gboolean
+-gst_video_crop_get_image_details_from_caps (GstVideoCrop * vcrop,
+- GstVideoCropImageDetails * details, GstCaps * caps)
++gst_video_crop_get_image_details_from_structure (GstVideoCrop * vcrop,
++ GstVideoCropImageDetails * details, GstStructure * structure)
+ {
+- GstStructure *structure;
+ gint width, height;
+
+- structure = gst_caps_get_structure (caps, 0);
+ if (!gst_structure_get_int (structure, "width", &width) ||
+ !gst_structure_get_int (structure, "height", &height)) {
+ goto incomplete_format;
+@@ -356,6 +354,18 @@ incomplete_format:
+ }
+
+ static gboolean
++gst_video_crop_get_image_details_from_caps (GstVideoCrop * vcrop,
++ GstVideoCropImageDetails * details, GstCaps * caps)
++{
++ GstStructure *structure;
++
++ structure = gst_caps_get_structure (caps, 0);
++
++ return gst_video_crop_get_image_details_from_structure (vcrop, details,
++ structure);
++}
++
++static gboolean
+ gst_video_crop_get_unit_size (GstBaseTransform * trans, GstCaps * caps,
+ guint * size)
+ {
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good/0011-videocrop-change-the-unit-of-rowstride-to-byte.patch b/common/recipes-multimedia/gstreamer/gst-plugins-good/0011-videocrop-change-the-unit-of-rowstride-to-byte.patch
new file mode 100644
index 0000000..89c2025
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good/0011-videocrop-change-the-unit-of-rowstride-to-byte.patch
@@ -0,0 +1,36 @@
+From 88b1d76187a840987ef548bd9c3023ebfd97ea5a Mon Sep 17 00:00:00 2001
+From: Kazunori Kobayashi <kkobayas@igel.co.jp>
+Date: Wed, 26 Sep 2012 10:34:31 +0900
+Subject: [PATCH 11/31] videocrop: change the unit of rowstride to byte
+
+Set rowstride units to bytes in order to align with other plugins.
+---
+ gst/videocrop/gstvideocrop.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/gst/videocrop/gstvideocrop.c b/gst/videocrop/gstvideocrop.c
+index 80c6d3d..6af348a 100644
+--- a/gst/videocrop/gstvideocrop.c
++++ b/gst/videocrop/gstvideocrop.c
+@@ -633,8 +633,16 @@ gst_video_crop_transform_caps (GstBaseTransform * trans,
+ gst_structure_set_value (new_structure, "height", &h_val);
+
+ /* set rowstride when creating output caps */
+- if (vcrop->stride_supported && (direction == GST_PAD_SINK))
+- gst_structure_set_value (new_structure, "rowstride", in_width);
++ if (vcrop->stride_supported && (direction == GST_PAD_SINK)) {
++ GstVideoCropImageDetails img_details = { 0, };
++ GValue stride = { 0, };
++
++ gst_video_crop_get_image_details_from_structure (vcrop, &img_details,
++ structure);
++ g_value_init (&stride, G_TYPE_INT);
++ g_value_set_int (&stride, (gint) img_details.stride);
++ gst_structure_set_value (new_structure, "rowstride", &stride);
++ }
+ g_value_unset (&w_val);
+ g_value_unset (&h_val);
+ GST_LOG_OBJECT (vcrop, "transformed structure %2d: %" GST_PTR_FORMAT
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good/0012-videocrop-add-tests-to-determine-if-width-and-height.patch b/common/recipes-multimedia/gstreamer/gst-plugins-good/0012-videocrop-add-tests-to-determine-if-width-and-height.patch
new file mode 100644
index 0000000..5712fdf
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good/0012-videocrop-add-tests-to-determine-if-width-and-height.patch
@@ -0,0 +1,39 @@
+From 93c3d86c39fceb5a9dd6b390627da5090ee171dd Mon Sep 17 00:00:00 2001
+From: Kazunori Kobayashi <kkobayas@igel.co.jp>
+Date: Thu, 4 Oct 2012 10:33:03 +0900
+Subject: [PATCH 12/31] videocrop: add tests to determine if width and height
+ caps hold range value before getting image details
+
+This check is necessary because gst_video_crop_get_image_details_from_structure()
+can't be performed when caps contain range value.
+---
+ gst/videocrop/gstvideocrop.c | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+diff --git a/gst/videocrop/gstvideocrop.c b/gst/videocrop/gstvideocrop.c
+index 6af348a..059b11a 100644
+--- a/gst/videocrop/gstvideocrop.c
++++ b/gst/videocrop/gstvideocrop.c
+@@ -637,11 +637,14 @@ gst_video_crop_transform_caps (GstBaseTransform * trans,
+ GstVideoCropImageDetails img_details = { 0, };
+ GValue stride = { 0, };
+
+- gst_video_crop_get_image_details_from_structure (vcrop, &img_details,
+- structure);
+- g_value_init (&stride, G_TYPE_INT);
+- g_value_set_int (&stride, (gint) img_details.stride);
+- gst_structure_set_value (new_structure, "rowstride", &stride);
++ if (!GST_VALUE_HOLDS_INT_RANGE (&w_val) &&
++ !GST_VALUE_HOLDS_INT_RANGE (&h_val) &&
++ gst_video_crop_get_image_details_from_structure (vcrop, &img_details,
++ structure)) {
++ g_value_init (&stride, G_TYPE_INT);
++ g_value_set_int (&stride, (gint) img_details.stride);
++ gst_structure_set_value (new_structure, "rowstride", &stride);
++ }
+ }
+ g_value_unset (&w_val);
+ g_value_unset (&h_val);
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good/0013-videocrop-replace-the-processing-to-set-gint-value-t.patch b/common/recipes-multimedia/gstreamer/gst-plugins-good/0013-videocrop-replace-the-processing-to-set-gint-value-t.patch
new file mode 100644
index 0000000..bb0121b
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good/0013-videocrop-replace-the-processing-to-set-gint-value-t.patch
@@ -0,0 +1,35 @@
+From 5cb7845d61eadad90c1a0a2bc5078ec4c4b3dc98 Mon Sep 17 00:00:00 2001
+From: Kazunori Kobayashi <kkobayas@igel.co.jp>
+Date: Thu, 4 Oct 2012 10:57:10 +0900
+Subject: [PATCH 13/31] videocrop: replace the processing to set gint value to
+ structure with gst_structure_set
+
+---
+ gst/videocrop/gstvideocrop.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/gst/videocrop/gstvideocrop.c b/gst/videocrop/gstvideocrop.c
+index 059b11a..9c5df28 100644
+--- a/gst/videocrop/gstvideocrop.c
++++ b/gst/videocrop/gstvideocrop.c
+@@ -635,15 +635,13 @@ gst_video_crop_transform_caps (GstBaseTransform * trans,
+ /* set rowstride when creating output caps */
+ if (vcrop->stride_supported && (direction == GST_PAD_SINK)) {
+ GstVideoCropImageDetails img_details = { 0, };
+- GValue stride = { 0, };
+
+ if (!GST_VALUE_HOLDS_INT_RANGE (&w_val) &&
+ !GST_VALUE_HOLDS_INT_RANGE (&h_val) &&
+ gst_video_crop_get_image_details_from_structure (vcrop, &img_details,
+ structure)) {
+- g_value_init (&stride, G_TYPE_INT);
+- g_value_set_int (&stride, (gint) img_details.stride);
+- gst_structure_set_value (new_structure, "rowstride", &stride);
++ gst_structure_set (new_structure, "rowstride", G_TYPE_INT,
++ (gint) img_details.stride, NULL);
+ }
+ }
+ g_value_unset (&w_val);
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good/0014-videocrop-don-t-set-rowstride-only-when-the-color-sp.patch b/common/recipes-multimedia/gstreamer/gst-plugins-good/0014-videocrop-don-t-set-rowstride-only-when-the-color-sp.patch
new file mode 100644
index 0000000..3ae31e1
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good/0014-videocrop-don-t-set-rowstride-only-when-the-color-sp.patch
@@ -0,0 +1,66 @@
+From 61154856964b78b3c601e687d6f081e666f94958 Mon Sep 17 00:00:00 2001
+From: Kazunori Kobayashi <kkobayas@igel.co.jp>
+Date: Thu, 4 Oct 2012 11:08:56 +0900
+Subject: [PATCH 14/31] videocrop: don't set rowstride only when the color
+ space is the planar
+
+videocrop wouldn't support zero-copy cropping in the planar format.
+Therefore, rowstride shouldn't set only when the color space is the planar.
+---
+ gst/videocrop/gstvideocrop.c | 30 ++++++++++++++++++++++--------
+ 1 file changed, 22 insertions(+), 8 deletions(-)
+
+diff --git a/gst/videocrop/gstvideocrop.c b/gst/videocrop/gstvideocrop.c
+index 9c5df28..f2d2949 100644
+--- a/gst/videocrop/gstvideocrop.c
++++ b/gst/videocrop/gstvideocrop.c
+@@ -610,6 +610,8 @@ gst_video_crop_transform_caps (GstBaseTransform * trans,
+ GstStructure *structure, *new_structure;
+ GValue w_val = { 0, }, h_val = {
+ 0,};
++ GstVideoCropImageDetails img_details = { 0, };
++ guint rowstride;
+
+ structure = gst_caps_get_structure (caps, i);
+
+@@ -633,17 +635,29 @@ gst_video_crop_transform_caps (GstBaseTransform * trans,
+ gst_structure_set_value (new_structure, "height", &h_val);
+
+ /* set rowstride when creating output caps */
+- if (vcrop->stride_supported && (direction == GST_PAD_SINK)) {
+- GstVideoCropImageDetails img_details = { 0, };
+-
+- if (!GST_VALUE_HOLDS_INT_RANGE (&w_val) &&
+- !GST_VALUE_HOLDS_INT_RANGE (&h_val) &&
+- gst_video_crop_get_image_details_from_structure (vcrop, &img_details,
++ if (!GST_VALUE_HOLDS_INT_RANGE (&w_val) &&
++ !GST_VALUE_HOLDS_INT_RANGE (&h_val)) {
++ if (!gst_video_crop_get_image_details_from_structure (vcrop, &img_details,
+ structure)) {
+- gst_structure_set (new_structure, "rowstride", G_TYPE_INT,
+- (gint) img_details.stride, NULL);
++ GST_ERROR_OBJECT (vcrop, "couldn't get image details from structure");
++ goto add_structure;
+ }
++ } else {
++ GST_LOG_OBJECT (vcrop, "go through setting rowstride");
++ goto add_structure;
+ }
++
++ if (img_details.packing == VIDEO_CROP_PIXEL_FORMAT_PACKED_SIMPLE ||
++ img_details.packing == VIDEO_CROP_PIXEL_FORMAT_PACKED_COMPLEX)
++ rowstride = img_details.stride;
++ else
++ rowstride = 0;
++
++ if (vcrop->stride_supported && (direction == GST_PAD_SINK) && rowstride)
++ gst_structure_set (new_structure, "rowstride", G_TYPE_INT,
++ (gint) rowstride, NULL);
++
++ add_structure:
+ g_value_unset (&w_val);
+ g_value_unset (&h_val);
+ GST_LOG_OBJECT (vcrop, "transformed structure %2d: %" GST_PTR_FORMAT
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good/0015-videocrop-fix-wrong-subbuffer-size.patch b/common/recipes-multimedia/gstreamer/gst-plugins-good/0015-videocrop-fix-wrong-subbuffer-size.patch
new file mode 100644
index 0000000..0682416
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good/0015-videocrop-fix-wrong-subbuffer-size.patch
@@ -0,0 +1,27 @@
+From 2b7594421cbde82ee1e67e625514321f9517ea76 Mon Sep 17 00:00:00 2001
+From: Kazunori Kobayashi <kkobayas@igel.co.jp>
+Date: Thu, 4 Oct 2012 12:02:54 +0900
+Subject: [PATCH 15/31] videocrop: fix wrong subbuffer size
+
+It wasn't just subbuffer size but in a unit of stride.
+This patch corrects it.
+---
+ gst/videocrop/gstvideocrop.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/gst/videocrop/gstvideocrop.c b/gst/videocrop/gstvideocrop.c
+index f2d2949..0743719 100644
+--- a/gst/videocrop/gstvideocrop.c
++++ b/gst/videocrop/gstvideocrop.c
+@@ -781,7 +781,7 @@ gst_video_crop_prepare_output_buffer (GstBaseTransform * trans,
+ return GST_FLOW_OK;
+ }
+
+- sub_size = vcrop->out.height * vcrop->out.stride;
++ sub_size = vcrop->in.size - sub_offset;
+ *buf = gst_buffer_create_sub (input, sub_offset, sub_size);
+ if (*buf == NULL) {
+ GST_ERROR_OBJECT (vcrop, "failed to create subbuffer");
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good/0016-videocrop-support-getting-NV12-image-details.patch b/common/recipes-multimedia/gstreamer/gst-plugins-good/0016-videocrop-support-getting-NV12-image-details.patch
new file mode 100644
index 0000000..e5a1bed
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good/0016-videocrop-support-getting-NV12-image-details.patch
@@ -0,0 +1,84 @@
+From 47cf0121df5c54d665ccbf9a721cddf547fbbce3 Mon Sep 17 00:00:00 2001
+From: Kazunori Kobayashi <kkobayas@igel.co.jp>
+Date: Thu, 4 Oct 2012 11:29:44 +0900
+Subject: [PATCH 16/31] videocrop: support getting NV12 image details
+
+This patch adds a new pixel format definition that is NV12 format.
+The color format type of NV12 is classified into VIDEO_CROP_PIXEL_FORMAT_SEMI_PLANAR.
+When rowstride or chroma_byte_offset is contained in caps, image
+details reflects these value.
+
+This is preliminary for NV12 zero-copy cropping.
+---
+ gst/videocrop/gstvideocrop.c | 21 +++++++++++++++++++++
+ gst/videocrop/gstvideocrop.h | 8 ++++++--
+ 2 files changed, 27 insertions(+), 2 deletions(-)
+
+diff --git a/gst/videocrop/gstvideocrop.c b/gst/videocrop/gstvideocrop.c
+index 0743719..b6336da 100644
+--- a/gst/videocrop/gstvideocrop.c
++++ b/gst/videocrop/gstvideocrop.c
+@@ -328,6 +328,27 @@ gst_video_crop_get_image_details_from_structure (GstVideoCrop * vcrop,
+ details->v_stride * (GST_ROUND_UP_2 (height) / 2);
+ break;
+ }
++ case GST_MAKE_FOURCC ('N', 'V', '1', '2'):
++ {
++ gint stride, chroma_byte_offset;
++
++ details->packing = VIDEO_CROP_PIXEL_FORMAT_SEMI_PLANAR;
++
++ if (gst_structure_get_int (structure, "rowstride", &stride))
++ details->stride = stride;
++ else
++ details->stride = GST_ROUND_UP_2 (width);
++
++ details->y_off = 0;
++ if (gst_structure_get_int (structure, "chroma_byte_offset",
++ &chroma_byte_offset))
++ details->uv_off = chroma_byte_offset;
++ else
++ details->uv_off = details->stride * GST_ROUND_UP_2 (height);
++
++ details->size = details->uv_off * 3 / 2;
++ }
++ break;
+ default:
+ goto unknown_format;
+ }
+diff --git a/gst/videocrop/gstvideocrop.h b/gst/videocrop/gstvideocrop.h
+index 5cfe03e..2e5d5e6 100644
+--- a/gst/videocrop/gstvideocrop.h
++++ b/gst/videocrop/gstvideocrop.h
+@@ -37,7 +37,8 @@ G_BEGIN_DECLS
+ {
+ VIDEO_CROP_PIXEL_FORMAT_PACKED_SIMPLE = 0, /* RGBx, AYUV */
+ VIDEO_CROP_PIXEL_FORMAT_PACKED_COMPLEX, /* UYVY, YVYU */
+- VIDEO_CROP_PIXEL_FORMAT_PLANAR /* I420, YV12 */
++ VIDEO_CROP_PIXEL_FORMAT_PLANAR, /* I420, YV12 */
++ VIDEO_CROP_PIXEL_FORMAT_SEMI_PLANAR /* NV12 */
+ } VideoCropPixelFormat;
+
+ typedef struct _GstVideoCropImageDetails GstVideoCropImageDetails;
+@@ -51,7 +52,7 @@ struct _GstVideoCropImageDetails
+ guint size;
+
+ /* for packed RGB and YUV */
+- guint stride;
++ guint stride; /* common use in semi-planar */
+ guint bytes_per_pixel;
+ guint8 macro_y_off; /* for YUY2, YVYU, UYVY, Y offset within macropixel in bytes */
+
+@@ -59,6 +60,9 @@ struct _GstVideoCropImageDetails
+ guint y_stride, y_off;
+ guint u_stride, u_off;
+ guint v_stride, v_off;
++
++ /* for semi-planar YUV */
++ guint uv_off;
+ };
+
+ typedef struct _GstVideoCrop GstVideoCrop;
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good/0017-videocrop-add-NV12-format-caps-template.patch b/common/recipes-multimedia/gstreamer/gst-plugins-good/0017-videocrop-add-NV12-format-caps-template.patch
new file mode 100644
index 0000000..11bf99e
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good/0017-videocrop-add-NV12-format-caps-template.patch
@@ -0,0 +1,25 @@
+From d2d5af3b3912ff588c613803f366984eca82c53f Mon Sep 17 00:00:00 2001
+From: Kazunori Kobayashi <kkobayas@igel.co.jp>
+Date: Thu, 4 Oct 2012 12:11:38 +0900
+Subject: [PATCH 17/31] videocrop: add NV12 format caps template
+
+This is preliminary for NV12 zero-copy cropping.
+---
+ gst/videocrop/gstvideocrop.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/gst/videocrop/gstvideocrop.c b/gst/videocrop/gstvideocrop.c
+index b6336da..df02302 100644
+--- a/gst/videocrop/gstvideocrop.c
++++ b/gst/videocrop/gstvideocrop.c
+@@ -102,6 +102,7 @@ enum
+ GST_VIDEO_CAPS_YUV ("Y800") ";" \
+ GST_VIDEO_CAPS_YUV ("I420") ";" \
+ GST_VIDEO_CAPS_YUV ("YV12") ";" \
++ GST_VIDEO_CAPS_YUV ("NV12") ";" \
+ GST_VIDEO_CAPS_RGB_16 ";" \
+ GST_VIDEO_CAPS_RGB_15 ";" \
+ GST_VIDEO_CAPS_GRAY
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good/0018-videocrop-kick-off-NV12-zero-copy-cropping.patch b/common/recipes-multimedia/gstreamer/gst-plugins-good/0018-videocrop-kick-off-NV12-zero-copy-cropping.patch
new file mode 100644
index 0000000..4e391db
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good/0018-videocrop-kick-off-NV12-zero-copy-cropping.patch
@@ -0,0 +1,105 @@
+From 795110fd2b53f1197e94c61078153b3433a1d296 Mon Sep 17 00:00:00 2001
+From: Kazunori Kobayashi <kkobayas@igel.co.jp>
+Date: Thu, 4 Oct 2012 13:45:06 +0900
+Subject: [PATCH 18/31] videocrop: kick off NV12 zero-copy cropping
+
+This patch allows videocrop plugin to do zero-copy cropping by
+adjusting the buffer offsets that are rowstride and chroma_byte_offset.
+First of all, the function of cropping with memcpy is passed through
+when the semi planar is set. Then, chroma_byte_offset is adjusted
+to compensate for the extra offset due to creating the subbuffer,
+which is caused by offsetting the buffer address based on Y plane.
+---
+ gst/videocrop/gstvideocrop.c | 37 ++++++++++++++++++++++++++++++++-----
+ 1 file changed, 32 insertions(+), 5 deletions(-)
+
+diff --git a/gst/videocrop/gstvideocrop.c b/gst/videocrop/gstvideocrop.c
+index df02302..6b1da8a 100644
+--- a/gst/videocrop/gstvideocrop.c
++++ b/gst/videocrop/gstvideocrop.c
+@@ -522,7 +522,8 @@ gst_video_crop_transform (GstBaseTransform * trans, GstBuffer * inbuf,
+
+ if (vcrop->stride_supported &&
+ ((vcrop->in.packing == VIDEO_CROP_PIXEL_FORMAT_PACKED_SIMPLE) ||
+- (vcrop->in.packing == VIDEO_CROP_PIXEL_FORMAT_PACKED_COMPLEX))) {
++ (vcrop->in.packing == VIDEO_CROP_PIXEL_FORMAT_PACKED_COMPLEX) ||
++ (vcrop->in.packing == VIDEO_CROP_PIXEL_FORMAT_SEMI_PLANAR))) {
+ GST_LOG_OBJECT (vcrop, "passthrough because of zero-copy cropping");
+ return GST_FLOW_OK;
+ }
+@@ -634,6 +635,7 @@ gst_video_crop_transform_caps (GstBaseTransform * trans,
+ 0,};
+ GstVideoCropImageDetails img_details = { 0, };
+ guint rowstride;
++ gint chroma_byte_offset, delta_chroma_offs;
+
+ structure = gst_caps_get_structure (caps, i);
+
+@@ -656,7 +658,7 @@ gst_video_crop_transform_caps (GstBaseTransform * trans,
+ gst_structure_set_value (new_structure, "width", &w_val);
+ gst_structure_set_value (new_structure, "height", &h_val);
+
+- /* set rowstride when creating output caps */
++ /* set rowstride and adjust chroma_byte_offset when creating output caps */
+ if (!GST_VALUE_HOLDS_INT_RANGE (&w_val) &&
+ !GST_VALUE_HOLDS_INT_RANGE (&h_val)) {
+ if (!gst_video_crop_get_image_details_from_structure (vcrop, &img_details,
+@@ -665,20 +667,42 @@ gst_video_crop_transform_caps (GstBaseTransform * trans,
+ goto add_structure;
+ }
+ } else {
+- GST_LOG_OBJECT (vcrop, "go through setting rowstride");
++ GST_LOG_OBJECT (vcrop,
++ "go through setting rowstride and adjusting chroma_byte_offset");
+ goto add_structure;
+ }
+
+ if (img_details.packing == VIDEO_CROP_PIXEL_FORMAT_PACKED_SIMPLE ||
+- img_details.packing == VIDEO_CROP_PIXEL_FORMAT_PACKED_COMPLEX)
++ img_details.packing == VIDEO_CROP_PIXEL_FORMAT_PACKED_COMPLEX) {
+ rowstride = img_details.stride;
+- else
++ delta_chroma_offs = 0;
++ } else if (img_details.packing == VIDEO_CROP_PIXEL_FORMAT_SEMI_PLANAR) {
++ guint ratio_y_c;
++
++ rowstride = img_details.stride;
++ /* Y plane / UV plane */
++ ratio_y_c = img_details.uv_off / (img_details.size - img_details.uv_off);
++ delta_chroma_offs = rowstride * vcrop->crop_top / ratio_y_c;
++ } else {
+ rowstride = 0;
++ delta_chroma_offs = 0;
++ }
+
+ if (vcrop->stride_supported && (direction == GST_PAD_SINK) && rowstride)
+ gst_structure_set (new_structure, "rowstride", G_TYPE_INT,
+ (gint) rowstride, NULL);
+
++ if (vcrop->stride_supported &&
++ gst_structure_get_int (structure, "chroma_byte_offset",
++ &chroma_byte_offset) && delta_chroma_offs) {
++ /* Adjust chroma_byte_offset because it would exceed the proper value
++ by delta_chroma_offs. It is due to offsetting the buffer address that
++ indicates Y plane with subbuffer for zero-copy cropping. */
++ chroma_byte_offset -= delta_chroma_offs;
++ gst_structure_set (new_structure, "chroma_byte_offset", G_TYPE_INT,
++ chroma_byte_offset, NULL);
++ }
++
+ add_structure:
+ g_value_unset (&w_val);
+ g_value_unset (&h_val);
+@@ -797,6 +821,9 @@ gst_video_crop_prepare_output_buffer (GstBaseTransform * trans,
+ } else if (vcrop->in.packing == VIDEO_CROP_PIXEL_FORMAT_PACKED_COMPLEX) {
+ sub_offset = (vcrop->crop_top * vcrop->in.stride) +
+ (ROUND_DOWN_2 (vcrop->crop_left) * vcrop->in.bytes_per_pixel);
++ } else if (vcrop->in.packing == VIDEO_CROP_PIXEL_FORMAT_SEMI_PLANAR) {
++ sub_offset = (vcrop->crop_top * vcrop->in.stride) +
++ ROUND_DOWN_2 (vcrop->crop_left);
+ } else {
+ GST_LOG_OBJECT (vcrop,
+ "can't do zero-copy cropping except for packed format");
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good/0019-videocrop-send-a-query-by-the-first-invorker-of-quer.patch b/common/recipes-multimedia/gstreamer/gst-plugins-good/0019-videocrop-send-a-query-by-the-first-invorker-of-quer.patch
new file mode 100644
index 0000000..217ebd0
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good/0019-videocrop-send-a-query-by-the-first-invorker-of-quer.patch
@@ -0,0 +1,123 @@
+From 554ffc759f9a87c4eac81fab91a2ac29e296c33c Mon Sep 17 00:00:00 2001
+From: Kazunori Kobayashi <kkobayas@igel.co.jp>
+Date: Thu, 4 Oct 2012 17:22:01 +0900
+Subject: [PATCH 19/31] videocrop: send a query by the first invorker of
+ query_stride_supported
+
+The query_stride_supported() might be failed because start() method
+can be called before the pipeline is constructed. To resolve this issue,
+this patch has the first invoker of query_stride_supported() send
+the query to downstream plugins. The result of query is cached
+at the first invoking.
+---
+ gst/videocrop/gstvideocrop.c | 30 +++++++++++++-----------------
+ gst/videocrop/gstvideocrop.h | 1 -
+ 2 files changed, 13 insertions(+), 18 deletions(-)
+
+diff --git a/gst/videocrop/gstvideocrop.c b/gst/videocrop/gstvideocrop.c
+index 6b1da8a..da30c1b 100644
+--- a/gst/videocrop/gstvideocrop.c
++++ b/gst/videocrop/gstvideocrop.c
+@@ -137,9 +137,9 @@ static gboolean gst_video_crop_set_caps (GstBaseTransform * trans,
+ GstCaps * in_caps, GstCaps * outcaps);
+ static gboolean gst_video_crop_src_event (GstBaseTransform * trans,
+ GstEvent * event);
+-static gboolean gst_video_crop_start (GstBaseTransform * trans);
+ static GstFlowReturn gst_video_crop_prepare_output_buffer (GstBaseTransform *
+ trans, GstBuffer * input, gint size, GstCaps * caps, GstBuffer ** buf);
++static gboolean gst_video_crop_query_stride_supported (GstVideoCrop * vcrop);
+
+ static void
+ gst_video_crop_base_init (gpointer g_class)
+@@ -232,7 +232,6 @@ gst_video_crop_class_init (GstVideoCropClass * klass)
+ basetransform_class->set_caps = GST_DEBUG_FUNCPTR (gst_video_crop_set_caps);
+ basetransform_class->get_unit_size =
+ GST_DEBUG_FUNCPTR (gst_video_crop_get_unit_size);
+- basetransform_class->start = GST_DEBUG_FUNCPTR (gst_video_crop_start);
+ basetransform_class->prepare_output_buffer =
+ GST_DEBUG_FUNCPTR (gst_video_crop_prepare_output_buffer);
+
+@@ -520,7 +519,7 @@ gst_video_crop_transform (GstBaseTransform * trans, GstBuffer * inbuf,
+ {
+ GstVideoCrop *vcrop = GST_VIDEO_CROP (trans);
+
+- if (vcrop->stride_supported &&
++ if (gst_video_crop_query_stride_supported (vcrop) &&
+ ((vcrop->in.packing == VIDEO_CROP_PIXEL_FORMAT_PACKED_SIMPLE) ||
+ (vcrop->in.packing == VIDEO_CROP_PIXEL_FORMAT_PACKED_COMPLEX) ||
+ (vcrop->in.packing == VIDEO_CROP_PIXEL_FORMAT_SEMI_PLANAR))) {
+@@ -688,11 +687,12 @@ gst_video_crop_transform_caps (GstBaseTransform * trans,
+ delta_chroma_offs = 0;
+ }
+
+- if (vcrop->stride_supported && (direction == GST_PAD_SINK) && rowstride)
++ if (gst_video_crop_query_stride_supported (vcrop) &&
++ (direction == GST_PAD_SINK) && rowstride)
+ gst_structure_set (new_structure, "rowstride", G_TYPE_INT,
+ (gint) rowstride, NULL);
+
+- if (vcrop->stride_supported &&
++ if (gst_video_crop_query_stride_supported (vcrop) &&
+ gst_structure_get_int (structure, "chroma_byte_offset",
+ &chroma_byte_offset) && delta_chroma_offs) {
+ /* Adjust chroma_byte_offset because it would exceed the proper value
+@@ -772,10 +772,14 @@ cropping_too_much:
+ static gboolean
+ gst_video_crop_query_stride_supported (GstVideoCrop * vcrop)
+ {
+- gboolean result = FALSE;
++ static gboolean result = FALSE;
+ GstPad *peer = gst_pad_get_peer (GST_BASE_TRANSFORM (vcrop)->srcpad);
+ GstStructure *structure;
+ GstQuery *query;
++ static gboolean is_query_done = FALSE;
++
++ if (is_query_done)
++ return result;
+
+ structure = gst_structure_empty_new ("GstQueryStrideSupported");
+ gst_structure_set (structure, "stride-supported", G_TYPE_BOOLEAN, FALSE,
+@@ -788,17 +792,9 @@ gst_video_crop_query_stride_supported (GstVideoCrop * vcrop)
+ gst_query_unref (query);
+ gst_object_unref (peer);
+
+- return result;
+-}
+-
+-static gboolean
+-gst_video_crop_start (GstBaseTransform * trans)
+-{
+- GstVideoCrop *vcrop = GST_VIDEO_CROP (trans);
+-
+- vcrop->stride_supported = gst_video_crop_query_stride_supported (vcrop);
++ is_query_done = TRUE;
+
+- return TRUE;
++ return result;
+ }
+
+ static GstFlowReturn
+@@ -808,7 +804,7 @@ gst_video_crop_prepare_output_buffer (GstBaseTransform * trans,
+ GstVideoCrop *vcrop = GST_VIDEO_CROP (trans);
+ guint sub_offset, sub_size;
+
+- if (!vcrop->stride_supported) {
++ if (!gst_video_crop_query_stride_supported (vcrop)) {
+ GST_LOG_OBJECT
+ (vcrop,
+ "creating subbuffer isn't needed because downstream plugins don't support rowstride");
+diff --git a/gst/videocrop/gstvideocrop.h b/gst/videocrop/gstvideocrop.h
+index 2e5d5e6..1534b3d 100644
+--- a/gst/videocrop/gstvideocrop.h
++++ b/gst/videocrop/gstvideocrop.h
+@@ -83,7 +83,6 @@ struct _GstVideoCrop
+
+ /* query for rowstride */
+ GstQueryType query_type_stride;
+- gboolean stride_supported;
+ };
+
+ struct _GstVideoCropClass
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good/0020-videocrop-set-tile-boundary-offset-in-caps-for-T-L-a.patch b/common/recipes-multimedia/gstreamer/gst-plugins-good/0020-videocrop-set-tile-boundary-offset-in-caps-for-T-L-a.patch
new file mode 100644
index 0000000..1970394
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good/0020-videocrop-set-tile-boundary-offset-in-caps-for-T-L-a.patch
@@ -0,0 +1,44 @@
+From efde8be8052d31a13629160c55f59e3be661a48c Mon Sep 17 00:00:00 2001
+From: Kazunori Kobayashi <kkobayas@igel.co.jp>
+Date: Fri, 12 Oct 2012 18:33:29 +0900
+Subject: [PATCH 20/31] videocrop: set tile boundary offset in caps for T/L
+ addressing
+
+This change is necessary for cropping the image data that is stored
+as tiles in memory. Thease capabilities notify downstream plugins of
+the offset to the previous tile boundary.
+---
+ gst/videocrop/gstvideocrop.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/gst/videocrop/gstvideocrop.c b/gst/videocrop/gstvideocrop.c
+index da30c1b..dbebcfa 100644
+--- a/gst/videocrop/gstvideocrop.c
++++ b/gst/videocrop/gstvideocrop.c
+@@ -677,11 +677,23 @@ gst_video_crop_transform_caps (GstBaseTransform * trans,
+ delta_chroma_offs = 0;
+ } else if (img_details.packing == VIDEO_CROP_PIXEL_FORMAT_SEMI_PLANAR) {
+ guint ratio_y_c;
++ GstStructure *structure;
++ gint tile_height;
+
+ rowstride = img_details.stride;
+ /* Y plane / UV plane */
+ ratio_y_c = img_details.uv_off / (img_details.size - img_details.uv_off);
+ delta_chroma_offs = rowstride * vcrop->crop_top / ratio_y_c;
++
++ /* set tile boudary for T/L addressing */
++ structure = gst_caps_get_structure (caps, 0);
++ if (gst_structure_get_int (structure, "tile-height", &tile_height)) {
++ gst_structure_set (new_structure, "tile_boundary_y_offset",
++ G_TYPE_INT, vcrop->crop_top % tile_height, NULL);
++
++ gst_structure_set (new_structure, "tile_boundary_c_offset",
++ G_TYPE_INT, vcrop->crop_top / ratio_y_c % tile_height, NULL);
++ }
+ } else {
+ rowstride = 0;
+ delta_chroma_offs = 0;
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good/0021-videocrop-support-cropping-interlaced-images.patch b/common/recipes-multimedia/gstreamer/gst-plugins-good/0021-videocrop-support-cropping-interlaced-images.patch
new file mode 100644
index 0000000..7d66fe4
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good/0021-videocrop-support-cropping-interlaced-images.patch
@@ -0,0 +1,99 @@
+From b2975883315542cc9beead18a6bfe3bf1dab06b7 Mon Sep 17 00:00:00 2001
+From: Kazunori Kobayashi <kkobayas@igel.co.jp>
+Date: Tue, 16 Oct 2012 16:42:17 +0900
+Subject: [PATCH 21/31] videocrop: support cropping interlaced images
+
+This patch supports it by adjusting the subbuffer offset and
+chroma_byte_offset in caps.
+---
+ gst/videocrop/gstvideocrop.c | 43 ++++++++++++++++++++++++++++++++++++------
+ gst/videocrop/gstvideocrop.h | 2 ++
+ 2 files changed, 39 insertions(+), 6 deletions(-)
+
+diff --git a/gst/videocrop/gstvideocrop.c b/gst/videocrop/gstvideocrop.c
+index dbebcfa..4d2a027 100644
+--- a/gst/videocrop/gstvideocrop.c
++++ b/gst/videocrop/gstvideocrop.c
+@@ -679,20 +679,44 @@ gst_video_crop_transform_caps (GstBaseTransform * trans,
+ guint ratio_y_c;
+ GstStructure *structure;
+ gint tile_height;
++ gboolean interlaced;
++ const gchar *layout;
++
++ structure = gst_caps_get_structure (caps, 0);
++ if (gst_structure_get_boolean (structure, "interlaced", &interlaced) &&
++ (interlaced == TRUE) &&
++ ((layout =
++ gst_structure_get_string (structure, "field-layout")) != NULL)
++ && (strcmp (layout, "sequential") == 0))
++ vcrop->interlaced = TRUE;
++ else
++ vcrop->interlaced = FALSE;
+
+ rowstride = img_details.stride;
+ /* Y plane / UV plane */
+ ratio_y_c = img_details.uv_off / (img_details.size - img_details.uv_off);
+- delta_chroma_offs = rowstride * vcrop->crop_top / ratio_y_c;
++ if (vcrop->interlaced)
++ delta_chroma_offs = rowstride * vcrop->crop_top / ratio_y_c / 2;
++ else
++ delta_chroma_offs = rowstride * vcrop->crop_top / ratio_y_c;
+
+ /* set tile boudary for T/L addressing */
+- structure = gst_caps_get_structure (caps, 0);
+ if (gst_structure_get_int (structure, "tile-height", &tile_height)) {
++ gint tile_y_offs, tile_c_offs;
++
++ if (vcrop->interlaced) {
++ tile_y_offs = vcrop->crop_top / 2 % tile_height;
++ tile_c_offs = vcrop->crop_top / ratio_y_c / 2 % tile_height;
++ } else {
++ tile_y_offs = vcrop->crop_top % tile_height;
++ tile_c_offs = vcrop->crop_top / ratio_y_c % tile_height;
++ }
++
+ gst_structure_set (new_structure, "tile_boundary_y_offset",
+- G_TYPE_INT, vcrop->crop_top % tile_height, NULL);
++ G_TYPE_INT, tile_y_offs, NULL);
+
+ gst_structure_set (new_structure, "tile_boundary_c_offset",
+- G_TYPE_INT, vcrop->crop_top / ratio_y_c % tile_height, NULL);
++ G_TYPE_INT, tile_c_offs, NULL);
+ }
+ } else {
+ rowstride = 0;
+@@ -830,8 +854,15 @@ gst_video_crop_prepare_output_buffer (GstBaseTransform * trans,
+ sub_offset = (vcrop->crop_top * vcrop->in.stride) +
+ (ROUND_DOWN_2 (vcrop->crop_left) * vcrop->in.bytes_per_pixel);
+ } else if (vcrop->in.packing == VIDEO_CROP_PIXEL_FORMAT_SEMI_PLANAR) {
+- sub_offset = (vcrop->crop_top * vcrop->in.stride) +
+- ROUND_DOWN_2 (vcrop->crop_left);
++ GstStructure *structure;
++
++ structure = gst_caps_get_structure (caps, 0);
++ if (vcrop->interlaced)
++ sub_offset = (vcrop->crop_top / 2 * vcrop->in.stride) +
++ ROUND_DOWN_2 (vcrop->crop_left);
++ else
++ sub_offset = (vcrop->crop_top * vcrop->in.stride) +
++ ROUND_DOWN_2 (vcrop->crop_left);
+ } else {
+ GST_LOG_OBJECT (vcrop,
+ "can't do zero-copy cropping except for packed format");
+diff --git a/gst/videocrop/gstvideocrop.h b/gst/videocrop/gstvideocrop.h
+index 1534b3d..a72cacb 100644
+--- a/gst/videocrop/gstvideocrop.h
++++ b/gst/videocrop/gstvideocrop.h
+@@ -83,6 +83,8 @@ struct _GstVideoCrop
+
+ /* query for rowstride */
+ GstQueryType query_type_stride;
++
++ gboolean interlaced;
+ };
+
+ struct _GstVideoCropClass
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good/0022-videocrop-move-output-buffer-size-calculation-to-tra.patch b/common/recipes-multimedia/gstreamer/gst-plugins-good/0022-videocrop-move-output-buffer-size-calculation-to-tra.patch
new file mode 100644
index 0000000..1c62e0d
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good/0022-videocrop-move-output-buffer-size-calculation-to-tra.patch
@@ -0,0 +1,178 @@
+From e22281e0458c48f1d38b7a2abf20121378a811f8 Mon Sep 17 00:00:00 2001
+From: Kazunori Kobayashi <kkobayas@igel.co.jp>
+Date: Thu, 18 Oct 2012 18:27:03 +0900
+Subject: [PATCH 22/31] videocrop: move output buffer size calculation to
+ transform_size()
+
+transform_size() is the optional method that can be overridden to
+calculate buffer sizes. The default implementation uses get_unit_size(),
+but when performing zero-copy cropping, transform_size() should be used
+because the buffer size calculation is different from the default.
+The buffer size calculation should be performed using the tranform_size()
+override, rather than being inlined in prepare_output_buffer().
+---
+ gst/videocrop/gstvideocrop.c | 120 +++++++++++++++++++++++++++++++++---------
+ 1 file changed, 95 insertions(+), 25 deletions(-)
+
+diff --git a/gst/videocrop/gstvideocrop.c b/gst/videocrop/gstvideocrop.c
+index 4d2a027..4887137 100644
+--- a/gst/videocrop/gstvideocrop.c
++++ b/gst/videocrop/gstvideocrop.c
+@@ -140,6 +140,9 @@ static gboolean gst_video_crop_src_event (GstBaseTransform * trans,
+ static GstFlowReturn gst_video_crop_prepare_output_buffer (GstBaseTransform *
+ trans, GstBuffer * input, gint size, GstCaps * caps, GstBuffer ** buf);
+ static gboolean gst_video_crop_query_stride_supported (GstVideoCrop * vcrop);
++static gboolean gst_videocrop_transform_size (GstBaseTransform * trans,
++ GstPadDirection direction, GstCaps * caps, guint size, GstCaps * othercaps,
++ guint * othersize);
+
+ static void
+ gst_video_crop_base_init (gpointer g_class)
+@@ -234,6 +237,8 @@ gst_video_crop_class_init (GstVideoCropClass * klass)
+ GST_DEBUG_FUNCPTR (gst_video_crop_get_unit_size);
+ basetransform_class->prepare_output_buffer =
+ GST_DEBUG_FUNCPTR (gst_video_crop_prepare_output_buffer);
++ basetransform_class->transform_size =
++ GST_DEBUG_FUNCPTR (gst_videocrop_transform_size);
+
+ basetransform_class->passthrough_on_same_caps = FALSE;
+ basetransform_class->src_event = GST_DEBUG_FUNCPTR (gst_video_crop_src_event);
+@@ -838,7 +843,6 @@ gst_video_crop_prepare_output_buffer (GstBaseTransform * trans,
+ GstBuffer * input, gint size, GstCaps * caps, GstBuffer ** buf)
+ {
+ GstVideoCrop *vcrop = GST_VIDEO_CROP (trans);
+- guint sub_offset, sub_size;
+
+ if (!gst_video_crop_query_stride_supported (vcrop)) {
+ GST_LOG_OBJECT
+@@ -847,30 +851,7 @@ gst_video_crop_prepare_output_buffer (GstBaseTransform * trans,
+ return GST_FLOW_OK;
+ }
+
+- if (vcrop->in.packing == VIDEO_CROP_PIXEL_FORMAT_PACKED_SIMPLE) {
+- sub_offset = (vcrop->crop_top * vcrop->in.stride) +
+- (vcrop->crop_left * vcrop->in.bytes_per_pixel);
+- } else if (vcrop->in.packing == VIDEO_CROP_PIXEL_FORMAT_PACKED_COMPLEX) {
+- sub_offset = (vcrop->crop_top * vcrop->in.stride) +
+- (ROUND_DOWN_2 (vcrop->crop_left) * vcrop->in.bytes_per_pixel);
+- } else if (vcrop->in.packing == VIDEO_CROP_PIXEL_FORMAT_SEMI_PLANAR) {
+- GstStructure *structure;
+-
+- structure = gst_caps_get_structure (caps, 0);
+- if (vcrop->interlaced)
+- sub_offset = (vcrop->crop_top / 2 * vcrop->in.stride) +
+- ROUND_DOWN_2 (vcrop->crop_left);
+- else
+- sub_offset = (vcrop->crop_top * vcrop->in.stride) +
+- ROUND_DOWN_2 (vcrop->crop_left);
+- } else {
+- GST_LOG_OBJECT (vcrop,
+- "can't do zero-copy cropping except for packed format");
+- return GST_FLOW_OK;
+- }
+-
+- sub_size = vcrop->in.size - sub_offset;
+- *buf = gst_buffer_create_sub (input, sub_offset, sub_size);
++ *buf = gst_buffer_create_sub (input, vcrop->in.size - size, size);
+ if (*buf == NULL) {
+ GST_ERROR_OBJECT (vcrop, "failed to create subbuffer");
+ return GST_FLOW_ERROR;
+@@ -880,6 +861,95 @@ gst_video_crop_prepare_output_buffer (GstBaseTransform * trans,
+ return GST_FLOW_OK;
+ }
+
++static gboolean
++gst_videocrop_transform_size (GstBaseTransform * trans,
++ GstPadDirection direction, GstCaps * caps, guint size, GstCaps * othercaps,
++ guint * othersize)
++{
++ GstVideoCrop *vcrop = GST_VIDEO_CROP (trans);
++ guint inunitsize;
++
++ if (!gst_video_crop_query_stride_supported (vcrop) ||
++ direction == GST_PAD_SRC) {
++ guint outunitsize, units;
++
++ if (!gst_video_crop_get_unit_size (trans, caps, &inunitsize))
++ goto no_in_size;
++
++ GST_DEBUG_OBJECT (vcrop, "input size %d, input unit size %d", size,
++ inunitsize);
++
++ /* input size must be a multiple of the unit_size of the input caps */
++ if (inunitsize == 0 || (size % inunitsize != 0))
++ goto no_multiple;
++
++ /* get the amount of units */
++ units = size / inunitsize;
++
++ /* now get the unit size of the output */
++ if (!gst_video_crop_get_unit_size (trans, othercaps, &outunitsize))
++ goto no_out_size;
++
++ /* the output size is the unit_size times the amount of units on the
++ * input */
++ *othersize = units * outunitsize;
++ } else {
++ guint sub_offset;
++
++ /* Calculate a subbufer size for zero-copy cropping. The subbuffer is
++ created in prepare_output_buffer (). */
++ if (vcrop->in.packing == VIDEO_CROP_PIXEL_FORMAT_PACKED_SIMPLE) {
++ sub_offset = (vcrop->crop_top * vcrop->in.stride) +
++ (vcrop->crop_left * vcrop->in.bytes_per_pixel);
++ } else if (vcrop->in.packing == VIDEO_CROP_PIXEL_FORMAT_PACKED_COMPLEX) {
++ sub_offset = (vcrop->crop_top * vcrop->in.stride) +
++ (ROUND_DOWN_2 (vcrop->crop_left) * vcrop->in.bytes_per_pixel);
++ } else if (vcrop->in.packing == VIDEO_CROP_PIXEL_FORMAT_SEMI_PLANAR) {
++ GstStructure *structure;
++
++ structure = gst_caps_get_structure (caps, 0);
++ if (vcrop->interlaced)
++ sub_offset = (vcrop->crop_top / 2 * vcrop->in.stride) +
++ ROUND_DOWN_2 (vcrop->crop_left);
++ else
++ sub_offset = (vcrop->crop_top * vcrop->in.stride) +
++ ROUND_DOWN_2 (vcrop->crop_left);
++ } else {
++ GST_LOG_OBJECT (vcrop,
++ "can't do zero-copy cropping except for packed format");
++ return FALSE;
++ }
++
++ *othersize = vcrop->in.size - sub_offset;
++ }
++
++ GST_DEBUG_OBJECT (vcrop, "transformed size to %d", *othersize);
++
++ return TRUE;
++
++ /* ERRORS */
++no_in_size:
++ {
++ GST_DEBUG_OBJECT (vcrop, "could not get in_size");
++ g_warning ("%s: could not get in_size", GST_ELEMENT_NAME (trans));
++ return FALSE;
++ }
++no_multiple:
++ {
++ GST_DEBUG_OBJECT (vcrop, "Size %u is not a multiple of unit size %u", size,
++ inunitsize);
++ g_warning ("%s: size %u is not a multiple of unit size %u",
++ GST_ELEMENT_NAME (trans), size, inunitsize);
++ return FALSE;
++ }
++no_out_size:
++ {
++ GST_DEBUG_OBJECT (vcrop, "could not get out_size");
++ g_warning ("%s: could not get out_size", GST_ELEMENT_NAME (trans));
++ return FALSE;
++ }
++}
++
+ static void
+ gst_video_crop_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good/0023-videocrop-skip-the-transforming-caps-process-when-th.patch b/common/recipes-multimedia/gstreamer/gst-plugins-good/0023-videocrop-skip-the-transforming-caps-process-when-th.patch
new file mode 100644
index 0000000..5c33ec6
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good/0023-videocrop-skip-the-transforming-caps-process-when-th.patch
@@ -0,0 +1,32 @@
+From d13fa761751f252c89032248fbf3b363d4f1827c Mon Sep 17 00:00:00 2001
+From: Kazunori Kobayashi <kkobayas@igel.co.jp>
+Date: Thu, 29 Nov 2012 14:06:33 +0900
+Subject: [PATCH 23/31] videocrop: skip the transforming caps process when the
+ passthrough mode is set
+
+When the passthrough mode is set, the basetransform class tries to accommodate
+a difference between input and output caps. This behavior causes
+the reallocation of the output buffers, and discarding the physical buffers
+used for zero-copy processing.
+To avoid this problem, the transforming caps process shouldn't be performed.
+---
+ gst/videocrop/gstvideocrop.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/gst/videocrop/gstvideocrop.c b/gst/videocrop/gstvideocrop.c
+index 4887137..caeb0b1 100644
+--- a/gst/videocrop/gstvideocrop.c
++++ b/gst/videocrop/gstvideocrop.c
+@@ -614,6 +614,9 @@ gst_video_crop_transform_caps (GstBaseTransform * trans,
+
+ vcrop = GST_VIDEO_CROP (trans);
+
++ if (gst_base_transform_is_passthrough (trans))
++ return gst_caps_ref (caps);
++
+ GST_OBJECT_LOCK (vcrop);
+
+ GST_LOG_OBJECT (vcrop, "l=%d,r=%d,b=%d,t=%d",
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good/0024-v4l2src-fix-RGB32-colorspace-deinitions.patch b/common/recipes-multimedia/gstreamer/gst-plugins-good/0024-v4l2src-fix-RGB32-colorspace-deinitions.patch
new file mode 100644
index 0000000..e141df9
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good/0024-v4l2src-fix-RGB32-colorspace-deinitions.patch
@@ -0,0 +1,69 @@
+From e7782d58ed397e0f66cbb62b5c59f3adea8227c4 Mon Sep 17 00:00:00 2001
+From: Kazunori Kobayashi <kkobayas@igel.co.jp>
+Date: Mon, 16 Apr 2012 11:05:07 +0900
+Subject: [PATCH 24/31] v4l2src: fix RGB32 colorspace deinitions
+
+This patch makes RGB32 colorspace definitions used in the caps negotiation
+suitable for actual v4l2 driver's output format.
+---
+ sys/v4l2/gstv4l2object.c | 24 +++++++++++++++---------
+ 1 file changed, 15 insertions(+), 9 deletions(-)
+
+diff --git a/sys/v4l2/gstv4l2object.c b/sys/v4l2/gstv4l2object.c
+index 81d1cb7..0678305 100644
+--- a/sys/v4l2/gstv4l2object.c
++++ b/sys/v4l2/gstv4l2object.c
+@@ -1208,14 +1208,16 @@ gst_v4l2_object_v4l2fourcc_to_structure (guint32 fourcc)
+ b_mask = 0xff0000;
+ break;
+ case V4L2_PIX_FMT_RGB32:
+- bpp = depth = 32;
++ bpp = 32;
++ depth = 24;
+ endianness = G_BIG_ENDIAN;
+- r_mask = 0xff000000;
+- g_mask = 0x00ff0000;
+- b_mask = 0x0000ff00;
++ r_mask = 0x00ff0000;
++ g_mask = 0x0000ff00;
++ b_mask = 0x000000ff;
+ break;
+ case V4L2_PIX_FMT_BGR32:
+- bpp = depth = 32;
++ bpp = 32;
++ depth = 24;
+ endianness = G_BIG_ENDIAN;
+ r_mask = 0x000000ff;
+ g_mask = 0x0000ff00;
+@@ -1480,9 +1482,10 @@ gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps,
+ #endif
+ }
+ } else if (!strcmp (mimetype, "video/x-raw-rgb")) {
+- gint depth, endianness, r_mask;
++ gint depth, bpp, endianness, r_mask;
+
+ gst_structure_get_int (structure, "depth", &depth);
++ gst_structure_get_int (structure, "bpp", &bpp);
+ gst_structure_get_int (structure, "endianness", &endianness);
+ gst_structure_get_int (structure, "red_mask", &r_mask);
+
+@@ -1499,10 +1502,13 @@ gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps,
+ V4L2_PIX_FMT_RGB565 : V4L2_PIX_FMT_RGB565X;
+ break;
+ case 24:
+- fourcc = (r_mask == 0xFF) ? V4L2_PIX_FMT_BGR24 : V4L2_PIX_FMT_RGB24;
+- break;
+ case 32:
+- fourcc = (r_mask == 0xFF) ? V4L2_PIX_FMT_BGR32 : V4L2_PIX_FMT_RGB32;
++ if (bpp == 24)
++ fourcc = (r_mask == 0xFF) ? V4L2_PIX_FMT_BGR24 : V4L2_PIX_FMT_RGB24;
++ else if (bpp == 32)
++ fourcc = (r_mask == 0xFF) ? V4L2_PIX_FMT_BGR32 : V4L2_PIX_FMT_RGB32;
++ else
++ GST_ERROR_OBJECT (v4l2object, "Invalid value bpp = %d", bpp);
+ break;
+ }
+ } else if (strcmp (mimetype, "video/x-dv") == 0) {
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good/0025-sys-v4l2-gstv4l2-skip-set-caps-processing-if-the-par.patch b/common/recipes-multimedia/gstreamer/gst-plugins-good/0025-sys-v4l2-gstv4l2-skip-set-caps-processing-if-the-par.patch
new file mode 100644
index 0000000..53e7acd
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good/0025-sys-v4l2-gstv4l2-skip-set-caps-processing-if-the-par.patch
@@ -0,0 +1,86 @@
+From 91b8fe5f2e81eb1c5fcdd2f27e5d40ce64a4433f Mon Sep 17 00:00:00 2001
+From: Kazunori Kobayashi <kkobayas@igel.co.jp>
+Date: Wed, 16 May 2012 15:41:40 +0900
+Subject: [PATCH 25/31] sys/v4l2/gstv4l2: skip set caps processing if the
+ parameters are unchanged
+
+v4l2src re-creates the buffer pool in set_caps() when the buffers
+already have been allocated. If always-copy is set to false,
+the buffer dequeued from V4L2 driver can be passed to next plugin
+without copying. Therefore, set_caps() could free the buffer which
+is in use.
+
+set_caps() may be invoked by core libraries even if there is no change
+to the caps value. This behavior could free the buffer which is in use
+by another plugin. This patch skips the set_caps() processing if the caps
+parameters are unchanged.
+---
+ sys/v4l2/gstv4l2src.c | 36 ++++++++++++++++++++++++++++--------
+ 1 file changed, 28 insertions(+), 8 deletions(-)
+
+diff --git a/sys/v4l2/gstv4l2src.c b/sys/v4l2/gstv4l2src.c
+index d3f9a3c..3f9c6ba 100644
+--- a/sys/v4l2/gstv4l2src.c
++++ b/sys/v4l2/gstv4l2src.c
+@@ -628,6 +628,7 @@ gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps)
+ struct v4l2_fmtdesc *format;
+ guint fps_n, fps_d;
+ guint size;
++ struct v4l2_format prev_format;
+
+ v4l2src = GST_V4L2SRC (src);
+
+@@ -635,8 +636,35 @@ gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps)
+ if (!GST_V4L2_IS_OPEN (v4l2src->v4l2object))
+ return FALSE;
+
++ /* we want our own v4l2 type of fourcc codes */
++ if (!gst_v4l2_object_get_caps_info (v4l2src->v4l2object, caps, &format, &w,
++ &h, &interlaced, &fps_n, &fps_d, &size)) {
++ GST_INFO_OBJECT (v4l2src,
++ "can't get capture format from caps %" GST_PTR_FORMAT, caps);
++ return FALSE;
++ }
++
+ /* make sure we stop capturing and dealloc buffers */
+ if (GST_V4L2_IS_ACTIVE (v4l2src->v4l2object)) {
++ memset (&prev_format, 0x00, sizeof (struct v4l2_format));
++ prev_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
++ if (v4l2_ioctl (v4l2src->v4l2object->video_fd, VIDIOC_G_FMT,
++ &prev_format) < 0) {
++ GST_ERROR_OBJECT (v4l2src, "Call to G_FMT failed: (%s)",
++ g_strerror (errno));
++ return FALSE;
++ }
++
++ if (prev_format.fmt.pix.width == w &&
++ prev_format.fmt.pix.height == h &&
++ prev_format.fmt.pix.pixelformat == format->pixelformat &&
++ (v4l2src->fps_n == 0 || v4l2src->fps_n == fps_n) &&
++ (v4l2src->fps_d == 0 || v4l2src->fps_d == fps_d) &&
++ v4l2src->frame_byte_size == size) {
++ GST_LOG_OBJECT (v4l2src, "skip set caps because of no need to change");
++ return TRUE;
++ }
++
+ /* both will throw an element-error on failure */
+ if (!gst_v4l2src_capture_stop (v4l2src))
+ return FALSE;
+@@ -644,14 +672,6 @@ gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps)
+ return FALSE;
+ }
+
+- /* we want our own v4l2 type of fourcc codes */
+- if (!gst_v4l2_object_get_caps_info (v4l2src->v4l2object, caps, &format, &w,
+- &h, &interlaced, &fps_n, &fps_d, &size)) {
+- GST_INFO_OBJECT (v4l2src,
+- "can't get capture format from caps %" GST_PTR_FORMAT, caps);
+- return FALSE;
+- }
+-
+ GST_DEBUG_OBJECT (v4l2src, "trying to set_capture %dx%d at %d/%d fps, "
+ "format %s", w, h, fps_n, fps_d, format->description);
+
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good/0026-sys-v4l2-gstv4l2-return-an-error-from-set_caps-if-tr.patch b/common/recipes-multimedia/gstreamer/gst-plugins-good/0026-sys-v4l2-gstv4l2-return-an-error-from-set_caps-if-tr.patch
new file mode 100644
index 0000000..e73f3a7
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good/0026-sys-v4l2-gstv4l2-return-an-error-from-set_caps-if-tr.patch
@@ -0,0 +1,66 @@
+From 2cda1fcdf8147fdddbca0f2f2d584bda9cc9d283 Mon Sep 17 00:00:00 2001
+From: Kazunori Kobayashi <kkobayas@igel.co.jp>
+Date: Wed, 23 May 2012 16:24:16 +0900
+Subject: [PATCH 26/31] sys/v4l2/gstv4l2: return an error from set_caps() if
+ trying to re-create in-use buffers
+
+Whether the caps can be changed depends on the always-copy option.
+
+If the caps of a buffer are changed, the buffer must be
+re-created because the buffer size may change. If always-copy is
+set to false, a buffer which is in use could be freed so that it
+can be re-created.
+
+For this reason, if always-copy is set to false, changing the caps is
+not supported and this patch returns an error.
+---
+ sys/v4l2/gstv4l2src.c | 24 ++++++++++++++++++------
+ 1 file changed, 18 insertions(+), 6 deletions(-)
+
+diff --git a/sys/v4l2/gstv4l2src.c b/sys/v4l2/gstv4l2src.c
+index 3f9c6ba..3109429 100644
+--- a/sys/v4l2/gstv4l2src.c
++++ b/sys/v4l2/gstv4l2src.c
+@@ -646,6 +646,8 @@ gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps)
+
+ /* make sure we stop capturing and dealloc buffers */
+ if (GST_V4L2_IS_ACTIVE (v4l2src->v4l2object)) {
++ gboolean caps_changed = FALSE;
++
+ memset (&prev_format, 0x00, sizeof (struct v4l2_format));
+ prev_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ if (v4l2_ioctl (v4l2src->v4l2object->video_fd, VIDIOC_G_FMT,
+@@ -655,14 +657,24 @@ gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps)
+ return FALSE;
+ }
+
+- if (prev_format.fmt.pix.width == w &&
+- prev_format.fmt.pix.height == h &&
+- prev_format.fmt.pix.pixelformat == format->pixelformat &&
+- (v4l2src->fps_n == 0 || v4l2src->fps_n == fps_n) &&
+- (v4l2src->fps_d == 0 || v4l2src->fps_d == fps_d) &&
+- v4l2src->frame_byte_size == size) {
++ if (prev_format.fmt.pix.width != w ||
++ prev_format.fmt.pix.height != h ||
++ prev_format.fmt.pix.pixelformat != format->pixelformat ||
++ (v4l2src->fps_n != 0 && v4l2src->fps_n != fps_n) ||
++ (v4l2src->fps_d != 0 && v4l2src->fps_d != fps_d) ||
++ v4l2src->frame_byte_size != size) {
++ caps_changed = TRUE;
++ }
++
++ if (!caps_changed) {
+ GST_LOG_OBJECT (v4l2src, "skip set caps because of no need to change");
+ return TRUE;
++ } else if (!v4l2src->always_copy && caps_changed) {
++ GST_ERROR_OBJECT (v4l2src,
++ "can't change caps if v4l2src->always_copy is FALSE");
++ return FALSE;
++ } else {
++ GST_LOG_OBJECT (v4l2src, "run set caps");
+ }
+
+ /* both will throw an element-error on failure */
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good/0027-videocrop-add-a-new-function-to-determine-if-source-.patch b/common/recipes-multimedia/gstreamer/gst-plugins-good/0027-videocrop-add-a-new-function-to-determine-if-source-.patch
new file mode 100644
index 0000000..cc41aaa
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good/0027-videocrop-add-a-new-function-to-determine-if-source-.patch
@@ -0,0 +1,67 @@
+From a4185ee69f456d244f3bc5d1dc56800d112a3067 Mon Sep 17 00:00:00 2001
+From: Kazunori Kobayashi <kkobayas@igel.co.jp>
+Date: Mon, 29 Oct 2012 11:52:32 +0900
+Subject: [PATCH 27/31] videocrop: add a new function to determine if source
+ images are interlaced
+
+This patch groups the processing to determine if source images are
+interlaced to gst_video_crop_is_interlaced().
+---
+ gst/videocrop/gstvideocrop.c | 32 ++++++++++++++++++++++----------
+ 1 file changed, 22 insertions(+), 10 deletions(-)
+
+diff --git a/gst/videocrop/gstvideocrop.c b/gst/videocrop/gstvideocrop.c
+index caeb0b1..d02948d 100644
+--- a/gst/videocrop/gstvideocrop.c
++++ b/gst/videocrop/gstvideocrop.c
+@@ -604,6 +604,26 @@ gst_video_crop_transform_dimension_value (const GValue * src_val,
+ return ret;
+ }
+
++static gboolean
++gst_video_crop_is_interlaced (GstCaps * caps)
++{
++ gboolean interlaced;
++ const gchar *layout;
++ GstStructure *structure;
++ gboolean result;
++
++ structure = gst_caps_get_structure (caps, 0);
++ if (gst_structure_get_boolean (structure, "interlaced", &interlaced) &&
++ (interlaced == TRUE) &&
++ ((layout = gst_structure_get_string (structure, "field-layout")) != NULL)
++ && (strcmp (layout, "sequential") == 0))
++ result = TRUE;
++ else
++ result = FALSE;
++
++ return result;
++}
++
+ static GstCaps *
+ gst_video_crop_transform_caps (GstBaseTransform * trans,
+ GstPadDirection direction, GstCaps * caps)
+@@ -687,18 +707,10 @@ gst_video_crop_transform_caps (GstBaseTransform * trans,
+ guint ratio_y_c;
+ GstStructure *structure;
+ gint tile_height;
+- gboolean interlaced;
+- const gchar *layout;
+
+ structure = gst_caps_get_structure (caps, 0);
+- if (gst_structure_get_boolean (structure, "interlaced", &interlaced) &&
+- (interlaced == TRUE) &&
+- ((layout =
+- gst_structure_get_string (structure, "field-layout")) != NULL)
+- && (strcmp (layout, "sequential") == 0))
+- vcrop->interlaced = TRUE;
+- else
+- vcrop->interlaced = FALSE;
++
++ vcrop->interlaced = gst_video_crop_is_interlaced (caps);
+
+ rowstride = img_details.stride;
+ /* Y plane / UV plane */
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good/0028-videocrop-set-result-of-determing-if-source-images-a.patch b/common/recipes-multimedia/gstreamer/gst-plugins-good/0028-videocrop-set-result-of-determing-if-source-images-a.patch
new file mode 100644
index 0000000..d5c39b2
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good/0028-videocrop-set-result-of-determing-if-source-images-a.patch
@@ -0,0 +1,35 @@
+From d9e4f81f59fea3a0b4342e7c6b3312384d479827 Mon Sep 17 00:00:00 2001
+From: Kazunori Kobayashi <kkobayas@igel.co.jp>
+Date: Mon, 29 Oct 2012 14:53:32 +0900
+Subject: [PATCH 28/31] videocrop: set result of determing if source images
+ are interlaced at the head of transform_caps
+
+---
+ gst/videocrop/gstvideocrop.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/gst/videocrop/gstvideocrop.c b/gst/videocrop/gstvideocrop.c
+index d02948d..93d6512 100644
+--- a/gst/videocrop/gstvideocrop.c
++++ b/gst/videocrop/gstvideocrop.c
+@@ -642,6 +642,8 @@ gst_video_crop_transform_caps (GstBaseTransform * trans,
+ GST_LOG_OBJECT (vcrop, "l=%d,r=%d,b=%d,t=%d",
+ vcrop->crop_left, vcrop->crop_right, vcrop->crop_bottom, vcrop->crop_top);
+
++ vcrop->interlaced = gst_video_crop_is_interlaced (caps);
++
+ if (direction == GST_PAD_SRC) {
+ dx = vcrop->crop_left + vcrop->crop_right;
+ dy = vcrop->crop_top + vcrop->crop_bottom;
+@@ -710,8 +712,6 @@ gst_video_crop_transform_caps (GstBaseTransform * trans,
+
+ structure = gst_caps_get_structure (caps, 0);
+
+- vcrop->interlaced = gst_video_crop_is_interlaced (caps);
+-
+ rowstride = img_details.stride;
+ /* Y plane / UV plane */
+ ratio_y_c = img_details.uv_off / (img_details.size - img_details.uv_off);
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good/0029-videocrop-round-down-cropping-parameters-when-the-co.patch b/common/recipes-multimedia/gstreamer/gst-plugins-good/0029-videocrop-round-down-cropping-parameters-when-the-co.patch
new file mode 100644
index 0000000..7d1b8ee
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good/0029-videocrop-round-down-cropping-parameters-when-the-co.patch
@@ -0,0 +1,193 @@
+From 077d4c596e51be368eb495b4aa3e8020acf11d56 Mon Sep 17 00:00:00 2001
+From: Kazunori Kobayashi <kkobayas@igel.co.jp>
+Date: Mon, 29 Oct 2012 14:25:22 +0900
+Subject: [PATCH 29/31] videocrop: round down cropping parameters when the
+ color format is NV12
+
+When the color format is NV12, there are restrictions as the following.
+This change properly rounds down cropping parameters according to the
+restrictions.
+
+* Top: even number or multiple of 4 when a interlaced image is received.
+* Left: even number
+* Right: even number
+---
+ gst/videocrop/gstvideocrop.c | 86 +++++++++++++++++++++++++++++++++---------
+ gst/videocrop/gstvideocrop.h | 9 +++++
+ 2 files changed, 77 insertions(+), 18 deletions(-)
+
+diff --git a/gst/videocrop/gstvideocrop.c b/gst/videocrop/gstvideocrop.c
+index 93d6512..8fcc80e 100644
+--- a/gst/videocrop/gstvideocrop.c
++++ b/gst/videocrop/gstvideocrop.c
+@@ -624,6 +624,40 @@ gst_video_crop_is_interlaced (GstCaps * caps)
+ return result;
+ }
+
++static gboolean
++gst_video_crop_round_down_crop_properties (GstVideoCrop * vcrop, GstCaps * caps,
++ GstVideoCropRectangle * vcrop_rect)
++{
++ GstStructure *structure;
++ guint32 format = 0;
++ gboolean round_down_done;
++
++ g_return_val_if_fail (vcrop_rect != NULL, FALSE);
++
++ structure = gst_caps_get_structure (caps, 0);
++ if (!gst_structure_get_fourcc (structure, "format", &format)) {
++ GST_WARNING_OBJECT (vcrop, "failed to get fourcc");
++ return FALSE;
++ }
++
++ if (vcrop->interlaced && format == GST_MAKE_FOURCC ('N', 'V', '1', '2')) {
++ vcrop_rect->top = GST_ROUND_DOWN_4 (vcrop_rect->top);
++ vcrop_rect->left = GST_ROUND_DOWN_2 (vcrop_rect->left);
++ vcrop_rect->right = GST_ROUND_DOWN_2 (vcrop_rect->right);
++ round_down_done = TRUE;
++ } else if (!vcrop->interlaced &&
++ format == GST_MAKE_FOURCC ('N', 'V', '1', '2')) {
++ vcrop_rect->top = GST_ROUND_DOWN_2 (vcrop_rect->top);
++ vcrop_rect->left = GST_ROUND_DOWN_2 (vcrop_rect->left);
++ vcrop_rect->right = GST_ROUND_DOWN_2 (vcrop_rect->right);
++ round_down_done = TRUE;
++ } else {
++ round_down_done = FALSE;
++ }
++
++ return round_down_done;
++}
++
+ static GstCaps *
+ gst_video_crop_transform_caps (GstBaseTransform * trans,
+ GstPadDirection direction, GstCaps * caps)
+@@ -631,6 +665,7 @@ gst_video_crop_transform_caps (GstBaseTransform * trans,
+ GstVideoCrop *vcrop;
+ GstCaps *other_caps;
+ gint dy, dx, i;
++ GstVideoCropRectangle rounded_rect;
+
+ vcrop = GST_VIDEO_CROP (trans);
+
+@@ -644,12 +679,21 @@ gst_video_crop_transform_caps (GstBaseTransform * trans,
+
+ vcrop->interlaced = gst_video_crop_is_interlaced (caps);
+
++ rounded_rect.top = vcrop->crop_top;
++ rounded_rect.bottom = vcrop->crop_bottom;
++ rounded_rect.left = vcrop->crop_left;
++ rounded_rect.right = vcrop->crop_right;
++ if (gst_video_crop_round_down_crop_properties (vcrop, caps, &rounded_rect))
++ GST_LOG_OBJECT (vcrop, "round down l=%d,r=%d,b=%d,t=%d",
++ rounded_rect.left, rounded_rect.right, rounded_rect.bottom,
++ rounded_rect.top);
++
+ if (direction == GST_PAD_SRC) {
+- dx = vcrop->crop_left + vcrop->crop_right;
+- dy = vcrop->crop_top + vcrop->crop_bottom;
++ dx = rounded_rect.left + rounded_rect.right;
++ dy = rounded_rect.top + rounded_rect.bottom;
+ } else {
+- dx = 0 - (vcrop->crop_left + vcrop->crop_right);
+- dy = 0 - (vcrop->crop_top + vcrop->crop_bottom);
++ dx = 0 - (rounded_rect.left + rounded_rect.right);
++ dy = 0 - (rounded_rect.top + rounded_rect.bottom);
+ }
+ GST_OBJECT_UNLOCK (vcrop);
+
+@@ -716,20 +760,20 @@ gst_video_crop_transform_caps (GstBaseTransform * trans,
+ /* Y plane / UV plane */
+ ratio_y_c = img_details.uv_off / (img_details.size - img_details.uv_off);
+ if (vcrop->interlaced)
+- delta_chroma_offs = rowstride * vcrop->crop_top / ratio_y_c / 2;
++ delta_chroma_offs = rowstride * rounded_rect.top / ratio_y_c / 2;
+ else
+- delta_chroma_offs = rowstride * vcrop->crop_top / ratio_y_c;
++ delta_chroma_offs = rowstride * rounded_rect.top / ratio_y_c;
+
+ /* set tile boudary for T/L addressing */
+ if (gst_structure_get_int (structure, "tile-height", &tile_height)) {
+ gint tile_y_offs, tile_c_offs;
+
+ if (vcrop->interlaced) {
+- tile_y_offs = vcrop->crop_top / 2 % tile_height;
+- tile_c_offs = vcrop->crop_top / ratio_y_c / 2 % tile_height;
++ tile_y_offs = rounded_rect.top / 2 % tile_height;
++ tile_c_offs = rounded_rect.top / ratio_y_c / 2 % tile_height;
+ } else {
+- tile_y_offs = vcrop->crop_top % tile_height;
+- tile_c_offs = vcrop->crop_top / ratio_y_c % tile_height;
++ tile_y_offs = rounded_rect.top % tile_height;
++ tile_c_offs = rounded_rect.top / ratio_y_c % tile_height;
+ }
+
+ gst_structure_set (new_structure, "tile_boundary_y_offset",
+@@ -910,25 +954,31 @@ gst_videocrop_transform_size (GstBaseTransform * trans,
+ *othersize = units * outunitsize;
+ } else {
+ guint sub_offset;
++ GstVideoCropRectangle rounded_rect;
++
++ rounded_rect.top = vcrop->crop_top;
++ rounded_rect.bottom = vcrop->crop_bottom;
++ rounded_rect.left = vcrop->crop_left;
++ rounded_rect.right = vcrop->crop_right;
++ gst_video_crop_round_down_crop_properties (vcrop, caps, &rounded_rect);
+
+ /* Calculate a subbufer size for zero-copy cropping. The subbuffer is
+ created in prepare_output_buffer (). */
+ if (vcrop->in.packing == VIDEO_CROP_PIXEL_FORMAT_PACKED_SIMPLE) {
+- sub_offset = (vcrop->crop_top * vcrop->in.stride) +
+- (vcrop->crop_left * vcrop->in.bytes_per_pixel);
++ sub_offset = (rounded_rect.top * vcrop->in.stride) +
++ (rounded_rect.left * vcrop->in.bytes_per_pixel);
+ } else if (vcrop->in.packing == VIDEO_CROP_PIXEL_FORMAT_PACKED_COMPLEX) {
+- sub_offset = (vcrop->crop_top * vcrop->in.stride) +
+- (ROUND_DOWN_2 (vcrop->crop_left) * vcrop->in.bytes_per_pixel);
++ sub_offset = (rounded_rect.top * vcrop->in.stride) +
++ (ROUND_DOWN_2 (rounded_rect.left) * vcrop->in.bytes_per_pixel);
+ } else if (vcrop->in.packing == VIDEO_CROP_PIXEL_FORMAT_SEMI_PLANAR) {
+ GstStructure *structure;
+
+ structure = gst_caps_get_structure (caps, 0);
+ if (vcrop->interlaced)
+- sub_offset = (vcrop->crop_top / 2 * vcrop->in.stride) +
+- ROUND_DOWN_2 (vcrop->crop_left);
++ sub_offset = (rounded_rect.top / 2 * vcrop->in.stride) +
++ rounded_rect.left;
+ else
+- sub_offset = (vcrop->crop_top * vcrop->in.stride) +
+- ROUND_DOWN_2 (vcrop->crop_left);
++ sub_offset = (rounded_rect.top * vcrop->in.stride) + rounded_rect.left;
+ } else {
+ GST_LOG_OBJECT (vcrop,
+ "can't do zero-copy cropping except for packed format");
+diff --git a/gst/videocrop/gstvideocrop.h b/gst/videocrop/gstvideocrop.h
+index a72cacb..4885c37 100644
+--- a/gst/videocrop/gstvideocrop.h
++++ b/gst/videocrop/gstvideocrop.h
+@@ -67,6 +67,7 @@ struct _GstVideoCropImageDetails
+
+ typedef struct _GstVideoCrop GstVideoCrop;
+ typedef struct _GstVideoCropClass GstVideoCropClass;
++typedef struct _GstVideoCropRectangle GstVideoCropRectangle;
+
+ struct _GstVideoCrop
+ {
+@@ -94,5 +95,13 @@ struct _GstVideoCropClass
+
+ GType gst_video_crop_get_type (void);
+
++struct _GstVideoCropRectangle
++{
++ gint left;
++ gint right;
++ gint top;
++ gint bottom;
++};
++
+ G_END_DECLS
+ #endif /* __GST_VIDEO_CROP_H__ */
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good/0030-videocrop-hold-a-lock-to-prevent-from-accessing-crop.patch b/common/recipes-multimedia/gstreamer/gst-plugins-good/0030-videocrop-hold-a-lock-to-prevent-from-accessing-crop.patch
new file mode 100644
index 0000000..5114174
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good/0030-videocrop-hold-a-lock-to-prevent-from-accessing-crop.patch
@@ -0,0 +1,30 @@
+From 34b6056ac873388ce008817819cefe930ee9901f Mon Sep 17 00:00:00 2001
+From: Kazunori Kobayashi <kkobayas@igel.co.jp>
+Date: Wed, 31 Oct 2012 12:33:58 +0900
+Subject: [PATCH 30/31] videocrop: hold a lock to prevent from accessing
+ cropping params on performing set_property
+
+---
+ gst/videocrop/gstvideocrop.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/gst/videocrop/gstvideocrop.c b/gst/videocrop/gstvideocrop.c
+index 8fcc80e..2114dae 100644
+--- a/gst/videocrop/gstvideocrop.c
++++ b/gst/videocrop/gstvideocrop.c
+@@ -956,10 +956,12 @@ gst_videocrop_transform_size (GstBaseTransform * trans,
+ guint sub_offset;
+ GstVideoCropRectangle rounded_rect;
+
++ GST_OBJECT_LOCK (vcrop);
+ rounded_rect.top = vcrop->crop_top;
+ rounded_rect.bottom = vcrop->crop_bottom;
+ rounded_rect.left = vcrop->crop_left;
+ rounded_rect.right = vcrop->crop_right;
++ GST_OBJECT_UNLOCK (vcrop);
+ gst_video_crop_round_down_crop_properties (vcrop, caps, &rounded_rect);
+
+ /* Calculate a subbufer size for zero-copy cropping. The subbuffer is
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good/0031-videocrop-fix-a-memory-leak-caused-by-invoking-gst_p.patch b/common/recipes-multimedia/gstreamer/gst-plugins-good/0031-videocrop-fix-a-memory-leak-caused-by-invoking-gst_p.patch
new file mode 100644
index 0000000..248f8f7
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good/0031-videocrop-fix-a-memory-leak-caused-by-invoking-gst_p.patch
@@ -0,0 +1,39 @@
+From d152c33c21eba3b9df2918fb8187ff5f839f766f Mon Sep 17 00:00:00 2001
+From: Kazunori Kobayashi <kkobayas@igel.co.jp>
+Date: Tue, 22 Jan 2013 18:40:28 +0900
+Subject: [PATCH 31/31] videocrop: fix a memory leak caused by invoking
+ gst_pad_get_peer()
+
+Once is_query_done is set to TRUE, the function exits without decreasing
+the reference count of a GstPad instance.
+To fix the issue, this patch moves the call to gst_pad_get_peer() (which
+increases the GstPad refence count) to after is_query_done is tested.
+---
+ gst/videocrop/gstvideocrop.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/gst/videocrop/gstvideocrop.c b/gst/videocrop/gstvideocrop.c
+index 2114dae..49edc6e 100644
+--- a/gst/videocrop/gstvideocrop.c
++++ b/gst/videocrop/gstvideocrop.c
+@@ -873,7 +873,7 @@ static gboolean
+ gst_video_crop_query_stride_supported (GstVideoCrop * vcrop)
+ {
+ static gboolean result = FALSE;
+- GstPad *peer = gst_pad_get_peer (GST_BASE_TRANSFORM (vcrop)->srcpad);
++ GstPad *peer;
+ GstStructure *structure;
+ GstQuery *query;
+ static gboolean is_query_done = FALSE;
+@@ -881,6 +881,8 @@ gst_video_crop_query_stride_supported (GstVideoCrop * vcrop)
+ if (is_query_done)
+ return result;
+
++ peer = gst_pad_get_peer (GST_BASE_TRANSFORM (vcrop)->srcpad);
++
+ structure = gst_structure_empty_new ("GstQueryStrideSupported");
+ gst_structure_set (structure, "stride-supported", G_TYPE_BOOLEAN, FALSE,
+ NULL);
+--
+1.7.9.5
+