diff options
author | Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com> | 2015-03-25 10:47:45 +0900 |
---|---|---|
committer | Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com> | 2015-03-25 10:47:45 +0900 |
commit | 1c35920d85e424b3f65aa6df1dbde689dd6ec007 (patch) | |
tree | 58b2cacb3674111aad5a4ded694db0cef5cf55f3 /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')
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" |