summaryrefslogtreecommitdiffstats
path: root/common/recipes-multimedia/gstreamer
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
commit BSP v1.8.0
Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
Diffstat (limited to 'common/recipes-multimedia/gstreamer')
-rw-r--r--common/recipes-multimedia/gstreamer/gst-openmax/0001-Stop-using-deprecated-GLib-thread-API.patch335
-rw-r--r--common/recipes-multimedia/gstreamer/gst-openmax/0001-base_videodec-change-the-tile-height-for-T-L-address.patch27
-rw-r--r--common/recipes-multimedia/gstreamer/gst-openmax/disable_configure.patch15
-rw-r--r--common/recipes-multimedia/gstreamer/gst-openmax/gst-openmax.conf7
-rw-r--r--common/recipes-multimedia/gstreamer/gst-openmax_git.bb53
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-bad/0001-Setup-MERAM-for-A1.patch78
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-bad_0.10.23.bbappend27
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-base/0001-gstaudiosink-wait-for-gst_ring_buffer_advance-when-p.patch79
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-base_0.10.36.bbappend5
-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
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-good_0.10.31.bbappend37
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-package.inc40
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-private-libs.inc18
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-ugly/0001-asfdemux-asfpacket-set-frame-start-code-to-VC-1-adva.patch99
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins-ugly_0.10.19.bbappend5
-rw-r--r--common/recipes-multimedia/gstreamer/gst-plugins.inc29
-rw-r--r--common/recipes-multimedia/gstreamer/gstreamer1.0-libav/libav_e500mc.patch21
-rw-r--r--common/recipes-multimedia/gstreamer/gstreamer1.0-libav_1.2.3.bbappend9
-rw-r--r--common/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.2.3.bbappend21
-rw-r--r--common/recipes-multimedia/gstreamer/gstreamer1.0-plugins-base_1.2.3.bbappend5
-rw-r--r--common/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good_1.2.3.bbappend5
-rw-r--r--common/recipes-multimedia/gstreamer/gstreamer1.0_1.2.3.bbappend1
52 files changed, 3329 insertions, 0 deletions
diff --git a/common/recipes-multimedia/gstreamer/gst-openmax/0001-Stop-using-deprecated-GLib-thread-API.patch b/common/recipes-multimedia/gstreamer/gst-openmax/0001-Stop-using-deprecated-GLib-thread-API.patch
new file mode 100644
index 0000000..34b51fa
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-openmax/0001-Stop-using-deprecated-GLib-thread-API.patch
@@ -0,0 +1,335 @@
+From 4244ae9ac47f9a72f10797dcf71ca4427393528d Mon Sep 17 00:00:00 2001
+From: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
+Date: Mon, 22 Apr 2013 15:06:19 +0900
+Subject: [PATCH] Stop using deprecated GLib thread API
+
+Signed-off-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
+---
+ omx/gstomx_base_filter.c | 12 ++++-----
+ omx/gstomx_base_filter.h | 2 +-
+ omx/gstomx_util.c | 62 ++++++++++++++++++++++++----------------------
+ omx/gstomx_util.h | 8 +++---
+ 4 files changed, 44 insertions(+), 40 deletions(-)
+
+diff --git a/omx/gstomx_base_filter.c b/omx/gstomx_base_filter.c
+index 674dcaa..46120b7 100644
+--- a/omx/gstomx_base_filter.c
++++ b/omx/gstomx_base_filter.c
+@@ -121,7 +121,7 @@ change_state (GstElement * element, GstStateChange transition)
+
+ switch (transition) {
+ case GST_STATE_CHANGE_PAUSED_TO_READY:
+- g_mutex_lock (self->ready_lock);
++ g_mutex_lock (&self->ready_lock);
+ if (self->ready) {
+ /* unlock */
+ g_omx_port_finish (self->in_port);
+@@ -131,7 +131,7 @@ change_state (GstElement * element, GstStateChange transition)
+ g_omx_core_unload (core);
+ self->ready = FALSE;
+ }
+- g_mutex_unlock (self->ready_lock);
++ g_mutex_unlock (&self->ready_lock);
+ if (core->omx_state != OMX_StateLoaded &&
+ core->omx_state != OMX_StateInvalid) {
+ ret = GST_STATE_CHANGE_FAILURE;
+@@ -163,7 +163,7 @@ finalize (GObject * obj)
+
+ g_omx_core_free (self->gomx);
+
+- g_mutex_free (self->ready_lock);
++ g_mutex_clear (&self->ready_lock);
+
+ G_OBJECT_CLASS (parent_class)->finalize (obj);
+ }
+@@ -576,7 +576,7 @@ pad_chain (GstPad * pad, GstBuffer * buf)
+ GST_LOG_OBJECT (self, "state: %d", gomx->omx_state);
+
+ if (G_UNLIKELY (gomx->omx_state == OMX_StateLoaded)) {
+- g_mutex_lock (self->ready_lock);
++ g_mutex_lock (&self->ready_lock);
+
+ GST_INFO_OBJECT (self, "omx: prepare");
+
+@@ -594,7 +594,7 @@ pad_chain (GstPad * pad, GstBuffer * buf)
+ gst_pad_start_task (self->srcpad, output_loop, self->srcpad);
+ }
+
+- g_mutex_unlock (self->ready_lock);
++ g_mutex_unlock (&self->ready_lock);
+
+ if (gomx->omx_state != OMX_StateIdle)
+ goto out_flushing;
+@@ -890,7 +890,7 @@ type_instance_init (GTypeInstance * instance, gpointer g_class)
+ self->in_port = g_omx_core_new_port (self->gomx, 0);
+ self->out_port = g_omx_core_new_port (self->gomx, 1);
+
+- self->ready_lock = g_mutex_new ();
++ g_mutex_init (&self->ready_lock);
+
+ self->sinkpad =
+ gst_pad_new_from_template (gst_element_class_get_pad_template
+diff --git a/omx/gstomx_base_filter.h b/omx/gstomx_base_filter.h
+index 3175b8a..632344c 100644
+--- a/omx/gstomx_base_filter.h
++++ b/omx/gstomx_base_filter.h
+@@ -49,7 +49,7 @@ struct GstOmxBaseFilter
+
+ gboolean use_timestamps; /** @todo remove; timestamps should always be used */
+ gboolean ready;
+- GMutex *ready_lock;
++ GMutex ready_lock;
+
+ GstOmxBaseFilterCb omx_setup;
+ GstFlowReturn last_pad_push_return;
+diff --git a/omx/gstomx_util.c b/omx/gstomx_util.c
+index aed5d4f..2c9d430 100644
+--- a/omx/gstomx_util.c
++++ b/omx/gstomx_util.c
+@@ -78,7 +78,7 @@ static OMX_CALLBACKTYPE callbacks =
+ { EventHandler, EmptyBufferDone, FillBufferDone };
+
+ /* protect implementations hash_table */
+-static GMutex *imp_mutex;
++static GMutex imp_mutex;
+ static GHashTable *implementations;
+ static gboolean initialized;
+
+@@ -151,7 +151,7 @@ imp_new (const gchar * name)
+ return NULL;
+ }
+
+- imp->mutex = g_mutex_new ();
++ g_mutex_init(&imp->mutex);
+ imp->sym_table.init = dlsym (handle, "OMX_Init");
+ imp->sym_table.deinit = dlsym (handle, "OMX_Deinit");
+ imp->sym_table.get_handle = dlsym (handle, "OMX_GetHandle");
+@@ -167,7 +167,7 @@ imp_free (GOmxImp * imp)
+ if (imp->dl_handle) {
+ dlclose (imp->dl_handle);
+ }
+- g_mutex_free (imp->mutex);
++ g_mutex_clear(&imp->mutex);
+ g_free (imp);
+ }
+
+@@ -177,19 +177,19 @@ request_imp (const gchar * name, gboolean disable_postproc)
+ GOmxImp *imp = NULL;
+ int retry = 1;
+
+- g_mutex_lock (imp_mutex);
++ g_mutex_lock (&imp_mutex);
+ imp = g_hash_table_lookup (implementations, name);
+ if (!imp) {
+ imp = imp_new (name);
+ if (imp)
+ g_hash_table_insert (implementations, g_strdup (name), imp);
+ }
+- g_mutex_unlock (imp_mutex);
++ g_mutex_unlock (&imp_mutex);
+
+ if (!imp)
+ return NULL;
+
+- g_mutex_lock (imp->mutex);
++ g_mutex_lock (&imp->mutex);
+ reinit:
+ if (imp->client_count == 0) {
+ OMX_ERRORTYPE (*r_config) (OMX_STRING path);
+@@ -200,7 +200,7 @@ reinit:
+ if (r_config)
+ omx_error = r_config (FILE_OMXR_CFG_NO_IPC);
+ if ((r_config == NULL) || (omx_error != OMX_ErrorNone)) {
+- g_mutex_unlock (imp->mutex);
++ g_mutex_unlock (&imp->mutex);
+ return NULL;
+ }
+ }
+@@ -211,12 +211,12 @@ reinit:
+ imp->sym_table.deinit ();
+ goto reinit;
+ }
+- g_mutex_unlock (imp->mutex);
++ g_mutex_unlock (&imp->mutex);
+ return NULL;
+ }
+ }
+ imp->client_count++;
+- g_mutex_unlock (imp->mutex);
++ g_mutex_unlock (&imp->mutex);
+
+ return imp;
+ }
+@@ -224,12 +224,12 @@ reinit:
+ static inline void
+ release_imp (GOmxImp * imp)
+ {
+- g_mutex_lock (imp->mutex);
++ g_mutex_lock (&imp->mutex);
+ imp->client_count--;
+ if (imp->client_count == 0) {
+ imp->sym_table.deinit ();
+ }
+- g_mutex_unlock (imp->mutex);
++ g_mutex_unlock (&imp->mutex);
+ }
+
+ void
+@@ -237,7 +237,7 @@ g_omx_init (void)
+ {
+ if (!initialized) {
+ /* safe as plugin_init is safe */
+- imp_mutex = g_mutex_new ();
++ g_mutex_init(&imp_mutex);
+ implementations = g_hash_table_new_full (g_str_hash,
+ g_str_equal, g_free, (GDestroyNotify) imp_free);
+ initialized = TRUE;
+@@ -249,7 +249,7 @@ g_omx_deinit (void)
+ {
+ if (initialized) {
+ g_hash_table_destroy (implementations);
+- g_mutex_free (imp_mutex);
++ g_mutex_clear (&imp_mutex);
+ initialized = FALSE;
+ }
+ }
+@@ -268,8 +268,8 @@ g_omx_core_new (void *object)
+ core->object = object;
+ core->ports = g_ptr_array_new ();
+
+- core->omx_state_condition = g_cond_new ();
+- core->omx_state_mutex = g_mutex_new ();
++ g_cond_init(&core->omx_state_condition);
++ g_mutex_init(&core->omx_state_mutex);
+
+ core->done_sem = g_sem_new ();
+ core->flush_sem = g_sem_new ();
+@@ -289,8 +289,8 @@ g_omx_core_free (GOmxCore * core)
+ g_sem_free (core->flush_sem);
+ g_sem_free (core->done_sem);
+
+- g_mutex_free (core->omx_state_mutex);
+- g_cond_free (core->omx_state_condition);
++ g_mutex_clear (&core->omx_state_mutex);
++ g_cond_clear (&core->omx_state_condition);
+
+ g_ptr_array_free (core->ports, TRUE);
+
+@@ -501,7 +501,7 @@ g_omx_port_new (GOmxCore * core, guint index)
+
+ port->enabled = TRUE;
+ port->queue = async_queue_new ();
+- port->mutex = g_mutex_new ();
++ g_mutex_init (&port->mutex);
+
+ return port;
+ }
+@@ -509,7 +509,7 @@ g_omx_port_new (GOmxCore * core, guint index)
+ void
+ g_omx_port_free (GOmxPort * port)
+ {
+- g_mutex_free (port->mutex);
++ g_mutex_clear (&port->mutex);
+ async_queue_free (port->queue);
+
+ g_free (port->buffers);
+@@ -726,7 +726,7 @@ g_omx_port_finish (GOmxPort * port)
+ static inline void
+ change_state (GOmxCore * core, OMX_STATETYPE state)
+ {
+- g_mutex_lock (core->omx_state_mutex);
++ g_mutex_lock (&core->omx_state_mutex);
+
+ GST_DEBUG_OBJECT (core->object, "state=%d", state);
+ OMX_SendCommand (core->omx_handle, OMX_CommandStateSet, state, NULL);
+@@ -735,13 +735,13 @@ change_state (GOmxCore * core, OMX_STATETYPE state)
+ static inline void
+ complete_change_state (GOmxCore * core, OMX_STATETYPE state)
+ {
+- g_mutex_lock (core->omx_state_mutex);
++ g_mutex_lock (&core->omx_state_mutex);
+
+ core->omx_state = state;
+- g_cond_signal (core->omx_state_condition);
++ g_cond_signal (&core->omx_state_condition);
+ GST_DEBUG_OBJECT (core->object, "state=%d", state);
+
+- g_mutex_unlock (core->omx_state_mutex);
++ g_mutex_unlock (&core->omx_state_mutex);
+ }
+
+ static inline void
+@@ -755,9 +755,13 @@ wait_for_state (GOmxCore * core, OMX_STATETYPE state)
+
+ /* try once */
+ if (core->omx_state != state) {
++ gint64 t = g_get_monotonic_time () +
++ ((gint64)tv.tv_sec * G_USEC_PER_SEC + tv.tv_usec -
++ g_get_real_time ());
++
+ signaled =
+- g_cond_timed_wait (core->omx_state_condition, core->omx_state_mutex,
+- &tv);
++ g_cond_wait_until (&core->omx_state_condition, &core->omx_state_mutex,
++ t);
+
+ if (!signaled) {
+ GST_ERROR_OBJECT (core->object, "timed out switching from '%s' to '%s'",
+@@ -774,7 +778,7 @@ wait_for_state (GOmxCore * core, OMX_STATETYPE state)
+ }
+
+ leave:
+- g_mutex_unlock (core->omx_state_mutex);
++ g_mutex_unlock (&core->omx_state_mutex);
+ }
+
+ /*
+@@ -926,9 +930,9 @@ EventHandler (OMX_HANDLETYPE omx_handle,
+ */
+ if (is_err_type_state_change (core->omx_error)) {
+ /* unlock wait_for_state */
+- g_mutex_lock (core->omx_state_mutex);
+- g_cond_signal (core->omx_state_condition);
+- g_mutex_unlock (core->omx_state_mutex);
++ g_mutex_lock (&core->omx_state_mutex);
++ g_cond_signal (&core->omx_state_condition);
++ g_mutex_unlock (&core->omx_state_mutex);
+ }
+
+ GST_ELEMENT_ERROR (core->object, STREAM, FAILED, (NULL),
+diff --git a/omx/gstomx_util.h b/omx/gstomx_util.h
+index b2a0de5..9a0f062 100644
+--- a/omx/gstomx_util.h
++++ b/omx/gstomx_util.h
+@@ -65,7 +65,7 @@ struct GOmxImp
+ guint client_count;
+ void *dl_handle;
+ GOmxSymbolTable sym_table;
+- GMutex *mutex;
++ GMutex mutex;
+ };
+
+ struct GOmxCore
+@@ -76,8 +76,8 @@ struct GOmxCore
+ OMX_ERRORTYPE omx_error;
+
+ OMX_STATETYPE omx_state;
+- GCond *omx_state_condition;
+- GMutex *omx_state_mutex;
++ GCond omx_state_condition;
++ GMutex omx_state_mutex;
+
+ GPtrArray *ports;
+
+@@ -107,7 +107,7 @@ struct GOmxPort
+ guint port_index;
+ OMX_BUFFERHEADERTYPE **buffers;
+
+- GMutex *mutex;
++ GMutex mutex;
+ gboolean enabled;
+ gboolean omx_allocate; /**< Setup with OMX_AllocateBuffer rather than OMX_UseBuffer */
+ AsyncQueue *queue;
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-openmax/0001-base_videodec-change-the-tile-height-for-T-L-address.patch b/common/recipes-multimedia/gstreamer/gst-openmax/0001-base_videodec-change-the-tile-height-for-T-L-address.patch
new file mode 100644
index 0000000..9f2dca2
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-openmax/0001-base_videodec-change-the-tile-height-for-T-L-address.patch
@@ -0,0 +1,27 @@
+From 5ae3622b9711655479744ed8a95c20d095dcbf1e Mon Sep 17 00:00:00 2001
+From: Kazunori Kobayashi <kkobayas@igel.co.jp>
+Date: Wed, 10 Apr 2013 11:05:30 +0900
+Subject: [PATCH] base_videodec: change the tile height for T/L addressing
+
+This change is added to follow the change of the tile height to be
+tuned for the R-CarM1A in the REL OMX.
+---
+ omx/gstomx_base_videodec.c | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/omx/gstomx_base_videodec.c b/omx/gstomx_base_videodec.c
+index 247f596..da5585d 100644
+--- a/omx/gstomx_base_videodec.c
++++ b/omx/gstomx_base_videodec.c
+@@ -203,7 +203,7 @@ settings_changed_cb (GOmxCore * core)
+ ALIGN2UP (stride, stride);
+ chroma_byte_offset = stride * ALIGN32 (sliceheight);
+ #define OMXR_TILE_WIDTH 32
+-#define OMXR_TILE_HEIGHT 8
++#define OMXR_TILE_HEIGHT 16
+ gst_structure_set (struc, "tile-width", G_TYPE_INT, OMXR_TILE_WIDTH,
+ NULL);
+ gst_structure_set (struc, "tile-height", G_TYPE_INT, OMXR_TILE_HEIGHT,
+--
+1.7.5.4
+
diff --git a/common/recipes-multimedia/gstreamer/gst-openmax/disable_configure.patch b/common/recipes-multimedia/gstreamer/gst-openmax/disable_configure.patch
new file mode 100644
index 0000000..863a8b2
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-openmax/disable_configure.patch
@@ -0,0 +1,15 @@
+diff --git a/autogen.sh b/autogen.sh
+index e69af6d..081ac8c 100755
+--- a/autogen.sh
++++ b/autogen.sh
+@@ -112,10 +112,3 @@ test ! -z "$CONFIGURE_DEF_OPT" && echo " ./configure default flags: $CONFIGURE_
+ test ! -z "$CONFIGURE_EXT_OPT" && echo " ./configure external flags: $CONFIGURE_EXT_OPT"
+ test ! -z "$CONFIGURE_FILE_OPT" && echo " ./configure enable/disable flags: $CONFIGURE_FILE_OPT"
+ echo
+-
+-./configure $CONFIGURE_DEF_OPT $CONFIGURE_EXT_OPT $CONFIGURE_FILE_OPT || {
+- echo " configure failed"
+- exit 1
+-}
+-
+-echo "Now type 'make' to compile $package."
diff --git a/common/recipes-multimedia/gstreamer/gst-openmax/gst-openmax.conf b/common/recipes-multimedia/gstreamer/gst-openmax/gst-openmax.conf
new file mode 100644
index 0000000..0e4e4a0
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-openmax/gst-openmax.conf
@@ -0,0 +1,7 @@
+omx_h264dec,
+ type=GstOmxH264Dec,
+ library-name=libomxshvpu5avc.so,
+ component-name=OMX.re.video_decoder.avc,
+ rank=256,
+ src=video/x-raw-yuv,
+ sink="video/x-h264, stream-format={avc,byte-stream}";
diff --git a/common/recipes-multimedia/gstreamer/gst-openmax_git.bb b/common/recipes-multimedia/gstreamer/gst-openmax_git.bb
new file mode 100644
index 0000000..3ae3788
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-openmax_git.bb
@@ -0,0 +1,53 @@
+DESCRIPTION = "GStreamer plug-in that allows communication with OpenMAX IL components"
+AUTHOR = "Katsuya Matsubara <matsu@igel.co.jp>"
+BUGTRACKER = ""
+
+DEFAULT_PREFERENCE = "-1"
+DEPENDS = "gstreamer"
+RDEPENDS_${PN} = "libomxil"
+LICENSE = "LGPLv2.1"
+LICENSE_FLAGS = "commercial"
+
+require gst-plugins.inc
+inherit gettext
+
+LIBV="0.10"
+PR = "r1"
+
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+LIC_FILES_CHKSUM = "file://COPYING;md5=fbc093901857fcd118f065f900982c24"
+EXTRA_OECONF += "--disable-valgrind"
+
+# for armadillo800eva
+SRCREV_armadillo800eva = "43e0be40d82f83308d0a17cd74060b280c30c2a8"
+SRC_URI_armadillo800eva = "git://github.com/matsu/gst-openmax.git \
+ file://gst-openmax.conf \
+"
+
+SRCREV = "3dad1ec6803bb2f2627188ce0e957dbeaa57b1be"
+SRC_URI = "git://github.com/renesas-devel/gst-openmax.git \
+ file://0001-base_videodec-change-the-tile-height-for-T-L-address.patch \
+ file://0001-Stop-using-deprecated-GLib-thread-API.patch \
+ file://disable_configure.patch \
+"
+
+S = "${WORKDIR}/git/"
+
+# for -Werror-deprecated-declarations
+CPPFLAGS += "-Wno-deprecated-declarations"
+EXTRA_OECONF := "${@'${EXTRA_OECONF}'.replace('--disable-experimental', '--enable-experimental')}"
+
+do_configure_prepend() {
+ (cd ${S}; sh autogen.sh --noconfigure)
+}
+
+do_install_append_armadillo800eva() {
+ install -d ${D}/home/root/.config/
+ install -m 644 ${WORKDIR}/gst-openmax.conf ${D}/home/root/.config/.
+}
+
+FILES_${PN} += "${libdir}/gstreamer-${LIBV}/libgstomx.so /home/root/.config"
+FILES_${PN}-dev += "${libdir}/gstreamer-0.10/libgstomx.la"
+FILES_${PN}-staticdev += "${libdir}/gstreamer-0.10/libgstomx.a"
+FILES_${PN}-dbg += "${libdir}/gstreamer-0.10/.debug/"
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-bad/0001-Setup-MERAM-for-A1.patch b/common/recipes-multimedia/gstreamer/gst-plugins-bad/0001-Setup-MERAM-for-A1.patch
new file mode 100644
index 0000000..802d159
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-bad/0001-Setup-MERAM-for-A1.patch
@@ -0,0 +1,78 @@
+From 0e02696530388011f573f0a5cc91af97ed84184d Mon Sep 17 00:00:00 2001
+From: Damian Hobson-Garcia <dhobsong@igel.co.jp>
+Date: Thu, 13 Sep 2012 13:14:13 +0900
+Subject: [PATCH] Setup MERAM for A1
+
+The A1 MERAM settings are different from E1 settings. Namely A1 has
+more MERAM memory available and so can use more caching.
+---
+ ext/directfb/dfbvideosink.c | 14 +++++++-------
+ 1 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/ext/directfb/dfbvideosink.c b/ext/directfb/dfbvideosink.c
+index 39aa4cc..e680681 100644
+--- a/ext/directfb/dfbvideosink.c
++++ b/ext/directfb/dfbvideosink.c
+@@ -994,7 +994,7 @@ gst_dfbvideosink_setup (GstDfbVideoSink * dfbvideosink)
+ meram_write_icb (dfbvideosink->meram, dfbvideosink->icby[DST], MExxCTRL,
+ val | (7 << 4));
+ meram_write_icb (dfbvideosink->meram, dfbvideosink->icby[DST], MExxCTRL,
+- 0x90400702);
++ 0x90c00702);
+ /* NOTE: MExxSBSIZE is setting up afterward, that is in gst_dfbvideosink_setcaps(). */
+ meram_write_icb (dfbvideosink->meram, dfbvideosink->icby[DST], MExxSSARB,
+ 0);
+@@ -1665,7 +1665,7 @@ gst_dfbvideosink_setup_meram (GstDfbVideoSink * dfbvideosink, GstCaps * caps,
+ 0) ? dfbvideosink->chroma_byte_offset / stride : video_height;
+
+ /* set up a readahead icb for Y plane
+- 4 lines / block-line, 8 lines held, 16 lines allocated */
++ 32 lines / block-line, 32 lines held, 64 lines allocated */
+ if (dfbvideosink->icby[SRC]) {
+ addr =
+ meram_get_icb_address (dfbvideosink->meram, dfbvideosink->icby[SRC], 0);
+@@ -1680,13 +1680,13 @@ gst_dfbvideosink_setup_meram (GstDfbVideoSink * dfbvideosink, GstCaps * caps,
+ return;
+ }
+ meram_write_icb (dfbvideosink->meram, dfbvideosink->icby[SRC], MExxMCNF,
+- 0x010f0000);
++ 0x003f0000);
+ meram_read_icb (dfbvideosink->meram, dfbvideosink->icby[SRC], MExxCTRL, &val);
+ if (val & (7 << 4))
+ meram_write_icb (dfbvideosink->meram, dfbvideosink->icby[SRC], MExxCTRL,
+ val | 7 << 4);
+ meram_write_icb (dfbvideosink->meram, dfbvideosink->icby[SRC], MExxCTRL,
+- 0xa0000701);
++ 0xd0000701);
+ meram_write_icb (dfbvideosink->meram, dfbvideosink->icby[SRC], MExxSSARB, 0);
+ meram_write_icb (dfbvideosink->meram, dfbvideosink->icby[SRC], MExxBSIZE,
+ (((sliceheight + dfbvideosink->tile_boundary_y_offset -
+@@ -1717,7 +1717,7 @@ gst_dfbvideosink_setup_meram (GstDfbVideoSink * dfbvideosink, GstCaps * caps,
+ uiomux_register ((void *) addr, addr, 4096 * sliceheight);
+
+ /* set up a readahead icb for CbCr plane
+- 4 lines / block-line, 8 lines held, 16 lines allocated */
++ 16 lines / block-line, 16 lines held, 32 lines allocated */
+ if (dfbvideosink->icbc[SRC]) {
+ addr =
+ meram_get_icb_address (dfbvideosink->meram, dfbvideosink->icbc[SRC], 0);
+@@ -1733,14 +1733,14 @@ gst_dfbvideosink_setup_meram (GstDfbVideoSink * dfbvideosink, GstCaps * caps,
+ return;
+ }
+ meram_write_icb (dfbvideosink->meram, dfbvideosink->icbc[SRC], MExxMCNF,
+- 0x010f0000);
++ 0x001f0000);
+ meram_read_icb (dfbvideosink->meram, dfbvideosink->icbc[SRC], MExxCTRL,
+ &val);
+ if (val & (7 << 4))
+ meram_write_icb (dfbvideosink->meram, dfbvideosink->icbc[SRC], MExxCTRL,
+ val | 7 << 4);
+ meram_write_icb (dfbvideosink->meram, dfbvideosink->icbc[SRC], MExxCTRL,
+- 0xa0200701);
++ 0xc0800701);
+ meram_write_icb (dfbvideosink->meram, dfbvideosink->icbc[SRC], MExxBSIZE,
+ (((sliceheight / 2 + dfbvideosink->tile_boundary_c_offset -
+ 1) & 0x1fff) << 16) | ((stride - 1) & 0x7fff));
+--
+1.7.0.4
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-bad_0.10.23.bbappend b/common/recipes-multimedia/gstreamer/gst-plugins-bad_0.10.23.bbappend
new file mode 100644
index 0000000..6dd2399
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-bad_0.10.23.bbappend
@@ -0,0 +1,27 @@
+DEPENDS += "gstreamer libxml2"
+EXTRA_OECONF := "${@'${EXTRA_OECONF}'.replace('--disable-experimental', '--enable-experimental')}"
+EXTRA_OECONF += "--with-plugins=h264parse,asfmux,videoparsers"
+
+TARGET_CFLAGS += "-D_GNU_SOURCE"
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+# For armadillo
+SRCREV_armadillo800eva = "6c0a11cb57d4425f6d721a6756c5af4d9dd269e5"
+SRC_URI_armadillo800eva = "git://github.com/matsu/gst-plugins-bad.git \
+ file://0001-Setup-MERAM-for-A1.patch"
+S_armadillo800eva = "${WORKDIR}/git/"
+DEPENDS_append_armadillo800eva = " directfb libuiomux libshvio"
+EXTRA_OECONF_armadillo800eva := "${@'${EXTRA_OECONF}'.replace('--disable-directfb', '--enable-directfb')}"
+
+EXTRA_OECONF_append_armadillo800eva = " \
+ --disable-librfb --enable-introspection=no \
+ --disable-nls --disable-static --disable-gsettings \
+"
+
+do_configure_armadillo800eva() {
+ (cd ${S}; sh autogen.sh --noconfigure)
+ oe_runconf
+}
+
+FILES_${PN} += "${bindir}"
+require gst-plugins-private-libs.inc
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-base/0001-gstaudiosink-wait-for-gst_ring_buffer_advance-when-p.patch b/common/recipes-multimedia/gstreamer/gst-plugins-base/0001-gstaudiosink-wait-for-gst_ring_buffer_advance-when-p.patch
new file mode 100644
index 0000000..7d04c8c
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-base/0001-gstaudiosink-wait-for-gst_ring_buffer_advance-when-p.patch
@@ -0,0 +1,79 @@
+From d46fff879acb78b6cd42937864f80e22389e3acb Mon Sep 17 00:00:00 2001
+From: Hideki EIRAKU <hdk@igel.co.jp>
+Date: Fri, 18 May 2012 19:30:27 +0900
+Subject: [PATCH] gstaudiosink: wait for gst_ring_buffer_advance when pausing
+
+If gst_ring_buffer_advance is called after paused, the time of
+audio sink is updated and the base_time will be increased when resuming.
+The base_time change makes a cleared buffer play.
+Gstaudiosrc may have the same problem.
+---
+ gst-libs/gst/audio/gstaudiosink.c | 9 +++++++++
+ gst-libs/gst/audio/gstaudiosink.h | 3 +++
+ 2 files changed, 12 insertions(+)
+
+diff --git a/gst-libs/gst/audio/gstaudiosink.c b/gst-libs/gst/audio/gstaudiosink.c
+index c5fec73..72984bf 100644
+--- a/gst-libs/gst/audio/gstaudiosink.c
++++ b/gst-libs/gst/audio/gstaudiosink.c
+@@ -265,6 +265,8 @@ audioringbuffer_thread_func (GstRingBuffer * buf)
+ gst_ring_buffer_advance (buf, 1);
+ } else {
+ GST_OBJECT_LOCK (abuf);
++ sink->buffer_running = FALSE;
++ g_cond_signal (sink->pause_cond);
+ if (!abuf->running)
+ goto stop_running;
+ if (G_UNLIKELY (g_atomic_int_get (&buf->state) ==
+@@ -280,6 +282,7 @@ audioringbuffer_thread_func (GstRingBuffer * buf)
+ if (!abuf->running)
+ goto stop_running;
+ GST_DEBUG_OBJECT (sink, "continue running");
++ sink->buffer_running = TRUE;
+ GST_OBJECT_UNLOCK (abuf);
+ }
+ }
+@@ -429,6 +432,8 @@ gst_audioringbuffer_activate (GstRingBuffer * buf, gboolean active)
+
+ GST_DEBUG_OBJECT (sink, "starting thread");
+
++ sink->pause_cond = g_cond_new ();
++ sink->buffer_running = TRUE;
+ #if !GLIB_CHECK_VERSION (2, 31, 0)
+ sink->thread =
+ g_thread_create ((GThreadFunc) audioringbuffer_thread_func, buf, TRUE,
+@@ -454,6 +459,7 @@ gst_audioringbuffer_activate (GstRingBuffer * buf, gboolean active)
+
+ /* join the thread */
+ g_thread_join (sink->thread);
++ g_cond_free (sink->pause_cond);
+
+ GST_OBJECT_LOCK (buf);
+ }
+@@ -531,6 +537,9 @@ gst_audioringbuffer_pause (GstRingBuffer * buf)
+ GST_DEBUG_OBJECT (sink, "reset done");
+ }
+
++ if (sink->buffer_running)
++ g_cond_wait (sink->pause_cond, GST_OBJECT_GET_LOCK (buf));
++
+ return TRUE;
+ }
+
+diff --git a/gst-libs/gst/audio/gstaudiosink.h b/gst-libs/gst/audio/gstaudiosink.h
+index 83a4e95..8c32d5a 100644
+--- a/gst-libs/gst/audio/gstaudiosink.h
++++ b/gst-libs/gst/audio/gstaudiosink.h
+@@ -49,6 +49,9 @@ struct _GstAudioSink {
+ /*< private >*/ /* with LOCK */
+ GThread *thread;
+
++ GCond *pause_cond;
++ gboolean buffer_running;
++
+ /*< private >*/
+ gpointer _gst_reserved[GST_PADDING];
+ };
+--
+1.7.10.4
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-base_0.10.36.bbappend b/common/recipes-multimedia/gstreamer/gst-plugins-base_0.10.36.bbappend
new file mode 100644
index 0000000..8765eea
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-base_0.10.36.bbappend
@@ -0,0 +1,5 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+SRC_URI += "file://0001-gstaudiosink-wait-for-gst_ring_buffer_advance-when-p.patch"
+
+require gst-plugins-private-libs.inc
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
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-good_0.10.31.bbappend b/common/recipes-multimedia/gstreamer/gst-plugins-good_0.10.31.bbappend
new file mode 100644
index 0000000..a055a97
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-good_0.10.31.bbappend
@@ -0,0 +1,37 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+PACKAGECONFIG_armadillo800eva += "v4l"
+
+SRC_URI_append_armadillo800eva = " \
+ file://0001-sys-v4l2-gstv4l2-fix-the-depth-value-for-RGB32.patch \
+ file://0002-Revert-sys-v4l2-gstv4l2-fix-the-depth-value-for-RGB3.patch \
+ file://0003-sys-v4l2-gstv4l2-register-uiomux-memory-regions-via-.patch \
+ file://0004-sys-v4l2-gstv4l2-release-corresponding-uiomux-handle.patch \
+ file://0005-videocrop-correct-coding-style-with-gst-indent.patch \
+ file://0006-videocrop-send-a-query-whether-the-rowstride-capabil.patch \
+ file://0007-videocrop-set-rowstride-capability.patch \
+ file://0008-videocrop-kick-off-the-zero-copy-cropping.patch \
+ file://0009-avidemux-set-frame-start-code-to-VC-1-advanced-profi.patch \
+ file://0010-videocrop-add-gst_video_crop_get_image_details_from_.patch \
+ file://0011-videocrop-change-the-unit-of-rowstride-to-byte.patch \
+ file://0012-videocrop-add-tests-to-determine-if-width-and-height.patch \
+ file://0013-videocrop-replace-the-processing-to-set-gint-value-t.patch \
+ file://0014-videocrop-don-t-set-rowstride-only-when-the-color-sp.patch \
+ file://0015-videocrop-fix-wrong-subbuffer-size.patch \
+ file://0016-videocrop-support-getting-NV12-image-details.patch \
+ file://0017-videocrop-add-NV12-format-caps-template.patch \
+ file://0018-videocrop-kick-off-NV12-zero-copy-cropping.patch \
+ file://0019-videocrop-send-a-query-by-the-first-invorker-of-quer.patch \
+ file://0020-videocrop-set-tile-boundary-offset-in-caps-for-T-L-a.patch \
+ file://0021-videocrop-support-cropping-interlaced-images.patch \
+ file://0022-videocrop-move-output-buffer-size-calculation-to-tra.patch \
+ file://0023-videocrop-skip-the-transforming-caps-process-when-th.patch \
+ file://0024-v4l2src-fix-RGB32-colorspace-deinitions.patch \
+ file://0025-sys-v4l2-gstv4l2-skip-set-caps-processing-if-the-par.patch \
+ file://0026-sys-v4l2-gstv4l2-return-an-error-from-set_caps-if-tr.patch \
+ file://0027-videocrop-add-a-new-function-to-determine-if-source-.patch \
+ file://0028-videocrop-set-result-of-determing-if-source-images-a.patch \
+ file://0029-videocrop-round-down-cropping-parameters-when-the-co.patch \
+ file://0030-videocrop-hold-a-lock-to-prevent-from-accessing-crop.patch \
+ file://0031-videocrop-fix-a-memory-leak-caused-by-invoking-gst_p.patch \
+ "
+require gst-plugins-private-libs.inc
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-package.inc b/common/recipes-multimedia/gstreamer/gst-plugins-package.inc
new file mode 100644
index 0000000..7ae3ef6
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-package.inc
@@ -0,0 +1,40 @@
+LIBV = "0.10"
+
+python populate_packages_prepend () {
+ gst_libdir = d.expand('${libdir}/gstreamer-${LIBV}')
+ postinst = d.getVar('plugin_postinst', True)
+ glibdir = d.getVar('libdir', True)
+
+ do_split_packages(d, glibdir, '^lib(.*)\.so\.*', 'lib%s', 'gstreamer %s library', extra_depends='', allow_links=True)
+ do_split_packages(d, gst_libdir, 'libgst(.*)\.so$', d.expand('${PN}-%s'), 'GStreamer plugin for %s', postinst=postinst, extra_depends=d.expand('${PN}'))
+ do_split_packages(d, gst_libdir, 'libgst(.*)\.la$', d.expand('${PN}-%s-dev'), 'GStreamer plugin for %s (development files)', extra_depends=d.expand('${PN}-dev'))
+ do_split_packages(d, gst_libdir, 'libgst(.*)\.a$', d.expand('${PN}-%s-staticdev'), 'GStreamer plugin for %s (static development files)', extra_depends=d.expand('${PN}-staticdev'))
+
+ pn = d.getVar('PN', True)
+ metapkg = pn + '-meta'
+ d.setVar('ALLOW_EMPTY_' + metapkg, "1")
+ d.setVar('FILES_' + metapkg, "")
+ blacklist = [ pn + '-locale', pn + '-dev', pn + '-dbg', pn + '-doc' ]
+ metapkg_rdepends = []
+ packages = d.getVar('PACKAGES', True).split()
+ for pkg in packages[1:]:
+ if not pkg in blacklist and not pkg in metapkg_rdepends and not pkg.endswith('-dev') and not pkg.endswith('-dbg') and not pkg.count('locale') and not pkg.count('-staticdev'):
+ metapkg_rdepends.append(pkg)
+ d.setVar('RDEPENDS_' + metapkg, ' '.join(metapkg_rdepends))
+ d.setVar('DESCRIPTION_' + metapkg, pn + ' meta package')
+}
+
+# metapkg has runtime dependency on PN
+# each plugin depends on PN, plugin-dev on PN-dev and plugin-staticdev on PN-staticdev
+# so we need them even when empty (like in gst-plugins-good case)
+ALLOW_EMPTY_${PN} = "1"
+ALLOW_EMPTY_${PN}-dev = "1"
+ALLOW_EMPTY_${PN}-staticdev = "1"
+
+PACKAGES += "${PN}-apps ${PN}-meta ${PN}-glib"
+FILES_${PN}-apps = "${bindir}"
+
+FILES_${PN} = "${datadir}/gstreamer-${LIBV}"
+FILES_${PN}-dbg += "${libdir}/gstreamer-${LIBV}/.debug"
+FILES_${PN}-glib = "${datadir}/glib-2.0"
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-private-libs.inc b/common/recipes-multimedia/gstreamer/gst-plugins-private-libs.inc
new file mode 100644
index 0000000..ca59ea3
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-private-libs.inc
@@ -0,0 +1,18 @@
+PACKAGESPLITFUNCS_prepend += " add_private_libs_packages "
+
+python add_private_libs_packages () {
+ import os
+ import re
+
+ pn = d.getVar('PN', True)
+ gst_libdir = d.expand('${libdir}/gstreamer-${LIBV}')
+
+ dvar = d.getVar('PKGD', True)
+
+ for dirpath, dirnames, filenames in os.walk(dvar + gst_libdir):
+ for f in filenames:
+ m = re.match('libgst(.*)\.so$', f)
+ if m:
+ plugins = m.group(1)
+ d.setVar('PRIVATE_LIBS_' + pn + '-' + plugins , 'libgst' + plugins + '.so')
+}
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-ugly/0001-asfdemux-asfpacket-set-frame-start-code-to-VC-1-adva.patch b/common/recipes-multimedia/gstreamer/gst-plugins-ugly/0001-asfdemux-asfpacket-set-frame-start-code-to-VC-1-adva.patch
new file mode 100644
index 0000000..d065c7c
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-ugly/0001-asfdemux-asfpacket-set-frame-start-code-to-VC-1-adva.patch
@@ -0,0 +1,99 @@
+From 258bf9862e5b7179562f0cae9fb470f6486dca3a Mon Sep 17 00:00:00 2001
+From: Kazunori Kobayashi <kkobayas@igel.co.jp>
+Date: Thu, 12 Jul 2012 12:08:15 +0900
+Subject: [PATCH] asfdemux/asfpacket: 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.
+---
+ gst/asfdemux/asfpacket.c | 36 +++++++++++++++++++++++++++++++++---
+ 1 file changed, 33 insertions(+), 3 deletions(-)
+
+diff --git a/gst/asfdemux/asfpacket.c b/gst/asfdemux/asfpacket.c
+index 552a559..77209f1 100644
+--- a/gst/asfdemux/asfpacket.c
++++ b/gst/asfdemux/asfpacket.c
+@@ -71,9 +71,10 @@ asf_packet_read_varlen_int (guint lentype_flags, guint lentype_bit_offset,
+
+ static GstBuffer *
+ asf_packet_create_payload_buffer (AsfPacket * packet, const guint8 ** p_data,
+- guint * p_size, guint payload_len)
++ guint * p_size, guint payload_len, gboolean need_st_code)
+ {
+ guint off;
++ guint8 *st_code;
+
+ g_assert (payload_len <= *p_size);
+
+@@ -83,6 +84,21 @@ asf_packet_create_payload_buffer (AsfPacket * packet, const guint8 ** p_data,
+ *p_data += payload_len;
+ *p_size -= payload_len;
+
++ /* set start code for VC-1 advanced profile */
++ if (need_st_code && off >= 4) {
++ st_code = GST_BUFFER_DATA (packet->buf) + (off - 4);
++ /* check if this packet has a start code */
++ if (st_code[4] != 0x00 || st_code[5] != 0x00 || st_code[6] != 0x01 ||
++ st_code[7] != 0x0d) {
++ st_code[0] = 0x00;
++ st_code[1] = 0x00;
++ st_code[2] = 0x01;
++ st_code[3] = 0x0d;
++
++ return gst_buffer_create_sub (packet->buf, off - 4, payload_len + 4);
++ }
++ }
++
+ return gst_buffer_create_sub (packet->buf, off, payload_len);
+ }
+
+@@ -274,6 +290,9 @@ gst_asf_demux_parse_payload (GstASFDemux * demux, AsfPacket * packet,
+ gboolean is_compressed;
+ guint payload_len;
+ guint stream_num;
++ GstStructure *structure;
++ guint32 fourcc;
++ gboolean need_st_code = FALSE;
+
+ if (G_UNLIKELY (*p_size < 1)) {
+ GST_WARNING_OBJECT (demux, "Short packet!");
+@@ -353,6 +372,17 @@ gst_asf_demux_parse_payload (GstASFDemux * demux, AsfPacket * packet,
+ return TRUE;
+ }
+
++ structure = gst_caps_get_structure (stream->caps, 0);
++ if (gst_structure_get_fourcc (structure, "format", &fourcc)) {
++ /*
++ * set start code for VC-1 advanced profile if fourcc is 'WVC1' and this
++ * packet is at the head of a payload.
++ */
++ if (fourcc == GST_MAKE_FOURCC ('W', 'V', 'C', '1')
++ && payload.mo_offset == 0)
++ need_st_code = TRUE;
++ }
++
+ if (G_UNLIKELY (!is_compressed)) {
+ GST_LOG_OBJECT (demux, "replicated data length: %u", payload.rep_data_len);
+
+@@ -384,7 +414,7 @@ gst_asf_demux_parse_payload (GstASFDemux * demux, AsfPacket * packet,
+ if ((stream = gst_asf_demux_get_stream (demux, stream_num))
+ && payload_len) {
+ payload.buf = asf_packet_create_payload_buffer (packet, p_data, p_size,
+- payload_len);
++ payload_len, need_st_code);
+
+ /* n-th fragment of a fragmented media object? */
+ if (payload.mo_offset != 0) {
+@@ -443,7 +473,7 @@ gst_asf_demux_parse_payload (GstASFDemux * demux, AsfPacket * packet,
+
+ if (G_LIKELY (sub_payload_len > 0)) {
+ payload.buf = asf_packet_create_payload_buffer (packet,
+- &payload_data, &payload_len, sub_payload_len);
++ &payload_data, &payload_len, sub_payload_len, need_st_code);
+
+ payload.ts = ts;
+ if (G_LIKELY (ts_delta))
+--
+1.7.9.5
+
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins-ugly_0.10.19.bbappend b/common/recipes-multimedia/gstreamer/gst-plugins-ugly_0.10.19.bbappend
new file mode 100644
index 0000000..b8c651f
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins-ugly_0.10.19.bbappend
@@ -0,0 +1,5 @@
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+SRC_URI_bockw += " \
+ file://0001-asfdemux-asfpacket-set-frame-start-code-to-VC-1-adva.patch \
+"
+require gst-plugins-private-libs.inc
diff --git a/common/recipes-multimedia/gstreamer/gst-plugins.inc b/common/recipes-multimedia/gstreamer/gst-plugins.inc
new file mode 100644
index 0000000..fc9567a
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gst-plugins.inc
@@ -0,0 +1,29 @@
+DESCRIPTION = "Plugins for GStreamer"
+HOMEPAGE = "http://gstreamer.freedesktop.org/"
+BUGTRACKER = "https://bugzilla.gnome.org/enter_bug.cgi?product=Gstreamer"
+SECTION = "multimedia"
+DEPENDS = "gstreamer"
+
+inherit autotools pkgconfig
+
+FILESPATH =. "${FILE_DIRNAME}/gst-plugins:"
+
+SRC_URI = "http://gstreamer.freedesktop.org/src/${BPN}/${BPN}-${PV}.tar.bz2"
+
+GSTREAMER_DEBUG ?= "--disable-debug"
+EXTRA_OECONF = "--disable-valgrind ${GSTREAMER_DEBUG} --disable-examples "
+
+acpaths = "-I ${S}/common/m4 -I ${S}/m4"
+
+require gst-plugins-package.inc
+
+PACKAGES_DYNAMIC += "^${PN}-.*"
+
+# apply gstreamer hack after Makefile.in.in in source is replaced by our version from
+# ${STAGING_DATADIR_NATIVE}/gettext/po/Makefile.in.in, but before configure is executed
+# http://lists.linuxtogo.org/pipermail/openembedded-core/2012-November/032233.html
+oe_runconf_prepend() {
+ if [ -e ${S}/po/Makefile.in.in ]; then
+ sed -i -e "1a\\" -e 'GETTEXT_PACKAGE = @GETTEXT_PACKAGE@' ${S}/po/Makefile.in.in
+ fi
+}
diff --git a/common/recipes-multimedia/gstreamer/gstreamer1.0-libav/libav_e500mc.patch b/common/recipes-multimedia/gstreamer/gstreamer1.0-libav/libav_e500mc.patch
new file mode 100644
index 0000000..eba4988
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gstreamer1.0-libav/libav_e500mc.patch
@@ -0,0 +1,21 @@
+diff --git a/gst-libs/ext/libav/configure b/gst-libs/ext/libav/configure
+index 8473069..4f74952 100755
+--- a/gst-libs/ext/libav/configure
++++ b/gst-libs/ext/libav/configure
+Fix gst-ffmpeg build issues for libav on e500mc (fsl-p4080)
+
+Upstream-Status: Backport
+
+Signed-off-by: Yao Zhao <yao.zhao@windriver.com>
+
+@@ -2210,6 +2210,10 @@ elif enabled ppc; then
+ cpuflags="-mcpu=cell"
+ enable ldbrx
+ ;;
++ e500mc)
++ cpuflags="-mcpu=e500mc"
++ disable altivec
++ ;;
+ e500v2)
+ cpuflags="-mcpu=8548 -mhard-float -mfloat-gprs=double"
+ disable altivec
diff --git a/common/recipes-multimedia/gstreamer/gstreamer1.0-libav_1.2.3.bbappend b/common/recipes-multimedia/gstreamer/gstreamer1.0-libav_1.2.3.bbappend
new file mode 100644
index 0000000..d55fea3
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gstreamer1.0-libav_1.2.3.bbappend
@@ -0,0 +1,9 @@
+PACKAGECONFIG ??= " orc "
+
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+SRC_URI += " \
+ file://libav_e500mc.patch \
+ "
+
+INSANE_SKIP_${PN} += "textrel"
diff --git a/common/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.2.3.bbappend b/common/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.2.3.bbappend
new file mode 100644
index 0000000..0a0f5d9
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad_1.2.3.bbappend
@@ -0,0 +1,21 @@
+PACKAGECONFIG ??= " \
+ ${@base_contains('DISTRO_FEATURES', 'wayland', 'wayland', '', d)} \
+ ${@base_contains('DISTRO_FEATURES', 'opengl', 'eglgles', '', d)} \
+ ${@base_contains('DISTRO_FEATURES', 'bluetooth', 'bluez', '', d)} \
+ ${@base_contains('DISTRO_FEATURES', 'directfb', 'directfb', '', d)} \
+ curl uvch264 neon \
+ hls sbc dash bz2 smoothstreaming \
+ "
+
+DEPENDS += "directfb faad2 libxml2 libuiomux libshvio"
+
+FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
+
+TARGET_CFLAGS += "-D_GNU_SOURCE"
+PACKAGECONFIG[directfb] = "--enable-directfb,--disable-directfb,directfb"
+
+PACKAGECONFIG := "${@'${PACKAGECONFIG}'.replace('curl', '')}"
+PACKAGECONFIG := "${@'${PACKAGECONFIG}'.replace('eglgles', '')}"
+PACKAGECONFIG += "faad directfb"
+
+EXTRA_OECONF += "--enable-directfb --enable-experimental --disable-nls"
diff --git a/common/recipes-multimedia/gstreamer/gstreamer1.0-plugins-base_1.2.3.bbappend b/common/recipes-multimedia/gstreamer/gstreamer1.0-plugins-base_1.2.3.bbappend
new file mode 100644
index 0000000..2f46ba3
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gstreamer1.0-plugins-base_1.2.3.bbappend
@@ -0,0 +1,5 @@
+PACKAGECONFIG ??= " \
+ ${@base_contains('DISTRO_FEATURES', 'x11', 'x11', '', d)} \
+ ${@base_contains('DISTRO_FEATURES', 'alsa', 'alsa', '', d)} \
+ ivorbis ogg theora vorbis \
+ "
diff --git a/common/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good_1.2.3.bbappend b/common/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good_1.2.3.bbappend
new file mode 100644
index 0000000..910b031
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gstreamer1.0-plugins-good_1.2.3.bbappend
@@ -0,0 +1,5 @@
+PACKAGECONFIG ??= " \
+ ${@base_contains('DISTRO_FEATURES', 'x11', 'x11', '', d)} \
+ ${@base_contains('DISTRO_FEATURES', 'pulseaudio', 'pulseaudio', '', d)} \
+ cairo flac gdk-pixbuf jpeg libpng soup speex taglib \
+ "
diff --git a/common/recipes-multimedia/gstreamer/gstreamer1.0_1.2.3.bbappend b/common/recipes-multimedia/gstreamer/gstreamer1.0_1.2.3.bbappend
new file mode 100644
index 0000000..35c76f2
--- /dev/null
+++ b/common/recipes-multimedia/gstreamer/gstreamer1.0_1.2.3.bbappend
@@ -0,0 +1 @@
+PRIVATE_LIBS_${PN} = "libgstcoreelements.so"