summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorharinarayan <harinarayan@24075187-2e39-4e88-bbb8-bc8aa768f540>2012-01-19 11:31:01 +0000
committerharinarayan <harinarayan@24075187-2e39-4e88-bbb8-bc8aa768f540>2012-01-19 11:31:01 +0000
commit197c9239e6d00c2c6649afd84cd6e5a394702b8b (patch)
tree1e0a9d84fe5e8d1d452323fa2689f08576350f9d
parent427e41df45c8e79ffa8da6860408fdb91cccdf8c (diff)
Merge to trunk for DM81xx release 0.4HEADmaster
git-svn-id: https://gstreamer.ti.com/svn/gstreamer_ti/trunk@1023 24075187-2e39-4e88-bbb8-bc8aa768f540
-rwxr-xr-xgstreamer_ti_dm81xx/Makefile.common13
-rw-r--r--gstreamer_ti_dm81xx/opensource_build/Makefile18
-rwxr-xr-xgstreamer_ti_dm81xx/opensource_build/Packages.make.dm81xx53
-rw-r--r--gstreamer_ti_dm81xx/opensource_build/distfiles/gst-plugins-good-0.10.28.tar.gzbin0 -> 4536686 bytes
-rw-r--r--gstreamer_ti_dm81xx/opensource_build/distfiles/gst-plugins-good-0.10.28.tar.gz.sha256sum1
-rw-r--r--gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-bad-0.10.21/0008-h264parse-modifications-for-playbin.patch203
-rw-r--r--gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-bad-0.10.21/0009-mpeg4videoparse-push-flush-stop-and-new-segment24
-rw-r--r--gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-base-0.10.32/0026-playbin-link-omx_scaler-to-do-HW-accel-scale-remove-identity.patch50
-rw-r--r--gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-base-0.10.32/0026-playbin-link-omx_scaler-to-do-HW-accel-scale.patch43
-rw-r--r--gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0001-v4l2-fix-handling-of-RGB32-BGR32-formats.patch53
-rw-r--r--gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0002-v4l2sink-Add-rotation-support.patch128
-rw-r--r--gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0003-v4l2sink-Add-flip-property.patch187
-rw-r--r--gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0004-v4l2sink-Add-support-for-omap24xxvout-driver.patch59
-rw-r--r--gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0005-v4l2sink-Add-support-for-omap_vout-driver.patch34
-rw-r--r--gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0006-v4l2-increase-v4l2sink-element-rank.patch26
-rw-r--r--gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0007-use-GstQueryBuffers-to-get-buffer-requirements.patch97
-rw-r--r--gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0008-add-rowstride-support.patch572
-rw-r--r--gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0009-use-GstEventCrop-to-get-crop-info.patch119
-rw-r--r--gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0010-v4l2-prefer-NV12.patch28
-rw-r--r--gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0011-v4l2sink-fix-issue-seen-with-autoconvert.patch49
-rwxr-xr-xgstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0012-v4l2sink-Add-Userptr-support.patch440
-rw-r--r--gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0013-v4l2sink-interlaced-seq-tb-format.patch38
-rwxr-xr-xgstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0014-v4l2src-Add-Userptr-support.patch332
-rw-r--r--gstreamer_ti_dm81xx/opensource_build/patchfiles/gstreamer-0.10.32/0006-queue-free-erroneous-buffer.patch12
-rw-r--r--gstreamer_ti_dm81xx/ti_build/Makefile4
-rw-r--r--gstreamer_ti_dm81xx/ti_build/gst-openmax/ChangeLog6
-rw-r--r--gstreamer_ti_dm81xx/ti_build/gst-openmax/configure.ac3
-rwxr-xr-xgstreamer_ti_dm81xx/ti_build/gst-openmax/ext/Makefile8
-rwxr-xr-xgstreamer_ti_dm81xx/ti_build/gst-openmax/omx/Makefile.am9
-rwxr-xr-xgstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx.c16
-rw-r--r--gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_aacdec.c608
-rw-r--r--gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_aacenc.c360
-rw-r--r--gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_aacenc.h1
-rw-r--r--gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_audiodec.c1
-rwxr-xr-xgstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_ctrl.h1
-rw-r--r--gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_filter.c59
-rw-r--r--gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_filter.h2
-rw-r--r--gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_filter2.c1028
-rw-r--r--gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_filter2.h89
-rw-r--r--gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_vfpc2.c297
-rw-r--r--gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_vfpc2.h70
-rw-r--r--gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_videodec.c43
-rwxr-xr-xgstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_buffertransport.c71
-rw-r--r--gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_buffertransport.h2
-rw-r--r--gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_deiscaler.c403
-rw-r--r--gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_deiscaler.h55
-rwxr-xr-xgstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_h264dec.c9
-rw-r--r--gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_h264enc.c374
-rw-r--r--gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_h264enc.h8
-rwxr-xr-xgstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_mjpegdec.c157
-rw-r--r--gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_mjpegdec.h51
-rwxr-xr-xgstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_mpeg2dec.c2
-rwxr-xr-xgstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_port.c254
-rw-r--r--gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_port.h5
-rw-r--r--gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_scaler.c12
-rw-r--r--gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_util.h4
-rwxr-xr-xgstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_videomixer.c119
-rwxr-xr-xgstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_videomixer.h4
-rwxr-xr-xgstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomxbufferalloc.c348
-rwxr-xr-xgstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomxbufferalloc.h96
-rw-r--r--gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstperf.c5
-rw-r--r--gstreamer_ti_dm81xx/ti_build/gst-openmax/util/sem.c13
62 files changed, 6676 insertions, 500 deletions
diff --git a/gstreamer_ti_dm81xx/Makefile.common b/gstreamer_ti_dm81xx/Makefile.common
index 509f5fe..8e9df31 100755
--- a/gstreamer_ti_dm81xx/Makefile.common
+++ b/gstreamer_ti_dm81xx/Makefile.common
@@ -39,10 +39,10 @@
#
# These paths must be specified or the build will fail.
#------------------------------------------------------------------------------
-TARGET_ROOT_DIR = /proj/NEE/hari/prashant_gstreamer/target
-GSTREAMER_DIR = /opt/gstreamer
-GST_TI_PLATFORM = dm814x
-EZSDK_INSTALL_DIR = /proj/NEE/hari/ti-ezsdk_dm814x-evm_5_02_01_59
+TARGET_ROOT_DIR = /home2/hari/ti-ezsdk_dm816x-evm_5_03_01_15/rootfs
+GSTREAMER_DIR = /usr
+GST_TI_PLATFORM = dm816x
+EZSDK_INSTALL_DIR = /home2/hari/ti-ezsdk_dm816x-evm_5_03_01_15
#------------------------------------------------------------------------------
# Build configuration:
#
@@ -365,6 +365,10 @@ CFLAGS_dm816x = -march=armv7-a -mtune=cortex-a8
CFLAGS_dm816x += -mfpu=neon -mfloat-abi=softfp
CFLAGS_dm814x = -march=armv7-a -mtune=cortex-a8
CFLAGS_dm814x += -mfpu=neon -mfloat-abi=softfp
+ASFLAGS_dm816x = -march=armv7-a -mtune=cortex-a8
+ASFLAGS_dm816x += -mfpu=neon -mfloat-abi=softfp
+ASFLAGS_dm814x = -march=armv7-a -mtune=cortex-a8
+ASFLAGS_dm814x += -mfpu=neon -mfloat-abi=softfp
LDFLAGS_all = -L$(TARGET_GSTREAMER_DIR)/lib
LDFLAGS_dm355 = -L$(LINUXLIBS_INSTALL_DIR)/lib
@@ -429,6 +433,7 @@ CC_CONFIGURE_OPTS += NM=$(MVTOOL_PREFIX)nm
CC_CONFIGURE_OPTS += RANLIB=$(MVTOOL_PREFIX)ranlib
CC_CONFIGURE_OPTS += CPPFLAGS="$(CPPFLAGS_all) $(CPPFLAGS_$(GST_TI_PLATFORM))"
CC_CONFIGURE_OPTS += CFLAGS="$(CFLAGS_all) $(CFLAGS_$(GST_TI_PLATFORM))"
+CC_CONFIGURE_OPTS += ASFLAGS="$(ASFLAGS_$(GST_TI_PLATFORM))"
CC_CONFIGURE_OPTS += LDFLAGS="$(LDFLAGS_all) $(LDFLAGS_$(GST_TI_PLATFORM))"
export CC = $(MVTOOL_PREFIX)gcc
diff --git a/gstreamer_ti_dm81xx/opensource_build/Makefile b/gstreamer_ti_dm81xx/opensource_build/Makefile
index 1822a59..175d445 100644
--- a/gstreamer_ti_dm81xx/opensource_build/Makefile
+++ b/gstreamer_ti_dm81xx/opensource_build/Makefile
@@ -34,6 +34,7 @@ endif
PACKAGES = $(BASE_PACKAGES) $(PLUGIN_PACKAGES)
+PATCHFILES = $(foreach x, $(PACKAGES), $(addprefix patchfiles/$(PACKAGE_$(x)_ARCHIVE_BASENAME)/, $(PACKAGE_$(x)_PRECONFIG_PATCHES)))
#------------------------------------------------------------------------------
# Build targets
#------------------------------------------------------------------------------
@@ -49,25 +50,16 @@ all: .plugins
.plugins: .base
$(CMD_PREFIX) $(MAKE) plugins $(BUILD_INSTALL) && touch $@
-base:
- $(CMD_PREFIX) $(MAKE) orc $(BUILD_INSTALL)
- $(CMD_PREFIX) $(MAKE) glib $(BUILD_INSTALL)
- $(CMD_PREFIX) $(MAKE) check $(BUILD_INSTALL)
- $(CMD_PREFIX) $(MAKE) gstreamer $(BUILD_INSTALL)
- $(CMD_PREFIX) $(MAKE) id3tag $(BUILD_INSTALL)
- $(CMD_PREFIX) $(MAKE) mad $(BUILD_INSTALL)
- $(CMD_PREFIX) $(MAKE) lame $(BUILD_INSTALL)
- $(CMD_PREFIX) $(MAKE) faad $(BUILD_INSTALL)
- $(CMD_PREFIX) $(MAKE) faac $(BUILD_INSTALL)
- $(CMD_PREFIX) $(MAKE) plugins_base $(BUILD_INSTALL)
- $(CMD_PREFIX) $(MAKE) ffmpeg $(BUILD_INSTALL)
- $(CMD_PREFIX) $(MAKE) plugin_h264 $(BUILD_INSTALL)
+base: $(BASE_PACKAGES)
plugins: $(PLUGIN_PACKAGES)
$(PACKAGES): % : %.build
install:
+patchfiles.tar.gz: $(PATCHFILES)
+ $(CMD_PREFIX) tar zcvf patchfiles.tar.gz $(PATCHFILES)
+
#------------------------------------------------------------------------------
# clean: Remove all build sources
#------------------------------------------------------------------------------
diff --git a/gstreamer_ti_dm81xx/opensource_build/Packages.make.dm81xx b/gstreamer_ti_dm81xx/opensource_build/Packages.make.dm81xx
index 3f6691d..9224e38 100755
--- a/gstreamer_ti_dm81xx/opensource_build/Packages.make.dm81xx
+++ b/gstreamer_ti_dm81xx/opensource_build/Packages.make.dm81xx
@@ -15,6 +15,18 @@
# Packages processed by this build script.
#------------------------------------------------------------------------------
+#-------------------------------------------------------------------------------
+# Package orc
+#-------------------------------------------------------------------------------
+PACKAGE_orc_BUILD_TARGET = orc
+PACKAGE_orc_ARCHIVE_BASENAME = orc-0.4.14
+PACKAGE_orc_PRECONFIG_PATCHES =
+PACKAGE_orc_CONFIGURE_OPTS =
+PACKAGE_orc_POSTCONFIG_PATCHES =
+PACKAGE_orc_DESCRIPTION = \
+ ORC compiler
+BASE_PACKAGES += $(PACKAGE_orc_BUILD_TARGET)
+
#------------------------------------------------------------------------------
# Package glib
#------------------------------------------------------------------------------
@@ -39,19 +51,6 @@ PACKAGE_check_BUILD_DIRS =
PACKAGE_check_DESCRIPTION = Check: a unit test framework for C
BASE_PACKAGES += $(PACKAGE_check_BUILD_TARGET)
-#-------------------------------------------------------------------------------
-# Package orc
-#-------------------------------------------------------------------------------
-PACKAGE_orc_BUILD_TARGET = orc
-PACKAGE_orc_ARCHIVE_BASENAME = orc-0.4.14
-PACKAGE_orc_PRECONFIG_PATCHES =
-PACKAGE_orc_CONFIGURE_OPTS =
-PACKAGE_orc_POSTCONFIG_PATCHES =
-PACKAGE_orc_DESCRIPTION = \
- ORC compiler
-PLUGIN_PACKAGES += $(PACKAGE_orc_BUILD_TARGET)
-
-
#------------------------------------------------------------------------------
# Package gstreamer
#------------------------------------------------------------------------------
@@ -61,7 +60,8 @@ PACKAGE_gstreamer_PRECONFIG_PATCHES = \
0001-gst-launch-add-loop-argument.patch \
0003-add-GstQueryBuffers-query.patch \
0004-Add-GstEventCrop-event.patch \
- 0005-basetransform-don-t-do-unnecessary-pad_alloc.patch
+ 0005-basetransform-don-t-do-unnecessary-pad_alloc.patch \
+ 0006-queue-free-erroneous-buffer.patch
PACKAGE_gstreamer_CONFIGURE_OPTS = --disable-loadsave --disable-tests --disable-examples
PACKAGE_gstreamer_POSTCONFIG_PATCHES =
PACKAGE_gstreamer_BUILD_DIRS =
@@ -122,7 +122,8 @@ PACKAGE_plugins_base_PRECONFIG_PATCHES = \
0022-stride-support-for-32bit-RGB-formats.patch \
0023-ffmpegcolorspace-support-for-rowstride.patch \
0024-discoverer-rowstride-support.patch \
- 0025-playsink-link-omx_colorconv-to-do-HW-accel-color-con.patch
+ 0025-playsink-link-omx_colorconv-to-do-HW-accel-color-con.patch \
+ 0026-playbin-link-omx_scaler-to-do-HW-accel-scale-remove-identity.patch
PACKAGE_plugins_base_RUN_AUTOGEN = true
PACKAGE_plugins_base_CONFIGURE_OPTS = --disable-examples --disable-x --disable-ogg --disable-vorbis --disable-pango $(ALSA_SUPPORT)
PACKAGE_plugins_base_POSTCONFIG_PATCHES =
@@ -133,7 +134,7 @@ BASE_PACKAGES += $(PACKAGE_plugins_base_BUILD_TARGET)
# Package plugins_good
#------------------------------------------------------------------------------
PACKAGE_plugins_good_BUILD_TARGET = plugins_good
-PACKAGE_plugins_good_ARCHIVE_BASENAME = gst-plugins-good-0.10.27
+PACKAGE_plugins_good_ARCHIVE_BASENAME = gst-plugins-good-0.10.28
PACKAGE_plugins_good_CONFIGURE_OPTS = --disable-x --disable-shout2 --enable-experimental --disable-aalib --disable-esd
PACKAGE_plugins_good_PRECONFIG_PATCHES = \
0001-v4l2-fix-handling-of-RGB32-BGR32-formats.patch \
@@ -148,7 +149,8 @@ PACKAGE_plugins_good_PRECONFIG_PATCHES = \
0010-v4l2-prefer-NV12.patch \
0011-v4l2sink-fix-issue-seen-with-autoconvert.patch \
0012-v4l2sink-Add-Userptr-support.patch \
- 0013-v4l2sink-interlaced-seq-tb-format.patch
+ 0013-v4l2sink-interlaced-seq-tb-format.patch \
+ 0014-v4l2src-Add-Userptr-support.patch
PACKAGE_plugins_good_POSTCONFIG_PATCHES =
PACKAGE_plugins_good_DESCRIPTION = \
Select plugins from GStreamer good-plugins (avi, qtdemux, oss, v4l2)
@@ -163,10 +165,11 @@ PACKAGE_plugins_bad_PRECONFIG_PATCHES = \
0001-freeze-Add-timeout-property.patch \
0002-fixes-to-mux-h264-stream-utilizing-ctts.patch \
0003-ugly-hack-to-avoid-a-memcpy.patch \
- 0004-h264parse-Add-workaround-for-separate-codec_config-a.patch \
0005-jpegparse-ignore-unhandled-application-markers.patch \
0006-mpegvideoparse-merge-sequence-header.patch \
- 0007-h264parse-fix-boundary-condition.patch
+ 0007-h264parse-fix-boundary-condition.patch \
+ 0008-h264parse-modifications-for-playbin.patch \
+ 0009-mpeg4videoparse-push-flush-stop-and-new-segment
PACKAGE_plugins_bad_POSTCONFIG_PATCHES =
PACKAGE_plugins_bad_BUILD_DIRS =
PACKAGE_plugins_bad_CONFIGURE_OPTS = --disable-sdl
@@ -246,15 +249,3 @@ PACKAGE_plugin_h264_DESCRIPTION = \
Plugin to build nalbytestream_h264 parser
PLUGIN_PACKAGES += $(PACKAGE_plugin_h264_BUILD_TARGET)
-#-------------------------------------------------------------------------------
-# Package orc
-#-------------------------------------------------------------------------------
-PACKAGE_orc_BUILD_TARGET = orc
-PACKAGE_orc_ARCHIVE_BASENAME = orc-0.4.14
-PACKAGE_orc_PRECONFIG_PATCHES =
-PACKAGE_orc_CONFIGURE_OPTS =
-PACKAGE_orc_POSTCONFIG_PATCHES =
-PACKAGE_orc_DESCRIPTION = \
- ORC compiler
-PLUGIN_PACKAGES += $(PACKAGE_orc_BUILD_TARGET)
-
diff --git a/gstreamer_ti_dm81xx/opensource_build/distfiles/gst-plugins-good-0.10.28.tar.gz b/gstreamer_ti_dm81xx/opensource_build/distfiles/gst-plugins-good-0.10.28.tar.gz
new file mode 100644
index 0000000..2183303
--- /dev/null
+++ b/gstreamer_ti_dm81xx/opensource_build/distfiles/gst-plugins-good-0.10.28.tar.gz
Binary files differ
diff --git a/gstreamer_ti_dm81xx/opensource_build/distfiles/gst-plugins-good-0.10.28.tar.gz.sha256sum b/gstreamer_ti_dm81xx/opensource_build/distfiles/gst-plugins-good-0.10.28.tar.gz.sha256sum
new file mode 100644
index 0000000..6fc6195
--- /dev/null
+++ b/gstreamer_ti_dm81xx/opensource_build/distfiles/gst-plugins-good-0.10.28.tar.gz.sha256sum
@@ -0,0 +1 @@
+61a96f9985c362b7d3ce2052f027db5d7228dcde02451471c7c87f28d9993685 gst-plugins-good-0.10.28.tar.gz
diff --git a/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-bad-0.10.21/0008-h264parse-modifications-for-playbin.patch b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-bad-0.10.21/0008-h264parse-modifications-for-playbin.patch
new file mode 100644
index 0000000..0a00615
--- /dev/null
+++ b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-bad-0.10.21/0008-h264parse-modifications-for-playbin.patch
@@ -0,0 +1,203 @@
+--- gst-plugins-bad-0.10.21.bkp/gst/h264parse/gsth264parse.c 2011-11-28 20:17:08.483609875 +0530
++++ gst-plugins-bad-0.10.21/gst/h264parse/gsth264parse.c 2011-11-30 12:04:48.163610030 +0530
+@@ -38,19 +38,21 @@
+ static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+- GST_STATIC_CAPS ("video/x-h264"));
++ GST_STATIC_CAPS ("video/x-h264,"
++ "framed = (boolean)false"));
+
+ static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+- GST_STATIC_CAPS ("video/x-h264"));
++ GST_STATIC_CAPS ("video/x-h264,"
++ "framed = (boolean)true"));
+
+ GST_DEBUG_CATEGORY_STATIC (h264_parse_debug);
+ #define GST_CAT_DEFAULT h264_parse_debug
+
+-#define DEFAULT_SPLIT_PACKETIZED FALSE
+-#define DEFAULT_ACCESS_UNIT FALSE
+-#define DEFAULT_OUTPUT_FORMAT GST_H264_PARSE_FORMAT_INPUT
++#define DEFAULT_SPLIT_PACKETIZED TRUE
++#define DEFAULT_ACCESS_UNIT TRUE
++#define DEFAULT_OUTPUT_FORMAT GST_H264_PARSE_FORMAT_BYTE
+ #define DEFAULT_CONFIG_INTERVAL (0)
+
+ enum
+@@ -964,7 +966,7 @@ gst_h264_parse_init (GstH264Parse * h264
+ h264parse->interval = DEFAULT_CONFIG_INTERVAL;
+ h264parse->last_report = GST_CLOCK_TIME_NONE;
+
+- h264parse->format = GST_H264_PARSE_FORMAT_INPUT;
++ h264parse->format = DEFAULT_OUTPUT_FORMAT;
+
+ gst_h264_parse_reset (h264parse);
+ }
+@@ -1128,11 +1130,11 @@ gst_h264_parse_make_codec_data (GstH264P
+ num_sps++;
+ /* size bytes also count */
+ sps_size += GST_BUFFER_SIZE (nal) - 4 + 2;
+- if (GST_BUFFER_SIZE (nal) >= 7) {
++ if (GST_BUFFER_SIZE (nal) >= 8) {
+ found = TRUE;
+- profile_idc = (GST_BUFFER_DATA (nal))[4];
+- profile_comp = (GST_BUFFER_DATA (nal))[5];
+- level_idc = (GST_BUFFER_DATA (nal))[6];
++ profile_idc = (GST_BUFFER_DATA (nal))[5];
++ profile_comp = (GST_BUFFER_DATA (nal))[6];
++ level_idc = (GST_BUFFER_DATA (nal))[7];
+ }
+ }
+ }
+@@ -1307,16 +1309,18 @@ gst_h264_parse_update_src_caps (GstH264P
+ alignment = "au";
+ } else {
+ if (h264parse->packetized) {
+- /* if packetized input, take upstream alignment if validly provided,
+- * otherwise assume au aligned ... */
+- alignment = gst_structure_get_string (structure, "alignment");
+- if (!alignment || (alignment &&
+- strcmp (alignment, "au") != 0 &&
+- strcmp (alignment, "nal") != 0)) {
+- if (h264parse->split_packetized)
+- alignment = "nal";
+- else
++ if (h264parse->split_packetized)
++ alignment = "nal";
++ else {
++ /* if packetized input is not split,
++ * take upstream alignment if validly provided,
++ * otherwise assume au aligned ... */
++ alignment = gst_structure_get_string (structure, "alignment");
++ if (!alignment || (alignment &&
++ strcmp (alignment, "au") != 0 &&
++ strcmp (alignment, "nal") != 0)) {
+ alignment = "au";
++ }
+ }
+ } else {
+ alignment = "nal";
+@@ -1596,7 +1600,7 @@ gst_h264_parse_push_codec_buffer (GstH26
+ static GstFlowReturn
+ gst_h264_parse_push_buffer (GstH264Parse * h264parse, GstBuffer * buf)
+ {
+- GstFlowReturn ret = GST_FLOW_OK;
++ GstFlowReturn res = GST_FLOW_OK;
+
+ /* We can send pending events if this is the first call, since we now have
+ * caps for the srcpad */
+@@ -1615,6 +1619,33 @@ gst_h264_parse_push_buffer (GstH264Parse
+ }
+ }
+
++ if (G_UNLIKELY (h264parse->width == 0 || h264parse->height == 0)) {
++ GST_DEBUG ("Delaying actual push until we are configured");
++ h264parse->gather = g_list_append (h264parse->gather, buf);
++ goto beach;
++ }
++
++ if (G_UNLIKELY (h264parse->gather)) {
++ GList *pendingbuffers = h264parse->gather;
++ GList *tmp;
++
++ GST_DEBUG ("Pushing out pending buffers");
++
++ /* Yes, we're recursively calling in... */
++ h264parse->gather = NULL;
++ for (tmp = pendingbuffers; tmp; tmp = tmp->next) {
++ res = gst_h264_parse_push_buffer (h264parse, (GstBuffer *) tmp->data);
++ if (res != GST_FLOW_OK && res != GST_FLOW_NOT_LINKED)
++ break;
++ }
++ g_list_free (pendingbuffers);
++
++ if (res != GST_FLOW_OK && res != GST_FLOW_NOT_LINKED) {
++ gst_buffer_unref (buf);
++ goto beach;
++ }
++ }
++
+ /* start of picture is good time to slip in codec_data NALUs
+ * (when outputting NALS and transforming to bytestream) */
+ if (G_UNLIKELY (h264parse->codec_nals && h264parse->picture_start)) {
+@@ -1626,7 +1657,7 @@ gst_h264_parse_push_buffer (GstH264Parse
+ GST_BUFFER_DURATION (nals->data) = 0;
+
+ gst_buffer_set_caps (nals->data, h264parse->src_caps);
+- ret = gst_pad_push (h264parse->srcpad, nals->data);
++ (void) gst_pad_push (h264parse->srcpad, nals->data);
+ nals = g_slist_delete_link (nals, nals);
+ }
+ h264parse->codec_nals = NULL;
+@@ -1736,7 +1767,10 @@ gst_h264_parse_push_buffer (GstH264Parse
+ }
+
+ gst_buffer_set_caps (buf, h264parse->src_caps);
+- return gst_pad_push (h264parse->srcpad, buf);
++ res = gst_pad_push (h264parse->srcpad, buf);
++
++beach:
++ return res;
+ }
+
+ /* takes over ownership of nal and returns fresh buffer */
+@@ -1782,7 +1816,6 @@ gst_h264_parse_push_nal (GstH264Parse *
+ /* first_mb_in_slice == 0 considered start of frame */
+ start = h264parse->picture_start && (data[nal_length + 1] & 0x80);
+ if (G_UNLIKELY (!next_nal)) {
+- printf("Frame complete!!\n");
+ complete = TRUE;
+ } else {
+ /* consider a coded slices (IDR or not) to start a picture,
+@@ -2098,9 +2131,6 @@ gst_h264_parse_chain_forward (GstH264Par
+
+ /* packetized will have no next data, which serves fine here */
+ next_data = (guint8 *) gst_adapter_peek (h264parse->adapter, 6);
+- GST_DEBUG("next_data:%p",next_data);
+- if(next_data == NULL)
+- return GST_FLOW_OK;
+ outbuf = gst_h264_parse_push_nal (h264parse, outbuf, next_data, &start);
+ if (!outbuf) {
+ /* no complete unit yet, go for next round */
+@@ -2110,10 +2140,10 @@ gst_h264_parse_chain_forward (GstH264Par
+ /* Ignore upstream dts that stalls or goes backward. Upstream elements
+ * like filesrc would keep on writing timestamp=0. XXX: is this correct?
+ * TODO: better way to detect whether upstream timstamps are useful */
+- if (h264parse->last_outbuf_dts != GST_CLOCK_TIME_NONE
++ /* if (h264parse->last_outbuf_dts != GST_CLOCK_TIME_NONE
+ && outbuf_dts != GST_CLOCK_TIME_NONE
+ && outbuf_dts <= h264parse->last_outbuf_dts)
+- outbuf_dts = GST_CLOCK_TIME_NONE;
++ outbuf_dts = GST_CLOCK_TIME_NONE;*/
+
+ if ((got_frame || delta_unit) && start) {
+ GstH264Sps *sps = h264parse->sps;
+@@ -2445,7 +2475,7 @@ gst_h264_parse_chain_reverse (GstH264Par
+
+ /* if we have a discont, move buffers to the decode list */
+ if (G_UNLIKELY (discont)) {
+- guint start, stop, last;
++ guint start, last;
+ guint32 code;
+ GstBuffer *prev;
+ GstClockTime timestamp;
+@@ -2454,7 +2484,6 @@ gst_h264_parse_chain_reverse (GstH264Par
+ "received discont, copy gathered buffers for decoding");
+
+ /* init start code accumulator */
+- stop = -1;
+ prev = h264parse->prev;
+ h264parse->prev = NULL;
+
+@@ -2700,7 +2729,7 @@ static gboolean
+ plugin_init (GstPlugin * plugin)
+ {
+ return gst_element_register (plugin, "h264parse",
+- GST_RANK_NONE, GST_TYPE_H264PARSE);
++ (GST_RANK_PRIMARY + 1), GST_TYPE_H264PARSE);
+ }
+
+ GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
diff --git a/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-bad-0.10.21/0009-mpeg4videoparse-push-flush-stop-and-new-segment b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-bad-0.10.21/0009-mpeg4videoparse-push-flush-stop-and-new-segment
new file mode 100644
index 0000000..3672c07
--- /dev/null
+++ b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-bad-0.10.21/0009-mpeg4videoparse-push-flush-stop-and-new-segment
@@ -0,0 +1,24 @@
+--- gst-plugins-bad-0.10.21.orig/gst/mpeg4videoparse/mpeg4videoparse.c 2010-12-24 17:29:38.000000000 +0530
++++ gst-plugins-bad-0.10.21/gst/mpeg4videoparse/mpeg4videoparse.c 2012-01-15 17:06:11.053523827 +0530
+@@ -550,7 +550,12 @@ gst_mpeg4vparse_push (GstMpeg4VParse * p
+ parse->last_report = timestamp;
+ }
+ }
+- }
++ }
++ if (parse->pending_segment != NULL) {
++ /* Send new segment event received after flush/seek etc.*/
++ gst_pad_push_event (parse->srcpad, parse->pending_segment);
++ parse->pending_segment = NULL;
++ }
+ gst_buffer_set_caps (out_buf, GST_PAD_CAPS (parse->srcpad));
+ gst_pad_push (parse->srcpad, out_buf);
+ }
+@@ -806,6 +811,7 @@ gst_mpeg4vparse_sink_event (GstPad * pad
+
+ switch (GST_EVENT_TYPE (event)) {
+ case GST_EVENT_FLUSH_STOP:
++ res = gst_pad_event_default (pad, event);
+ parse->last_report = GST_CLOCK_TIME_NONE;
+ gst_adapter_clear (parse->adapter);
+ parse->state = PARSE_NEED_START;
diff --git a/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-base-0.10.32/0026-playbin-link-omx_scaler-to-do-HW-accel-scale-remove-identity.patch b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-base-0.10.32/0026-playbin-link-omx_scaler-to-do-HW-accel-scale-remove-identity.patch
new file mode 100644
index 0000000..d1abf80
--- /dev/null
+++ b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-base-0.10.32/0026-playbin-link-omx_scaler-to-do-HW-accel-scale-remove-identity.patch
@@ -0,0 +1,50 @@
+--- gst-plugins-base-0.10.32.orig/gst/playback/gstplaybin.c 2010-10-13 17:24:05.000000000 +0530
++++ gst-plugins-base-0.10.32/gst/playback/gstplaybin.c 2011-11-24 16:40:02.843360968 +0530
+@@ -830,7 +830,7 @@ gen_video_element (GstPlayBin * play_bin
+ GstElement *element;
+ GstElement *conv;
+
+- GstElement *scale;
++ //GstElement *scale;
+ GstElement *sink;
+ GstElement *identity;
+ GstPad *pad;
+@@ -859,29 +859,29 @@ gen_video_element (GstPlayBin * play_bin
+ element = gst_bin_new ("vbin");
+ gst_bin_add (GST_BIN_CAST (element), sink);
+
+- conv = gst_element_factory_make ("ffmpegcolorspace", "vconv");
++ conv = gst_element_factory_make ("omx_scaler", "vconv");
+ if (conv == NULL)
+ goto no_colorspace;
+ gst_bin_add (GST_BIN_CAST (element), conv);
+
+- scale = gst_element_factory_make ("videoscale", "vscale");
++/* scale = gst_element_factory_make ("identity", "vscale");
+ if (scale == NULL)
+ goto no_videoscale;
+- gst_bin_add (GST_BIN_CAST (element), scale);
++ gst_bin_add (GST_BIN_CAST (element), scale);*/
+
+- identity = gst_element_factory_make ("identity", "id");
++ /* identity = gst_element_factory_make ("identity", "id");
+ g_object_set (identity, "silent", TRUE, NULL);
+ g_signal_connect (identity, "handoff", G_CALLBACK (handoff), play_bin);
+- gst_bin_add (GST_BIN_CAST (element), identity);
++ gst_bin_add (GST_BIN_CAST (element), identity);*/
+
+- gst_element_link_pads (identity, "src", conv, "sink");
+- gst_element_link_pads (conv, "src", scale, "sink");
++// gst_element_link_pads (identity, "src", conv, "sink");
++ // gst_element_link_pads (conv, "src", scale, "sink");
+ /* be more careful with the pad from the custom sink element, it might not
+ * be named 'sink' */
+- if (!gst_element_link_pads (scale, "src", sink, NULL))
++ if (!gst_element_link_pads (conv, "src", sink, NULL))
+ goto link_failed;
+
+- pad = gst_element_get_static_pad (identity, "sink");
++ pad = gst_element_get_static_pad (conv, "sink");
+ gst_element_add_pad (element, gst_ghost_pad_new ("sink", pad));
+ gst_object_unref (pad);
+
diff --git a/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-base-0.10.32/0026-playbin-link-omx_scaler-to-do-HW-accel-scale.patch b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-base-0.10.32/0026-playbin-link-omx_scaler-to-do-HW-accel-scale.patch
new file mode 100644
index 0000000..59c47f5
--- /dev/null
+++ b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-base-0.10.32/0026-playbin-link-omx_scaler-to-do-HW-accel-scale.patch
@@ -0,0 +1,43 @@
+--- gst-plugins-base-0.10.32.orig/gst/playback/gstplaybin.c 2010-10-13 17:24:05.000000000 +0530
++++ gst-plugins-base-0.10.32/gst/playback/gstplaybin.c 2011-11-18 17:38:05.287360205 +0530
+@@ -830,7 +830,7 @@ gen_video_element (GstPlayBin * play_bin
+ GstElement *element;
+ GstElement *conv;
+
+- GstElement *scale;
++ //GstElement *scale;
+ GstElement *sink;
+ GstElement *identity;
+ GstPad *pad;
+@@ -859,15 +859,15 @@ gen_video_element (GstPlayBin * play_bin
+ element = gst_bin_new ("vbin");
+ gst_bin_add (GST_BIN_CAST (element), sink);
+
+- conv = gst_element_factory_make ("ffmpegcolorspace", "vconv");
++ conv = gst_element_factory_make ("omx_scaler", "vconv");
+ if (conv == NULL)
+ goto no_colorspace;
+ gst_bin_add (GST_BIN_CAST (element), conv);
+
+- scale = gst_element_factory_make ("videoscale", "vscale");
++/* scale = gst_element_factory_make ("identity", "vscale");
+ if (scale == NULL)
+ goto no_videoscale;
+- gst_bin_add (GST_BIN_CAST (element), scale);
++ gst_bin_add (GST_BIN_CAST (element), scale);*/
+
+ identity = gst_element_factory_make ("identity", "id");
+ g_object_set (identity, "silent", TRUE, NULL);
+@@ -875,10 +875,10 @@ gen_video_element (GstPlayBin * play_bin
+ gst_bin_add (GST_BIN_CAST (element), identity);
+
+ gst_element_link_pads (identity, "src", conv, "sink");
+- gst_element_link_pads (conv, "src", scale, "sink");
++ // gst_element_link_pads (conv, "src", scale, "sink");
+ /* be more careful with the pad from the custom sink element, it might not
+ * be named 'sink' */
+- if (!gst_element_link_pads (scale, "src", sink, NULL))
++ if (!gst_element_link_pads (conv, "src", sink, NULL))
+ goto link_failed;
+
+ pad = gst_element_get_static_pad (identity, "sink");
diff --git a/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0001-v4l2-fix-handling-of-RGB32-BGR32-formats.patch b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0001-v4l2-fix-handling-of-RGB32-BGR32-formats.patch
new file mode 100644
index 0000000..623567d
--- /dev/null
+++ b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0001-v4l2-fix-handling-of-RGB32-BGR32-formats.patch
@@ -0,0 +1,53 @@
+From 194aa8513c02fbfcabf04b45ff4c81bf8a94527f Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Tue, 14 Sep 2010 07:42:50 -0500
+Subject: [PATCH 01/11] v4l2: fix handling of RGB32/BGR32 formats
+
+bpp is 32, but depth is only 24..
+---
+ sys/v4l2/gstv4l2object.c | 12 +++++++-----
+ 1 files changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/sys/v4l2/gstv4l2object.c b/sys/v4l2/gstv4l2object.c
+index 7e15489..f5672b5 100644
+--- a/sys/v4l2/gstv4l2object.c
++++ b/sys/v4l2/gstv4l2object.c
+@@ -1132,14 +1132,16 @@ gst_v4l2_object_v4l2fourcc_to_structure (guint32 fourcc)
+ b_mask = 0xff0000;
+ break;
+ case V4L2_PIX_FMT_RGB32:
+- bpp = depth = 32;
++ depth = 24;
++ bpp = 32;
+ endianness = G_BIG_ENDIAN;
+ r_mask = 0xff000000;
+ g_mask = 0x00ff0000;
+ b_mask = 0x0000ff00;
+ break;
+ case V4L2_PIX_FMT_BGR32:
+- bpp = depth = 32;
++ depth = 24;
++ bpp = 32;
+ endianness = G_BIG_ENDIAN;
+ r_mask = 0x000000ff;
+ g_mask = 0x0000ff00;
+@@ -1404,13 +1406,13 @@ 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, 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);
+
+- switch (depth) {
++ switch (bpp) {
+ case 8:
+ fourcc = V4L2_PIX_FMT_RGB332;
+ break;
+--
+1.7.0.4
+
diff --git a/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0002-v4l2sink-Add-rotation-support.patch b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0002-v4l2sink-Add-rotation-support.patch
new file mode 100644
index 0000000..b405ea0
--- /dev/null
+++ b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0002-v4l2sink-Add-rotation-support.patch
@@ -0,0 +1,128 @@
+From d43a9444fc5f7655a8acd2978039667a04222ba0 Mon Sep 17 00:00:00 2001
+From: Kiran Nataraju <knataraju@ti.com>
+Date: Fri, 27 Aug 2010 09:00:57 +0200
+Subject: [PATCH 02/11] v4l2sink: Add rotation support.
+
+Signed-off-by: Kiran Nataraju <knataraju@ti.com>
+Signed-off-by: Daniel Diaz <ddiaz@ti.com>
+---
+ sys/v4l2/gstv4l2sink.c | 34 ++++++++++++++++++++++++++++++++++
+ sys/v4l2/gstv4l2sink.h | 1 +
+ 2 files changed, 35 insertions(+), 0 deletions(-)
+
+diff --git a/sys/v4l2/gstv4l2sink.c b/sys/v4l2/gstv4l2sink.c
+index aa6785c..5abf915 100644
+--- a/sys/v4l2/gstv4l2sink.c
++++ b/sys/v4l2/gstv4l2sink.c
+@@ -72,6 +72,10 @@ GST_DEBUG_CATEGORY (v4l2sink_debug);
+ #define PROP_DEF_MIN_QUEUED_BUFS 1
+ #define DEFAULT_PROP_DEVICE "/dev/video1"
+
++#define MIN_ROTATION_ANGLE 0
++#define MAX_ROTATION_ANGLE 360
++#define DEFAULT_ROTATION_ANGLE 0
++
+ enum
+ {
+ PROP_0,
+@@ -86,6 +90,7 @@ enum
+ PROP_CROP_LEFT,
+ PROP_CROP_WIDTH,
+ PROP_CROP_HEIGHT,
++ PROP_ROTATION,
+ };
+
+
+@@ -220,6 +225,7 @@ static GstFlowReturn gst_v4l2sink_buffer_alloc (GstBaseSink * bsink,
+ guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf);
+ static GstFlowReturn gst_v4l2sink_show_frame (GstBaseSink * bsink,
+ GstBuffer * buf);
++static void gst_v4l2sink_set_rotation (GstV4l2Sink * v4l2sink);
+
+ static void
+ gst_v4l2sink_base_init (gpointer g_class)
+@@ -306,6 +312,11 @@ gst_v4l2sink_class_init (GstV4l2SinkClass * klass)
+ "The height of the video crop; default is equal to negotiated image height",
+ 0, 0xffffffff, 0, G_PARAM_READWRITE));
+
++ g_object_class_install_property (gobject_class, PROP_ROTATION,
++ g_param_spec_int ("rotation", "Rotation angle",
++ "Rotation angle for the image", MIN_ROTATION_ANGLE,
++ MAX_ROTATION_ANGLE, DEFAULT_ROTATION_ANGLE, G_PARAM_READWRITE));
++
+ basesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_v4l2sink_get_caps);
+ basesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_v4l2sink_set_caps);
+ basesink_class->buffer_alloc = GST_DEBUG_FUNCPTR (gst_v4l2sink_buffer_alloc);
+@@ -336,6 +347,7 @@ gst_v4l2sink_init (GstV4l2Sink * v4l2sink, GstV4l2SinkClass * klass)
+ v4l2sink->overlay_fields_set = 0;
+ v4l2sink->crop_fields_set = 0;
+ v4l2sink->state = 0;
++ v4l2sink->rotation = 0;
+ }
+
+
+@@ -475,6 +487,20 @@ gst_v4l2sink_sync_crop_fields (GstV4l2Sink * v4l2sink)
+ }
+ }
+
++static void
++gst_v4l2sink_set_rotation (GstV4l2Sink * v4l2sink)
++{
++ if (GST_V4L2_IS_OPEN (v4l2sink->v4l2object)) {
++ struct v4l2_control control;
++ gint fd = v4l2sink->v4l2object->video_fd;
++
++ memset (&control, 0x00, sizeof (struct v4l2_control));
++ control.id = V4L2_CID_ROTATE;
++ control.value = v4l2sink->rotation;
++ g_return_if_fail (v4l2_ioctl (fd, VIDIOC_S_CTRL, &control) >= 0);
++ }
++}
++
+
+ static void
+ gst_v4l2sink_set_property (GObject * object,
+@@ -531,6 +557,10 @@ gst_v4l2sink_set_property (GObject * object,
+ v4l2sink->crop_fields_set |= RECT_HEIGHT_SET;
+ gst_v4l2sink_sync_crop_fields (v4l2sink);
+ break;
++ case PROP_ROTATION:
++ v4l2sink->rotation = g_value_get_int (value);
++ gst_v4l2sink_set_rotation (v4l2sink);
++ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+@@ -578,6 +608,9 @@ gst_v4l2sink_get_property (GObject * object,
+ case PROP_CROP_HEIGHT:
+ g_value_set_uint (value, v4l2sink->crop.height);
+ break;
++ case PROP_ROTATION:
++ g_value_set_int (value, v4l2sink->rotation);
++ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+@@ -600,6 +633,7 @@ gst_v4l2sink_change_state (GstElement * element, GstStateChange transition)
+ /* open the device */
+ if (!gst_v4l2_object_start (v4l2sink->v4l2object))
+ return GST_STATE_CHANGE_FAILURE;
++ gst_v4l2sink_set_rotation (v4l2sink);
+ break;
+ default:
+ break;
+diff --git a/sys/v4l2/gstv4l2sink.h b/sys/v4l2/gstv4l2sink.h
+index 8fe8222..1239621 100644
+--- a/sys/v4l2/gstv4l2sink.h
++++ b/sys/v4l2/gstv4l2sink.h
+@@ -75,6 +75,7 @@ struct _GstV4l2Sink {
+ guint8 overlay_fields_set, crop_fields_set;
+
+ guint8 state;
++ gint rotation;
+ };
+
+ struct _GstV4l2SinkClass {
+--
+1.7.0.4
+
diff --git a/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0003-v4l2sink-Add-flip-property.patch b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0003-v4l2sink-Add-flip-property.patch
new file mode 100644
index 0000000..09839ad
--- /dev/null
+++ b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0003-v4l2sink-Add-flip-property.patch
@@ -0,0 +1,187 @@
+From 1381c64fd606d8ab7169eef52386139a4848c439 Mon Sep 17 00:00:00 2001
+From: Kiran Nataraju <knataraju@ti.com>
+Date: Tue, 21 Sep 2010 06:21:23 +0200
+Subject: [PATCH 03/11] v4l2sink: Add flip property.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Kiran Nataraju <knataraju@ti.com>
+Signed-off-by: Daniel Díaz <yosoy@danieldiaz.org>
+---
+ sys/v4l2/gstv4l2sink.c | 88 +++++++++++++++++++++++++++++++++++++++++++++--
+ sys/v4l2/gstv4l2sink.h | 1 +
+ 2 files changed, 85 insertions(+), 4 deletions(-)
+
+diff --git a/sys/v4l2/gstv4l2sink.c b/sys/v4l2/gstv4l2sink.c
+index 5abf915..6163747 100644
+--- a/sys/v4l2/gstv4l2sink.c
++++ b/sys/v4l2/gstv4l2sink.c
+@@ -91,6 +91,7 @@ enum
+ PROP_CROP_WIDTH,
+ PROP_CROP_HEIGHT,
+ PROP_ROTATION,
++ PROP_FLIP,
+ };
+
+
+@@ -129,6 +130,34 @@ gst_v4l2sink_iface_supported (GstImplementsInterface * iface, GType iface_type)
+ return TRUE;
+ }
+
++/*
++ * Flip state
++ */
++enum
++{
++ FLIP_NONE = 0,
++ FLIP_HORIZONTAL = 1,
++ FLIP_VERTICAL = 2,
++};
++
++#define GST_TYPE_V4L2_FLIP (gst_v4l2_flip_get_type ())
++static GType
++gst_v4l2_flip_get_type (void)
++{
++ static GType type = 0;
++
++ if (!type) {
++ static GEnumValue vals[] = {
++ {FLIP_NONE, "No Flip", "none"},
++ {FLIP_HORIZONTAL, "Horizontal Flip", "horiz"},
++ {FLIP_VERTICAL, "Vertical Flip", "vert"},
++ {0, NULL, NULL},
++ };
++ type = g_enum_register_static ("GstV4l2SinkFlip", vals);
++ }
++ return type;
++}
++
+ static void
+ gst_v4l2sink_interface_init (GstImplementsInterfaceClass * klass)
+ {
+@@ -225,7 +254,7 @@ static GstFlowReturn gst_v4l2sink_buffer_alloc (GstBaseSink * bsink,
+ guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf);
+ static GstFlowReturn gst_v4l2sink_show_frame (GstBaseSink * bsink,
+ GstBuffer * buf);
+-static void gst_v4l2sink_set_rotation (GstV4l2Sink * v4l2sink);
++static void gst_v4l2sink_sync_rotation (GstV4l2Sink * v4l2sink);
+
+ static void
+ gst_v4l2sink_base_init (gpointer g_class)
+@@ -317,6 +346,11 @@ gst_v4l2sink_class_init (GstV4l2SinkClass * klass)
+ "Rotation angle for the image", MIN_ROTATION_ANGLE,
+ MAX_ROTATION_ANGLE, DEFAULT_ROTATION_ANGLE, G_PARAM_READWRITE));
+
++ g_object_class_install_property (gobject_class, PROP_FLIP,
++ g_param_spec_enum ("flip", "Flip State",
++ "Flip horizontal/vertical",
++ GST_TYPE_V4L2_FLIP, FLIP_NONE, G_PARAM_READWRITE));
++
+ basesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_v4l2sink_get_caps);
+ basesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_v4l2sink_set_caps);
+ basesink_class->buffer_alloc = GST_DEBUG_FUNCPTR (gst_v4l2sink_buffer_alloc);
+@@ -348,8 +382,46 @@ gst_v4l2sink_init (GstV4l2Sink * v4l2sink, GstV4l2SinkClass * klass)
+ v4l2sink->crop_fields_set = 0;
+ v4l2sink->state = 0;
+ v4l2sink->rotation = 0;
++ v4l2sink->flip = FLIP_NONE;
+ }
+
++static void
++gst_v4l2sink_sync_flip (GstV4l2Sink * v4l2sink)
++{
++ if (GST_V4L2_IS_OPEN (v4l2sink->v4l2object)) {
++ struct v4l2_control control;
++ gint fd = v4l2sink->v4l2object->video_fd;
++
++ memset (&control, 0x00, sizeof (struct v4l2_control));
++
++ switch (v4l2sink->flip) {
++ case FLIP_VERTICAL:
++ v4l2sink->rotation = 0;
++ control.value = 1;
++ break;
++ case FLIP_HORIZONTAL:
++ /* Horizontal Flip = Vertical Flip + 180 rotation */
++ v4l2sink->rotation = 180;
++ control.value = 1;
++ break;
++ case FLIP_NONE:
++ /* In the below switch case logic we need to handle FLIP_NONE
++ * case since the v4l2 driver holds on to the last configured
++ * flip value even after the device file is closed.
++ */
++ control.value = 0;
++ break;
++ default:
++ GST_WARNING_OBJECT (v4l2sink, "Invalid flip property");
++ control.value = 0;
++ break;
++ }
++
++ gst_v4l2sink_sync_rotation (v4l2sink);
++ control.id = V4L2_CID_VFLIP;
++ g_return_if_fail (v4l2_ioctl (fd, VIDIOC_S_CTRL, &control) >= 0);
++ }
++}
+
+ static void
+ gst_v4l2sink_dispose (GObject * object)
+@@ -488,7 +560,7 @@ gst_v4l2sink_sync_crop_fields (GstV4l2Sink * v4l2sink)
+ }
+
+ static void
+-gst_v4l2sink_set_rotation (GstV4l2Sink * v4l2sink)
++gst_v4l2sink_sync_rotation (GstV4l2Sink * v4l2sink)
+ {
+ if (GST_V4L2_IS_OPEN (v4l2sink->v4l2object)) {
+ struct v4l2_control control;
+@@ -559,7 +631,11 @@ gst_v4l2sink_set_property (GObject * object,
+ break;
+ case PROP_ROTATION:
+ v4l2sink->rotation = g_value_get_int (value);
+- gst_v4l2sink_set_rotation (v4l2sink);
++ gst_v4l2sink_sync_rotation (v4l2sink);
++ break;
++ case PROP_FLIP:
++ v4l2sink->flip = g_value_get_enum (value);
++ gst_v4l2sink_sync_flip (v4l2sink);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+@@ -611,6 +687,9 @@ gst_v4l2sink_get_property (GObject * object,
+ case PROP_ROTATION:
+ g_value_set_int (value, v4l2sink->rotation);
+ break;
++ case PROP_FLIP:
++ g_value_set_enum (value, v4l2sink->flip);
++ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+@@ -633,7 +712,8 @@ gst_v4l2sink_change_state (GstElement * element, GstStateChange transition)
+ /* open the device */
+ if (!gst_v4l2_object_start (v4l2sink->v4l2object))
+ return GST_STATE_CHANGE_FAILURE;
+- gst_v4l2sink_set_rotation (v4l2sink);
++ gst_v4l2sink_sync_rotation (v4l2sink);
++ gst_v4l2sink_sync_flip (v4l2sink);
+ break;
+ default:
+ break;
+diff --git a/sys/v4l2/gstv4l2sink.h b/sys/v4l2/gstv4l2sink.h
+index 1239621..907973a 100644
+--- a/sys/v4l2/gstv4l2sink.h
++++ b/sys/v4l2/gstv4l2sink.h
+@@ -76,6 +76,7 @@ struct _GstV4l2Sink {
+
+ guint8 state;
+ gint rotation;
++ gint flip;
+ };
+
+ struct _GstV4l2SinkClass {
+--
+1.7.0.4
+
diff --git a/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0004-v4l2sink-Add-support-for-omap24xxvout-driver.patch b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0004-v4l2sink-Add-support-for-omap24xxvout-driver.patch
new file mode 100644
index 0000000..528e9a6
--- /dev/null
+++ b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0004-v4l2sink-Add-support-for-omap24xxvout-driver.patch
@@ -0,0 +1,59 @@
+From 39de525898eea073c1f2486b99b56ef25b6df289 Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Sun, 4 Apr 2010 06:46:21 -0500
+Subject: [PATCH 04/11] v4l2sink: Add support for omap24xxvout driver
+
+---
+ sys/v4l2/gstv4l2sink.c | 22 +++++++++++++++++++++-
+ 1 files changed, 21 insertions(+), 1 deletions(-)
+
+diff --git a/sys/v4l2/gstv4l2sink.c b/sys/v4l2/gstv4l2sink.c
+index 6163747..4408428 100644
+--- a/sys/v4l2/gstv4l2sink.c
++++ b/sys/v4l2/gstv4l2sink.c
+@@ -888,6 +888,18 @@ gst_v4l2sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,
+ /* initialize the buffer pool if not initialized yet (first buffer): */
+ if (G_UNLIKELY (!v4l2sink->pool)) {
+
++ gboolean no_pending_streamon = FALSE;
++ char *driver = (char *) v4l2sink->v4l2object->vcap.driver;
++
++ /* the omap24xxvout driver wants us to start streaming before we
++ * queue the first buffer:
++ */
++ if (!strcmp ("omap24xxvout", driver)) {
++ GST_DEBUG_OBJECT (v4l2sink,
++ "enabling no_pending_streamon hack for omap24xxvout driver");
++ no_pending_streamon = TRUE;
++ }
++
+ /* set_caps() might not be called yet.. so just to make sure: */
+ if (!gst_v4l2sink_set_caps (bsink, caps)) {
+ return GST_FLOW_ERROR;
+@@ -909,7 +921,14 @@ gst_v4l2sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,
+ gst_v4l2_xoverlay_prepare_xwindow_id (v4l2sink->v4l2object, TRUE);
+ #endif
+
+- v4l2sink->state = STATE_PENDING_STREAMON;
++ if (no_pending_streamon) {
++ if (!gst_v4l2_object_start_streaming (v4l2sink->v4l2object)) {
++ return GST_FLOW_ERROR;
++ }
++ v4l2sink->state = STATE_STREAMING;
++ } else {
++ v4l2sink->state = STATE_PENDING_STREAMON;
++ }
+
+ GST_INFO_OBJECT (v4l2sink, "outputting buffers via mmap()");
+
+@@ -996,6 +1015,7 @@ gst_v4l2sink_show_frame (GstBaseSink * bsink, GstBuffer * buf)
+ if (!gst_v4l2_buffer_pool_qbuf (v4l2sink->pool, GST_V4L2_BUFFER (buf))) {
+ return GST_FLOW_ERROR;
+ }
++
+ if (v4l2sink->state == STATE_PENDING_STREAMON) {
+ if (!gst_v4l2_object_start_streaming (v4l2sink->v4l2object)) {
+ return GST_FLOW_ERROR;
+--
+1.7.0.4
+
diff --git a/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0005-v4l2sink-Add-support-for-omap_vout-driver.patch b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0005-v4l2sink-Add-support-for-omap_vout-driver.patch
new file mode 100644
index 0000000..7ec58cd
--- /dev/null
+++ b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0005-v4l2sink-Add-support-for-omap_vout-driver.patch
@@ -0,0 +1,34 @@
+From 1fabe36f40e872942c80041225bdbf41db561bea Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Sun, 4 Apr 2010 06:47:55 -0500
+Subject: [PATCH 05/11] v4l2sink: Add support for omap_vout driver
+
+---
+ sys/v4l2/gstv4l2sink.c | 11 +++++++++++
+ 1 files changed, 11 insertions(+), 0 deletions(-)
+
+diff --git a/sys/v4l2/gstv4l2sink.c b/sys/v4l2/gstv4l2sink.c
+index 4408428..66dda8e 100644
+--- a/sys/v4l2/gstv4l2sink.c
++++ b/sys/v4l2/gstv4l2sink.c
+@@ -900,6 +900,17 @@ gst_v4l2sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,
+ no_pending_streamon = TRUE;
+ }
+
++ /* workaround for bug in omap_vout driver, when we ask for more
++ * than four buffers:
++ */
++ if (!strcmp ("omap_vout", driver)) {
++ if (v4l2sink->num_buffers > 4) {
++ v4l2sink->num_buffers = 4;
++ GST_DEBUG_OBJECT (v4l2sink,
++ "limiting to 4 buffers to work-around omap_vout driver bug");
++ }
++ }
++
+ /* set_caps() might not be called yet.. so just to make sure: */
+ if (!gst_v4l2sink_set_caps (bsink, caps)) {
+ return GST_FLOW_ERROR;
+--
+1.7.0.4
+
diff --git a/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0006-v4l2-increase-v4l2sink-element-rank.patch b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0006-v4l2-increase-v4l2sink-element-rank.patch
new file mode 100644
index 0000000..cd417e3
--- /dev/null
+++ b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0006-v4l2-increase-v4l2sink-element-rank.patch
@@ -0,0 +1,26 @@
+From 14d6f0fac0875981c418ac6577d23eafb5ff3f01 Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Wed, 14 Apr 2010 03:29:20 -0500
+Subject: [PATCH 06/11] v4l2: increase v4l2sink element rank
+
+Increase rank so that it is autoplugged.
+---
+ sys/v4l2/gstv4l2.c | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/sys/v4l2/gstv4l2.c b/sys/v4l2/gstv4l2.c
+index 4a7056f..cba4157 100644
+--- a/sys/v4l2/gstv4l2.c
++++ b/sys/v4l2/gstv4l2.c
+@@ -55,7 +55,7 @@ plugin_init (GstPlugin * plugin)
+ if (!gst_element_register (plugin, "v4l2src", GST_RANK_PRIMARY,
+ GST_TYPE_V4L2SRC) ||
+ #ifdef HAVE_EXPERIMENTAL
+- !gst_element_register (plugin, "v4l2sink", GST_RANK_NONE,
++ !gst_element_register (plugin, "v4l2sink", GST_RANK_PRIMARY,
+ GST_TYPE_V4L2SINK) ||
+ #endif
+ /* !gst_element_register (plugin, "v4l2jpegsrc", */
+--
+1.7.0.4
+
diff --git a/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0007-use-GstQueryBuffers-to-get-buffer-requirements.patch b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0007-use-GstQueryBuffers-to-get-buffer-requirements.patch
new file mode 100644
index 0000000..70ceae5
--- /dev/null
+++ b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0007-use-GstQueryBuffers-to-get-buffer-requirements.patch
@@ -0,0 +1,97 @@
+From 15c17ea368079fd5de19868af6d9ffad1cb09f3a Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Wed, 19 May 2010 17:33:46 -0500
+Subject: [PATCH 07/11] use GstQueryBuffers to get buffer requirements
+
+---
+ sys/v4l2/gstv4l2sink.c | 40 ++++++++++++++++++++++++++++++++++++++++
+ sys/v4l2/gstv4l2sink.h | 1 +
+ 2 files changed, 41 insertions(+), 0 deletions(-)
+
+diff --git a/sys/v4l2/gstv4l2sink.c b/sys/v4l2/gstv4l2sink.c
+index 66dda8e..12323f7 100644
+--- a/sys/v4l2/gstv4l2sink.c
++++ b/sys/v4l2/gstv4l2sink.c
+@@ -373,6 +373,7 @@ gst_v4l2sink_init (GstV4l2Sink * v4l2sink, GstV4l2SinkClass * klass)
+
+ /* number of buffers requested */
+ v4l2sink->num_buffers = PROP_DEF_QUEUE_SIZE;
++ v4l2sink->num_buffers_can_change = TRUE;
+ v4l2sink->min_queued_bufs = PROP_DEF_MIN_QUEUED_BUFS;
+
+ v4l2sink->probed_caps = NULL;
+@@ -808,6 +809,7 @@ static gboolean
+ gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
+ {
+ GstV4l2Sink *v4l2sink = GST_V4L2SINK (bsink);
++ GstQuery *query;
+ gint w = 0, h = 0;
+ gboolean interlaced;
+ struct v4l2_fmtdesc *format;
+@@ -855,6 +857,39 @@ gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
+ return FALSE;
+ }
+
++ /* query to find if anyone upstream using these buffers has any
++ * minimum requirements:
++ */
++ query = gst_query_new_buffers (caps);
++ if (gst_element_query (GST_ELEMENT (v4l2sink), query)) {
++ gint min_buffers, min_width, min_height;
++
++ gst_query_parse_buffers_count (query, &min_buffers);
++
++ /* XXX need to account for some buffers used by queue, etc.. probably
++ * queue should handle query, pass on to sink pad, and then add some
++ * number of buffers to the min, so this value is dynamic depending
++ * on the pipeline?
++ */
++ if (min_buffers != -1) {
++ min_buffers += 3 + v4l2sink->min_queued_bufs;
++ }
++
++ if (min_buffers > v4l2sink->num_buffers) {
++ v4l2sink->num_buffers_can_change = FALSE;
++ v4l2sink->num_buffers = min_buffers;
++ }
++
++ gst_query_parse_buffers_dimensions (query, &min_width, &min_height);
++ if (min_width > w) {
++ w = min_width;
++ }
++ if (min_height > h) {
++ h = min_height;
++ }
++ }
++ gst_query_unref (query);
++
+ if (!gst_v4l2_object_set_format (v4l2sink->v4l2object, format->pixelformat,
+ w, h, interlaced)) {
+ /* error already posted */
+@@ -944,6 +979,11 @@ gst_v4l2sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,
+ GST_INFO_OBJECT (v4l2sink, "outputting buffers via mmap()");
+
+ if (v4l2sink->num_buffers != v4l2sink->pool->buffer_count) {
++ if (!v4l2sink->num_buffers_can_change) {
++ GST_WARNING_OBJECT (v4l2sink,
++ "I can't handle a differing number of buffers!!!!");
++ return GST_FLOW_ERROR;
++ }
+ v4l2sink->num_buffers = v4l2sink->pool->buffer_count;
+ g_object_notify (G_OBJECT (v4l2sink), "queue-size");
+ }
+diff --git a/sys/v4l2/gstv4l2sink.h b/sys/v4l2/gstv4l2sink.h
+index 907973a..7649fa1 100644
+--- a/sys/v4l2/gstv4l2sink.h
++++ b/sys/v4l2/gstv4l2sink.h
+@@ -58,6 +58,7 @@ struct _GstV4l2Sink {
+ GstCaps *current_caps; /* the current negotiated caps */
+ GstV4l2BufferPool *pool;
+ guint32 num_buffers;
++ gboolean num_buffers_can_change;
+ guint32 min_queued_bufs;
+
+ gint video_width, video_height; /* original (unscaled) video w/h */
+--
+1.7.0.4
+
diff --git a/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0008-add-rowstride-support.patch b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0008-add-rowstride-support.patch
new file mode 100644
index 0000000..1075a89
--- /dev/null
+++ b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0008-add-rowstride-support.patch
@@ -0,0 +1,572 @@
+From a86d0326df31103c2ee38ee1e0c62802a758ef13 Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Fri, 21 May 2010 15:21:32 -0500
+Subject: [PATCH 08/11] add rowstride support
+
+---
+ sys/v4l2/gstv4l2object.c | 141 +++++++++++++++++++++++++++++++++++++---------
+ sys/v4l2/gstv4l2object.h | 6 +-
+ sys/v4l2/gstv4l2sink.c | 61 +++++++++++++-------
+ sys/v4l2/gstv4l2src.c | 28 +++++----
+ 4 files changed, 174 insertions(+), 62 deletions(-)
+
+diff --git a/sys/v4l2/gstv4l2object.c b/sys/v4l2/gstv4l2object.c
+index f5672b5..5e34456 100644
+--- a/sys/v4l2/gstv4l2object.c
++++ b/sys/v4l2/gstv4l2object.c
+@@ -1064,16 +1064,23 @@ gst_v4l2_object_get_format_list (GstV4l2Object * v4l2object)
+ return v4l2object->formats;
+ }
+
+-
+-GstStructure *
+-gst_v4l2_object_v4l2fourcc_to_structure (guint32 fourcc)
++/*
++ * gst_v4l2_object_v4l2fourcc_to_structures:
++ * @fourcc: requested format
++ * @structures: an array of at least MAX_STRUCTS_PER_FOURCC to return the
++ * results in
++ *
++ * Returns the number of structures returned via structures
++ */
++gint
++gst_v4l2_object_v4l2fourcc_to_structures (guint32 fourcc,
++ GstStructure ** structures)
+ {
+- GstStructure *structure = NULL;
+-
++ gint count = 0;
+ switch (fourcc) {
+ case V4L2_PIX_FMT_MJPEG: /* Motion-JPEG */
+ case V4L2_PIX_FMT_JPEG: /* JFIF JPEG */
+- structure = gst_structure_new ("image/jpeg", NULL);
++ structures[count++] = gst_structure_new ("image/jpeg", NULL);
+ break;
+ case V4L2_PIX_FMT_RGB332:
+ case V4L2_PIX_FMT_RGB555:
+@@ -1151,17 +1158,25 @@ gst_v4l2_object_v4l2fourcc_to_structure (guint32 fourcc)
+ g_assert_not_reached ();
+ break;
+ }
+- structure = gst_structure_new ("video/x-raw-rgb",
++ structures[count++] = gst_structure_new ("video/x-raw-rgb",
+ "bpp", G_TYPE_INT, bpp,
+ "depth", G_TYPE_INT, depth,
+ "red_mask", G_TYPE_INT, r_mask,
+ "green_mask", G_TYPE_INT, g_mask,
+ "blue_mask", G_TYPE_INT, b_mask,
+ "endianness", G_TYPE_INT, endianness, NULL);
++ structures[count++] = gst_structure_new ("video/x-raw-rgb-strided",
++ "bpp", G_TYPE_INT, bpp,
++ "depth", G_TYPE_INT, depth,
++ "red_mask", G_TYPE_INT, r_mask,
++ "green_mask", G_TYPE_INT, g_mask,
++ "blue_mask", G_TYPE_INT, b_mask,
++ "endianness", G_TYPE_INT, endianness,
++ "rowstride", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
+ break;
+ }
+ case V4L2_PIX_FMT_GREY: /* 8 Greyscale */
+- structure = gst_structure_new ("video/x-raw-gray",
++ structures[count++] = gst_structure_new ("video/x-raw-gray",
+ "bpp", G_TYPE_INT, 8, NULL);
+ break;
+ case V4L2_PIX_FMT_YYUV: /* 16 YUV 4:2:2 */
+@@ -1227,38 +1242,41 @@ gst_v4l2_object_v4l2fourcc_to_structure (guint32 fourcc)
+ g_assert_not_reached ();
+ break;
+ }
+- structure = gst_structure_new ("video/x-raw-yuv",
++ structures[count++] = gst_structure_new ("video/x-raw-yuv",
+ "format", GST_TYPE_FOURCC, fcc, NULL);
++ structures[count++] = gst_structure_new ("video/x-raw-yuv-strided",
++ "format", GST_TYPE_FOURCC, fcc,
++ "rowstride", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
+ break;
+ }
+ case V4L2_PIX_FMT_DV:
+- structure =
++ structures[count++] =
+ gst_structure_new ("video/x-dv", "systemstream", G_TYPE_BOOLEAN, TRUE,
+ NULL);
+ break;
+ case V4L2_PIX_FMT_MPEG: /* MPEG */
+- structure = gst_structure_new ("video/mpegts", NULL);
++ structures[count++] = gst_structure_new ("video/mpegts", NULL);
+ break;
+ case V4L2_PIX_FMT_WNVA: /* Winnov hw compres */
+ break;
+ #ifdef V4L2_PIX_FMT_SBGGR8
+ case V4L2_PIX_FMT_SBGGR8:
+- structure = gst_structure_new ("video/x-raw-bayer", NULL);
++ structures[count++] = gst_structure_new ("video/x-raw-bayer", NULL);
+ break;
+ #endif
+ #ifdef V4L2_PIX_FMT_SN9C10X
+ case V4L2_PIX_FMT_SN9C10X:
+- structure = gst_structure_new ("video/x-sonix", NULL);
++ structures[count++] = gst_structure_new ("video/x-sonix", NULL);
+ break;
+ #endif
+ #ifdef V4L2_PIX_FMT_PWC1
+ case V4L2_PIX_FMT_PWC1:
+- structure = gst_structure_new ("video/x-pwc1", NULL);
++ structures[count++] = gst_structure_new ("video/x-pwc1", NULL);
+ break;
+ #endif
+ #ifdef V4L2_PIX_FMT_PWC2
+ case V4L2_PIX_FMT_PWC2:
+- structure = gst_structure_new ("video/x-pwc2", NULL);
++ structures[count++] = gst_structure_new ("video/x-pwc2", NULL);
+ break;
+ #endif
+ default:
+@@ -1267,7 +1285,7 @@ gst_v4l2_object_v4l2fourcc_to_structure (guint32 fourcc)
+ break;
+ }
+
+- return structure;
++ return count;
+ }
+
+
+@@ -1278,22 +1296,23 @@ gst_v4l2_object_get_all_caps (void)
+ static GstCaps *caps = NULL;
+
+ if (caps == NULL) {
+- GstStructure *structure;
+-
+ guint i;
+
+ caps = gst_caps_new_empty ();
+ for (i = 0; i < GST_V4L2_FORMAT_COUNT; i++) {
+- structure =
+- gst_v4l2_object_v4l2fourcc_to_structure (gst_v4l2_formats[i].format);
+- if (structure) {
++ GstStructure *structures[MAX_STRUCTS_PER_FOURCC];
++ gint count, j;
++ count =
++ gst_v4l2_object_v4l2fourcc_to_structures (gst_v4l2_formats[i].format,
++ structures);
++ for (j = 0; j < count; j++) {
+ if (gst_v4l2_formats[i].dimensions) {
+- gst_structure_set (structure,
++ gst_structure_set (structures[j],
+ "width", GST_TYPE_INT_RANGE, 1, GST_V4L2_MAX_SIZE,
+ "height", GST_TYPE_INT_RANGE, 1, GST_V4L2_MAX_SIZE,
+ "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, 100, 1, NULL);
+ }
+- gst_caps_append_structure (caps, structure);
++ gst_caps_append_structure (caps, structures[j]);
+ }
+ }
+ }
+@@ -1306,12 +1325,14 @@ gst_v4l2_object_get_all_caps (void)
+ * @caps: given input caps
+ * @format: location for the v4l format
+ * @w/@h: location for width and height
++ * @rs: required rowstride in bytes, or 0 if natural stride (based on format
++ * and width) or not-applicable
+ * @fps_n/@fps_d: location for framerate
+ * @size: location for expected size of the frame or 0 if unknown
+ */
+ gboolean
+ gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps,
+- struct v4l2_fmtdesc ** format, gint * w, gint * h,
++ struct v4l2_fmtdesc ** format, gint * w, gint * h, gint * rs,
+ gboolean * interlaced, guint * fps_n, guint * fps_d, guint * size)
+ {
+ GstStructure *structure;
+@@ -1319,10 +1340,12 @@ gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps,
+ guint32 fourcc;
+ const gchar *mimetype;
+ guint outsize;
++ struct v4l2_format fmt = { 0, };
+
+ /* default unknown values */
+ fourcc = 0;
+ outsize = 0;
++ *rs = 0;
+
+ structure = gst_caps_get_structure (caps, 0);
+
+@@ -1351,61 +1374,73 @@ gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps,
+ *fps_n = gst_value_get_fraction_numerator (framerate);
+ *fps_d = gst_value_get_fraction_denominator (framerate);
+
+- if (!strcmp (mimetype, "video/x-raw-yuv")) {
++ if (!strcmp (mimetype, "video/x-raw-yuv") ||
++ !strcmp (mimetype, "video/x-raw-yuv-strided")) {
+ gst_structure_get_fourcc (structure, "format", &fourcc);
+
+ switch (fourcc) {
+ case GST_MAKE_FOURCC ('I', '4', '2', '0'):
+ case GST_MAKE_FOURCC ('I', 'Y', 'U', 'V'):
+ fourcc = V4L2_PIX_FMT_YUV420;
++ *rs = GST_ROUND_UP_4 (*w);
+ outsize = GST_ROUND_UP_4 (*w) * GST_ROUND_UP_2 (*h);
+ outsize += 2 * ((GST_ROUND_UP_8 (*w) / 2) * (GST_ROUND_UP_2 (*h) / 2));
+ break;
+ case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'):
+ fourcc = V4L2_PIX_FMT_YUYV;
++ *rs = GST_ROUND_UP_2 (*w) * 2;
+ outsize = (GST_ROUND_UP_2 (*w) * 2) * *h;
+ break;
+ case GST_MAKE_FOURCC ('Y', '4', '1', 'P'):
+ fourcc = V4L2_PIX_FMT_Y41P;
++ *rs = GST_ROUND_UP_2 (*w) * 2;
+ outsize = (GST_ROUND_UP_2 (*w) * 2) * *h;
+ break;
+ case GST_MAKE_FOURCC ('U', 'Y', 'V', 'Y'):
+ fourcc = V4L2_PIX_FMT_UYVY;
++ *rs = GST_ROUND_UP_2 (*w) * 2;
+ outsize = (GST_ROUND_UP_2 (*w) * 2) * *h;
+ break;
+ case GST_MAKE_FOURCC ('Y', 'V', '1', '2'):
+ fourcc = V4L2_PIX_FMT_YVU420;
++ *rs = GST_ROUND_UP_4 (*w);
+ outsize = GST_ROUND_UP_4 (*w) * GST_ROUND_UP_2 (*h);
+ outsize += 2 * ((GST_ROUND_UP_8 (*w) / 2) * (GST_ROUND_UP_2 (*h) / 2));
+ break;
+ case GST_MAKE_FOURCC ('Y', '4', '1', 'B'):
+ fourcc = V4L2_PIX_FMT_YUV411P;
++ *rs = GST_ROUND_UP_4 (*w);
+ outsize = GST_ROUND_UP_4 (*w) * *h;
+ outsize += 2 * ((GST_ROUND_UP_8 (*w) / 4) * *h);
+ break;
+ case GST_MAKE_FOURCC ('Y', '4', '2', 'B'):
+ fourcc = V4L2_PIX_FMT_YUV422P;
++ *rs = GST_ROUND_UP_4 (*w);
+ outsize = GST_ROUND_UP_4 (*w) * *h;
+ outsize += 2 * ((GST_ROUND_UP_8 (*w) / 2) * *h);
+ break;
+ case GST_MAKE_FOURCC ('N', 'V', '1', '2'):
+ fourcc = V4L2_PIX_FMT_NV12;
++ *rs = GST_ROUND_UP_4 (*w);
+ outsize = GST_ROUND_UP_4 (*w) * GST_ROUND_UP_2 (*h);
+ outsize += (GST_ROUND_UP_4 (*w) * *h) / 2;
+ break;
+ case GST_MAKE_FOURCC ('N', 'V', '2', '1'):
+ fourcc = V4L2_PIX_FMT_NV21;
++ *rs = GST_ROUND_UP_4 (*w);
+ outsize = GST_ROUND_UP_4 (*w) * GST_ROUND_UP_2 (*h);
+ outsize += (GST_ROUND_UP_4 (*w) * *h) / 2;
+ break;
+ #ifdef V4L2_PIX_FMT_YVYU
+ case GST_MAKE_FOURCC ('Y', 'V', 'Y', 'U'):
+ fourcc = V4L2_PIX_FMT_YVYU;
++ *rs = GST_ROUND_UP_2 (*w) * 2;
+ outsize = (GST_ROUND_UP_2 (*w) * 2) * *h;
+ break;
+ #endif
+ }
+- } else if (!strcmp (mimetype, "video/x-raw-rgb")) {
++ } else if (!strcmp (mimetype, "video/x-raw-rgb") ||
++ !strcmp (mimetype, "video/x-raw-rgb-strided")) {
+ gint bpp, endianness, r_mask;
+
+ gst_structure_get_int (structure, "bpp", &bpp);
+@@ -1415,20 +1450,25 @@ gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps,
+ switch (bpp) {
+ case 8:
+ fourcc = V4L2_PIX_FMT_RGB332;
++ *rs = *w;
+ break;
+ case 15:
+ fourcc = (endianness == G_LITTLE_ENDIAN) ?
+ V4L2_PIX_FMT_RGB555 : V4L2_PIX_FMT_RGB555X;
++ *rs = 2 * *w;
+ break;
+ case 16:
+ fourcc = (endianness == G_LITTLE_ENDIAN) ?
+ V4L2_PIX_FMT_RGB565 : V4L2_PIX_FMT_RGB565X;
++ *rs = 2 * *w;
+ break;
+ case 24:
+ fourcc = (r_mask == 0xFF) ? V4L2_PIX_FMT_BGR24 : V4L2_PIX_FMT_RGB24;
++ *rs = 3 * *w;
+ break;
+ case 32:
+ fourcc = (r_mask == 0xFF) ? V4L2_PIX_FMT_BGR32 : V4L2_PIX_FMT_RGB32;
++ *rs = 4 * *w;
+ break;
+ }
+ } else if (strcmp (mimetype, "video/x-dv") == 0) {
+@@ -1458,6 +1498,25 @@ gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps,
+ if (fourcc == 0)
+ return FALSE;
+
++ /* check what stride the driver supports */
++ fmt.type = v4l2object->type;
++ fmt.fmt.pix.width = *w;
++ fmt.fmt.pix.height = *h;
++ fmt.fmt.pix.pixelformat = fourcc;
++ fmt.fmt.pix.field = V4L2_FIELD_ANY;
++ fmt.fmt.pix.bytesperline = *rs;
++ if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_TRY_FMT, &fmt) >= 0) {
++ if (fmt.fmt.pix.bytesperline == *rs) {
++ *rs = 0;
++ } else {
++ *rs = fmt.fmt.pix.bytesperline;
++ }
++ GST_INFO_OBJECT (v4l2object->element, "rowstride: %d", *rs);
++ } else {
++ GST_WARNING_OBJECT (v4l2object->element,
++ "VIDIOC_TRY_FMT should not fail.. driver problem?");
++ }
++
+ done:
+ *format = gst_v4l2_object_get_format_from_fourcc (v4l2object, fourcc);
+ *size = outsize;
+@@ -1465,6 +1524,36 @@ done:
+ return TRUE;
+ }
+
++/* Update caps to reflect rowstride that has been requested by the
++ * driver
++ */
++GstCaps *
++gst_v4l2_object_update_rowstride (GstV4l2Object * v4l2object,
++ GstCaps * caps, gint rs)
++{
++ GstStructure *structure;
++ const gchar *mimetype;
++
++ caps = gst_caps_make_writable (caps);
++
++ structure = gst_caps_get_structure (caps, 0);
++ mimetype = gst_structure_get_name (structure);
++
++ if (!strcmp (mimetype, "video/x-raw-yuv")) {
++ mimetype = "video/x-raw-yuv-strided";
++ gst_structure_set_name (structure, mimetype);
++ } else if (!strcmp (mimetype, "video/x-raw-rgb")) {
++ mimetype = "video/x-raw-rgb-strided";
++ gst_structure_set_name (structure, mimetype);
++ }
++
++ if (!strcmp (mimetype, "video/x-raw-yuv-strided") ||
++ !strcmp (mimetype, "video/x-raw-rgb-strided")) {
++ gst_structure_set (structure, "rowstride", G_TYPE_INT, rs, NULL);
++ }
++
++ return caps;
++}
+
+ static gboolean
+ gst_v4l2_object_get_nearest_size (GstV4l2Object * v4l2object,
+diff --git a/sys/v4l2/gstv4l2object.h b/sys/v4l2/gstv4l2object.h
+index a0dd41c..228e7c7 100644
+--- a/sys/v4l2/gstv4l2object.h
++++ b/sys/v4l2/gstv4l2object.h
+@@ -179,15 +179,17 @@ GstCaps* gst_v4l2_object_probe_caps_for_format (GstV4l2Object *v4l2object,
+ const GstStructure * template);
+
+ gboolean gst_v4l2_object_get_caps_info (GstV4l2Object *v4l2object, GstCaps *caps,
+- struct v4l2_fmtdesc **format, gint *w, gint *h,
++ struct v4l2_fmtdesc **format, gint *w, gint *h, gint *rs,
+ gboolean * interlaced, guint *fps_n, guint *fps_d, guint *size);
+
++GstCaps * gst_v4l2_object_update_rowstride (GstV4l2Object * v4l2object, GstCaps * caps, gint rs);
+
+ GSList* gst_v4l2_object_get_format_list (GstV4l2Object *v4l2object);
+
+ GstCaps* gst_v4l2_object_get_all_caps (void);
+
+-GstStructure* gst_v4l2_object_v4l2fourcc_to_structure (guint32 fourcc);
++#define MAX_STRUCTS_PER_FOURCC 2
++gint gst_v4l2_object_v4l2fourcc_to_structures (guint32 fourcc, GstStructure ** structures);
+
+ gboolean gst_v4l2_object_set_format (GstV4l2Object *v4l2object, guint32 pixelformat, guint32 width, guint32 height, gboolean interlaced);
+
+diff --git a/sys/v4l2/gstv4l2sink.c b/sys/v4l2/gstv4l2sink.c
+index 12323f7..a1f78cf 100644
+--- a/sys/v4l2/gstv4l2sink.c
++++ b/sys/v4l2/gstv4l2sink.c
+@@ -776,24 +776,23 @@ gst_v4l2sink_get_caps (GstBaseSink * bsink)
+ for (walk = v4l2sink->v4l2object->formats; walk; walk = walk->next) {
+ struct v4l2_fmtdesc *format;
+
+- GstStructure *template;
++ GstStructure *templates[MAX_STRUCTS_PER_FOURCC];
++ gint count, i;
+
+ format = (struct v4l2_fmtdesc *) walk->data;
+
+- template = gst_v4l2_object_v4l2fourcc_to_structure (format->pixelformat);
++ count = gst_v4l2_object_v4l2fourcc_to_structures (format->pixelformat,
++ templates);
+
+- if (template) {
++ for (i = 0; i < count; i++) {
+ GstCaps *tmp;
+
+- tmp =
+- gst_v4l2_object_probe_caps_for_format (v4l2sink->v4l2object,
+- format->pixelformat, template);
++ tmp = gst_v4l2_object_probe_caps_for_format (v4l2sink->v4l2object,
++ format->pixelformat, templates[i]);
+ if (tmp)
+ gst_caps_append (ret, tmp);
+
+- gst_structure_free (template);
+- } else {
+- GST_DEBUG_OBJECT (v4l2sink, "unknown format %u", format->pixelformat);
++ gst_structure_free (templates[i]);
+ }
+ }
+
+@@ -810,7 +809,7 @@ gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
+ {
+ GstV4l2Sink *v4l2sink = GST_V4L2SINK (bsink);
+ GstQuery *query;
+- gint w = 0, h = 0;
++ gint w = 0, h = 0, rs = 0;
+ gboolean interlaced;
+ struct v4l2_fmtdesc *format;
+ guint fps_n, fps_d;
+@@ -823,11 +822,36 @@ gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
+ return FALSE;
+ }
+
++ /* we want our own v4l2 type of fourcc codes */
++ if (!gst_v4l2_object_get_caps_info (v4l2sink->v4l2object, caps,
++ &format, &w, &h, &rs, &interlaced, &fps_n, &fps_d, &size)) {
++ GST_DEBUG_OBJECT (v4l2sink, "can't get capture format from caps %p", caps);
++ return FALSE;
++ }
++
++ if (!format) {
++ GST_DEBUG_OBJECT (v4l2sink, "unrecognized caps!!");
++ return FALSE;
++ }
++
++ /* we need to make our own ref before we potentially update the
++ * caps, to avoid that we release a ref that is not owned by us
++ * when we make the caps writable
++ */
++ caps = gst_caps_ref (caps);
++
++ /* if necessary, update caps for rowstride */
++ if (rs) {
++ caps = gst_v4l2_object_update_rowstride (v4l2sink->v4l2object, caps, rs);
++ GST_DEBUG_OBJECT (v4l2sink, "updated caps: %" GST_PTR_FORMAT, caps);
++ }
++
+ if (v4l2sink->current_caps) {
+ GST_DEBUG_OBJECT (v4l2sink, "already have caps set.. are they equal?");
+ LOG_CAPS (v4l2sink, v4l2sink->current_caps);
+ if (gst_caps_is_equal (v4l2sink->current_caps, caps)) {
+ GST_DEBUG_OBJECT (v4l2sink, "yes they are!");
++ gst_caps_unref (caps);
+ return TRUE;
+ }
+ GST_DEBUG_OBJECT (v4l2sink, "no they aren't!");
+@@ -842,18 +866,7 @@ gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
+ *
+ */
+ GST_DEBUG_OBJECT (v4l2sink, "warning, changing caps not supported yet");
+- return FALSE;
+- }
+-
+- /* we want our own v4l2 type of fourcc codes */
+- if (!gst_v4l2_object_get_caps_info (v4l2sink->v4l2object, caps,
+- &format, &w, &h, &interlaced, &fps_n, &fps_d, &size)) {
+- GST_DEBUG_OBJECT (v4l2sink, "can't get capture format from caps %p", caps);
+- return FALSE;
+- }
+-
+- if (!format) {
+- GST_DEBUG_OBJECT (v4l2sink, "unrecognized caps!!");
++ gst_caps_unref (caps);
+ return FALSE;
+ }
+
+@@ -893,6 +906,7 @@ gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
+ if (!gst_v4l2_object_set_format (v4l2sink->v4l2object, format->pixelformat,
+ w, h, interlaced)) {
+ /* error already posted */
++ gst_caps_unref (caps);
+ return FALSE;
+ }
+
+@@ -951,6 +965,9 @@ gst_v4l2sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,
+ return GST_FLOW_ERROR;
+ }
+
++ /* caps may have changed in _set_caps() if we need rowstride */
++ caps = v4l2sink->current_caps;
++
+ GST_V4L2_CHECK_OPEN (v4l2sink->v4l2object);
+
+ if (!(v4l2sink->pool = gst_v4l2_buffer_pool_new (GST_ELEMENT (v4l2sink),
+diff --git a/sys/v4l2/gstv4l2src.c b/sys/v4l2/gstv4l2src.c
+index 4a37d35..a9a7787 100644
+--- a/sys/v4l2/gstv4l2src.c
++++ b/sys/v4l2/gstv4l2src.c
+@@ -581,24 +581,23 @@ gst_v4l2src_get_caps (GstBaseSrc * src)
+ for (walk = v4l2src->v4l2object->formats; walk; walk = walk->next) {
+ struct v4l2_fmtdesc *format;
+
+- GstStructure *template;
++ GstStructure *templates[MAX_STRUCTS_PER_FOURCC];
++ gint count, i;
+
+ format = (struct v4l2_fmtdesc *) walk->data;
+
+- template = gst_v4l2_object_v4l2fourcc_to_structure (format->pixelformat);
++ count = gst_v4l2_object_v4l2fourcc_to_structures (format->pixelformat,
++ templates);
+
+- if (template) {
++ for (i = 0; i < count; i++) {
+ GstCaps *tmp;
+
+- tmp =
+- gst_v4l2_object_probe_caps_for_format (v4l2src->v4l2object,
+- format->pixelformat, template);
++ tmp = gst_v4l2_object_probe_caps_for_format (v4l2src->v4l2object,
++ format->pixelformat, templates[i]);
+ if (tmp)
+ gst_caps_append (ret, tmp);
+
+- gst_structure_free (template);
+- } else {
+- GST_DEBUG_OBJECT (v4l2src, "unknown format %u", format->pixelformat);
++ gst_structure_free (templates[i]);
+ }
+ }
+
+@@ -613,7 +612,7 @@ static gboolean
+ gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps)
+ {
+ GstV4l2Src *v4l2src;
+- gint w = 0, h = 0;
++ gint w = 0, h = 0, rs = 0;
+ gboolean interlaced;
+ struct v4l2_fmtdesc *format;
+ guint fps_n, fps_d;
+@@ -635,13 +634,18 @@ gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps)
+ }
+
+ /* 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)) {
++ if (!gst_v4l2_object_get_caps_info (v4l2src->v4l2object, caps, &format,
++ &w, &h, &rs, &interlaced, &fps_n, &fps_d, &size)) {
+ GST_INFO_OBJECT (v4l2src,
+ "can't get capture format from caps %" GST_PTR_FORMAT, caps);
+ return FALSE;
+ }
+
++ /* if necessary, update caps for rowstride */
++ if (rs) {
++ caps = gst_v4l2_object_update_rowstride (v4l2src->v4l2object, caps, rs);
++ }
++
+ 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.0.4
+
diff --git a/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0009-use-GstEventCrop-to-get-crop-info.patch b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0009-use-GstEventCrop-to-get-crop-info.patch
new file mode 100644
index 0000000..8b8679e
--- /dev/null
+++ b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0009-use-GstEventCrop-to-get-crop-info.patch
@@ -0,0 +1,119 @@
+From e7497b9f0c6c88b764d8f95e01197e2a2ea0dd95 Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Tue, 25 May 2010 11:02:45 -0500
+Subject: [PATCH 09/11] use GstEventCrop to get crop info
+
+---
+ sys/v4l2/gstv4l2sink.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 files changed, 62 insertions(+), 1 deletions(-)
+
+diff --git a/sys/v4l2/gstv4l2sink.c b/sys/v4l2/gstv4l2sink.c
+index a1f78cf..feafe7a 100644
+--- a/sys/v4l2/gstv4l2sink.c
++++ b/sys/v4l2/gstv4l2sink.c
+@@ -252,6 +252,7 @@ static GstCaps *gst_v4l2sink_get_caps (GstBaseSink * bsink);
+ static gboolean gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps);
+ static GstFlowReturn gst_v4l2sink_buffer_alloc (GstBaseSink * bsink,
+ guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf);
++static gboolean gst_v4l2sink_event (GstBaseSink * bsink, GstEvent * event);
+ static GstFlowReturn gst_v4l2sink_show_frame (GstBaseSink * bsink,
+ GstBuffer * buf);
+ static void gst_v4l2sink_sync_rotation (GstV4l2Sink * v4l2sink);
+@@ -354,6 +355,7 @@ gst_v4l2sink_class_init (GstV4l2SinkClass * klass)
+ basesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_v4l2sink_get_caps);
+ basesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_v4l2sink_set_caps);
+ basesink_class->buffer_alloc = GST_DEBUG_FUNCPTR (gst_v4l2sink_buffer_alloc);
++ basesink_class->event = GST_DEBUG_FUNCPTR (gst_v4l2sink_event);
+ basesink_class->render = GST_DEBUG_FUNCPTR (gst_v4l2sink_show_frame);
+ }
+
+@@ -895,11 +897,22 @@ gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
+
+ gst_query_parse_buffers_dimensions (query, &min_width, &min_height);
+ if (min_width > w) {
++ v4l2sink->crop.width = w;
++ v4l2sink->crop_fields_set |= RECT_WIDTH_SET;
+ w = min_width;
+ }
+ if (min_height > h) {
++ v4l2sink->crop.height = h;
++ v4l2sink->crop_fields_set |= RECT_HEIGHT_SET;
+ h = min_height;
+ }
++
++ /* clear top/left crop values.. otherwise by default display will try
++ * to center, rather than scale, the image if it is too big to fit on
++ * display
++ */
++ v4l2sink->crop.top = v4l2sink->crop.left = 0;
++ v4l2sink->crop_fields_set |= RECT_TOP_SET | RECT_LEFT_SET;
+ }
+ gst_query_unref (query);
+
+@@ -919,7 +932,13 @@ gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
+ GST_VIDEO_SINK_WIDTH (v4l2sink) = w;
+ GST_VIDEO_SINK_HEIGHT (v4l2sink) = h;
+
+- v4l2sink->current_caps = gst_caps_ref (caps);
++ /* this needs to go after gst_v4l2_object_set_format() to ensure driver
++ * has proper width/height (so we don't confuse it's error checking by
++ * setting a crop larger than the picture size)
++ */
++ gst_v4l2sink_sync_crop_fields (v4l2sink);
++
++ v4l2sink->current_caps = caps;
+
+ return TRUE;
+ }
+@@ -1023,6 +1042,48 @@ gst_v4l2sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,
+ }
+ }
+
++/* called to handle events */
++static gboolean
++gst_v4l2sink_event (GstBaseSink * bsink, GstEvent * event)
++{
++ GstV4l2Sink *v4l2sink = GST_V4L2SINK (bsink);
++ GstEventType type = GST_EVENT_TYPE (event);
++
++ GST_DEBUG_OBJECT (v4l2sink, "event %" GST_PTR_FORMAT, event);
++
++ switch (type) {
++ case GST_EVENT_CROP:{
++ gint top, left, width, height;
++ gst_event_parse_crop (event, &top, &left, &width, &height);
++ if (top >= 0) {
++ v4l2sink->crop.top = top;
++ v4l2sink->crop_fields_set |= RECT_TOP_SET;
++ }
++ if (left >= 0) {
++ v4l2sink->crop.left = left;
++ v4l2sink->crop_fields_set |= RECT_LEFT_SET;
++ }
++ if (width >= 0) {
++ v4l2sink->crop.width = width;
++ v4l2sink->crop_fields_set |= RECT_WIDTH_SET;
++ }
++ if (height >= 0) {
++ v4l2sink->crop.height = height;
++ v4l2sink->crop_fields_set |= RECT_HEIGHT_SET;
++ }
++ gst_v4l2sink_sync_crop_fields (v4l2sink);
++ return TRUE;
++ }
++ default:{
++ if (GST_BASE_SINK_CLASS (parent_class)->event) {
++ return GST_BASE_SINK_CLASS (parent_class)->event (bsink, event);
++ } else {
++ return TRUE;
++ }
++ }
++ }
++}
++
+ /* called after A/V sync to render frame */
+ static GstFlowReturn
+ gst_v4l2sink_show_frame (GstBaseSink * bsink, GstBuffer * buf)
+--
+1.7.0.4
+
diff --git a/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0010-v4l2-prefer-NV12.patch b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0010-v4l2-prefer-NV12.patch
new file mode 100644
index 0000000..d47ef9a
--- /dev/null
+++ b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0010-v4l2-prefer-NV12.patch
@@ -0,0 +1,28 @@
+From 107c18830342c69229857f968dff33071d07992d Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Tue, 14 Sep 2010 07:44:01 -0500
+Subject: [PATCH 10/11] v4l2: prefer NV12
+
+All else being equal, the buffer sizes are smaller compared to a 422 format
+like YUY2/UYVY.. although ideally rank would come from driver.
+---
+ sys/v4l2/gstv4l2object.c | 3 +++
+ 1 files changed, 3 insertions(+), 0 deletions(-)
+
+diff --git a/sys/v4l2/gstv4l2object.c b/sys/v4l2/gstv4l2object.c
+index 5e34456..644edcf 100644
+--- a/sys/v4l2/gstv4l2object.c
++++ b/sys/v4l2/gstv4l2object.c
+@@ -886,6 +886,9 @@ gst_v4l2_object_format_get_rank (const struct v4l2_fmtdesc *fmt)
+ break;
+
+ case V4L2_PIX_FMT_NV12: /* 12 Y/CbCr 4:2:0 */
++ rank = YUV_BASE_RANK + 11;
++ break;
++
+ case V4L2_PIX_FMT_NV21: /* 12 Y/CrCb 4:2:0 */
+ case V4L2_PIX_FMT_YYUV: /* 16 YUV 4:2:2 */
+ case V4L2_PIX_FMT_HI240: /* 8 8-bit color */
+--
+1.7.0.4
+
diff --git a/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0011-v4l2sink-fix-issue-seen-with-autoconvert.patch b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0011-v4l2sink-fix-issue-seen-with-autoconvert.patch
new file mode 100644
index 0000000..44c82af
--- /dev/null
+++ b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0011-v4l2sink-fix-issue-seen-with-autoconvert.patch
@@ -0,0 +1,49 @@
+From 4e319948c62aafd5339c38d065fd8dbfa5a09ced Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Thu, 13 Jan 2011 09:43:08 -0600
+Subject: [PATCH 11/11] v4l2sink: fix issue seen with autoconvert
+
+In this scenario _set_caps() will get called earlier than _buffer_alloc()
+so we need to not override the number of buffers in the case that the
+upstream element answers the query about number of requested buffers.
+---
+ sys/v4l2/gstv4l2sink.c | 6 ++++--
+ 1 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/sys/v4l2/gstv4l2sink.c b/sys/v4l2/gstv4l2sink.c
+index feafe7a..ca6ae15 100644
+--- a/sys/v4l2/gstv4l2sink.c
++++ b/sys/v4l2/gstv4l2sink.c
+@@ -881,6 +881,8 @@ gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
+
+ gst_query_parse_buffers_count (query, &min_buffers);
+
++ GST_DEBUG_OBJECT (v4l2sink, "min_buffers=%d", min_buffers);
++
+ /* XXX need to account for some buffers used by queue, etc.. probably
+ * queue should handle query, pass on to sink pad, and then add some
+ * number of buffers to the min, so this value is dynamic depending
+@@ -888,10 +890,10 @@ gst_v4l2sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
+ */
+ if (min_buffers != -1) {
+ min_buffers += 3 + v4l2sink->min_queued_bufs;
++ v4l2sink->num_buffers_can_change = FALSE;
+ }
+
+ if (min_buffers > v4l2sink->num_buffers) {
+- v4l2sink->num_buffers_can_change = FALSE;
+ v4l2sink->num_buffers = min_buffers;
+ }
+
+@@ -972,7 +974,7 @@ gst_v4l2sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,
+ * than four buffers:
+ */
+ if (!strcmp ("omap_vout", driver)) {
+- if (v4l2sink->num_buffers > 4) {
++ if (v4l2sink->num_buffers_can_change && v4l2sink->num_buffers > 4) {
+ v4l2sink->num_buffers = 4;
+ GST_DEBUG_OBJECT (v4l2sink,
+ "limiting to 4 buffers to work-around omap_vout driver bug");
+--
+1.7.0.4
+
diff --git a/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0012-v4l2sink-Add-Userptr-support.patch b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0012-v4l2sink-Add-Userptr-support.patch
new file mode 100755
index 0000000..bed7c4e
--- /dev/null
+++ b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0012-v4l2sink-Add-Userptr-support.patch
@@ -0,0 +1,440 @@
+diff -Npru gst-plugins-good-0.10.27_11_patch_applied/sys/v4l2/gstv4l2sink.c gst-plugins-good-0.10.27/sys/v4l2/gstv4l2sink.c
+--- gst-plugins-good-0.10.27_11_patch_applied/sys/v4l2/gstv4l2sink.c 2011-11-03 12:15:30.899616681 +0530
++++ gst-plugins-good-0.10.27/sys/v4l2/gstv4l2sink.c 2011-11-03 12:29:07.527616613 +0530
+@@ -62,6 +62,7 @@
+
+ #include "gstv4l2sink.h"
+ #include "gst/gst-i18n-plugin.h"
++#include "gstv4l2_userpointer.h"
+
+ #include <string.h>
+
+@@ -92,6 +93,7 @@ enum
+ PROP_CROP_HEIGHT,
+ PROP_ROTATION,
+ PROP_FLIP,
++ PROP_USERPOINTER,
+ };
+
+
+@@ -352,6 +354,11 @@ gst_v4l2sink_class_init (GstV4l2SinkClas
+ "Flip horizontal/vertical",
+ GST_TYPE_V4L2_FLIP, FLIP_NONE, G_PARAM_READWRITE));
+
++ g_object_class_install_property (gobject_class, PROP_USERPOINTER,
++ g_param_spec_boolean("userpointer", "User Pointer",
++ "configures using user pointer for display without memcopy",
++ TRUE, G_PARAM_READWRITE));
++
+ basesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_v4l2sink_get_caps);
+ basesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_v4l2sink_set_caps);
+ basesink_class->buffer_alloc = GST_DEBUG_FUNCPTR (gst_v4l2sink_buffer_alloc);
+@@ -386,6 +393,8 @@ gst_v4l2sink_init (GstV4l2Sink * v4l2sin
+ v4l2sink->state = 0;
+ v4l2sink->rotation = 0;
+ v4l2sink->flip = FLIP_NONE;
++ v4l2sink->gst_buf_array = NULL;
++ v4l2sink->enableUserPtr = TRUE;
+ }
+
+ static void
+@@ -640,6 +649,9 @@ gst_v4l2sink_set_property (GObject * obj
+ v4l2sink->flip = g_value_get_enum (value);
+ gst_v4l2sink_sync_flip (v4l2sink);
+ break;
++ case PROP_USERPOINTER:
++ v4l2sink->enableUserPtr = g_value_get_boolean (value);
++ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+@@ -693,6 +705,9 @@ gst_v4l2sink_get_property (GObject * obj
+ case PROP_FLIP:
+ g_value_set_enum (value, v4l2sink->flip);
+ break;
++ case PROP_USERPOINTER:
++ g_value_set_boolean (value, v4l2sink->enableUserPtr);
++ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+@@ -705,6 +720,7 @@ gst_v4l2sink_change_state (GstElement *
+ {
+ GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
+ GstV4l2Sink *v4l2sink = GST_V4L2SINK (element);
++ gint i = 0;
+
+ GST_DEBUG_OBJECT (v4l2sink, "%d -> %d",
+ GST_STATE_TRANSITION_CURRENT (transition),
+@@ -718,11 +734,30 @@ gst_v4l2sink_change_state (GstElement *
+ gst_v4l2sink_sync_rotation (v4l2sink);
+ gst_v4l2sink_sync_flip (v4l2sink);
+ break;
++ case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
++ break;
+ default:
+ break;
+ }
+-
+- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
++ if(transition == GST_STATE_CHANGE_PAUSED_TO_READY){
++ if(v4l2sink->enableUserPtr) {
++ GST_DEBUG_OBJECT (v4l2sink, "!!!!!!!!!unreference all the remaining buffers!!!!!!!!!");
++ printf("\n!!!!!!!!!unreference all the remaining buffers!!!!!!!!!");
++ if(v4l2sink->gst_buf_array != NULL){
++ for(i = 0;i<v4l2sink->num_buffers;i++) {
++ if(v4l2sink->gst_buf_array[i] != NULL) {
++ gst_buffer_unref(v4l2sink->gst_buf_array[i]);
++ v4l2sink->gst_buf_array[i] = NULL;
++ }
++ }
++ }
++ }
++ ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
++ }
++ else{
++ ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
++ }
++
+
+ switch (transition) {
+ case GST_STATE_CHANGE_PAUSED_TO_READY:
+@@ -734,9 +769,14 @@ gst_v4l2sink_change_state (GstElement *
+ }
+ break;
+ case GST_STATE_CHANGE_READY_TO_NULL:
+- if (NULL != v4l2sink->pool)
++ if (NULL != v4l2sink->pool){
+ gst_v4l2_buffer_pool_destroy (v4l2sink->pool);
+ v4l2sink->pool = NULL;
++ }
++ if(v4l2sink->gst_buf_array){
++ gst_v4l2sink_userpointer_deinit(v4l2sink);
++ }
++
+ /* close the device */
+ if (!gst_v4l2_object_stop (v4l2sink->v4l2object))
+ return GST_STATE_CHANGE_FAILURE;
+@@ -871,6 +911,18 @@ gst_v4l2sink_set_caps (GstBaseSink * bsi
+ gst_caps_unref (caps);
+ return FALSE;
+ }
++ if (v4l2sink->gst_buf_array) {
++ /* TODO: if we've already allocated buffers, we probably need to
++ * do something here to free and reallocate....
++ *
++ * gst_v4l2_object_stop_streaming()
++ * gst_v4l2_buffer_pool_destroy()
++ *
++ */
++ GST_DEBUG_OBJECT (v4l2sink, "warning, changing caps not supported yet");
++ gst_caps_unref (caps);
++ return FALSE;
++ }
+
+ /* query to find if anyone upstream using these buffers has any
+ * minimum requirements:
+@@ -1092,11 +1144,13 @@ gst_v4l2sink_show_frame (GstBaseSink * b
+ {
+ GstV4l2Sink *v4l2sink = GST_V4L2SINK (bsink);
+ GstBuffer *newbuf = NULL;
++ gint retval = 0;
+
+ GST_DEBUG_OBJECT (v4l2sink, "render buffer: %p", buf);
+
+- if (!GST_IS_V4L2_BUFFER (buf)) {
+- GstFlowReturn ret;
++ if(!v4l2sink->enableUserPtr){
++ if (!GST_IS_V4L2_BUFFER (buf)) {
++ GstFlowReturn ret;
+
+ /* special case check for sub-buffers: In certain cases, places like
+ * GstBaseTransform, which might check that the buffer is writable
+@@ -1175,7 +1229,37 @@ gst_v4l2sink_show_frame (GstBaseSink * b
+ gst_buffer_unref (GST_BUFFER (v4l2buf));
+ }
+ }
++ }
++ else {
++ /*configures the v4l2 to user pointer mode only once*/
++ if(v4l2sink->gst_buf_array == NULL) {
++ v4l2sink->state = STATE_PENDING_STREAMON;
++ /*Initializes the driver to use userpointers*/
++ retval = gst_v4l2sink_userpointer_init(bsink,v4l2sink);
++ if(retval > 0) {
++ GST_DEBUG_OBJECT (v4l2sink, "succeess fully initialized the driver for user pointer mode");
++ }
++ else {
++ GST_DEBUG_OBJECT (v4l2sink, "failed to initialized the driver for user pointer mode");
++ }
++ }
++
++ /*Enqueues the buffer with v4l2*/
++ gst_v4l2sink_enqueue_userpointer(v4l2sink,buf);
++
++ if (v4l2sink->state == STATE_PENDING_STREAMON) {
++ GST_DEBUG_OBJECT (v4l2sink, "Start streaming");
++ if (!gst_v4l2_object_start_streaming (v4l2sink->v4l2object)) {
++ GST_DEBUG_OBJECT (v4l2sink, "Failed to Start streaming");
++ return GST_FLOW_ERROR;
++ }
++ v4l2sink->state = STATE_STREAMING;
++ }
++
++ /*Dequeues the previous buffer from v4l2*/
++ gst_v4l2sink_dequeue_userpointer(v4l2sink,v4l2sink->min_queued_bufs);
+
++ }
+ return GST_FLOW_OK;
+ }
+
+diff -Npru gst-plugins-good-0.10.27_11_patch_applied/sys/v4l2/gstv4l2sink.h gst-plugins-good-0.10.27/sys/v4l2/gstv4l2sink.h
+--- gst-plugins-good-0.10.27_11_patch_applied/sys/v4l2/gstv4l2sink.h 2011-11-03 12:14:31.347616465 +0530
++++ gst-plugins-good-0.10.27/sys/v4l2/gstv4l2sink.h 2011-11-03 12:29:07.527616613 +0530
+@@ -78,6 +78,9 @@ struct _GstV4l2Sink {
+ guint8 state;
+ gint rotation;
+ gint flip;
++ GstBuffer **gst_buf_array;
++ gint queued_buff_count;
++ gboolean enableUserPtr;
+ };
+
+ struct _GstV4l2SinkClass {
+diff -Npru gst-plugins-good-0.10.27_11_patch_applied/sys/v4l2/gstv4l2_userpointer.c gst-plugins-good-0.10.27/sys/v4l2/gstv4l2_userpointer.c
+--- gst-plugins-good-0.10.27_11_patch_applied/sys/v4l2/gstv4l2_userpointer.c 1970-01-01 05:30:00.000000000 +0530
++++ gst-plugins-good-0.10.27/sys/v4l2/gstv4l2_userpointer.c 2011-11-03 12:46:39.599616724 +0530
+@@ -0,0 +1,130 @@
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++
++#include "gstv4l2colorbalance.h"
++#ifdef HAVE_XVIDEO
++#include "gstv4l2xoverlay.h"
++#endif
++#include "gstv4l2vidorient.h"
++
++#include "gstv4l2sink.h"
++#include "gst/gst-i18n-plugin.h"
++
++#include <string.h>
++#include "gstv4l2_userpointer.h"
++
++gint
++gst_v4l2sink_userpointer_init(GstBaseSink * bsink,GstV4l2Sink * v4l2sink)
++{
++
++ gint retval = 0,i =0;
++ struct v4l2_requestbuffers reqbuf = {0};
++
++ if(v4l2sink->gst_buf_array == NULL) {
++ memset (&reqbuf, 0, sizeof (struct v4l2_requestbuffers));
++ reqbuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
++ reqbuf.count = v4l2sink->num_buffers;
++ reqbuf.memory = V4L2_MEMORY_USERPTR;
++
++ if ((retval = v4l2_ioctl(v4l2sink->v4l2object->video_fd, VIDIOC_REQBUFS, &reqbuf))) {
++ GST_DEBUG_OBJECT (v4l2sink, "ioctl for VIDIOC_REQBUFS FAILED");
++ switch(errno) {
++ case EBUSY:
++ GST_DEBUG_OBJECT (v4l2sink, "Error : EBUSY");
++ break;
++ case EINVAL:
++ GST_DEBUG_OBJECT (v4l2sink, "Error : EINVAL");
++ break;
++ default:
++ GST_DEBUG_OBJECT (v4l2sink, "Error : unknown error");
++ break;
++ }// switch
++ } // if ..ioctl..
++
++ v4l2sink->queued_buff_count = 0;
++ /* allocate a gst buffer array to hold the buffers given to v4l2 for display */
++ v4l2sink->gst_buf_array = (GstBuffer **)malloc(sizeof(GstBuffer *)* (v4l2sink->num_buffers));
++ for(i =0; i<v4l2sink->num_buffers;i++) {
++ v4l2sink->gst_buf_array[i] = NULL;
++ }
++ }
++ else {
++ GST_DEBUG_OBJECT (v4l2sink, "Driver is already initialized");
++ }
++ return 1;
++}
++
++void
++gst_v4l2sink_enqueue_userpointer(GstV4l2Sink * v4l2sink,GstBuffer * buf)
++{
++
++ gint i=0;
++ struct v4l2_buffer v4l2buffer = {0};
++
++ for(i =0; i<v4l2sink->num_buffers;i++) {
++ if(v4l2sink->gst_buf_array[i] == NULL) {
++ v4l2sink->gst_buf_array[i] = buf;
++ break;
++ }
++ }
++
++ v4l2buffer.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
++ v4l2buffer.memory = V4L2_MEMORY_USERPTR;
++ v4l2buffer.m.userptr = (unsigned long)GST_BUFFER_DATA(buf);
++ v4l2buffer.length = GST_BUFFER_SIZE(buf);
++ v4l2buffer.index = i;
++
++ if (v4l2_ioctl (v4l2sink->v4l2object->video_fd, VIDIOC_QBUF, &v4l2buffer) < 0) {
++ GST_DEBUG_OBJECT (v4l2sink, "Queuing user buffer %p with v4l2 driver failed",buf);
++ v4l2sink->gst_buf_array[i] = NULL;
++ }
++ else {
++ GST_DEBUG_OBJECT (v4l2sink, "Queued user buffer %p with v4l2 driver",buf);
++ v4l2sink->queued_buff_count++;
++ /* add reference to the corresponding gst buffer so that upstream plugin
++ does not overwrites it while displaying */
++ gst_buffer_ref (buf);
++ }
++}
++
++void
++gst_v4l2sink_dequeue_userpointer(GstV4l2Sink * v4l2sink, int min_queue_count)
++{
++ struct v4l2_buffer buffer = {0};
++ memset (&buffer, 0x00, sizeof (buffer));
++ buffer.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
++ buffer.memory = V4L2_MEMORY_USERPTR;
++
++ while(v4l2sink->queued_buff_count > min_queue_count) {
++ if(v4l2_ioctl (v4l2sink->v4l2object->video_fd, VIDIOC_DQBUF, &buffer) >= 0) {
++ GST_DEBUG_OBJECT (v4l2sink, "Dequeued the buffer: %p",v4l2sink->gst_buf_array[buffer.index]);
++ v4l2sink->queued_buff_count--;
++ /* unreference the corresponding gst buffer so that upstream plugin can access */
++ if(v4l2sink->gst_buf_array[buffer.index])
++ gst_buffer_unref(v4l2sink->gst_buf_array[buffer.index]);
++
++ v4l2sink->gst_buf_array[buffer.index] = NULL;
++ }
++ else {
++ GST_DEBUG_OBJECT (v4l2sink, "Failed to dequeue the buffer");
++ break;
++ }
++ }
++}
++
++void
++gst_v4l2sink_userpointer_deinit(GstV4l2Sink * v4l2sink)
++{
++
++ if(v4l2sink->gst_buf_array) {
++ GST_DEBUG_OBJECT (v4l2sink, "Freeing the gst_buf_array");
++ gst_v4l2sink_dequeue_userpointer(v4l2sink, 0);
++ free(v4l2sink->gst_buf_array);
++ v4l2sink->gst_buf_array = NULL;
++ }
++
++}
++
++
+diff -Npru gst-plugins-good-0.10.27_11_patch_applied/sys/v4l2/gstv4l2_userpointer.h gst-plugins-good-0.10.27/sys/v4l2/gstv4l2_userpointer.h
+--- gst-plugins-good-0.10.27_11_patch_applied/sys/v4l2/gstv4l2_userpointer.h 1970-01-01 05:30:00.000000000 +0530
++++ gst-plugins-good-0.10.27/sys/v4l2/gstv4l2_userpointer.h 2011-11-03 12:18:32.587616929 +0530
+@@ -0,0 +1,20 @@
++#ifndef GSTV4L2SINK_USERPTR_H
++#define GSTV4L2SINK_USERPTR_H
++
++#include <gst/video/gstvideosink.h>
++#include <gstv4l2object.h>
++#include <gstv4l2bufferpool.h>
++#include"gstv4l2sink.h"
++#include <stdlib.h>
++
++
++gint
++gst_v4l2sink_userpointer_init(GstBaseSink * ,GstV4l2Sink *);
++void
++gst_v4l2sink_enqueue_userpointer(GstV4l2Sink * ,GstBuffer * );
++void
++gst_v4l2sink_dequeue_userpointer(GstV4l2Sink * , int );
++void
++gst_v4l2sink_userpointer_deinit(GstV4l2Sink * );
++
++#endif
+diff -Npru gst-plugins-good-0.10.27_11_patch_applied/sys/v4l2/Makefile.am gst-plugins-good-0.10.27/sys/v4l2/Makefile.am
+--- gst-plugins-good-0.10.27_11_patch_applied/sys/v4l2/Makefile.am 2011-01-02 17:10:29.000000000 +0530
++++ gst-plugins-good-0.10.27/sys/v4l2/Makefile.am 2011-11-03 12:29:12.103616704 +0530
+@@ -20,7 +20,8 @@ libgstvideo4linux2_la_SOURCES = gstv4l2.
+ $(xv_source)
+
+ if BUILD_EXPERIMENTAL
+-libgstvideo4linux2_la_SOURCES += gstv4l2sink.c
++libgstvideo4linux2_la_SOURCES += gstv4l2sink.c \
++ gstv4l2_userpointer.c
+ endif
+
+ libgstvideo4linux2_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) \
+@@ -49,6 +50,7 @@ noinst_HEADERS = \
+ gstv4l2bufferpool.h \
+ gstv4l2colorbalance.h \
+ gstv4l2object.h \
++ gstv4l2_userpointer.h \
+ gstv4l2sink.h \
+ gstv4l2src.h \
+ gstv4l2tuner.h \
+diff -Npru gst-plugins-good-0.10.27_11_patch_applied/sys/v4l2/Makefile.in gst-plugins-good-0.10.27/sys/v4l2/Makefile.in
+--- gst-plugins-good-0.10.27_11_patch_applied/sys/v4l2/Makefile.in 2011-01-21 15:59:42.000000000 +0530
++++ gst-plugins-good-0.10.27/sys/v4l2/Makefile.in 2011-11-03 12:29:12.103616704 +0530
+@@ -35,7 +35,7 @@ PRE_UNINSTALL = :
+ POST_UNINSTALL = :
+ build_triplet = @build@
+ host_triplet = @host@
+-@BUILD_EXPERIMENTAL_TRUE@am__append_1 = gstv4l2sink.c
++@BUILD_EXPERIMENTAL_TRUE@am__append_1 = gstv4l2sink.c gstv4l2_userpointer.c
+ subdir = sys/v4l2
+ DIST_COMMON = README $(noinst_HEADERS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in
+@@ -116,11 +116,11 @@ libgstvideo4linux2_la_DEPENDENCIES = $(a
+ am__libgstvideo4linux2_la_SOURCES_DIST = gstv4l2.c \
+ gstv4l2colorbalance.c gstv4l2object.c gstv4l2bufferpool.c \
+ gstv4l2src.c gstv4l2tuner.c gstv4l2vidorient.c v4l2_calls.c \
+- v4l2src_calls.c gstv4l2xoverlay.c gstv4l2sink.c
++ v4l2src_calls.c gstv4l2xoverlay.c gstv4l2sink.c gstv4l2_userpointer.c
+ @USE_XVIDEO_TRUE@am__objects_1 = \
+ @USE_XVIDEO_TRUE@ libgstvideo4linux2_la-gstv4l2xoverlay.lo
+ @BUILD_EXPERIMENTAL_TRUE@am__objects_2 = \
+-@BUILD_EXPERIMENTAL_TRUE@ libgstvideo4linux2_la-gstv4l2sink.lo
++@BUILD_EXPERIMENTAL_TRUE@ libgstvideo4linux2_la-gstv4l2sink.lo libgstvideo4linux2_la-gstv4l2_userpointer.lo
+ am_libgstvideo4linux2_la_OBJECTS = libgstvideo4linux2_la-gstv4l2.lo \
+ libgstvideo4linux2_la-gstv4l2colorbalance.lo \
+ libgstvideo4linux2_la-gstv4l2object.lo \
+@@ -524,6 +524,7 @@ noinst_HEADERS = \
+ gstv4l2bufferpool.h \
+ gstv4l2colorbalance.h \
+ gstv4l2object.h \
++ gstv4l2_userpointer.h \
+ gstv4l2sink.h \
+ gstv4l2src.h \
+ gstv4l2tuner.h \
+@@ -617,6 +618,7 @@ distclean-compile:
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstvideo4linux2_la-gstv4l2xoverlay.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstvideo4linux2_la-v4l2_calls.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstvideo4linux2_la-v4l2src_calls.Plo@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgstvideo4linux2_la-gstv4l2_userpointer.Plo@am__quote@
+
+ .c.o:
+ @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@@ -730,6 +732,15 @@ libgstvideo4linux2_la-gstv4l2sink.lo: gs
+ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstvideo4linux2_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstvideo4linux2_la_CFLAGS) $(CFLAGS) -c -o libgstvideo4linux2_la-gstv4l2sink.lo `test -f 'gstv4l2sink.c' || echo '$(srcdir)/'`gstv4l2sink.c
+
++libgstvideo4linux2_la-gstv4l2_userpointer.lo: gstv4l2_userpointer.c
++@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstvideo4linux2_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstvideo4linux2_la_CFLAGS) $(CFLAGS) -MT libgstvideo4linux2_la-gstv4l2_userpointer.lo -MD -MP -MF $(DEPDIR)/libgstvideo4linux2_la-gstv4l2_userpointer.Tpo -c -o libgstvideo4linux2_la-gstv4l2_userpointer.lo `test -f 'gstv4l2_userpointer.c' || echo '$(srcdir)/'`gstv4l2_userpointer.c
++@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgstvideo4linux2_la-gstv4l2_userpointer.Tpo $(DEPDIR)/libgstvideo4linux2_la-gstv4l2_userpointer.Plo
++@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gstv4l2_userpointer.c' object='libgstvideo4linux2_la-gstv4l2_userpointer.lo' libtool=yes @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(libgstvideo4linux2_la_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgstvideo4linux2_la_CFLAGS) $(CFLAGS) -c -o libgstvideo4linux2_la-gstv4l2_userpointer.lo `test -f 'gstv4l2_userpointer.c' || echo '$(srcdir)/'`gstv4l2_userpointer.c
++
++
+ mostlyclean-libtool:
+ -rm -f *.lo
+
diff --git a/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0013-v4l2sink-interlaced-seq-tb-format.patch b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0013-v4l2sink-interlaced-seq-tb-format.patch
new file mode 100644
index 0000000..1c32f15
--- /dev/null
+++ b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0013-v4l2sink-interlaced-seq-tb-format.patch
@@ -0,0 +1,38 @@
+diff -Npru gst-plugins-good-0.10.27.orig/sys/v4l2/gstv4l2object.c gst-plugins-good-0.10.27/sys/v4l2/gstv4l2object.c
+--- gst-plugins-good-0.10.27.orig/sys/v4l2/gstv4l2object.c 2011-11-04 16:37:53.000000000 +0530
++++ gst-plugins-good-0.10.27/sys/v4l2/gstv4l2object.c 2011-10-25 15:48:58.000000000 +0530
+@@ -1741,7 +1741,7 @@ return_data:
+ s = gst_structure_copy (template);
+ gst_structure_set (s, "width", G_TYPE_INT, (gint) width,
+ "height", G_TYPE_INT, (gint) height,
+- "interlaced", G_TYPE_BOOLEAN, interlaced, NULL);
++ /* "interlaced", G_TYPE_BOOLEAN, interlaced, */ NULL);
+
+ if (G_IS_VALUE (&rates)) {
+ /* only change the framerate on the template when we have a valid probed new
+@@ -1999,7 +1999,7 @@ default_frame_sizes:
+ else
+ gst_structure_set (tmp, "height", GST_TYPE_INT_RANGE, min_h, max_h, NULL);
+
+- gst_structure_set (tmp, "interlaced", G_TYPE_BOOLEAN, interlaced, NULL);
++ // gst_structure_set (tmp, "interlaced", G_TYPE_BOOLEAN, interlaced, NULL);
+
+ gst_caps_append_structure (ret, tmp);
+
+@@ -2038,7 +2038,7 @@ gst_v4l2_object_get_nearest_size (GstV4l
+ fmt.fmt.pix.width = *width;
+ fmt.fmt.pix.height = *height;
+ fmt.fmt.pix.pixelformat = pixelformat;
+- fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
++ fmt.fmt.pix.field = V4L2_FIELD_SEQ_TB;
+ r = v4l2_ioctl (fd, VIDIOC_TRY_FMT, &fmt);
+ }
+
+@@ -2084,6 +2084,7 @@ gst_v4l2_object_get_nearest_size (GstV4l
+ case V4L2_FIELD_NONE:
+ *interlaced = FALSE;
+ break;
++ case V4L2_FIELD_SEQ_TB:
+ case V4L2_FIELD_INTERLACED:
+ case V4L2_FIELD_INTERLACED_TB:
+ case V4L2_FIELD_INTERLACED_BT:
diff --git a/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0014-v4l2src-Add-Userptr-support.patch b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0014-v4l2src-Add-Userptr-support.patch
new file mode 100755
index 0000000..459bb07
--- /dev/null
+++ b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gst-plugins-good-0.10.28/0014-v4l2src-Add-Userptr-support.patch
@@ -0,0 +1,332 @@
+diff -Npru gst-plugins-good-0.10.28.orig/sys/v4l2/gstv4l2bufferpool.c gst-plugins-good-0.10.28/sys/v4l2/gstv4l2bufferpool.c
+--- gst-plugins-good-0.10.28.orig/sys/v4l2/gstv4l2bufferpool.c 2011-03-08 19:24:35.000000000 +0530
++++ gst-plugins-good-0.10.28/sys/v4l2/gstv4l2bufferpool.c 2012-01-06 17:30:50.399608721 +0530
+@@ -219,6 +219,41 @@ mmap_failed:
+ }
+ }
+
++static GstV4l2Buffer *
++gst_v4l2_buffer_new_userptr (GstV4l2BufferPool * pool, guint index, GstCaps * caps)
++{
++ GstV4l2Buffer *ret;
++ guint8 *data;
++ GstBuffer *buf;
++ GstPad *srcpad;
++
++ ret = (GstV4l2Buffer *) gst_mini_object_new (GST_TYPE_V4L2_BUFFER);
++
++ GST_LOG_OBJECT (pool->v4l2elem, "creating buffer %u, %p in pool %p", index,
++ ret, pool);
++
++ ret->pool =
++ (GstV4l2BufferPool *) gst_mini_object_ref (GST_MINI_OBJECT (pool));
++
++ ret->vbuffer.index = index;
++ ret->vbuffer.type = pool->type;
++ ret->vbuffer.memory = V4L2_MEMORY_USERPTR;
++
++ srcpad = GST_BASE_SRC_PAD(pool->v4l2elem);
++ gst_pad_alloc_buffer(srcpad,0,GST_V4L2SRC(pool->v4l2elem)->frame_byte_size,caps,&buf);
++ data = GST_BUFFER_DATA(buf);
++ gst_buffer_unref(buf);
++ ret->vbuffer.m.userptr = (unsigned long)data;
++
++ GST_BUFFER_DATA (ret) = data;
++ GST_BUFFER_SIZE (ret) = ret->vbuffer.length;
++
++ GST_BUFFER_FLAG_SET (ret, GST_BUFFER_FLAG_READONLY);
++
++ gst_buffer_set_caps (GST_BUFFER (ret), gst_caps_ref(caps));
++
++ return ret;
++}
+
+ /*
+ * GstV4l2BufferPool:
+@@ -327,13 +362,15 @@ get_v4l2_object (GstElement * v4l2elem)
+ *
+ * Returns: the new pool, use gst_v4l2_buffer_pool_destroy() to free resources
+ */
++
+ GstV4l2BufferPool *
+ gst_v4l2_buffer_pool_new (GstElement * v4l2elem, gint fd, gint num_buffers,
+- GstCaps * caps, gboolean requeuebuf, enum v4l2_buf_type type)
++ GstCaps * caps, gboolean requeuebuf, enum v4l2_buf_type type, enum v4l2_memory mem_type)
+ {
+ GstV4l2BufferPool *pool;
+ gint n;
+ struct v4l2_requestbuffers breq;
++ GstV4l2Buffer *(*buffer_new)(GstV4l2BufferPool * pool, guint index, GstCaps * caps);
+
+ pool = (GstV4l2BufferPool *) gst_mini_object_new (GST_TYPE_V4L2_BUFFER_POOL);
+
+@@ -349,7 +386,7 @@ gst_v4l2_buffer_pool_new (GstElement * v
+ memset (&breq, 0, sizeof (struct v4l2_requestbuffers));
+ breq.type = type;
+ breq.count = num_buffers;
+- breq.memory = V4L2_MEMORY_MMAP;
++ breq.memory = mem_type;
+
+ if (v4l2_ioctl (fd, VIDIOC_REQBUFS, &breq) < 0)
+ goto reqbufs_failed;
+@@ -372,10 +409,15 @@ gst_v4l2_buffer_pool_new (GstElement * v
+ pool->buffer_count = num_buffers;
+ pool->buffers = g_new0 (GstV4l2Buffer *, num_buffers);
+ pool->avail_buffers = g_async_queue_new ();
++ pool->mem_type = mem_type;
+
+- /* now, map the buffers: */
++ if(mem_type == V4L2_MEMORY_USERPTR)
++ buffer_new = gst_v4l2_buffer_new_userptr;
++ else
++ buffer_new = gst_v4l2_buffer_new;
++
+ for (n = 0; n < num_buffers; n++) {
+- pool->buffers[n] = gst_v4l2_buffer_new (pool, n, caps);
++ pool->buffers[n] = buffer_new (pool, n, caps);
+ if (!pool->buffers[n])
+ goto buffer_new_failed;
+ pool->num_live_buffers++;
+@@ -510,6 +552,9 @@ gst_v4l2_buffer_pool_qbuf (GstV4l2Buffer
+ {
+ GST_LOG_OBJECT (pool->v4l2elem, "enqueue pool buffer %d", buf->vbuffer.index);
+
++ if(buf->vbuffer.memory == V4L2_MEMORY_USERPTR)
++ buf->vbuffer.m.userptr = (unsigned long)GST_BUFFER_DATA(buf);
++
+ if (v4l2_ioctl (pool->video_fd, VIDIOC_QBUF, &buf->vbuffer) < 0)
+ return FALSE;
+
+@@ -539,7 +584,7 @@ gst_v4l2_buffer_pool_dqbuf (GstV4l2Buffe
+
+ memset (&buffer, 0x00, sizeof (buffer));
+ buffer.type = pool->type;
+- buffer.memory = V4L2_MEMORY_MMAP;
++ buffer.memory = pool->mem_type;
+
+
+ if (v4l2_ioctl (pool->video_fd, VIDIOC_DQBUF, &buffer) >= 0) {
+diff -Npru gst-plugins-good-0.10.28.orig/sys/v4l2/gstv4l2bufferpool.h gst-plugins-good-0.10.28/sys/v4l2/gstv4l2bufferpool.h
+--- gst-plugins-good-0.10.28.orig/sys/v4l2/gstv4l2bufferpool.h 2011-03-08 19:24:35.000000000 +0530
++++ gst-plugins-good-0.10.28/sys/v4l2/gstv4l2bufferpool.h 2012-01-06 16:27:51.691608198 +0530
+@@ -64,6 +64,7 @@ struct _GstV4l2BufferPool
+ gint video_fd; /* a dup(2) of the v4l2object's video_fd */
+ guint buffer_count;
+ GstV4l2Buffer **buffers;
++ enum v4l2_memory mem_type;
+ };
+
+ struct _GstV4l2Buffer {
+@@ -79,7 +80,7 @@ struct _GstV4l2Buffer {
+ };
+
+ void gst_v4l2_buffer_pool_destroy (GstV4l2BufferPool * pool);
+-GstV4l2BufferPool *gst_v4l2_buffer_pool_new (GstElement *v4l2elem, gint fd, gint num_buffers, GstCaps * caps, gboolean requeuebuf, enum v4l2_buf_type type);
++GstV4l2BufferPool *gst_v4l2_buffer_pool_new (GstElement *v4l2elem, gint fd, gint num_buffers, GstCaps * caps, gboolean requeuebuf, enum v4l2_buf_type type, enum v4l2_memory mem_type);
+
+
+ GstV4l2Buffer *gst_v4l2_buffer_pool_get (GstV4l2BufferPool *pool, gboolean blocking);
+diff -Npru gst-plugins-good-0.10.28.orig/sys/v4l2/gstv4l2object.c gst-plugins-good-0.10.28/sys/v4l2/gstv4l2object.c
+--- gst-plugins-good-0.10.28.orig/sys/v4l2/gstv4l2object.c 2012-01-04 14:41:22.979611574 +0530
++++ gst-plugins-good-0.10.28/sys/v4l2/gstv4l2object.c 2012-01-06 16:27:51.735609396 +0530
+@@ -40,7 +40,8 @@
+ #include "gstv4l2colorbalance.h"
+
+ #include "gst/gst-i18n-plugin.h"
+-
++#include "gstv4l2src.h"
++#include "gstv4l2sink.h"
+ /* videodev2.h is not versioned and we can't easily check for the presence
+ * of enum values at compile time, but the V4L2_CAP_VIDEO_OUTPUT_OVERLAY define
+ * was added in the same commit as V4L2_FIELD_INTERLACED_{TB,BT} (b2787845) */
+@@ -1510,7 +1511,8 @@ gst_v4l2_object_get_caps_info (GstV4l2Ob
+ fmt.fmt.pix.bytesperline = *rs;
+ if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_TRY_FMT, &fmt) >= 0) {
+ if (fmt.fmt.pix.bytesperline == *rs) {
+- *rs = 0;
++ if (GST_IS_V4L2SINK (v4l2object->element))
++ *rs = 0;
+ } else {
+ *rs = fmt.fmt.pix.bytesperline;
+ }
+diff -Npru gst-plugins-good-0.10.28.orig/sys/v4l2/gstv4l2sink.c gst-plugins-good-0.10.28/sys/v4l2/gstv4l2sink.c
+--- gst-plugins-good-0.10.28.orig/sys/v4l2/gstv4l2sink.c 2012-01-04 14:41:22.967609512 +0530
++++ gst-plugins-good-0.10.28/sys/v4l2/gstv4l2sink.c 2012-01-06 16:27:51.739609397 +0530
+@@ -1046,7 +1046,7 @@ gst_v4l2sink_buffer_alloc (GstBaseSink *
+ if (!(v4l2sink->pool = gst_v4l2_buffer_pool_new (GST_ELEMENT (v4l2sink),
+ v4l2sink->v4l2object->video_fd,
+ v4l2sink->num_buffers, caps, FALSE,
+- V4L2_BUF_TYPE_VIDEO_OUTPUT))) {
++ V4L2_BUF_TYPE_VIDEO_OUTPUT, V4L2_MEMORY_MMAP))) {
+ return GST_FLOW_ERROR;
+ }
+
+diff -Npru gst-plugins-good-0.10.28.orig/sys/v4l2/gstv4l2src.c gst-plugins-good-0.10.28/sys/v4l2/gstv4l2src.c
+--- gst-plugins-good-0.10.28.orig/sys/v4l2/gstv4l2src.c 2012-01-04 14:41:22.879611204 +0530
++++ gst-plugins-good-0.10.28/sys/v4l2/gstv4l2src.c 2012-01-06 17:29:28.836112240 +0530
+@@ -216,6 +216,10 @@ gst_v4l2src_get_read (GstV4l2Src * v4l2s
+ static GstFlowReturn
+ gst_v4l2src_get_mmap (GstV4l2Src * v4l2src, GstBuffer ** buf);
+
++/* DV query method */
++void gst_v4l2_object_set_dv_preset(GstV4l2Object * v4l2object);
++
++
+ static void
+ gst_v4l2src_base_init (gpointer g_class)
+ {
+@@ -608,6 +612,33 @@ gst_v4l2src_get_caps (GstBaseSrc * src)
+ return ret;
+ }
+
++void gst_v4l2_object_set_dv_preset(GstV4l2Object * v4l2object)
++{
++ struct v4l2_dv_preset dv_preset;
++
++ dv_preset.preset = 0x0;
++ v4l2_ioctl (v4l2object->video_fd, VIDIOC_QUERY_DV_PRESET, &dv_preset);
++
++ switch (dv_preset.preset) {
++ case V4L2_DV_720P60:
++ printf("\n Mode set is 720P60\n");
++ break;
++ case V4L2_DV_1080I60:
++ printf("\n Mode set is 1080I60\n");
++ break;
++ case V4L2_DV_1080P60:
++ printf("\n Mode set is 1080P60\n");
++ break;
++ case V4L2_DV_1080P30:
++ printf("\n Mode set is 1080P30\n");
++ break;
++ default:
++ printf("\n Mode set is %d\n", dv_preset.preset);
++ }
++ v4l2_ioctl (v4l2object->video_fd, VIDIOC_S_DV_PRESET, &dv_preset);
++
++}
++
+ static gboolean
+ gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps)
+ {
+@@ -633,6 +664,7 @@ gst_v4l2src_set_caps (GstBaseSrc * src,
+ return FALSE;
+ }
+
++ gst_v4l2_object_set_dv_preset(v4l2src->v4l2object);
+ /* we want our own v4l2 type of fourcc codes */
+ if (!gst_v4l2_object_get_caps_info (v4l2src->v4l2object, caps, &format,
+ &w, &h, &rs, &interlaced, &fps_n, &fps_d, &size)) {
+@@ -649,6 +681,9 @@ gst_v4l2src_set_caps (GstBaseSrc * src,
+ GST_DEBUG_OBJECT (v4l2src, "trying to set_capture %dx%d at %d/%d fps, "
+ "format %s", w, h, fps_n, fps_d, format->description);
+
++ /* now store the expected output size */
++ v4l2src->frame_byte_size = size;
++
+ if (!gst_v4l2src_set_capture (v4l2src, format->pixelformat, w, h,
+ interlaced, fps_n, fps_d))
+ /* error already posted */
+@@ -666,9 +701,6 @@ gst_v4l2src_set_caps (GstBaseSrc * src,
+ if (!gst_v4l2src_capture_start (v4l2src))
+ return FALSE;
+
+- /* now store the expected output size */
+- v4l2src->frame_byte_size = size;
+-
+ return TRUE;
+ }
+
+@@ -901,9 +933,7 @@ gst_v4l2src_get_mmap (GstV4l2Src * v4l2s
+ GstBuffer *temp;
+ GstFlowReturn ret;
+ guint size;
+- guint count = 0;
+
+-again:
+ ret = gst_v4l2src_grab_frame (v4l2src, &temp);
+ if (G_UNLIKELY (ret != GST_FLOW_OK))
+ goto done;
+@@ -911,31 +941,13 @@ again:
+ if (v4l2src->frame_byte_size > 0) {
+ size = GST_BUFFER_SIZE (temp);
+
+- /* if size does not match what we expected, try again */
+- if (size != v4l2src->frame_byte_size) {
+- GST_ELEMENT_WARNING (v4l2src, RESOURCE, READ,
+- (_("Got unexpected frame size of %u instead of %u."),
+- size, v4l2src->frame_byte_size), (NULL));
+- gst_buffer_unref (temp);
+- if (count++ > 50)
+- goto size_error;
+-
+- goto again;
+- }
++ if (size != v4l2src->frame_byte_size)
++ GST_BUFFER_SIZE (temp) = v4l2src->frame_byte_size;
+ }
+
+ *buf = temp;
+ done:
+ return ret;
+-
+- /* ERRORS */
+-size_error:
+- {
+- GST_ELEMENT_ERROR (v4l2src, RESOURCE, READ,
+- (_("Error reading %d bytes on device '%s'."),
+- v4l2src->frame_byte_size, v4l2src->v4l2object->videodev), (NULL));
+- return GST_FLOW_ERROR;
+- }
+ }
+
+ static GstFlowReturn
+diff -Npru gst-plugins-good-0.10.28.orig/sys/v4l2/v4l2src_calls.c gst-plugins-good-0.10.28/sys/v4l2/v4l2src_calls.c
+--- gst-plugins-good-0.10.28.orig/sys/v4l2/v4l2src_calls.c 2011-03-08 19:24:35.000000000 +0530
++++ gst-plugins-good-0.10.28/sys/v4l2/v4l2src_calls.c 2012-01-06 16:27:51.743610680 +0530
+@@ -110,6 +110,7 @@ gst_v4l2src_grab_frame (GstV4l2Src * v4l
+ GST_DEBUG_OBJECT (v4l2src, "grab frame");
+
+ for (;;) {
++#if 0
+ if (v4l2object->can_poll_device) {
+ ret = gst_poll_wait (v4l2object->poll, GST_CLOCK_TIME_NONE);
+ if (G_UNLIKELY (ret < 0)) {
+@@ -125,7 +126,7 @@ gst_v4l2src_grab_frame (GstV4l2Src * v4l
+ }
+ }
+ }
+-
++#endif
+ pool_buffer = GST_BUFFER (gst_v4l2_buffer_pool_dqbuf (pool));
+ if (pool_buffer)
+ break;
+@@ -163,15 +164,18 @@ gst_v4l2src_grab_frame (GstV4l2Src * v4l
+ GST_CAT_LOG_OBJECT (GST_CAT_PERFORMANCE, v4l2src,
+ "running out of buffers, making a copy to reuse current one");
+ }
++#if 0
+ *buf = gst_buffer_copy (pool_buffer);
+ GST_BUFFER_FLAG_UNSET (*buf, GST_BUFFER_FLAG_READONLY);
+ /* this will requeue */
+ gst_buffer_unref (pool_buffer);
++#else
++ *buf = pool_buffer;
++#endif
+ } else {
+ *buf = pool_buffer;
+ }
+ /* we set the buffer metadata in gst_v4l2src_create() */
+-
+ return GST_FLOW_OK;
+
+ /* ERRORS */
+@@ -309,7 +313,7 @@ gst_v4l2src_capture_init (GstV4l2Src * v
+
+ if (!(v4l2src->pool = gst_v4l2_buffer_pool_new (GST_ELEMENT (v4l2src),
+ v4l2src->v4l2object->video_fd,
+- v4l2src->num_buffers, caps, TRUE, V4L2_BUF_TYPE_VIDEO_CAPTURE)))
++ v4l2src->num_buffers, caps, TRUE, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_MEMORY_USERPTR)))
+ goto buffer_pool_new_failed;
+
+ GST_INFO_OBJECT (v4l2src, "capturing buffers via mmap()");
diff --git a/gstreamer_ti_dm81xx/opensource_build/patchfiles/gstreamer-0.10.32/0006-queue-free-erroneous-buffer.patch b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gstreamer-0.10.32/0006-queue-free-erroneous-buffer.patch
new file mode 100644
index 0000000..1b33670
--- /dev/null
+++ b/gstreamer_ti_dm81xx/opensource_build/patchfiles/gstreamer-0.10.32/0006-queue-free-erroneous-buffer.patch
@@ -0,0 +1,12 @@
+--- gstreamer-0.10.32.orig/plugins/elements/gstqueue.c 2011-01-06 22:45:35.000000000 +0530
++++ gstreamer-0.10.32/plugins/elements/gstqueue.c 2011-11-18 17:35:40.431361170 +0530
+@@ -1173,7 +1173,8 @@ next:
+ * task function does not shut down. */
+ queue->unexpected = TRUE;
+ result = GST_FLOW_OK;
+- }
++ }else if(result == GST_FLOW_WRONG_STATE)
++ gst_buffer_unref (buffer);
+ } else {
+ GstEvent *event = GST_EVENT_CAST (data);
+ GstEventType type = GST_EVENT_TYPE (event);
diff --git a/gstreamer_ti_dm81xx/ti_build/Makefile b/gstreamer_ti_dm81xx/ti_build/Makefile
index c1a79f2..8a3a5f2 100644
--- a/gstreamer_ti_dm81xx/ti_build/Makefile
+++ b/gstreamer_ti_dm81xx/ti_build/Makefile
@@ -57,6 +57,10 @@ $(TI_PLUGINS):
$(CMD_PREFIX) cd $@; ./configure $(CONFIGURE_VERBOSE) $(CC_CONFIGURE_OPTS) $(EXTRA_CONFIGURE_OPTS)
$(CMD_PREFIX) $(MAKE) $(MAKE_VERBOSE) -C $@ $(BUILD_INSTALL)
+my:
+ @echo Building gst-openmax
+ $(CMD_PREFIX) $(MAKE) $(MAKE_VERBOSE) -C gst-openmax $(BUILD_INSTALL)
+
install:
clean:
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/ChangeLog b/gstreamer_ti_dm81xx/ti_build/gst-openmax/ChangeLog
index 5d7d986..0f62f6a 100644
--- a/gstreamer_ti_dm81xx/ti_build/gst-openmax/ChangeLog
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/ChangeLog
@@ -1,3 +1,9 @@
+== TI Gstreamer Plugin Release 0.3 ==
+
+* Initial Public Release of the TI GStreamer DM81xx Plugin.
+* Adapted from GST-OpenMAX by Felipe Contreras <felipe.contreras@gmail.com>
+* Supports TI OMX libraries
+
== Release 0.10.0.4 ==
2008-06-19 Felipe Contreras <felipe.contreras@gmail.com>
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/configure.ac b/gstreamer_ti_dm81xx/ti_build/gst-openmax/configure.ac
index 1ec65d0..89e3c31 100644
--- a/gstreamer_ti_dm81xx/ti_build/gst-openmax/configure.ac
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/configure.ac
@@ -1,8 +1,7 @@
AC_PREREQ([2.52])
dnl AC_INIT([gst-openmax], m4_esyscmd([build-aux/git-version-gen]),
-AC_INIT([gst-openmax],
- [http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer&component=gst-openmax])
+AC_INIT([gst-openmax], [GST_DM81XX_00_04_00_00], [https://gstreamer.ti.com/gf/project/gstreamer_ti/forum/])
AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE([-Wall -Wno-portability])
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/ext/Makefile b/gstreamer_ti_dm81xx/ti_build/gst-openmax/ext/Makefile
index 45953cb..c412c39 100755
--- a/gstreamer_ti_dm81xx/ti_build/gst-openmax/ext/Makefile
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/ext/Makefile
@@ -26,7 +26,15 @@ all:
-Wl,-u,OMX_Init -Wl,-u,OMX_Deinit -Wl,-u,OMX_ComponentNameEnum -Wl,-u,OMX_GetHandle -Wl,-u,OMX_FreeHandle \
-Wl,-u,OMX_GetRolesOfComponent
+distclean:
+
clean:
rm -rf lib
install: all
+
+distdir:
+ mkdir -p $(distdir)
+ cp -f Makefile $(distdir)
+
+distclean:
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/Makefile.am b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/Makefile.am
index 00ea054..de5ee7c 100755
--- a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/Makefile.am
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/Makefile.am
@@ -3,6 +3,7 @@ plugin_LTLIBRARIES = libgstomx.la
libgstomx_la_SOURCES = gstomx.c gstomx.h \
gstomx_interface.c gstomx_interface.h \
gstomx_base_filter.c gstomx_base_filter.h \
+ gstomx_base_filter2.c gstomx_base_filter2.h \
gstomx_base_videodec.c gstomx_base_videodec.h \
gstomx_base_videoenc.c gstomx_base_videoenc.h \
gstomx_base_audiodec.c gstomx_base_audiodec.h \
@@ -13,9 +14,10 @@ libgstomx_la_SOURCES = gstomx.c gstomx.h \
gstomx_volume.c gstomx_volume.h \
gstomx_mpeg4dec.c gstomx_mpeg4dec.h \
gstomx_mpeg2dec.c gstomx_mpeg2dec.h \
+ gstomx_mjpegdec.c gstomx_mjpegdec.h \
gstomx_h263dec.c gstomx_h263dec.h \
gstomx_h264dec.c gstomx_h264dec.h \
- gstomx_vc1dec.c gstomx_vc1dec.h \
+ gstomx_vc1dec.c gstomx_vc1dec.h \
gstomx_wmvdec.c gstomx_wmvdec.h \
gstomx_mpeg4enc.c gstomx_mpeg4enc.h \
gstomx_h264enc.c gstomx_h264enc.h \
@@ -46,15 +48,18 @@ libgstomx_la_SOURCES = gstomx.c gstomx.h \
gstomx_filereadersrc.c gstomx_filereadersrc.h \
swcsc.c swcsc.h \
gstperf.c gstperf.h \
+ gstomxbufferalloc.c gstomxbufferalloc.h \
gstomx_buffertransport.c gstomx_buffertransport.h \
gstomx_base_vfpc.c gstomx_base_vfpc.h \
+ gstomx_base_vfpc2.c gstomx_base_vfpc2.h \
gstomx_base_ctrl.c gstomx_base_ctrl.h \
gstomx_scaler.c gstomx_scaler.h \
+ gstomx_deiscaler.c gstomx_deiscaler.h \
gstomx_noisefilter.c gstomx_noisefilter.h \
gstomx_videomixer.c gstomx_videomixer.h
libgstomx_la_LIBADD = $(OMXCORE_LIBS) $(GST_LIBS) $(GST_BASE_LIBS) -lgstvideo-0.10 $(top_builddir)/util/libutil.la
-libgstomx_la_CFLAGS = $(OMXCORE_CFLAGS) $(OMXTIAUDIODEC_CFLAGS) $(USE_OMXTIAUDIODEC) $(GST_CFLAGS) $(GST_BASE_CFLAGS) -I$(top_srcdir)/util \
+libgstomx_la_CFLAGS = -DUSE_OMXTICORE $(OMXCORE_CFLAGS) $(OMXTIAUDIODEC_CFLAGS) $(USE_OMXTIAUDIODEC) $(GST_CFLAGS) $(GST_BASE_CFLAGS) -I$(top_srcdir)/util \
-Dxdc_target_name__=GCArmv5T -Dxdc_target_types__=gnu/targets/arm/std.h -Dxdc__RESTRICT__ \
-I$(OMX_INSTALL_DIR)/include/openMaxv11 \
-I$(OMX_INSTALL_DIR)/packages \
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx.c b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx.c
index 9dc840f..e50c3e9 100755
--- a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx.c
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx.c
@@ -23,9 +23,10 @@
#include "gstomx_dummy.h"
#include "gstomx_mpeg4dec.h"
#include "gstomx_mpeg2dec.h"
+#include "gstomx_mjpegdec.h"
#include "gstomx_h263dec.h"
#include "gstomx_h264dec.h"
-#include "gstomx_vp6dec.h"
+// #include "gstomx_vp6dec.h"
#include "gstomx_wmvdec.h"
#include "gstomx_mpeg4enc.h"
#include "gstomx_h264enc.h"
@@ -53,15 +54,18 @@
#include "gstomx_videosink.h"
#include "gstomx_filereadersrc.h"
#include "gstomx_volume.h"
-#include "gstomx_camera.h"
+// #include "gstomx_camera.h"
#include "swcsc.h"
#include "gstperf.h"
#include "gstomx_scaler.h"
+#include "gstomx_deiscaler.h"
#include "gstomx_noisefilter.h"
#include "gstomx_base_ctrl.h"
#include "gstomx_vc1dec.h"
#include "gstomx_videomixer.h"
+#include "gstomxbufferalloc.h"
+
#include "config.h"
GST_DEBUG_CATEGORY (gstomx_debug);
@@ -82,6 +86,7 @@ static TableItem element_table[] =
// { "omx_dummy", "libOMX_Core.so", "OMX.TI.DUCATI1.MISC.SAMPLE", NULL, GST_RANK_NONE, gst_omx_dummy_get_type },
{ "omx_mpeg4dec", "libOMX_Core.so", "OMX.TI.DUCATI.VIDDEC", "", GST_RANK_PRIMARY, gst_omx_mpeg4dec_get_type },
{ "omx_h264dec", "libOMX_Core.so", "OMX.TI.DUCATI.VIDDEC", "", GST_RANK_PRIMARY, gst_omx_h264dec_get_type },
+ { "omx_mjpegdec", "libOMX_Core.so", "OMX.TI.DUCATI.VIDDEC", "", GST_RANK_PRIMARY, gst_omx_mjpegdec_get_type },
{ "omx_mpeg2dec", "libOMX_Core.so", "OMX.TI.DUCATI.VIDDEC", "", GST_RANK_PRIMARY, gst_omx_mpeg2dec_get_type },
// { "omx_h263dec", "libOMX_Core.so", "OMX.TI.DUCATI.VIDDEC", "", GST_RANK_PRIMARY, gst_omx_h263dec_get_type },
// { "omx_vp6dec", "libOMX_Core.so", "OMX.TI.DUCATI1.VIDEO.DECODER", "video_decoder.vp6", GST_RANK_PRIMARY, gst_omx_vp6dec_get_type },
@@ -97,8 +102,8 @@ static TableItem element_table[] =
// { "omx_amrnbenc", "libomxil-bellagio.so.0", "OMX.st.audio_encoder.amrnb", NULL, GST_RANK_NONE, gst_omx_amrnbenc_get_type },
// { "omx_amrwbdec", "libomxil-bellagio.so.0", "OMX.st.audio_decoder.amrwb", NULL, GST_RANK_NONE, gst_omx_amrwbdec_get_type },
// { "omx_amrwbenc", "libomxil-bellagio.so.0", "OMX.st.audio_encoder.amrwb", NULL, GST_RANK_NONE, gst_omx_amrwbenc_get_type },
-// { "omx_aacdec", "libOMX_Core.so", "OMX.TI.AUDIO.DECODE", "audio_decode.dsp.aac", GST_RANK_NONE, gst_omx_aacdec_get_type },
-// { "omx_aacenc", "libOMX_Core.so", "OMX.TI.AUDIO.ENCODE", "audio_encode.dsp.aac", GST_RANK_NONE, gst_omx_aacenc_get_type },
+ { "omx_aacdec", "libOMX_Core.so", "OMX.TI.DSP.AUDDEC", "", GST_RANK_PRIMARY, gst_omx_aacdec_get_type },
+ { "omx_aacenc", "libOMX_Core.so", "OMX.TI.DSP.AUDENC", "", GST_RANK_PRIMARY, gst_omx_aacenc_get_type },
// { "omx_adpcmdec", "libomxil-bellagio.so.0", "OMX.st.audio_decoder.adpcm", NULL, GST_RANK_NONE, gst_omx_adpcmdec_get_type },
// { "omx_adpcmenc", "libomxil-bellagio.so.0", "OMX.st.audio_encoder.adpcm", NULL, GST_RANK_NONE, gst_omx_adpcmenc_get_type },
// { "omx_g711dec", "libomxil-bellagio.so.0", "OMX.st.audio_decoder.g711", NULL, GST_RANK_NONE, gst_omx_g711dec_get_type },
@@ -115,7 +120,10 @@ static TableItem element_table[] =
// { "omx_volume", "libomxil-bellagio.so.0", "OMX.st.volume.component", NULL, GST_RANK_NONE, gst_omx_volume_get_type },
{ "swcsc", "libOMX_Core.so", NULL, NULL, GST_RANK_PRIMARY, gst_swcsc_get_type },
{ "gstperf", "libOMX_Core.so", NULL, NULL, GST_RANK_PRIMARY, gst_perf_get_type },
+ { "omxbufferalloc", "libOMX_Core.so", NULL, NULL, GST_RANK_PRIMARY, gst_omx_buffer_alloc_get_type },
{ "omx_scaler", "libOMX_Core.so", "OMX.TI.VPSSM3.VFPC.INDTXSCWB", "", GST_RANK_PRIMARY, gst_omx_scaler_get_type },
+ { "omx_mdeiscaler", "libOMX_Core.so", "OMX.TI.VPSSM3.VFPC.DEIMDUALOUT", "", GST_RANK_PRIMARY, gst_omx_mdeiscaler_get_type },
+ { "omx_hdeiscaler", "libOMX_Core.so", "OMX.TI.VPSSM3.VFPC.DEIHDUALOUT", "", GST_RANK_PRIMARY, gst_omx_hdeiscaler_get_type },
{ "omx_noisefilter", "libOMX_Core.so", "OMX.TI.VPSSM3.VFPC.NF", "", GST_RANK_PRIMARY, gst_omx_noisefilter_get_type },
{ "omx_ctrl", "libOMX_Core.so", "OMX.TI.VPSSM3.CTRL.DC", "", GST_RANK_PRIMARY, gst_omx_base_ctrl_get_type },
// { "omx_camera", "libOMX_Core.so", "OMX.TI.DUCATI1.VIDEO.CAMERA", NULL, GST_RANK_PRIMARY, gst_omx_camera_get_type },
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_aacdec.c b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_aacdec.c
index 09b0cc7..9dee258 100644
--- a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_aacdec.c
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_aacdec.c
@@ -29,8 +29,8 @@
enum
{
- ARG_0,
- ARG_FRAMEMODE,
+ ARG_0,
+ ARG_FRAMEMODE,
};
#define FRAMEMODE_DEFAULT FALSE
@@ -39,314 +39,454 @@ GSTOMX_BOILERPLATE (GstOmxAacDec, gst_omx_aacdec, GstOmxBaseAudioDec, GST_OMX_BA
typedef enum
{
- AAC_PROFILE_LC = 2,
- AAC_PROFILE_LC_SBR = 5,
- AAC_PROFILE_LC_SBR_PS = 6,
+ AAC_PROFILE_LC = 2,
+ AAC_PROFILE_LC_SBR = 5,
+ AAC_PROFILE_LC_SBR_PS = 6,
} AacVersion;
-static GstCaps *
+ static GstCaps *
generate_src_template (void)
{
- GstCaps *caps;
-
- caps = gst_caps_new_simple ("audio/x-raw-int",
- "endianness", G_TYPE_INT, G_BYTE_ORDER,
- "width", G_TYPE_INT, 16,
- "depth", G_TYPE_INT, 16,
- "rate", GST_TYPE_INT_RANGE, 8000, 96000,
- "signed", G_TYPE_BOOLEAN, TRUE,
- "channels", GST_TYPE_INT_RANGE, 1, 8,
- NULL);
-
- return caps;
+ GstCaps *caps;
+
+ caps = gst_caps_new_simple ("audio/x-raw-int",
+ "endianness", G_TYPE_INT, G_BYTE_ORDER,
+ "width", G_TYPE_INT, 16,
+ "depth", G_TYPE_INT, 16,
+ "rate", GST_TYPE_INT_RANGE, 8000, 96000,
+ "signed", G_TYPE_BOOLEAN, TRUE,
+ "channels", GST_TYPE_INT_RANGE, 1, 8,
+ NULL);
+
+ return caps;
}
-static GstCaps *
+ static GstCaps *
generate_sink_template (void)
{
- GstCaps *caps;
- GstStructure *struc;
- caps = gst_caps_new_empty ();
+ GstCaps *caps;
+ GstStructure *struc;
+ caps = gst_caps_new_empty ();
- struc = gst_structure_new ("audio/mpeg",
- "mpegversion", G_TYPE_INT, 4,
- "channels", GST_TYPE_INT_RANGE, 1, 8,
- "rate", GST_TYPE_INT_RANGE, 8000, 96000,
- "object_type", GST_TYPE_INT_RANGE, 1, 6,
- "parsed", G_TYPE_BOOLEAN, TRUE,
- NULL);
+ struc = gst_structure_new ("audio/mpeg",
+ "mpegversion", G_TYPE_INT, 4,
+ "channels", GST_TYPE_INT_RANGE, 1, 8,
+ "rate", GST_TYPE_INT_RANGE, 8000, 96000,
+ "object_type", GST_TYPE_INT_RANGE, 1, 6,
+ "parsed", G_TYPE_BOOLEAN, TRUE,
+ NULL);
- {
- GValue list;
- GValue val;
+ {
+ GValue list;
+ GValue val;
- list.g_type = val.g_type = 0;
+ list.g_type = val.g_type = 0;
- g_value_init (&list, GST_TYPE_LIST);
- g_value_init (&val, G_TYPE_INT);
+ g_value_init (&list, GST_TYPE_LIST);
+ g_value_init (&val, G_TYPE_INT);
- g_value_set_int (&val, 2);
- gst_value_list_append_value (&list, &val);
+ g_value_set_int (&val, 2);
+ gst_value_list_append_value (&list, &val);
- g_value_set_int (&val, 4);
- gst_value_list_append_value (&list, &val);
+ g_value_set_int (&val, 4);
+ gst_value_list_append_value (&list, &val);
- gst_structure_set_value (struc, "mpegversion", &list);
+ gst_structure_set_value (struc, "mpegversion", &list);
- g_value_unset (&val);
- g_value_unset (&list);
- }
+ g_value_unset (&val);
+ g_value_unset (&list);
+ }
- gst_caps_append_structure (caps, struc);
-
- return caps;
+ gst_caps_append_structure (caps, struc);
+ return caps;
}
-static void
+ static void
type_base_init (gpointer g_class)
{
- GstElementClass *element_class;
+ GstElementClass *element_class;
- element_class = GST_ELEMENT_CLASS (g_class);
+ element_class = GST_ELEMENT_CLASS (g_class);
- {
- GstElementDetails details;
+ {
+ GstElementDetails details;
- details.longname = "OpenMAX IL AAC audio decoder";
- details.klass = "Codec/Decoder/Audio";
- details.description = "Decodes audio in AAC format with OpenMAX IL";
- details.author = "Felipe Contreras";
+ details.longname = "OpenMAX IL AAC audio decoder";
+ details.klass = "Codec/Decoder/Audio";
+ details.description = "Decodes audio in AAC format with OpenMAX IL";
+ details.author = "Felipe Contreras";
- gst_element_class_set_details (element_class, &details);
- }
+ gst_element_class_set_details (element_class, &details);
+ }
- {
- GstPadTemplate *template;
+ {
+ GstPadTemplate *template;
- template = gst_pad_template_new ("src", GST_PAD_SRC,
- GST_PAD_ALWAYS,
- generate_src_template ());
+ template = gst_pad_template_new ("src", GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ generate_src_template ());
- gst_element_class_add_pad_template (element_class, template);
- }
+ gst_element_class_add_pad_template (element_class, template);
+ }
- {
- GstPadTemplate *template;
+ {
+ GstPadTemplate *template;
- template = gst_pad_template_new ("sink", GST_PAD_SINK,
- GST_PAD_ALWAYS,
- generate_sink_template ());
+ template = gst_pad_template_new ("sink", GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ generate_sink_template ());
- gst_element_class_add_pad_template (element_class, template);
- }
+ gst_element_class_add_pad_template (element_class, template);
+ }
}
-static void
+ static void
set_property (GObject *obj,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- GstOmxAacDec *self;
-
- self = GST_OMX_AACDEC (obj);
-
- switch (prop_id)
- {
- case ARG_FRAMEMODE:
- self->framemode = g_value_get_boolean (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
+ GstOmxAacDec *self;
+
+ self = GST_OMX_AACDEC (obj);
+
+ switch (prop_id)
+ {
+ case ARG_FRAMEMODE:
+ self->framemode = g_value_get_boolean (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
}
-static void
+ static void
get_property (GObject *obj,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- GstOmxAacDec *self;
-
- self = GST_OMX_AACDEC (obj);
-
- switch (prop_id)
- {
- case ARG_FRAMEMODE:
- g_value_set_boolean (value, self->framemode);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
+ GstOmxAacDec *self;
+
+ self = GST_OMX_AACDEC (obj);
+
+ switch (prop_id)
+ {
+ case ARG_FRAMEMODE:
+ g_value_set_boolean (value, self->framemode);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
}
-static void
+ static void
type_class_init (gpointer g_class,
- gpointer class_data)
+ gpointer class_data)
{
- GObjectClass *gobject_class;
+ GObjectClass *gobject_class;
- gobject_class = G_OBJECT_CLASS (g_class);
+ gobject_class = G_OBJECT_CLASS (g_class);
- /* Properties stuff */
- {
- gobject_class->set_property = set_property;
- gobject_class->get_property = get_property;
+ /* Properties stuff */
+ {
+ gobject_class->set_property = set_property;
+ gobject_class->get_property = get_property;
- g_object_class_install_property (gobject_class, ARG_FRAMEMODE,
- g_param_spec_boolean ("framemode", "Frame Mode",
- "Frame Mode", FRAMEMODE_DEFAULT, G_PARAM_READWRITE));
- }
+ g_object_class_install_property (gobject_class, ARG_FRAMEMODE,
+ g_param_spec_boolean ("framemode", "Frame Mode",
+ "Frame Mode", FRAMEMODE_DEFAULT, G_PARAM_READWRITE));
+ }
}
-static gboolean
+ static gboolean
sink_setcaps (GstPad *pad,
- GstCaps *caps)
+ GstCaps *caps)
{
- GstStructure *structure;
- GstOmxBaseFilter *omx_base;
- GstOmxBaseAudioDec *base_audiodec;
- GstOmxAacDec* self;
+ GstStructure *structure;
+ GstOmxBaseFilter *omx_base;
+ GstOmxBaseAudioDec *base_audiodec;
+ GstOmxAacDec* self;
- omx_base = GST_OMX_BASE_FILTER (GST_PAD_PARENT (pad));
- base_audiodec = GST_OMX_BASE_AUDIODEC (omx_base);
- self = GST_OMX_AACDEC (omx_base);
- GST_INFO_OBJECT (omx_base, "setcaps (sink): %" GST_PTR_FORMAT, caps);
+ omx_base = GST_OMX_BASE_FILTER (GST_PAD_PARENT (pad));
+ base_audiodec = GST_OMX_BASE_AUDIODEC (omx_base);
+ self = GST_OMX_AACDEC (omx_base);
- structure = gst_caps_get_structure (caps, 0);
+ GST_INFO_OBJECT (omx_base, "setcaps (sink): %" GST_PTR_FORMAT, caps);
- base_audiodec->rate = 44100;
- gst_structure_get_int (structure, "rate", &base_audiodec->rate);
+ structure = gst_caps_get_structure (caps, 0);
- base_audiodec->channels = 2;
- gst_structure_get_int (structure, "channels", &base_audiodec->channels);
- self->aacversion = 2;
- gst_structure_get_int (structure, "object_type", &self->aacversion);
+ base_audiodec->rate = 44100;
+ gst_structure_get_int (structure, "rate", &base_audiodec->rate);
- self->framed = gst_structure_has_field (structure, "framed");
+ base_audiodec->channels = 2;
+ gst_structure_get_int (structure, "channels", &base_audiodec->channels);
+
+ self->aacversion = 2;
+ gst_structure_get_int (structure, "object_type", &self->aacversion);
+
+ self->framed = gst_structure_has_field (structure, "framed");
+
+ omx_base->in_port->caps = gst_caps_copy (caps);
-#if 0
- {
- const GValue *codec_data;
- GstBuffer *buffer;
- codec_data = gst_structure_get_value (structure, "codec_data");
- if (codec_data)
- {
- buffer = gst_value_get_buffer (codec_data);
- omx_base->codec_data = buffer;
- gst_buffer_ref (buffer);
- }
- }
-#endif
- return gst_pad_set_caps (pad, caps);
+ return gst_pad_set_caps (pad, caps);
}
+ static gboolean
+src_setcaps (GstPad *pad,
+ GstCaps *caps)
+{
+ GstStructure *structure;
+ GstOmxBaseFilter *omx_base;
+ GstOmxBaseAudioDec *base_audiodec;
+ GstOmxAacDec* self;
-static void
-omx_setup (GstOmxBaseFilter *omx_base)
+
+ omx_base = GST_OMX_BASE_FILTER (GST_PAD_PARENT (pad));
+ base_audiodec = GST_OMX_BASE_AUDIODEC (omx_base);
+ self = GST_OMX_AACDEC (omx_base);
+
+ GST_INFO_OBJECT (omx_base, "setcaps (sink): %" GST_PTR_FORMAT, caps);
+
+ structure = gst_caps_get_structure (caps, 0);
+
+
+ base_audiodec->rate = 44100;
+ //gst_structure_get_int (structure, "rate", &base_audiodec->rate);
+
+ base_audiodec->channels = 2;
+ //gst_structure_get_int (structure, "channels", &base_audiodec->channels);
+
+ self->aacversion = 2;
+ //gst_structure_get_int (structure, "object_type", &self->aacversion);
+
+ self->framed = gst_structure_has_field (structure, "framed");
+
+ omx_base->out_port->caps = gst_caps_copy (caps);
+
+
+ return gst_pad_set_caps (pad, caps);
+}
+
+ static GstCaps *
+src_getcaps (GstPad *pad)
{
- GstOmxBaseAudioDec *base_audiodec = GST_OMX_BASE_AUDIODEC (omx_base);
- GstOmxAacDec *self = GST_OMX_AACDEC (omx_base);
-
- OMX_U32 streamFormat;
- gint profile;
-
- GST_DEBUG_OBJECT (omx_base, "Begin Set-Up");
-
- switch (self->aacversion)
- {
- case AAC_PROFILE_LC_SBR_PS:
- profile = OMX_AUDIO_AACObjectHE_PS;
- break;
- case AAC_PROFILE_LC_SBR:
- profile = OMX_AUDIO_AACObjectHE;
- break;
- case AAC_PROFILE_LC:
- default:
- profile = OMX_AUDIO_AACObjectLC;
- break;
- }
-
- // Does it come from a demuxer?
- if(self->framed)
- {
- streamFormat = OMX_AUDIO_AACStreamFormatRAW;
- GST_DEBUG_OBJECT (omx_base, "Format: Raw");
- }
- else
- {
- streamFormat = OMX_AUDIO_AACStreamFormatMax;
- GST_DEBUG_OBJECT (omx_base, "Format: Max");
- }
-
- {
- OMX_AUDIO_PARAM_AACPROFILETYPE param;
- G_OMX_PORT_GET_PARAM (omx_base->in_port, OMX_IndexParamAudioAac, &param);
- param.eAACProfile = profile;
- param.eAACStreamFormat = streamFormat;
- G_OMX_PORT_SET_PARAM (omx_base->in_port, OMX_IndexParamAudioAac, &param);
- }
-
- {
- OMX_AUDIO_PARAM_PCMMODETYPE param;
- G_OMX_PORT_GET_PARAM (omx_base->out_port, OMX_IndexParamAudioPcm, &param);
- param.nSamplingRate = base_audiodec->rate;
- GST_DEBUG_OBJECT (omx_base, "PCM Sample Rate: %ld", param.nSamplingRate);
- G_OMX_PORT_SET_PARAM (omx_base->out_port, OMX_IndexParamAudioPcm, &param);
- }
+ GstCaps *caps;
+ GstStructure *structure;
+ GstOmxBaseFilter *omx_base;
+ GstOmxBaseAudioDec *base_audiodec;
+ GstOmxAacDec* self;
-#ifdef USE_OMXTIAUDIODEC
- // This is specific for TI.
- {
- OMX_INDEXTYPE index;
- TI_OMX_DSP_DEFINITION audioinfo;
+ omx_base = GST_OMX_BASE_FILTER (GST_PAD_PARENT (pad));
+ base_audiodec = GST_OMX_BASE_AUDIODEC (omx_base);
+ self = GST_OMX_AACDEC (omx_base);
+ {
+ /* set pcm port */
+ OMX_AUDIO_PARAM_PCMMODETYPE param;
- GOmxCore *gomx = omx_base->gomx;
+ }
- memset (&audioinfo, 0, sizeof (audioinfo));
+ return caps;
+}
+ static GstCaps *
+sink_getcaps (GstPad *pad)
+{
+ GstCaps *caps = NULL;
+ GstStructure *structure = NULL;
+ GstOmxBaseFilter *omx_base;
+ GstOmxBaseAudioDec *base_audiodec;
+ GstOmxAacDec* self;
- audioinfo.framemode = self->framemode;
- GST_DEBUG_OBJECT (omx_base, "Frame Mode: %d", audioinfo.framemode);
- g_assert(
- OMX_GetExtensionIndex (
- gomx->omx_handle, "OMX.TI.index.config.aacdecHeaderInfo",
- &index) == OMX_ErrorNone);
+ omx_base = GST_OMX_BASE_FILTER (GST_PAD_PARENT (pad));
+ base_audiodec = GST_OMX_BASE_AUDIODEC (omx_base);
+ self = GST_OMX_AACDEC (omx_base);
- g_assert(
- OMX_SetConfig (
- gomx->omx_handle, index,
- &audioinfo) == OMX_ErrorNone);
- GST_DEBUG_OBJECT (omx_base, "End Set-Up");
- }
-#endif
+ //OMX_AUDIO_PARAM_AACPROFILETYPE param;
+
+ return caps;
}
-static void
-type_instance_init (GTypeInstance *instance,
- gpointer g_class)
+ static void
+omx_setup (GstOmxBaseFilter *omx_base)
{
- GstOmxBaseFilter *omx_base;
- GstOmxAacDec *self;
+ GstOmxBaseAudioDec *base_audiodec = GST_OMX_BASE_AUDIODEC (omx_base);
+ GstOmxAacDec *self = GST_OMX_AACDEC (omx_base);
+ //OMX_ERRORTYPE eError = OMX_ErrorUndefined;
+ OMX_PORT_PARAM_TYPE portInit;
+ OMX_PARAM_PORTDEFINITIONTYPE pInPortDef, pOutPortDef;
+ GOmxPort *port;
+ GOmxCore *gomx;
+ OMX_ERRORTYPE eError = OMX_ErrorNone;
+
+ OMX_U32 streamFormat;
+ gint profile;
+
+ gomx = (GOmxCore *) omx_base->gomx;
+
+ GST_DEBUG_OBJECT (omx_base, "Begin Set-Up");
+
+ switch (self->aacversion)
+ {
+ case AAC_PROFILE_LC_SBR_PS:
+ profile = OMX_AUDIO_AACObjectHE_PS;
+ break;
+ case AAC_PROFILE_LC_SBR:
+ profile = OMX_AUDIO_AACObjectHE;
+ break;
+ case AAC_PROFILE_LC:
+ default:
+ profile = OMX_AUDIO_AACObjectLC;
+ break;
+ }
+
+ // Does it come from a demuxer?
+ if(self->framed)
+ {
+ streamFormat = OMX_AUDIO_AACStreamFormatRAW;
+ GST_DEBUG_OBJECT (omx_base, "Format: Raw");
+ }
+ else
+ {
+ streamFormat = OMX_AUDIO_AACStreamFormatMax;
+ GST_DEBUG_OBJECT (omx_base, "Format: Max");
+ }
+
+ {
+ OMX_AUDIO_PARAM_AACPROFILETYPE param;
+ G_OMX_PORT_GET_PARAM (omx_base->in_port, OMX_IndexParamAudioAac, &param);
+ param.eAACProfile = profile;
+ param.eAACStreamFormat = streamFormat;
+ G_OMX_PORT_SET_PARAM (omx_base->in_port, OMX_IndexParamAudioAac, &param);
+ }
+
+ {
+ OMX_AUDIO_PARAM_PCMMODETYPE param;
+ G_OMX_PORT_GET_PARAM (omx_base->out_port, OMX_IndexParamAudioPcm, &param);
+ param.nSamplingRate = base_audiodec->rate;
+ GST_DEBUG_OBJECT (omx_base, "PCM Sample Rate: %ld", param.nSamplingRate);
+ G_OMX_PORT_SET_PARAM (omx_base->out_port, OMX_IndexParamAudioPcm, &param);
+ }
+ /*set port definition*/
+#if 1
+ _G_OMX_INIT_PARAM(&portInit);
+ portInit.nPorts = 2;
+ portInit.nStartPortNumber = 0;
+ G_OMX_PORT_SET_PARAM(omx_base->in_port,OMX_IndexParamAudioInit,&portInit);
+
+ _G_OMX_INIT_PARAM(&pInPortDef);
+ pInPortDef.nPortIndex = 0;//OMX_AUDDEC_INPUT_PORT;
+ pInPortDef.eDir = OMX_DirInput;
+ pInPortDef.nBufferCountActual = 1;
+ pInPortDef.nBufferCountMin = 1;
+ pInPortDef.nBufferSize = 4096; //width * height;
+
+ pInPortDef.bEnabled = OMX_TRUE;
+ pInPortDef.bPopulated = OMX_FALSE;
+ pInPortDef.eDomain = OMX_PortDomainAudio;
+ pInPortDef.bBuffersContiguous = OMX_FALSE;
+ pInPortDef.nBufferAlignment = 32;
+
+ /* OMX_VIDEO_PORTDEFINITION values for input port */
+ pInPortDef.format.audio.cMIMEType = "ADEC";
+ pInPortDef.format.audio.pNativeRender = NULL;
+ pInPortDef.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
+ pInPortDef.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ G_OMX_PORT_SET_DEFINITION (omx_base->in_port, &pInPortDef);
+
+ _G_OMX_INIT_PARAM(&pOutPortDef);
+ pOutPortDef.nPortIndex = 1;
+ pOutPortDef.eDir = OMX_DirOutput;
+ pOutPortDef.nBufferCountActual = 1;
+ pOutPortDef.nBufferCountMin = 1;
+
+ /* for referance purpose, in PT mode, stride and height would be used by FQ
+ It is padded inside components */
+ pOutPortDef.nBufferSize = 4608;
+ pOutPortDef.bEnabled = OMX_TRUE;
+ pOutPortDef.bPopulated = OMX_FALSE;
+ pOutPortDef.eDomain = OMX_PortDomainAudio;
+ pOutPortDef.bBuffersContiguous = OMX_FALSE;
+ pOutPortDef.nBufferAlignment = 32;
+
+ /* OMX_VIDEO_PORTDEFINITION values for output port */
+ pOutPortDef.format.audio.cMIMEType = "PCM";
+ pOutPortDef.format.audio.pNativeRender = NULL;
+ pOutPortDef.format.audio.bFlagErrorConcealment = OMX_FALSE;
+ pOutPortDef.format.audio.eEncoding = OMX_AUDIO_CodingUnused;
+ G_OMX_PORT_SET_DEFINITION (omx_base->out_port, &pOutPortDef);
+#endif
+ port = g_omx_core_get_port (gomx, "input", 0);
+ GST_DEBUG_OBJECT(self, "SendCommand(PortEnable, %x)", port->port_index);
+ eError = OMX_SendCommand (g_omx_core_get_handle (port->core),
+ OMX_CommandPortEnable, port->port_index, NULL);
+ g_sem_down (port->core->port_sem);
+ if (eError != OMX_ErrorNone) {
+ printf("\nSend command for port enable on port index=%d failed returned eError=%x",eError);
+ }
+
+ port = g_omx_core_get_port (gomx, "output", 1);
+ GST_DEBUG_OBJECT(self, "SendCommand(PortEnable, %x)", port->port_index);
+ eError = OMX_SendCommand (g_omx_core_get_handle (port->core),
+ OMX_CommandPortEnable, 1, NULL);
+ g_sem_down (port->core->port_sem);
+ if (eError != OMX_ErrorNone) {
+ printf("\nSend command for port enable on port index=%d failed returned eError=%x",port->port_index,eError);
+ }
+
+#ifdef USE_OMXTIAUDIODEC
+ // This is specific for TI.
+ {
+ OMX_INDEXTYPE index;
+ TI_OMX_DSP_DEFINITION audioinfo;
- self = GST_OMX_AACDEC (instance);
- omx_base = GST_OMX_BASE_FILTER (instance);
- GST_DEBUG_OBJECT (omx_base, "start");
+ GOmxCore *gomx = omx_base->gomx;
- omx_base->omx_setup = omx_setup;
+ memset (&audioinfo, 0, sizeof (audioinfo));
- gst_pad_set_setcaps_function (omx_base->sinkpad, sink_setcaps);
+ audioinfo.framemode = self->framemode;
+ GST_DEBUG_OBJECT (omx_base, "Frame Mode: %d", audioinfo.framemode);
- g_object_set (instance,
- "input-buffers", 3,
- "output-buffers", 3,
- NULL);
+ g_assert(
+ OMX_GetExtensionIndex (
+ gomx->omx_handle, "OMX.TI.index.config.aacdecHeaderInfo",
+ &index) == OMX_ErrorNone);
+
+ g_assert(
+ OMX_SetConfig (
+ gomx->omx_handle, index,
+ &audioinfo) == OMX_ErrorNone);
+
+ GST_DEBUG_OBJECT (omx_base, "End Set-Up");
+ }
+#endif
}
+
+ static void
+type_instance_init (GTypeInstance *instance,
+ gpointer g_class)
+{
+ GstOmxBaseFilter *omx_base;
+ GstOmxAacDec *self;
+
+ self = GST_OMX_AACDEC (instance);
+ omx_base = GST_OMX_BASE_FILTER (instance);
+ //GST_DEBUG_OBJECT (omx_base, "start");
+ omx_base->omx_setup = omx_setup;
+ //omx_base->in_port->always_copy = FALSE;
+ omx_base->out_port->always_copy = TRUE;
+
+ gst_pad_set_setcaps_function (omx_base->sinkpad, sink_setcaps);
+ gst_pad_set_getcaps_function (omx_base->srcpad, src_getcaps);
+ gst_pad_set_getcaps_function (omx_base->sinkpad, sink_getcaps);
+ gst_pad_set_setcaps_function (omx_base->srcpad, src_setcaps);
+}
+
+
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_aacenc.c b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_aacenc.c
index 7be7249..a725b0d 100644
--- a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_aacenc.c
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_aacenc.c
@@ -33,7 +33,7 @@ enum
ARG_OUTPUT_FORMAT,
};
-#define DEFAULT_BITRATE 64000 /* Guarantee that all the 3 formats will work using this default. */
+#define DEFAULT_BITRATE 128000 /* Guarantee that all the 3 formats will work using this default. */
#define MAX_BITRATE 256000 /* Maximum value supported by the component */
#define DEFAULT_PROFILE OMX_AUDIO_AACObjectLC
#define DEFAULT_OUTPUT_FORMAT OMX_AUDIO_AACStreamFormatRAW
@@ -41,10 +41,20 @@ enum
#define DEFAULT_CHANNELS 2
#define IN_BUFFER_SIZE 1024*8 /* 1024*8 Recommended buffer size */
#define OUT_BUFFER_SIZE 1024*8 /* 1024*8 Recommended buffer size */
+#define OMX_AUDENC_INPUT_PORT 0
+#define OMX_AUDENC_OUTPUT_PORT 1
+#define NUM_OF_IN_BUFFERS 1
+#define NUM_OF_OUT_BUFFERS 1
+#define NUM_OF_PORTS 2
+#define START_PORT_NUM 0
GSTOMX_BOILERPLATE (GstOmxAacEnc, gst_omx_aacenc, GstOmxBaseFilter, GST_OMX_BASE_FILTER_TYPE);
#define GST_TYPE_OMX_AACENC_PROFILE (gst_omx_aacenc_profile_get_type ())
+
+gint rateIdx[] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,
+ 11025,8000,7350};
+
static GType
gst_omx_aacenc_profile_get_type (void)
{
@@ -99,6 +109,48 @@ gst_omx_aacenc_output_format_get_type (void)
return gst_omx_aacenc_output_format_type;
}
+static void
+settings_changed_cb (GOmxCore *core)
+{
+
+ GstOmxBaseFilter *omx_base;
+ guint rate;
+ guint channels;
+ guint profile;
+
+ omx_base = core->object;
+ GST_DEBUG_OBJECT (omx_base, "settings changed");
+
+ {
+ OMX_AUDIO_PARAM_AACPROFILETYPE param;
+ _G_OMX_INIT_PARAM(&param);
+ G_OMX_PORT_GET_PARAM (omx_base->out_port, OMX_IndexParamAudioAac, &param);
+ rate = param.nSampleRate;
+ channels = param.nChannels;
+ profile = param.eAACProfile;
+
+ if (rate == 0)
+ {
+ /** @todo: this shouldn't happen. */
+ GST_WARNING_OBJECT (omx_base, "Bad samplerate");
+ rate = DEFAULT_RATE;
+ channels = DEFAULT_CHANNELS;
+ }
+ }
+
+ {
+ GstCaps *new_caps = NULL;
+ new_caps = gst_caps_new_simple ("audio/mpeg",
+ "mpegversion", G_TYPE_INT, profile,
+ "rate", G_TYPE_INT, rate,
+ "channels", G_TYPE_INT, channels,
+ NULL);
+
+ GST_INFO_OBJECT (omx_base, "caps are: %" GST_PTR_FORMAT, new_caps);
+ gst_pad_set_caps (omx_base->srcpad, new_caps);
+ }
+
+}
static GstCaps *
generate_src_template (void)
@@ -307,49 +359,280 @@ sink_setcaps (GstPad *pad,
gst_structure_get_int (structure, "rate", &self->rate);
gst_structure_get_int (structure, "channels", &self->channels);
+
+ {
+ /* set pcm port */
+ OMX_AUDIO_PARAM_PCMMODETYPE param;
+ G_OMX_PORT_GET_PARAM (omx_base->in_port, OMX_IndexParamAudioPcm, &param);
+
+ param.nSamplingRate = self->rate;
+ param.nChannels = self->channels;
+
+ G_OMX_PORT_SET_PARAM(omx_base->in_port, OMX_IndexParamAudioPcm, &param);
+
+ }
+ self->inport_configured = TRUE;
+
{
- GstCaps *src_caps;
+ GstCaps *sink_caps;
- src_caps = gst_caps_new_simple ("audio/mpeg",
+ sink_caps = gst_caps_new_simple ("audio/x-raw-int",
"mpegversion", G_TYPE_INT, 4,
"rate", G_TYPE_INT, self->rate,
"channels", G_TYPE_INT, self->channels,
NULL);
- GST_INFO_OBJECT (omx_base, "src caps are: %" GST_PTR_FORMAT, src_caps);
+ GST_INFO_OBJECT (omx_base, "src caps are: %" GST_PTR_FORMAT, sink_caps);
+
+
+ omx_base->in_port->caps = gst_caps_copy (sink_caps);
+
+ gst_caps_unref (sink_caps);
+ }
+
+ return gst_pad_set_caps (pad, caps);
+}
+
+static GstCaps *
+sink_getcaps (GstPad *pad)
+{
+
+ GstCaps *caps = NULL;
+ GstStructure *structure = NULL;
+ GstOmxBaseFilter *omx_base;
+
+ GstOmxAacEnc* self;
+
+
+ omx_base = GST_OMX_BASE_FILTER (GST_PAD_PARENT (pad));
+
+ self = GST_OMX_AACENC (omx_base);
+ if (omx_base->gomx->omx_state > OMX_StateLoaded)
+ {
+ /* currently, we cannot change caps once out of loaded.. later this
+ * could possibly be supported by enabling/disabling the port..
+ */
+ GST_DEBUG_OBJECT (self, "cannot getcaps in %d state", omx_base->gomx->omx_state);
+ return GST_PAD_CAPS (pad);
+ }
+ if (self->inport_configured)
+ {
+ OMX_AUDIO_PARAM_PCMMODETYPE param;
+
+ G_OMX_PORT_GET_PARAM (omx_base->in_port, OMX_IndexParamAudioPcm, &param);
+ caps = gst_caps_new_empty ();
+
+ GstStructure *struc = ("audio/x-raw-int",
+ "endianness", G_TYPE_INT, G_BYTE_ORDER,
+ "width", G_TYPE_INT, 16,
+ "depth", G_TYPE_INT, 16,
+ "rate", G_TYPE_INT, param.nSamplingRate,
+ "signed", G_TYPE_BOOLEAN, TRUE,
+ "channels", G_TYPE_INT, param.nChannels,
+ NULL);
+ gst_caps_append_structure (caps, structure);
+ }
+ else
+ {
+ GstPadTemplate *template;
+ template = gst_pad_template_new ("sink", GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ generate_sink_template ());
+ /* we don't have valid width/height/etc yet, so just use the template.. */
+ caps = gst_pad_template_get_caps(template);
+
+ GST_DEBUG_OBJECT (self, "caps=%"GST_PTR_FORMAT, caps);
+ }
+
+ return caps;
+
+}
+
+static guint gst_get_aac_rateIdx (guint rate)
+{
+ gint i;
+
+ for (i=0; i < 13; i++){
+ if (rate >= rateIdx[i])
+ return i;
+ }
+
+ return 15;
+}
+
+static GstBuffer *gst_omx_aacenc_generate_codec_data (GstOmxBaseFilter *omx_base){
+ GstBuffer *codec_data = NULL;
+ guchar *data;
+ guint sr_idx;
+ GstOmxAacEnc *self;
+
+ self = GST_OMX_AACENC (omx_base);
+ /*
+ * Now create the codec data header, it goes like
+ * 5 bit: profile
+ * 4 bit: sample rate index
+ * 4 bit: number of channels
+ * 3 bit: unused
+ */
+ sr_idx = gst_get_aac_rateIdx(self->rate);
+ codec_data = gst_buffer_new_and_alloc(2);
+ data = GST_BUFFER_DATA(codec_data);
+ data[0] = ((self->profile & 0x1F) << 3) | ((sr_idx & 0xE) >> 1);
+ data[1] = ((sr_idx & 0x1) << 7) | ((self->channels & 0xF) << 3);
+
+ return codec_data;
+}
- gst_pad_set_caps (omx_base->srcpad, src_caps);
+static gboolean
+src_setcaps (GstPad *pad,
+ GstCaps *caps)
+{
+
+ GstStructure *structure;
+ GstOmxBaseFilter *omx_base;
+
+ GstOmxAacEnc* self;
+
+ omx_base = GST_OMX_BASE_FILTER (GST_PAD_PARENT (pad));
+
+ self = GST_OMX_AACENC (omx_base);
+
+ GST_INFO_OBJECT (omx_base, "setcaps (sink): %" GST_PTR_FORMAT, caps);
+
+ structure = gst_caps_get_structure (caps, 0);
+
+ gst_structure_get_int (structure, "rate", &self->rate);
+ gst_structure_get_int (structure, "channels", &self->channels);
+ gst_structure_get_int (structure, "mpegversion", &self->profile);
+
+ {
+ /* set aac profile type port */
+ OMX_AUDIO_PARAM_AACPROFILETYPE param;
+
+ G_OMX_PORT_GET_PARAM (omx_base->out_port, OMX_IndexParamAudioAac, &param);
+
+ param.nSampleRate = self->rate;
+ param.nChannels = self->channels;
+ param.eAACProfile = self->profile;
+
+ G_OMX_PORT_SET_PARAM(omx_base->out_port, OMX_IndexParamAudioAac, &param);
+
+ }
- gst_caps_unref (src_caps);
+ if(self->output_format == OMX_AUDIO_AACStreamFormatADIF)
+ {
+ GstBuffer *codec_data;
+ codec_data = gst_omx_aacenc_generate_codec_data(omx_base);
+ gst_caps_set_simple (caps, "codec_data",
+ GST_TYPE_BUFFER, codec_data, (char *)NULL);
+ gst_buffer_unref (codec_data);
}
+ omx_base->in_port->caps = gst_caps_copy (caps);
+
+
return gst_pad_set_caps (pad, caps);
+
+}
+
+static GstCaps *
+src_getcaps (GstPad *pad)
+{
+
+ GstCaps *caps = NULL;
+ GstStructure *structure = NULL;
+ GstOmxBaseFilter *omx_base;
+ GstOmxAacEnc* self;
+
+
+ omx_base = GST_OMX_BASE_FILTER (GST_PAD_PARENT (pad));
+ self = GST_OMX_AACENC (omx_base);
+
+ if (omx_base->gomx->omx_state > OMX_StateLoaded)
+ {
+ /* currently, we cannot change caps once out of loaded.. later this
+ * could possibly be supported by enabling/disabling the port..
+ */
+ GST_DEBUG_OBJECT (self, "cannot getcaps in %d state", omx_base->gomx->omx_state);
+ return GST_PAD_CAPS (pad);
+ }
+ if (self->inport_configured)
+ {
+
+ OMX_AUDIO_PARAM_AACPROFILETYPE param;
+ G_OMX_PORT_GET_PARAM (omx_base->out_port, OMX_IndexParamAudioAac, &param);
+ caps = gst_caps_new_empty ();
+
+ GstStructure *struc = gst_structure_new ("audio/mpeg",
+ "mpegversion", G_TYPE_INT, &self->profile,
+ "rate", G_TYPE_INT,self->rate,
+ "channels", G_TYPE_INT, self->channels,
+ NULL);
+ gst_caps_append_structure (caps, struc);
+ }
+ else
+ {
+ GstPadTemplate *template;
+ template = gst_pad_template_new ("src", GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ generate_src_template ());
+ /* we don't have valid width/height/etc yet, so just use the template.. */
+ caps = gst_pad_template_get_caps(template);
+
+ GST_DEBUG_OBJECT (self, "caps=%"GST_PTR_FORMAT, caps);
+ }
+
+
+
+ return caps;
+
}
static void
omx_setup (GstOmxBaseFilter *omx_base)
{
+
GstOmxAacEnc *self;
GOmxCore *gomx;
+ GOmxPort *port;
+
+ OMX_PORT_PARAM_TYPE portInit;
+ OMX_PARAM_PORTDEFINITIONTYPE pInPortDef, pOutPortDef;
+ OMX_ERRORTYPE eError = OMX_ErrorNone;
self = GST_OMX_AACENC (omx_base);
gomx = (GOmxCore *) omx_base->gomx;
-
+
+
+
GST_INFO_OBJECT (omx_base, "begin");
- /* Input port configuration. */
+ _G_OMX_INIT_PARAM(&portInit);
+ portInit.nPorts = NUM_OF_PORTS;
+ portInit.nStartPortNumber = START_PORT_NUM;
+ G_OMX_PORT_SET_PARAM(omx_base->in_port,OMX_IndexParamAudioInit,&portInit);
- {
- OMX_PARAM_PORTDEFINITIONTYPE param;
- G_OMX_PORT_GET_DEFINITION (omx_base->in_port, &param);
+ _G_OMX_INIT_PARAM(&pInPortDef);
+ pInPortDef.nPortIndex = OMX_AUDENC_INPUT_PORT;
+ G_OMX_PORT_GET_DEFINITION (omx_base->in_port, &pInPortDef);
+ pInPortDef.nBufferCountActual = NUM_OF_IN_BUFFERS;
+ pInPortDef.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
+ G_OMX_PORT_SET_DEFINITION (omx_base->in_port, &pInPortDef);
- param.nBufferSize = IN_BUFFER_SIZE;
- G_OMX_PORT_SET_DEFINITION (omx_base->in_port, &param);
- }
+ _G_OMX_INIT_PARAM(&pOutPortDef);
+ pOutPortDef.nPortIndex = OMX_AUDENC_OUTPUT_PORT;
+ G_OMX_PORT_GET_DEFINITION (omx_base->out_port, &pOutPortDef);
+ pOutPortDef.nBufferCountActual = NUM_OF_OUT_BUFFERS;
+ pOutPortDef.format.audio.eEncoding = OMX_AUDIO_CodingAAC;
+ G_OMX_PORT_SET_DEFINITION (omx_base->out_port, &pOutPortDef);
+
+
+
+
/* PCM configuration. */
{
OMX_AUDIO_PARAM_PCMMODETYPE param;
-
+ _G_OMX_INIT_PARAM(&param);
G_OMX_PORT_GET_PARAM (omx_base->in_port, OMX_IndexParamAudioPcm, &param);
param.nSamplingRate = self->rate;
@@ -358,18 +641,10 @@ omx_setup (GstOmxBaseFilter *omx_base)
G_OMX_PORT_SET_PARAM (omx_base->in_port, OMX_IndexParamAudioPcm, &param);
}
- /* output port configuration. */
- {
- OMX_PARAM_PORTDEFINITIONTYPE param;
- G_OMX_PORT_GET_DEFINITION (omx_base->out_port, &param);
-
- param.nBufferSize = OUT_BUFFER_SIZE;
- G_OMX_PORT_SET_DEFINITION (omx_base->out_port, &param);
- }
/* AAC configuration. */
{
OMX_AUDIO_PARAM_AACPROFILETYPE param;
-
+ _G_OMX_INIT_PARAM(&param);
G_OMX_PORT_GET_PARAM (omx_base->out_port, OMX_IndexParamAudioAac, &param);
param.nSampleRate = self->rate;
@@ -387,6 +662,38 @@ omx_setup (GstOmxBaseFilter *omx_base)
G_OMX_PORT_SET_PARAM (omx_base->out_port, OMX_IndexParamAudioAac, &param);
}
+ GST_DEBUG_OBJECT(self, "SendCommand(PortEnable, %x)", port->port_index);
+ port = g_omx_core_get_port (gomx, "input", 0);
+ eError = OMX_SendCommand (g_omx_core_get_handle (port->core),
+ OMX_CommandPortEnable, port->port_index, NULL);
+ g_sem_down (port->core->port_sem);
+
+ if (eError != OMX_ErrorNone)
+ {
+
+ GST_DEBUG_OBJECT(self, "port enable on port %d failed error=%x", port->port_index,eError);
+ }
+ else
+ {
+ GST_DEBUG_OBJECT(self, "port enabled on port index %d ", port->port_index );
+ }
+
+ port = g_omx_core_get_port (gomx, "output", 1);
+ GST_DEBUG_OBJECT(self, "SendCommand(PortEnable, %x)", port->port_index);
+ eError = OMX_SendCommand (g_omx_core_get_handle (port->core),
+ OMX_CommandPortEnable, 1, NULL);
+ g_sem_down (port->core->port_sem);
+
+ if (eError != OMX_ErrorNone)
+ {
+ GST_DEBUG_OBJECT(self, "port enable on port %d failed error=%x", port->port_index,eError);
+ }
+ else
+ {
+ GST_DEBUG_OBJECT(self, "port enabled on port index %d ", port->port_index );
+ }
+
+
GST_INFO_OBJECT (omx_base, "end");
}
@@ -401,8 +708,13 @@ type_instance_init (GTypeInstance *instance,
self = GST_OMX_AACENC (instance);
omx_base->omx_setup = omx_setup;
+ omx_base->gomx->settings_changed_cb = settings_changed_cb;
+ omx_base->out_port->always_copy = TRUE;
gst_pad_set_setcaps_function (omx_base->sinkpad, sink_setcaps);
+ gst_pad_set_getcaps_function (omx_base->sinkpad, sink_getcaps);
+ gst_pad_set_setcaps_function (omx_base->srcpad, src_setcaps);
+ gst_pad_set_getcaps_function (omx_base->srcpad, src_getcaps);
self->bitrate = DEFAULT_BITRATE;
self->profile = DEFAULT_PROFILE;
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_aacenc.h b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_aacenc.h
index 7a6ff0d..9db435d 100644
--- a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_aacenc.h
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_aacenc.h
@@ -42,6 +42,7 @@ struct GstOmxAacEnc
gint output_format;
gint rate;
gint channels;
+ gboolean inport_configured;
};
struct GstOmxAacEncClass
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_audiodec.c b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_audiodec.c
index d6a3a86..649c7a9 100644
--- a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_audiodec.c
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_audiodec.c
@@ -95,6 +95,7 @@ settings_changed_cb (GOmxCore *core)
/** @todo: this shouldn't happen. */
GST_WARNING_OBJECT (omx_base, "Bad samplerate");
rate = 44100;
+ channels = 2;
}
}
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_ctrl.h b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_ctrl.h
index bcf23dc..4e70801 100755
--- a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_ctrl.h
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_ctrl.h
@@ -25,7 +25,6 @@
#include <gst/gst.h>
#include <gst/base/gstbasetransform.h>
-#include <xdc/std.h>
#include <OMX_TI_Index.h>
#include <OMX_TI_Common.h>
#include <omx_vfdc.h>
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_filter.c b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_filter.c
index 87770b5..a2de97d 100644
--- a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_filter.c
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_filter.c
@@ -3,6 +3,9 @@
*
* Author: Felipe Contreras <felipe.contreras@nokia.com>
*
+ * Modified by: David Soto <david.soto@ridgerun.com>
+ * Copyright (C) 2011 RidgeRun
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
@@ -101,32 +104,34 @@ setup_input_buffer (GstOmxBaseFilter *self, GstBuffer *buf)
/* retrieve incoming buffer port information */
port = GST_GET_OMXPORT (buf);
- /* configure input buffer size to match with upstream buffer */
- G_OMX_PORT_GET_DEFINITION (self->in_port, &param);
- param.nBufferSize = GST_BUFFER_SIZE (buf);
- param.nBufferCountActual = port->num_buffers;
- G_OMX_PORT_SET_DEFINITION (self->in_port, &param);
-
- /* allocate resource to save the incoming buffer port pBuffer pointer in
- * OmxBufferInfo structure.
- */
- in_port = self->in_port;
- in_port->share_buffer_info = malloc (sizeof(OmxBufferInfo));
- in_port->share_buffer_info->pBuffer = malloc (sizeof(int) * port->num_buffers);
- for (i=0; i < port->num_buffers; i++) {
- in_port->share_buffer_info->pBuffer[i] = port->buffers[i]->pBuffer;
- }
-
- /* disable omx_allocate alloc flag, so that we can fall back to shared method */
- self->in_port->omx_allocate = FALSE;
- self->in_port->always_copy = FALSE;
- }
- else
- {
- /* ask openmax to allocate input buffer */
- self->in_port->omx_allocate = TRUE;
- self->in_port->always_copy = TRUE;
- }
+ /* Check if output port has set always_copy */
+ if (port->always_copy != TRUE) {
+ /* configure input buffer size to match with upstream buffer */
+ G_OMX_PORT_GET_DEFINITION (self->in_port, &param);
+ param.nBufferSize = GST_BUFFER_SIZE (buf);
+ param.nBufferCountActual = port->num_buffers;
+ G_OMX_PORT_SET_DEFINITION (self->in_port, &param);
+
+ /* allocate resource to save the incoming buffer port pBuffer pointer in
+ * OmxBufferInfo structure.
+ */
+ in_port = self->in_port;
+ in_port->share_buffer_info = malloc (sizeof(OmxBufferInfo));
+ in_port->share_buffer_info->pBuffer = malloc (sizeof(int) * port->num_buffers);
+ for (i=0; i < port->num_buffers; i++) {
+ in_port->share_buffer_info->pBuffer[i] = port->buffers[i]->pBuffer;
+ }
+
+ /* disable omx_allocate alloc flag, so that we can fall back to shared method */
+ self->in_port->omx_allocate = FALSE;
+ self->in_port->always_copy = FALSE;
+
+ return;
+ }
+ }
+ /* ask openmax to allocate input buffer */
+ self->in_port->omx_allocate = TRUE;
+ self->in_port->always_copy = TRUE;
}
static GstStateChangeReturn
@@ -408,6 +413,8 @@ push_buffer (GstOmxBaseFilter *self,
}
PRINT_BUFFER (self, buf);
+ if (self->push_cb)
+ self->push_cb (self, buf);
/** @todo check if tainted */
GST_LOG_OBJECT (self, "begin");
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_filter.h b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_filter.h
index be5b4e7..1280aa4 100644
--- a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_filter.h
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_filter.h
@@ -34,6 +34,7 @@ G_BEGIN_DECLS
typedef struct GstOmxBaseFilter GstOmxBaseFilter;
typedef struct GstOmxBaseFilterClass GstOmxBaseFilterClass;
typedef void (*GstOmxBaseFilterCb) (GstOmxBaseFilter *self);
+typedef void (*GstOmxBaseFilterPushCb) (GstOmxBaseFilter *self, GstBuffer *buf);
#include "gstomx_util.h"
#include <async_queue.h>
@@ -56,6 +57,7 @@ struct GstOmxBaseFilter
GMutex *ready_lock;
GstOmxBaseFilterCb omx_setup;
+ GstOmxBaseFilterPushCb push_cb;
GstFlowReturn last_pad_push_return;
GstBuffer *codec_data;
GstClockTime duration;
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_filter2.c b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_filter2.c
new file mode 100644
index 0000000..fa40c95
--- /dev/null
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_filter2.c
@@ -0,0 +1,1028 @@
+/*
+ * Copyright (C) 2007-2009 Nokia Corporation.
+ *
+ * Author: Felipe Contreras <felipe.contreras@nokia.com>
+ *
+ * Modified by: David Soto <david.soto@ridgerun.com>
+ * Copyright (C) 2011 RidgeRun
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "gstomx_base_filter2.h"
+#include "gstomx.h"
+#include "gstomx_interface.h"
+#include "gstomx_buffertransport.h"
+
+enum
+{
+ ARG_0,
+ ARG_COMPONENT_ROLE,
+ ARG_COMPONENT_NAME,
+ ARG_LIBRARY_NAME,
+ ARG_USE_TIMESTAMPS,
+ ARG_NUM_INPUT_BUFFERS,
+ ARG_NUM_OUTPUT_BUFFERS,
+ ARG_GEN_TIMESTAMPS
+};
+
+static void init_interfaces (GType type);
+GSTOMX_BOILERPLATE_FULL (GstOmxBaseFilter2, gst_omx_base_filter2, GstElement, GST_TYPE_ELEMENT, init_interfaces);
+
+
+static GstFlowReturn push_buffer (GstOmxBaseFilter2 *self, GstBuffer *buf);
+static GstFlowReturn pad_chain (GstPad *pad, GstBuffer *buf);
+static gboolean pad_event (GstPad *pad, GstEvent *event);
+
+
+static void
+setup_ports (GstOmxBaseFilter2 *self)
+{
+ OMX_PARAM_PORTDEFINITIONTYPE param;
+ int i;
+ gboolean omx_allocate, share_buffer;
+ gboolean set_omx_allocate = FALSE, set_share_buffer = FALSE;
+
+ if (g_getenv ("OMX_ALLOCATE_ON"))
+ {
+ GST_DEBUG_OBJECT (self, "OMX_ALLOCATE_ON");
+ omx_allocate = TRUE;
+ share_buffer = FALSE;
+ set_omx_allocate = set_share_buffer = TRUE;
+ }
+ else if (g_getenv ("OMX_SHARE_HACK_ON"))
+ {
+ GST_DEBUG_OBJECT (self, "OMX_SHARE_HACK_ON");
+ share_buffer = TRUE;
+ set_share_buffer = TRUE;
+ }
+ else if (g_getenv ("OMX_SHARE_HACK_OFF"))
+ {
+ GST_DEBUG_OBJECT (self, "OMX_SHARE_HACK_OFF");
+ share_buffer = FALSE;
+ set_share_buffer = TRUE;
+ }
+
+ /* Input port configuration. */
+ G_OMX_PORT_GET_DEFINITION (self->in_port, &param);
+ g_omx_port_setup (self->in_port, &param);
+ gst_pad_set_element_private (self->sinkpad, self->in_port);
+ if (set_omx_allocate) self->in_port->omx_allocate = omx_allocate;
+ if (set_share_buffer) self->in_port->share_buffer = share_buffer;
+
+ /* Output port configuration. */
+ for (i = 0; i < NUM_OUTPUTS; i++) {
+ G_OMX_PORT_GET_DEFINITION (self->out_port[i], &param);
+ g_omx_port_setup (self->out_port[i], &param);
+ gst_pad_set_element_private (self->srcpad[i], self->out_port[i]);
+ if (set_omx_allocate) self->out_port[i]->omx_allocate = omx_allocate;
+ if (set_share_buffer) self->out_port[i]->share_buffer = share_buffer;
+ }
+}
+
+static void
+setup_input_buffer (GstOmxBaseFilter2 *self, GstBuffer *buf)
+{
+ if (GST_IS_OMXBUFFERTRANSPORT (buf))
+ {
+ OMX_PARAM_PORTDEFINITIONTYPE param, peer_param;
+ GOmxPort *port, *in_port;
+ gint i, shift = 0;
+
+ /* retrieve incoming buffer port information */
+ port = GST_GET_OMXPORT (buf);
+
+ /* configure input buffer size to match with upstream buffer */
+ G_OMX_PORT_GET_DEFINITION (self->in_port, &param);
+ G_OMX_PORT_GET_DEFINITION (port, &peer_param);
+
+ printf("this input params: %dx%d,%d %d %d\n", param.format.video.nFrameWidth,
+ param.format.video.nFrameHeight,
+ param.format.video.nStride,
+ param.nBufferSize, param.nBufferCountActual);
+ printf("peer output params: %dx%d,%d %d %d\n", peer_param.format.video.nFrameWidth,
+ peer_param.format.video.nFrameHeight,
+ peer_param.format.video.nStride,
+ peer_param.nBufferSize, peer_param.nBufferCountActual);
+ printf("incoming buffer: nFilledLen: %d, nOffset: %d nFlags: %x\n",
+ GST_GET_OMXBUFFER(buf)->nFilledLen,
+ GST_GET_OMXBUFFER(buf)->nOffset,
+ GST_GET_OMXBUFFER(buf)->nFlags);
+
+ param.nBufferSize = GST_BUFFER_SIZE (buf);
+ if (self->input_fields_separately) param.nBufferCountActual = port->num_buffers * 2;
+ else param.nBufferCountActual = port->num_buffers;
+ G_OMX_PORT_SET_DEFINITION (self->in_port, &param);
+
+ /* allocate resource to save the incoming buffer port pBuffer pointer in
+ * OmxBufferInfo structure.
+ */
+ in_port = self->in_port;
+ in_port->share_buffer_info = malloc (sizeof(OmxBufferInfo));
+ if (self->input_fields_separately) {
+ int t1, t2;
+ t1 = GST_GET_OMXBUFFER(buf)->nOffset / param.format.video.nStride;
+ t2 = t1 + t1 + ((param.format.video.nFrameHeight + 7) & 0xFFFFFFF8);
+ t1 = t2 * param.format.video.nStride;
+ self->second_field_offset = ( GST_GET_OMXBUFFER(buf)->nFilledLen + GST_GET_OMXBUFFER(buf)->nOffset ) / 3;
+ if (self->second_field_offset != t1) {
+ printf("Second field offset does not look right... correcting it from %d to %d\n",
+ self->second_field_offset, t1);
+ self->second_field_offset = t1;
+ }
+ in_port->share_buffer_info->pBuffer = malloc (sizeof(int) * port->num_buffers * 2);
+ for (i=0; i < port->num_buffers; i++) {
+ in_port->share_buffer_info->pBuffer[i<<1] = port->buffers[i]->pBuffer;
+ in_port->share_buffer_info->pBuffer[(i<<1)+1] = port->buffers[i]->pBuffer +
+ self->second_field_offset;
+ }
+ } else {
+ in_port->share_buffer_info->pBuffer = malloc (sizeof(int) * port->num_buffers);
+ for (i=0; i < port->num_buffers; i++) {
+ in_port->share_buffer_info->pBuffer[i] = port->buffers[i]->pBuffer;
+ }
+ }
+
+ /* disable omx_allocate alloc flag, so that we can fall back to shared method */
+ self->in_port->omx_allocate = FALSE;
+ self->in_port->always_copy = FALSE;
+ }
+ else
+ {
+ /* ask openmax to allocate input buffer */
+ self->in_port->omx_allocate = TRUE;
+ self->in_port->always_copy = TRUE;
+ self->input_fields_separately = FALSE;
+ }
+}
+
+static GstStateChangeReturn
+change_state (GstElement *element,
+ GstStateChange transition)
+{
+ GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
+ GstOmxBaseFilter2 *self;
+ GOmxCore *core;
+ int i;
+
+ self = GST_OMX_BASE_FILTER2 (element);
+ core = self->gomx;
+
+ GST_INFO_OBJECT (self, "begin: changing state %s -> %s",
+ gst_element_state_get_name (GST_STATE_TRANSITION_CURRENT (transition)),
+ gst_element_state_get_name (GST_STATE_TRANSITION_NEXT (transition)));
+
+ switch (transition)
+ {
+ case GST_STATE_CHANGE_NULL_TO_READY:
+ g_omx_core_init (core);
+ if (core->omx_state != OMX_StateLoaded)
+ {
+ ret = GST_STATE_CHANGE_FAILURE;
+ goto leave;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+
+ if (ret == GST_STATE_CHANGE_FAILURE)
+ goto leave;
+
+ switch (transition)
+ {
+ case GST_STATE_CHANGE_PAUSED_TO_READY:
+ g_mutex_lock (self->ready_lock);
+ if (self->ready)
+ {
+ /* unlock */
+ g_omx_port_finish (self->in_port);
+ for (i = 0; i < NUM_OUTPUTS; i++)
+ g_omx_port_finish (self->out_port[i]);
+
+ g_omx_core_stop (core);
+ g_omx_core_unload (core);
+ self->ready = FALSE;
+ }
+ g_mutex_unlock (self->ready_lock);
+ if (core->omx_state != OMX_StateLoaded &&
+ core->omx_state != OMX_StateInvalid)
+ {
+ ret = GST_STATE_CHANGE_FAILURE;
+ goto leave;
+ }
+ break;
+
+ case GST_STATE_CHANGE_READY_TO_NULL:
+ g_omx_core_deinit (core);
+ break;
+
+ default:
+ break;
+ }
+
+leave:
+ GST_LOG_OBJECT (self, "end");
+
+ return ret;
+}
+
+static void
+finalize (GObject *obj)
+{
+ GstOmxBaseFilter2 *self;
+
+ self = GST_OMX_BASE_FILTER2 (obj);
+
+ if (self->codec_data)
+ {
+ gst_buffer_unref (self->codec_data);
+ self->codec_data = NULL;
+ }
+
+ g_omx_core_free (self->gomx);
+
+ g_free (self->omx_role);
+ g_free (self->omx_component);
+ g_free (self->omx_library);
+
+ g_mutex_free (self->ready_lock);
+
+ G_OBJECT_CLASS (parent_class)->finalize (obj);
+}
+
+static void
+set_property (GObject *obj,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GstOmxBaseFilter2 *self;
+
+ self = GST_OMX_BASE_FILTER2 (obj);
+
+ switch (prop_id)
+ {
+ case ARG_COMPONENT_ROLE:
+ g_free (self->omx_role);
+ self->omx_role = g_value_dup_string (value);
+ break;
+ case ARG_COMPONENT_NAME:
+ g_free (self->omx_component);
+ self->omx_component = g_value_dup_string (value);
+ break;
+ case ARG_LIBRARY_NAME:
+ g_free (self->omx_library);
+ self->omx_library = g_value_dup_string (value);
+ break;
+ case ARG_USE_TIMESTAMPS:
+ self->gomx->use_timestamps = g_value_get_boolean (value);
+ break;
+ case ARG_GEN_TIMESTAMPS:
+ self->gomx->gen_timestamps = g_value_get_boolean (value);
+ break;
+ case ARG_NUM_INPUT_BUFFERS:
+ {
+ OMX_PARAM_PORTDEFINITIONTYPE param;
+ OMX_U32 nBufferCountActual = g_value_get_uint (value);
+ G_OMX_PORT_GET_DEFINITION (self->in_port, &param);
+ g_return_if_fail (nBufferCountActual >= param.nBufferCountMin);
+ param.nBufferCountActual = nBufferCountActual;
+ G_OMX_PORT_SET_DEFINITION (self->in_port, &param);
+ }
+ break;
+ case ARG_NUM_OUTPUT_BUFFERS:
+ {
+ OMX_PARAM_PORTDEFINITIONTYPE param;
+ OMX_U32 nBufferCountActual = g_value_get_uint (value);
+ int i;
+ for (i = 0; i < NUM_OUTPUTS; i++) {
+ G_OMX_PORT_GET_DEFINITION (self->out_port[i], &param);
+ g_return_if_fail (nBufferCountActual >= param.nBufferCountMin);
+ param.nBufferCountActual = nBufferCountActual;
+ G_OMX_PORT_SET_DEFINITION (self->out_port[i], &param);
+ }
+ }
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+get_property (GObject *obj,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GstOmxBaseFilter2 *self;
+
+ self = GST_OMX_BASE_FILTER2 (obj);
+
+ switch (prop_id)
+ {
+ case ARG_COMPONENT_ROLE:
+ g_value_set_string (value, self->omx_role);
+ break;
+ case ARG_COMPONENT_NAME:
+ g_value_set_string (value, self->omx_component);
+ break;
+ case ARG_LIBRARY_NAME:
+ g_value_set_string (value, self->omx_library);
+ break;
+ case ARG_USE_TIMESTAMPS:
+ g_value_set_boolean (value, self->gomx->use_timestamps);
+ break;
+ case ARG_GEN_TIMESTAMPS:
+ g_value_set_boolean (value, self->gomx->gen_timestamps);
+ break;
+ case ARG_NUM_INPUT_BUFFERS:
+ case ARG_NUM_OUTPUT_BUFFERS:
+ {
+ OMX_PARAM_PORTDEFINITIONTYPE param;
+ GOmxPort *port = (prop_id == ARG_NUM_INPUT_BUFFERS) ?
+ self->in_port : self->out_port[0];
+
+ G_OMX_PORT_GET_DEFINITION (port, &param);
+
+ g_value_set_uint (value, param.nBufferCountActual);
+ }
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+type_base_init (gpointer g_class)
+{
+}
+
+static void
+type_class_init (gpointer g_class,
+ gpointer class_data)
+{
+ GObjectClass *gobject_class;
+ GstElementClass *gstelement_class;
+ GstOmxBaseFilter2Class *bclass;
+
+ gobject_class = G_OBJECT_CLASS (g_class);
+ gstelement_class = GST_ELEMENT_CLASS (g_class);
+ bclass = GST_OMX_BASE_FILTER2_CLASS (g_class);
+
+ gobject_class->finalize = finalize;
+ gstelement_class->change_state = change_state;
+ bclass->push_buffer = push_buffer;
+ bclass->pad_chain = pad_chain;
+ bclass->pad_event = pad_event;
+
+ /* Properties stuff */
+ {
+ gobject_class->set_property = set_property;
+ gobject_class->get_property = get_property;
+
+ g_object_class_install_property (gobject_class, ARG_COMPONENT_ROLE,
+ g_param_spec_string ("component-role", "Component role",
+ "Role of the OpenMAX IL component",
+ NULL, G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, ARG_COMPONENT_NAME,
+ g_param_spec_string ("component-name", "Component name",
+ "Name of the OpenMAX IL component to use",
+ NULL, G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, ARG_LIBRARY_NAME,
+ g_param_spec_string ("library-name", "Library name",
+ "Name of the OpenMAX IL implementation library to use",
+ NULL, G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, ARG_USE_TIMESTAMPS,
+ g_param_spec_boolean ("use-timestamps", "Use timestamps",
+ "Whether or not to use timestamps",
+ TRUE, G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, ARG_GEN_TIMESTAMPS,
+ g_param_spec_boolean ("gen-timestamps", "Generate timestamps",
+ "Whether or not to generate timestamps using interpolation/extrapolation",
+ TRUE, G_PARAM_READWRITE));
+
+ /* note: the default values for these are just a guess.. since we wouldn't know
+ * until the OMX component is constructed. But that is ok, these properties are
+ * only for debugging
+ */
+ g_object_class_install_property (gobject_class, ARG_NUM_INPUT_BUFFERS,
+ g_param_spec_uint ("input-buffers", "Input buffers",
+ "The number of OMX input buffers",
+ 1, 10, 4, G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class, ARG_NUM_OUTPUT_BUFFERS,
+ g_param_spec_uint ("output-buffers", "Output buffers",
+ "The number of OMX output buffers",
+ 1, 10, 4, G_PARAM_READWRITE));
+ }
+}
+
+static GstFlowReturn
+push_buffer (GstOmxBaseFilter2 *self,
+ GstBuffer *buf)
+{
+ GstFlowReturn ret = GST_FLOW_ERROR;
+ int i;
+
+ for (i = 0; i< NUM_OUTPUTS; i++) {
+ if (GST_GET_OMXPORT(buf) == self->out_port[i]) {
+ break;
+ }
+ }
+
+ if (i == NUM_OUTPUTS) return ret;
+
+ GST_BUFFER_DURATION (buf) = self->duration;
+
+ if (self->gomx->gen_timestamps == TRUE) {
+ if (GST_CLOCK_TIME_NONE == GST_BUFFER_TIMESTAMP(buf) &&
+ GST_CLOCK_TIME_NONE != self->last_buf_timestamp[i] &&
+ GST_CLOCK_TIME_NONE != self->duration) {
+ GST_BUFFER_TIMESTAMP(buf) = self->last_buf_timestamp[i] + self->duration;
+ }
+ self->last_buf_timestamp[i] = GST_BUFFER_TIMESTAMP(buf);
+ }
+
+ PRINT_BUFFER (self, buf);
+ if (self->push_cb)
+ self->push_cb (self, buf);
+
+ /** @todo check if tainted */
+ GST_LOG_OBJECT (self, "begin");
+ ret = gst_pad_push (self->srcpad[i], buf);
+ GST_LOG_OBJECT (self, "end");
+
+ return ret;
+}
+
+static void
+output_loop (gpointer data)
+{
+ GstPad *pad;
+ GOmxCore *gomx;
+ GOmxPort *out_port;
+ GstOmxBaseFilter2 *self;
+ GstFlowReturn ret = GST_FLOW_OK;
+ GstOmxBaseFilter2Class *bclass;
+
+ pad = data;
+ self = GST_OMX_BASE_FILTER2 (gst_pad_get_parent (pad));
+ gomx = self->gomx;
+
+ bclass = GST_OMX_BASE_FILTER2_GET_CLASS (self);
+
+ GST_LOG_OBJECT (self, "begin");
+
+ if (!self->ready)
+ {
+ g_error ("not ready");
+ return;
+ }
+
+ out_port = (GOmxPort *)gst_pad_get_element_private(pad);
+
+ if (G_LIKELY (out_port->enabled))
+ {
+ gpointer obj = g_omx_port_recv (out_port);
+
+ if (G_UNLIKELY (!obj))
+ {
+ GST_WARNING_OBJECT (self, "null buffer: leaving");
+ ret = GST_FLOW_WRONG_STATE;
+ goto leave;
+ }
+
+ if (G_LIKELY (GST_IS_BUFFER (obj)))
+ {
+ if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (obj, GST_BUFFER_FLAG_IN_CAPS)))
+ {
+ GstCaps *caps = NULL;
+ GstStructure *structure;
+ GValue value = { 0 };
+
+ caps = gst_pad_get_negotiated_caps (pad);
+ caps = gst_caps_make_writable (caps);
+ structure = gst_caps_get_structure (caps, 0);
+
+ g_value_init (&value, GST_TYPE_BUFFER);
+ gst_value_set_buffer (&value, obj);
+ gst_buffer_unref (obj);
+ gst_structure_set_value (structure, "codec_data", &value);
+ g_value_unset (&value);
+
+ gst_pad_set_caps (pad, caps);
+ }
+ else
+ {
+ GstBuffer *buf = GST_BUFFER (obj);
+ ret = bclass->push_buffer (self, buf);
+ GST_DEBUG_OBJECT (self, "ret=%s", gst_flow_get_name (ret));
+ }
+ }
+ else if (GST_IS_EVENT (obj))
+ {
+ GST_DEBUG_OBJECT (self, "got eos");
+ gst_pad_push_event (pad, obj);
+ ret = GST_FLOW_UNEXPECTED;
+ goto leave;
+ }
+
+ }
+
+leave:
+
+ self->last_pad_push_return = ret;
+
+ if (gomx->omx_error != OMX_ErrorNone)
+ {
+ GST_DEBUG_OBJECT (self, "omx_error=%s", g_omx_error_to_str (gomx->omx_error));
+ ret = GST_FLOW_ERROR;
+ }
+
+ if (ret != GST_FLOW_OK)
+ {
+ GST_INFO_OBJECT (self, "pause task, reason: %s",
+ gst_flow_get_name (ret));
+ gst_pad_pause_task (pad);
+ }
+
+ GST_LOG_OBJECT (self, "end");
+
+ gst_object_unref (self);
+}
+
+static GstFlowReturn
+pad_chain (GstPad *pad,
+ GstBuffer *buf)
+{
+ GOmxCore *gomx;
+ GOmxPort *in_port;
+ GstOmxBaseFilter2 *self;
+ GstFlowReturn ret = GST_FLOW_OK;
+ int i;
+
+ self = GST_OMX_BASE_FILTER2 (GST_OBJECT_PARENT (pad));
+
+ //printf("INput!!\n");
+ PRINT_BUFFER (self, buf);
+
+ gomx = self->gomx;
+
+ GST_LOG_OBJECT (self, "begin: size=%u, state=%d", GST_BUFFER_SIZE (buf), gomx->omx_state);
+
+ if (G_UNLIKELY (gomx->omx_state == OMX_StateLoaded))
+ {
+ g_mutex_lock (self->ready_lock);
+
+ GST_INFO_OBJECT (self, "omx: prepare");
+
+ /** @todo this should probably go after doing preparations. */
+ if (self->omx_setup)
+ {
+ self->omx_setup (self);
+ }
+
+ setup_input_buffer (self, buf);
+
+ setup_ports (self);
+
+ g_omx_core_prepare (self->gomx);
+
+ if (gomx->omx_state == OMX_StateIdle)
+ {
+ self->ready = TRUE;
+ for (i = 0; i < NUM_OUTPUTS; i++)
+ gst_pad_start_task (self->srcpad[i], output_loop, self->srcpad[i]);
+ }
+
+ g_mutex_unlock (self->ready_lock);
+
+ if (gomx->omx_state != OMX_StateIdle)
+ goto out_flushing;
+ }
+
+ in_port = self->in_port;
+
+ if (G_LIKELY (in_port->enabled))
+ {
+ if (G_UNLIKELY (gomx->omx_state == OMX_StateIdle))
+ {
+ GST_INFO_OBJECT (self, "omx: play");
+ g_omx_core_start (gomx);
+
+ if (gomx->omx_state != OMX_StateExecuting)
+ goto out_flushing;
+
+ /* send buffer with codec data flag */
+ if (self->codec_data)
+ {
+ GST_BUFFER_FLAG_SET (self->codec_data, GST_BUFFER_FLAG_IN_CAPS); /* just in case */
+ g_omx_port_send (in_port, self->codec_data);
+ }
+
+ }
+
+ if (G_UNLIKELY (gomx->omx_state != OMX_StateExecuting))
+ {
+ GST_ERROR_OBJECT (self, "Whoa! very wrong");
+ }
+
+ while (TRUE)
+ {
+ gint sent;
+
+ if (self->last_pad_push_return != GST_FLOW_OK ||
+ !(gomx->omx_state == OMX_StateExecuting ||
+ gomx->omx_state == OMX_StatePause))
+ {
+ GST_DEBUG_OBJECT (self, "last_pad_push_return=%d", self->last_pad_push_return);
+ goto out_flushing;
+ }
+
+ if (self->input_fields_separately) {
+ g_omx_port_send_interlaced_fields (in_port, buf, self->second_field_offset);
+ gst_buffer_unref (buf);
+ break;
+ }
+
+ sent = g_omx_port_send (in_port, buf);
+
+ if (G_UNLIKELY (sent < 0))
+ {
+ ret = GST_FLOW_WRONG_STATE;
+ goto out_flushing;
+ }
+ else if (sent < GST_BUFFER_SIZE (buf))
+ {
+ GstBuffer *subbuf = gst_buffer_create_sub (buf, sent,
+ GST_BUFFER_SIZE (buf) - sent);
+ gst_buffer_unref (buf);
+ buf = subbuf;
+ }
+ else
+ {
+ gst_buffer_unref (buf);
+ break;
+ }
+ }
+ }
+ else
+ {
+ GST_WARNING_OBJECT (self, "done");
+ ret = GST_FLOW_UNEXPECTED;
+ }
+
+leave:
+
+ GST_LOG_OBJECT (self, "end");
+
+ return ret;
+
+ /* special conditions */
+out_flushing:
+ {
+ const gchar *error_msg = NULL;
+
+ if (gomx->omx_error)
+ {
+ error_msg = "Error from OpenMAX component";
+ }
+ else if (gomx->omx_state != OMX_StateExecuting &&
+ gomx->omx_state != OMX_StatePause)
+ {
+ error_msg = "OpenMAX component in wrong state";
+ }
+
+ if (error_msg)
+ {
+ GST_ELEMENT_ERROR (self, STREAM, FAILED, (NULL), (error_msg));
+ ret = GST_FLOW_ERROR;
+ }
+
+ gst_buffer_unref (buf);
+
+ goto leave;
+ }
+}
+
+static gboolean
+pad_event (GstPad *pad,
+ GstEvent *event)
+{
+ GstOmxBaseFilter2 *self;
+ GOmxCore *gomx;
+ gboolean ret = TRUE;
+ int i;
+
+ self = GST_OMX_BASE_FILTER2 (GST_OBJECT_PARENT (pad));
+ gomx = self->gomx;
+
+ GST_INFO_OBJECT (self, "begin: event=%s", GST_EVENT_TYPE_NAME (event));
+
+ switch (GST_EVENT_TYPE (event))
+ {
+ case GST_EVENT_EOS:
+ printf ("Recieved EOS event, press <CTRL+C> to terminate pipeline.\n");
+ /* if we are init'ed, and there is a running loop; then
+ * if we get a buffer to inform it of EOS, let it handle the rest
+ * in any other case, we send EOS */
+ if (self->ready && self->last_pad_push_return == GST_FLOW_OK)
+ {
+ /***** FIXME: EZSDK OMX componet does not execute FBD callback for an
+ ETB call when nFlags is set to OMX_BUFFERFLAG_EOS. Because of this
+ we are not able to trigger EOS on srcpad task. For now disable sending this event
+ until we get OMX component fixed. */
+ #if 0
+ if (g_omx_port_send (self->in_port, event) >= 0)
+ {
+ gst_event_unref (event);
+ break;
+ }
+ #endif
+ }
+
+ /* we tried, but it's up to us here */
+ for (i = 0; i < NUM_OUTPUTS-1; i++) {
+ gst_event_ref(event);
+ ret &= gst_pad_push_event (self->srcpad[i], event);
+ }
+ ret &= gst_pad_push_event (self->srcpad[i], event);
+ break;
+
+ case GST_EVENT_FLUSH_START:
+ for (i = 0; i < NUM_OUTPUTS-1; i++) {
+ gst_event_ref(event);
+ ret &= gst_pad_push_event (self->srcpad[i], event);
+ }
+ ret &= gst_pad_push_event (self->srcpad[i], event);
+ self->last_pad_push_return = GST_FLOW_WRONG_STATE;
+
+ g_omx_core_flush_start (gomx);
+
+ for (i = 0; i < NUM_OUTPUTS; i++)
+ gst_pad_pause_task (self->srcpad[i]);
+
+ ret = TRUE;
+ break;
+
+ case GST_EVENT_FLUSH_STOP:
+ for (i = 0; i < NUM_OUTPUTS-1; i++) {
+ gst_event_ref(event);
+ ret &= gst_pad_push_event (self->srcpad[i], event);
+ }
+ ret &= gst_pad_push_event (self->srcpad[i], event);
+ self->last_pad_push_return = GST_FLOW_OK;
+
+ g_omx_core_flush_stop (gomx);
+
+ if (self->ready)
+ for (i = 0; i < NUM_OUTPUTS; i++)
+ gst_pad_start_task (self->srcpad[i], output_loop, self->srcpad[i]);
+
+ ret = TRUE;
+ break;
+
+ case GST_EVENT_NEWSEGMENT:
+ for (i = 0; i < NUM_OUTPUTS-1; i++) {
+ self->last_buf_timestamp[i] = GST_CLOCK_TIME_NONE;
+ gst_event_ref(event);
+ ret &= gst_pad_push_event (self->srcpad[i], event);
+ }
+ self->last_buf_timestamp[i] = GST_CLOCK_TIME_NONE;
+ ret &= gst_pad_push_event (self->srcpad[i], event);
+ break;
+
+ default:
+ for (i = 0; i < NUM_OUTPUTS-1; i++) {
+ gst_event_ref(event);
+ ret &= gst_pad_push_event (self->srcpad[i], event);
+ }
+ ret &= gst_pad_push_event (self->srcpad[i], event);
+ break;
+ }
+
+ GST_LOG_OBJECT (self, "end");
+
+ return ret;
+}
+
+static gboolean
+activate_push (GstPad *pad,
+ gboolean active)
+{
+ gboolean result = TRUE;
+ GstOmxBaseFilter2 *self;
+ int i;
+
+ self = GST_OMX_BASE_FILTER2 (gst_pad_get_parent (pad));
+
+ if (active)
+ {
+ GST_DEBUG_OBJECT (self, "activate");
+ self->last_pad_push_return = GST_FLOW_OK;
+
+ /* we do not start the task yet if the pad is not connected */
+ if (gst_pad_is_linked (pad))
+ {
+ if (self->ready)
+ {
+ /** @todo link callback function also needed */
+ g_omx_port_resume (self->in_port);
+ for (i = 0; i < NUM_OUTPUTS; i++)
+ g_omx_port_resume (self->out_port[i]);
+
+ result = gst_pad_start_task (pad, output_loop, pad);
+ }
+ }
+ }
+ else
+ {
+ GST_DEBUG_OBJECT (self, "deactivate");
+
+ if (self->ready)
+ {
+ /** @todo disable this until we properly reinitialize the buffers. */
+#if 0
+ /* flush all buffers */
+ OMX_SendCommand (self->gomx->omx_handle, OMX_CommandFlush, OMX_ALL, NULL);
+#endif
+
+ /* unlock loops */
+ g_omx_port_pause (self->in_port);
+ for (i = 0; i < NUM_OUTPUTS; i++)
+ g_omx_port_pause (self->out_port[i]);
+ }
+
+ /* make sure streaming finishes */
+ result = gst_pad_stop_task (pad);
+ }
+
+ gst_object_unref (self);
+
+ return result;
+}
+
+/**
+ * overrides the default buffer allocation for output port to allow
+ * pad_alloc'ing from the srcpad
+ */
+static GstBuffer *
+buffer_alloc (GOmxPort *port, gint len)
+{
+ GstOmxBaseFilter2 *self = port->core->object;
+ GstBuffer *buf;
+ GstFlowReturn ret;
+ int i;
+
+ for (i = 0; i < NUM_OUTPUTS; i++)
+ if (port == self->out_port[i]) break;
+ if (i >= NUM_OUTPUTS) return NULL;
+
+#if 1
+ /** @todo remove this check */
+ if (G_LIKELY (self->in_port->enabled))
+ {
+ GstCaps *caps = NULL;
+
+ caps = gst_pad_get_negotiated_caps (self->srcpad[i]);
+
+ if (!caps)
+ {
+ /** @todo We shouldn't be doing this. */
+ GOmxCore *gomx = self->gomx;
+ GST_WARNING_OBJECT (self, "faking settings changed notification");
+ if (gomx->settings_changed_cb)
+ gomx->settings_changed_cb (gomx);
+ }
+ else
+ {
+ GST_LOG_OBJECT (self, "caps already fixed: %" GST_PTR_FORMAT, caps);
+ gst_caps_unref (caps);
+ }
+ }
+#endif
+
+ ret = gst_pad_alloc_buffer_and_set_caps (
+ self->srcpad[i], GST_BUFFER_OFFSET_NONE,
+ len, GST_PAD_CAPS (self->srcpad[i]), &buf);
+
+ if (ret == GST_FLOW_OK) return buf;
+
+ return NULL;
+}
+
+static void
+type_instance_init (GTypeInstance *instance,
+ gpointer g_class)
+{
+ GstOmxBaseFilter2 *self;
+ GstElementClass *element_class;
+ GstOmxBaseFilter2Class *bclass;
+ int i;
+ char srcname[10];
+
+ element_class = GST_ELEMENT_CLASS (g_class);
+ bclass = GST_OMX_BASE_FILTER2_CLASS (g_class);
+
+ self = GST_OMX_BASE_FILTER2 (instance);
+
+ GST_LOG_OBJECT (self, "begin");
+
+ /* GOmx */
+ self->gomx = g_omx_core_new (self, g_class);
+ self->in_port = g_omx_core_get_port (self->gomx, "in", 0);
+ self->in_port->omx_allocate = TRUE;
+ self->in_port->share_buffer = FALSE;
+
+ for (i = 0; i < NUM_OUTPUTS; i++) {
+ sprintf(srcname, "out_%02x", i);
+ self->out_port[i] = g_omx_core_get_port (self->gomx, srcname, 1+i);
+ self->out_port[i]->buffer_alloc = buffer_alloc;
+ self->out_port[i]->omx_allocate = TRUE;
+ self->out_port[i]->share_buffer = FALSE;
+ }
+ self->ready_lock = g_mutex_new ();
+
+ self->sinkpad =
+ gst_pad_new_from_template (gst_element_class_get_pad_template (element_class, "sink"), "sink");
+
+ gst_pad_set_chain_function (self->sinkpad, bclass->pad_chain);
+ gst_pad_set_event_function (self->sinkpad, bclass->pad_event);
+
+ gst_element_add_pad (GST_ELEMENT (self), self->sinkpad);
+
+ for (i = 0; i < NUM_OUTPUTS; i++) {
+ sprintf(srcname, "src_%02x", i);
+ self->srcpad[i] =
+ gst_pad_new_from_template (gst_element_class_get_pad_template (element_class, srcname), srcname);
+ gst_pad_set_activatepush_function (self->srcpad[i], activate_push);
+ gst_pad_use_fixed_caps (self->srcpad[i]);
+ gst_element_add_pad (GST_ELEMENT (self), self->srcpad[i]);
+ }
+ self->duration = GST_CLOCK_TIME_NONE;
+ self->input_fields_separately = FALSE;
+
+ GST_LOG_OBJECT (self, "end");
+}
+
+static void
+omx_interface_init (GstImplementsInterfaceClass *klass)
+{
+}
+
+static gboolean
+interface_supported (GstImplementsInterface *iface,
+ GType type)
+{
+ g_assert (type == GST_TYPE_OMX);
+ return TRUE;
+}
+
+static void
+interface_init (GstImplementsInterfaceClass *klass)
+{
+ klass->supported = interface_supported;
+}
+
+static void
+init_interfaces (GType type)
+{
+ GInterfaceInfo *iface_info;
+ GInterfaceInfo *omx_info;
+
+
+ iface_info = g_new0 (GInterfaceInfo, 1);
+ iface_info->interface_init = (GInterfaceInitFunc) interface_init;
+
+ g_type_add_interface_static (type, GST_TYPE_IMPLEMENTS_INTERFACE, iface_info);
+ g_free (iface_info);
+
+ omx_info = g_new0 (GInterfaceInfo, 1);
+ omx_info->interface_init = (GInterfaceInitFunc) omx_interface_init;
+
+ g_type_add_interface_static (type, GST_TYPE_OMX, omx_info);
+ g_free (omx_info);
+}
+
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_filter2.h b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_filter2.h
new file mode 100644
index 0000000..8571bca
--- /dev/null
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_filter2.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2007-2009 Nokia Corporation.
+ *
+ * Author: Felipe Contreras <felipe.contreras@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef GSTOMX_BASE_FILTER2_H
+#define GSTOMX_BASE_FILTER2_H
+
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+
+#define GST_OMX_BASE_FILTER2(obj) ((GstOmxBaseFilter2 *) (obj))
+#define GST_OMX_BASE_FILTER2_TYPE (gst_omx_base_filter2_get_type ())
+#define GST_OMX_BASE_FILTER2_CLASS(obj) ((GstOmxBaseFilter2Class *) (obj))
+#define GST_OMX_BASE_FILTER2_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_OMX_BASE_FILTER2_TYPE, GstOmxBaseFilter2Class))
+
+typedef struct GstOmxBaseFilter2 GstOmxBaseFilter2;
+typedef struct GstOmxBaseFilter2Class GstOmxBaseFilter2Class;
+typedef void (*GstOmxBaseFilter2Cb) (GstOmxBaseFilter2 *self);
+typedef void (*GstOmxBaseFilter2PushCb) (GstOmxBaseFilter2 *self, GstBuffer *buf);
+
+#include "gstomx_util.h"
+#include <async_queue.h>
+
+
+struct GstOmxBaseFilter2
+{
+ GstElement element;
+
+ GstPad *sinkpad;
+#define NUM_OUTPUTS 2
+ GstPad *srcpad[NUM_OUTPUTS];
+
+ GOmxCore *gomx;
+ GOmxPort *in_port;
+ GOmxPort *out_port[NUM_OUTPUTS];
+
+ char *omx_role;
+ char *omx_component;
+ char *omx_library;
+ gboolean ready;
+ GMutex *ready_lock;
+
+ GstOmxBaseFilter2Cb omx_setup;
+ GstOmxBaseFilter2PushCb push_cb;
+ GstFlowReturn last_pad_push_return;
+ GstBuffer *codec_data;
+ GstClockTime duration;
+ GstClockTime last_buf_timestamp[NUM_OUTPUTS];
+
+ /* Used in deinterlacer kind of components where
+ one input interlaced input buffer in the input
+ translates to 2 inputs to omx dei component
+ */
+ gboolean input_fields_separately;
+ gint second_field_offset;
+};
+
+struct GstOmxBaseFilter2Class
+{
+ GstElementClass parent_class;
+
+ GstFlowReturn (*push_buffer) (GstOmxBaseFilter2 *self, GstBuffer *buf);
+ GstFlowReturn (*pad_chain) (GstPad *pad, GstBuffer *buf);
+ gboolean (*pad_event) (GstPad *pad, GstEvent *event);
+};
+
+GType gst_omx_base_filter2_get_type (void);
+
+G_END_DECLS
+
+#endif /* GSTOMX_BASE_FILTER2_H */
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_vfpc2.c b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_vfpc2.c
new file mode 100644
index 0000000..d223e3b
--- /dev/null
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_vfpc2.c
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2011-2012 Texas Instruments Inc.
+ *
+ * Author: Brijesh Singh <bksingh@ti.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "gstomx_base_vfpc2.h"
+#include "gstomx.h"
+#include <gst/video/video.h>
+
+#include <OMX_TI_Index.h>
+
+#include <string.h> /* for memset */
+
+GSTOMX_BOILERPLATE (GstOmxBaseVfpc2, gst_omx_base_vfpc2, GstOmxBaseFilter2, GST_OMX_BASE_FILTER2_TYPE);
+
+static GstFlowReturn push_buffer (GstOmxBaseFilter2 *self, GstBuffer *buf);
+
+static gboolean
+pad_event (GstPad *pad, GstEvent *event)
+{
+ GstOmxBaseVfpc2 *self;
+ GstOmxBaseFilter2 *omx_base;
+
+ self = GST_OMX_BASE_VFPC2 (GST_OBJECT_PARENT (pad));
+ omx_base = GST_OMX_BASE_FILTER2 (self);
+
+ GST_INFO_OBJECT (self, "begin: event=%s", GST_EVENT_TYPE_NAME (event));
+
+ switch (GST_EVENT_TYPE (event))
+ {
+ case GST_EVENT_CROP:
+ {
+ gst_event_parse_crop (event, &self->top, &self->left, NULL, NULL);
+ return TRUE;
+ }
+ default:
+ {
+ return parent_class->pad_event (pad, event);
+ }
+ }
+}
+
+static void
+type_base_init (gpointer g_class)
+{
+ GstElementClass *element_class;
+ GstOmxBaseFilter2Class *bfilter_class = GST_OMX_BASE_FILTER2_CLASS (g_class);
+
+ element_class = GST_ELEMENT_CLASS (g_class);
+
+ bfilter_class->pad_event = pad_event;
+}
+
+static GstFlowReturn
+push_buffer (GstOmxBaseFilter2 *omx_base, GstBuffer *buf)
+{
+ return parent_class->push_buffer (omx_base, buf);
+}
+
+static gint
+gstomx_calculate_stride (int width, GstVideoFormat format)
+{
+ switch (format)
+ {
+ case GST_VIDEO_FORMAT_NV12:
+ return width;
+ case GST_VIDEO_FORMAT_YUY2:
+ return width * 2;
+ default:
+ GST_ERROR ("unsupported color format");
+ }
+ return -1;
+}
+
+static gboolean
+sink_setcaps (GstPad *pad,
+ GstCaps *caps)
+{
+ GstStructure *structure;
+ GstOmxBaseVfpc2 *self;
+ GstOmxBaseFilter2 *omx_base;
+ GOmxCore *gomx;
+ GstVideoFormat format;
+
+ self = GST_OMX_BASE_VFPC2 (GST_PAD_PARENT (pad));
+ omx_base = GST_OMX_BASE_FILTER2 (self);
+
+ gomx = (GOmxCore *) omx_base->gomx;
+
+ GST_INFO_OBJECT (self, "setcaps (sink): %" GST_PTR_FORMAT, caps);
+
+ g_return_val_if_fail (caps, FALSE);
+ g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);
+
+ structure = gst_caps_get_structure (caps, 0);
+
+ g_return_val_if_fail (structure, FALSE);
+
+ if (!gst_video_format_parse_caps_strided (caps,
+ &format, &self->in_width, &self->in_height, &self->in_stride))
+ {
+ GST_WARNING_OBJECT (self, "width and/or height is not set in caps");
+ return FALSE;
+ }
+
+ if (!self->in_stride)
+ {
+ self->in_stride = gstomx_calculate_stride (self->in_width, format);
+ }
+
+ {
+ const GValue *framerate = NULL;
+ framerate = gst_structure_get_value (structure, "framerate");
+ if (framerate)
+ {
+ self->framerate_num = gst_value_get_fraction_numerator (framerate);
+ self->framerate_denom = gst_value_get_fraction_denominator (framerate);
+
+ if (self->framerate_num && self->framerate_denom) {
+ omx_base->duration = gst_util_uint64_scale_int(GST_SECOND,
+ gst_value_get_fraction_denominator (framerate),
+ gst_value_get_fraction_numerator (framerate));
+ }
+ GST_DEBUG_OBJECT (self, "Nominal frame duration =%"GST_TIME_FORMAT,
+ GST_TIME_ARGS (omx_base->duration));
+ }
+ }
+ /* check for pixel-aspect-ratio, to set to src caps */
+ {
+ const GValue *v = NULL;
+ v = gst_structure_get_value (structure, "pixel-aspect-ratio");
+ if (v) {
+ self->pixel_aspect_ratio_num = gst_value_get_fraction_numerator (v);
+ self->pixel_aspect_ratio_denom = gst_value_get_fraction_denominator (v);
+ } else self->pixel_aspect_ratio_denom = 0;
+ }
+
+ if (!gst_structure_get_boolean (structure, "interlaced", &self->interlaced))
+ self->interlaced = FALSE;
+
+ if (self->sink_setcaps)
+ self->sink_setcaps (pad, caps);
+
+ return gst_pad_set_caps (pad, caps);
+}
+
+static gboolean
+src_setcaps (GstPad *pad, GstCaps *caps)
+{
+ GstOmxBaseVfpc2 *self;
+ GstOmxBaseFilter2 *omx_base;
+ GstVideoFormat format;
+ GstStructure *structure;
+ int i;
+
+ self = GST_OMX_BASE_VFPC2 (GST_PAD_PARENT (pad));
+ omx_base = GST_OMX_BASE_FILTER2 (self);
+ structure = gst_caps_get_structure (caps, 0);
+
+ GST_INFO_OBJECT (omx_base, "setcaps (src): %" GST_PTR_FORMAT, caps);
+ g_return_val_if_fail (caps, FALSE);
+ g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);
+
+ for (i=0; i<NUM_OUTPUTS; i++)
+ if (pad == omx_base->srcpad[i]) break;
+ if (!(i<NUM_OUTPUTS)) return FALSE;
+
+ if (!gst_video_format_parse_caps_strided (caps,
+ &format, &self->out_width[i], &self->out_height[i], &self->out_stride[i]))
+ {
+ GST_WARNING_OBJECT (self, "width and/or height is not set in caps");
+ return FALSE;
+ }
+
+ if (!self->out_stride[i])
+ {
+ self->out_stride[i] = gstomx_calculate_stride (self->out_width[i], format);
+ }
+
+ /* save the src caps later needed by omx transport buffer */
+ if (omx_base->out_port[i]->caps)
+ gst_caps_unref (omx_base->out_port[i]->caps);
+
+ omx_base->out_port[i]->caps = gst_caps_copy (caps);
+
+ return TRUE;
+}
+
+static void
+omx_setup (GstOmxBaseFilter2 *omx_base)
+{
+ GstOmxBaseVfpc2 *self;
+ GOmxCore *gomx;
+ GOmxPort *port;
+ int i;
+
+ self = GST_OMX_BASE_VFPC2 (omx_base);
+ gomx = (GOmxCore *) omx_base->gomx;
+
+ GST_INFO_OBJECT (omx_base, "begin");
+
+ if (self->omx_setup)
+ {
+ self->omx_setup (omx_base);
+ }
+
+ /* enable input port */
+ port = omx_base->in_port;
+ OMX_SendCommand (g_omx_core_get_handle (port->core),
+ OMX_CommandPortEnable, port->port_index, NULL);
+ g_sem_down (port->core->port_sem);
+
+ for (i=0; i<NUM_OUTPUTS; i++) {
+ /* enable output port */
+ port = omx_base->out_port[i];
+ OMX_SendCommand (g_omx_core_get_handle (port->core),
+ OMX_CommandPortEnable, port->port_index, NULL);
+ g_sem_down (port->core->port_sem);
+ }
+ /* indicate that port is now configured */
+ self->port_configured = TRUE;
+
+ GST_INFO_OBJECT (omx_base, "end");
+}
+
+static void
+type_class_init (gpointer g_class,
+ gpointer class_data)
+{
+ GObjectClass *gobject_class;
+
+ gobject_class = G_OBJECT_CLASS (g_class);
+ GST_OMX_BASE_FILTER2_CLASS (g_class)->push_buffer = push_buffer;
+}
+
+static void
+type_instance_init (GTypeInstance *instance,
+ gpointer g_class)
+{
+ GstOmxBaseFilter2 *omx_base;
+ GstOmxBaseVfpc2 *self;
+ char srcname[10];
+ int i;
+
+ omx_base = GST_OMX_BASE_FILTER2 (instance);
+ self = GST_OMX_BASE_VFPC2 (instance);
+
+ omx_base->omx_setup = omx_setup;
+ self->g_class = g_class;
+
+ gst_pad_set_setcaps_function (omx_base->sinkpad,
+ GST_DEBUG_FUNCPTR (sink_setcaps));
+ for (i=0; i<NUM_OUTPUTS; i++)
+ gst_pad_set_setcaps_function (omx_base->srcpad[i],
+ GST_DEBUG_FUNCPTR (src_setcaps));
+
+ /* free the existing core and ports */
+ g_omx_core_free (omx_base->gomx);
+ g_omx_port_free (omx_base->in_port);
+
+ /* create new core and ports */
+ omx_base->gomx = g_omx_core_new (omx_base, self->g_class);
+ omx_base->in_port = g_omx_core_get_port (omx_base->gomx, "in", OMX_VFPC_INPUT_PORT_START_INDEX);
+
+ omx_base->in_port->omx_allocate = TRUE;
+ omx_base->in_port->share_buffer = FALSE;
+ omx_base->in_port->always_copy = FALSE;
+ omx_base->in_port->port_index = OMX_VFPC_INPUT_PORT_START_INDEX;
+
+ for (i=0; i<NUM_OUTPUTS; i++) {
+ g_omx_port_free (omx_base->out_port[i]);
+ sprintf(srcname, "src_%02x", i);
+ omx_base->out_port[i] = g_omx_core_get_port (omx_base->gomx, "out",
+ OMX_VFPC_OUTPUT_PORT_START_INDEX + i);
+ omx_base->out_port[i]->port_index = OMX_VFPC_OUTPUT_PORT_START_INDEX + i;
+ omx_base->out_port[i]->omx_allocate = TRUE;
+ omx_base->out_port[i]->share_buffer = FALSE;
+ omx_base->out_port[i]->always_copy = FALSE;
+ }
+}
+
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_vfpc2.h b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_vfpc2.h
new file mode 100644
index 0000000..75bcd87
--- /dev/null
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_vfpc2.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2010-2011 Texas Instruments Inc.
+ *
+ * Author: Brijesh Singh <bksingh@ti.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef GSTOMX_BASE_VFPC2_H
+#define GSTOMX_BASE_VFPC2_H
+
+#include <gst/gst.h>
+
+#include <OMX_TI_Index.h>
+#include <OMX_TI_Common.h>
+#include <omx_vfpc.h>
+
+G_BEGIN_DECLS
+
+#define GST_OMX_BASE_VFPC2(obj) (GstOmxBaseVfpc2 *) (obj)
+#define GST_OMX_BASE_VFPC2_TYPE (gst_omx_base_vfpc2_get_type ())
+#define GST_OMX_BASE_VFPC2_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GST_OMX_BASE_VFPC2_TYPE, GstOmxBaseVfpc2Class))
+
+typedef struct GstOmxBaseVfpc2 GstOmxBaseVfpc2;
+typedef struct GstOmxBaseVfpc2Class GstOmxBaseVfpc2Class;
+
+#include "gstomx_base_filter2.h"
+
+struct GstOmxBaseVfpc2
+{
+ GstOmxBaseFilter2 omx_base;
+
+ gint framerate_num;
+ gint framerate_denom;
+ gboolean port_configured;
+ GstPadSetCapsFunction sink_setcaps;
+ gint in_width, in_height, in_stride;
+ gint out_width[NUM_OUTPUTS], out_height[NUM_OUTPUTS], out_stride[NUM_OUTPUTS];
+ gint left, top;
+ GstOmxBaseFilter2Cb omx_setup;
+ gpointer g_class;
+ gint pixel_aspect_ratio_num;
+ gint pixel_aspect_ratio_denom;
+ gboolean interlaced;
+};
+
+struct GstOmxBaseVfpc2Class
+{
+ GstOmxBaseFilter2Class parent_class;
+};
+
+GType gst_omx_base_vfpc2_get_type (void);
+
+G_END_DECLS
+
+#endif /* GSTOMX_BASE_VFPC2_H */
+
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_videodec.c b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_videodec.c
index a7428b6..106d5e4 100644
--- a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_videodec.c
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_base_videodec.c
@@ -21,11 +21,13 @@
#include "gstomx_base_videodec.h"
#include "gstomx.h"
+#include "gstomx_buffertransport.h"
#include <gst/video/video.h>
#ifdef USE_OMXTICORE
# include <OMX_TI_Index.h>
+# include <OMX_TI_Common.h>
#endif
#include <string.h> /* for memset */
@@ -66,7 +68,7 @@ static void
type_class_init (gpointer g_class,
gpointer class_data)
{
- GST_OMX_BASE_FILTER_CLASS (g_class)->push_buffer = push_buffer;
+ //GST_OMX_BASE_FILTER_CLASS (g_class)->push_buffer = push_buffer;
}
static GstFlowReturn
@@ -145,9 +147,6 @@ sink_setcaps (GstPad *pad,
width, height);
return FALSE;
}
- if(width % 16)
- width = ((width/16) + 1)*16;
-
{
const GValue *framerate = NULL;
framerate = gst_structure_get_value (structure, "framerate");
@@ -276,9 +275,9 @@ src_getcaps (GstPad *pad)
}
else
{
- gst_structure_set (struc,
- "rowstride", G_TYPE_INT, param.format.video.nStride,
- NULL);
+ gst_structure_set (struc,
+ "rowstride", G_TYPE_INT, param.format.video.nStride,
+ NULL);
}
}
@@ -460,6 +459,35 @@ omx_setup (GstOmxBaseFilter *omx_base)
GST_INFO_OBJECT (omx_base, "end");
}
+static void push_cb (GstOmxBaseFilter *omx_base, GstBuffer *buf)
+{
+ GstOmxBaseVideoDec *self;
+ OMX_BUFFERHEADERTYPE *omxbuffer;
+ GstCaps *caps, tmp;
+ GstStructure *structure;
+ gboolean i;
+
+ self = GST_OMX_BASE_VIDEODEC (omx_base);
+ omxbuffer = GST_GET_OMXBUFFER(buf);
+
+ /* Change interlaced flag in srcpad caps if decoder differs with
+ what is already got from the upstream element */
+ i = (0 != (omxbuffer->nFlags &
+ OMX_TI_BUFFERFLAG_VIDEO_FRAME_TYPE_INTERLACE));
+ if (i != self->interlaced) {
+ caps = gst_caps_copy(GST_PAD_CAPS(omx_base->srcpad));
+ self->interlaced = i;
+ structure = gst_caps_get_structure (caps, 0);
+ if (structure) {
+ gst_structure_set (structure,
+ "interlaced", G_TYPE_BOOLEAN, self->interlaced, NULL);
+ }
+ gst_pad_set_caps(omx_base->srcpad, caps);
+ if (GST_BUFFER_CAPS(buf)) gst_caps_unref(GST_BUFFER_CAPS(buf));
+ GST_BUFFER_CAPS(buf) = caps;
+ }
+}
+
static void
type_instance_init (GTypeInstance *instance,
gpointer g_class)
@@ -469,6 +497,7 @@ type_instance_init (GTypeInstance *instance,
omx_base = GST_OMX_BASE_FILTER (instance);
omx_base->omx_setup = omx_setup;
+ omx_base->push_cb = push_cb;
omx_base->gomx->settings_changed_cb = settings_changed_cb;
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_buffertransport.c b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_buffertransport.c
index b9837be..68f0257 100755
--- a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_buffertransport.c
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_buffertransport.c
@@ -98,13 +98,16 @@ release_buffer (GOmxPort *port, OMX_BUFFERHEADERTYPE *omx_buffer)
break;
}
}
+#include <sys/time.h>
static void gst_omxbuffertransport_finalize(GstBuffer *gstbuffer)
{
GstOmxBufferTransport *self = GST_OMXBUFFERTRANSPORT(gstbuffer);
int ii;
- GST_LOG("begin\n");
+ GST_LOG("begin\n");
+ static guint64 beftime = 0;
+ if(self->omxbuffer)
release_buffer (self->port, self->omxbuffer);
for(ii = 0; ii < self->numAdditionalHeaders; ii++) {
@@ -112,10 +115,27 @@ static void gst_omxbuffertransport_finalize(GstBuffer *gstbuffer)
if(self->addHeader[ii])
release_buffer(self->port,self->addHeader[ii]);
}
-
+ if(self->addHeader) {
+ free(self->addHeader);
+ //printf("free\n");
+ }
+ if(self->parent)
+ gst_buffer_unref(self->parent);
+
+ if(self->bufSem) {
+ struct timeval tv;
+ guint64 afttime;
+ gettimeofday(&tv, NULL);
+ afttime = (tv.tv_sec * 1000000 + tv.tv_usec);
+ //printf("sem up:%lld\n",(afttime-beftime) );
+ beftime = afttime;
+ g_sem_up(self->bufSem);
+ }
+
+ self->addHeader = NULL;
self->omxbuffer = NULL;
self->port = NULL;
-
+ self->parent = NULL;
/* Call GstBuffer's finalize routine, so our base class can do it's cleanup
* as well. If we don't do this, we'll have a memory leak that is very
* difficult to track down.
@@ -149,18 +169,56 @@ GstBuffer* gst_omxbuffertransport_new (GOmxPort *port, OMX_BUFFERHEADERTYPE *buf
tdt_buf->numAdditionalHeaders = 0;
tdt_buf->addHeader = NULL;
+ tdt_buf->parent = NULL;
+ tdt_buf->bufSem = NULL;
GST_LOG("end new\n");
return GST_BUFFER(tdt_buf);
}
+GstBuffer* gst_omxbuffertransport_clone (GstBuffer *parent, GOmxPort *port)
+{
+ GstOmxBufferTransport *tdt_buf;
+ tdt_buf = (GstOmxBufferTransport*)
+ gst_mini_object_new(GST_TYPE_OMXBUFFERTRANSPORT);
+
+ g_return_val_if_fail(tdt_buf != NULL, NULL);
+
+ GST_BUFFER_SIZE(tdt_buf) = GST_BUFFER_SIZE(parent);
+ GST_BUFFER_DATA(tdt_buf) = GST_BUFFER_DATA(parent);
+ GST_BUFFER_CAPS(GST_BUFFER (tdt_buf)) = gst_caps_ref (GST_BUFFER_CAPS(parent));
+ GST_BUFFER_TIMESTAMP(tdt_buf) = GST_BUFFER_TIMESTAMP(parent);
+ GST_BUFFER_DURATION(tdt_buf) = GST_BUFFER_DURATION(parent);
+
+ if (GST_BUFFER_DATA(tdt_buf) == NULL) {
+ gst_mini_object_unref(GST_MINI_OBJECT(tdt_buf));
+ return NULL;
+ }
+
+ tdt_buf->omxbuffer = NULL;
+ tdt_buf->port = port;
+ tdt_buf->numAdditionalHeaders = 0;
+ tdt_buf->addHeader = NULL;
+ tdt_buf->bufSem = NULL;
+ tdt_buf->parent = parent;
+
+ GST_LOG("end new\n");
+
+ return GST_BUFFER(tdt_buf);
+
+}
+
+
void gst_omxbuffertransport_set_additional_headers (GstOmxBufferTransport *self ,guint numHeaders,OMX_BUFFERHEADERTYPE **buffer)
{
int ii;
if(numHeaders == 0)
return;
+
+ if(self->addHeader)
+ free(self->addHeader);
self->addHeader = malloc(numHeaders*sizeof(OMX_BUFFERHEADERTYPE *));
@@ -173,4 +231,11 @@ void gst_omxbuffertransport_set_additional_headers (GstOmxBufferTransport *self
return ;
}
+void gst_omxbuffertransport_set_bufsem (GstOmxBufferTransport *self ,GSem *sem)
+{
+ self->bufSem = sem;
+ return ;
+}
+
+
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_buffertransport.h b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_buffertransport.h
index 74f1416..5f1c0e9 100644
--- a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_buffertransport.h
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_buffertransport.h
@@ -61,6 +61,8 @@ struct _GstOmxBufferTransport {
GOmxPort *port;
guint numAdditionalHeaders;
OMX_BUFFERHEADERTYPE **addHeader;
+ GstBuffer *parent;
+ GSem *bufSem;
};
struct _GstOmxBufferTransportClass {
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_deiscaler.c b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_deiscaler.c
new file mode 100644
index 0000000..3ceb208
--- /dev/null
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_deiscaler.c
@@ -0,0 +1,403 @@
+/*
+ * Copyright (C) 2011-2012 Texas Instruments Inc.
+ *
+ * Author: Brijesh Singh <bksingh@ti.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "gstomx_deiscaler.h"
+#include "gstomx.h"
+
+
+GSTOMX_BOILERPLATE (GstOmxMDeiScaler, gst_omx_mdeiscaler, GstOmxBaseVfpc2, GST_OMX_BASE_VFPC2_TYPE);
+GSTOMX_BOILERPLATE (GstOmxHDeiScaler, gst_omx_hdeiscaler, GstOmxBaseVfpc2, GST_OMX_BASE_VFPC2_TYPE);
+
+static GstStaticPadTemplate sink_template =
+ GST_STATIC_PAD_TEMPLATE ("sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV_STRIDED (
+ "{NV12}", "[ 0, max ]"))
+ );
+
+static GstStaticPadTemplate src_template_yuv2 =
+ GST_STATIC_PAD_TEMPLATE ("src_00",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV_STRIDED ( "{YUY2}", "[ 0, max ]" ))
+ );
+
+static GstStaticPadTemplate src_template_nv12 =
+ GST_STATIC_PAD_TEMPLATE ("src_01",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV_STRIDED (
+ "{NV12}", "[ 0, max ]"))
+ );
+
+#define YUV2_OUTPUT_IDX 0
+#define NV12_OUTPUT_IDX 1
+
+static const guint32 src_fourcc_list[NUM_OUTPUTS] = {
+ GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'),
+ GST_MAKE_FOURCC ('N', 'V', '1', '2')
+};
+
+static const OMX_COLOR_FORMATTYPE omx_color_format_list[NUM_OUTPUTS] = {
+ OMX_COLOR_FormatYCbYCr,
+ OMX_COLOR_FormatYUV420SemiPlanar
+};
+
+static const double buffersize_multiplier_list[NUM_OUTPUTS] = { 1, 1.5 };
+static const int rowstride_multiplier_list[NUM_OUTPUTS] = { 2, 1 };
+
+static void
+type_base_init (gpointer g_class)
+{
+ GstElementClass *element_class;
+
+ element_class = GST_ELEMENT_CLASS (g_class);
+
+ {
+ GstElementDetails details;
+
+ details.longname = "OpenMAX IL for OMX.TI.VPSSM3.VFPC.DEIMDUALOUT component";
+ details.klass = "Filter";
+ details.description = "Deinterlace and Scale video using VPSS Scaler module ";
+ details.author = "Harinarayan Bhatta";
+
+ gst_element_class_set_details (element_class, &details);
+ }
+
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&sink_template));
+
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&src_template_nv12));
+
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&src_template_yuv2));
+}
+
+static GstCaps*
+create_src_caps (GstOmxBaseFilter2 *omx_base, int idx)
+{
+ GstCaps *caps;
+ GstOmxBaseVfpc2 *self;
+ int width, height, rowstride;
+ GstStructure *struc;
+
+ self = GST_OMX_BASE_VFPC2 (omx_base);
+ caps = gst_pad_peer_get_caps (omx_base->srcpad[idx]);
+
+ width = self->in_width;
+ height = self->in_height;
+ rowstride = 0;
+
+ if ((NULL != caps) && (!gst_caps_is_empty (caps)) && (0 != gst_caps_get_size (caps)))
+ {
+ GstStructure *s;
+
+ s = gst_caps_get_structure (caps, 0);
+
+ if (!(gst_structure_get_int (s, "width", &width) &&
+ gst_structure_get_int (s, "height", &height))) {
+ width = self->in_width;
+ height = self->in_height;
+ } else
+ gst_structure_get_int (s, "rowstride", &rowstride);
+ }
+ /* Workaround: Make width multiple of 16, otherwise, scaler crashes */
+ width = (width+15) & 0xFFFFFFF0;
+
+ if (caps) gst_caps_unref (caps);
+
+ caps = gst_caps_new_empty ();
+ if (rowstride) {
+ struc = gst_structure_new (("video/x-raw-yuv-strided"),
+ "width", G_TYPE_INT, width,
+ "height", G_TYPE_INT, height,
+ "rowstride", G_TYPE_INT, rowstride,
+ "format", GST_TYPE_FOURCC, src_fourcc_list[idx],
+ NULL);
+ } else {
+ struc = gst_structure_new (("video/x-raw-yuv"),
+ "width", G_TYPE_INT, width,
+ "height", G_TYPE_INT, height,
+ "format", GST_TYPE_FOURCC, src_fourcc_list[idx],
+ NULL);
+ }
+
+ if (self->framerate_denom)
+ {
+ gst_structure_set (struc,
+ "framerate", GST_TYPE_FRACTION, self->framerate_num, self->framerate_denom, NULL);
+ }
+
+ if (self->pixel_aspect_ratio_denom)
+ {
+ gst_structure_set (struc,
+ "pixel-aspect-ratio", GST_TYPE_FRACTION, self->pixel_aspect_ratio_num,
+ self->pixel_aspect_ratio_denom, NULL);
+ }
+
+ gst_structure_set (struc,
+ "interlaced", G_TYPE_BOOLEAN, FALSE, NULL);
+
+
+ gst_caps_append_structure (caps, struc);
+
+ return caps;
+}
+
+static void
+omx_setup (GstOmxBaseFilter2 *omx_base)
+{
+ GOmxCore *gomx;
+ OMX_ERRORTYPE err;
+ OMX_PARAM_PORTDEFINITIONTYPE paramPort;
+ OMX_PARAM_BUFFER_MEMORYTYPE memTypeCfg;
+ OMX_PARAM_VFPC_NUMCHANNELPERHANDLE numChannels;
+ OMX_CONFIG_VIDCHANNEL_RESOLUTION chResolution;
+ OMX_CONFIG_ALG_ENABLE algEnable;
+ OMX_CONFIG_SUBSAMPLING_FACTOR sSubSamplinginfo = {NULL};
+
+ GstOmxBaseVfpc2 *self;
+ int i, x, y, shift = 0;
+
+ gomx = (GOmxCore *) omx_base->gomx;
+ self = GST_OMX_BASE_VFPC2 (omx_base);
+
+ GST_LOG_OBJECT (self, "begin");
+
+ omx_base->input_fields_separately = self->interlaced;
+
+ if (omx_base->duration != GST_CLOCK_TIME_NONE) {
+ omx_base->duration *= (GST_OMX_DEISCALER(self))->framerate_divisor;
+ self->framerate_denom *= (GST_OMX_DEISCALER(self))->framerate_divisor;
+ if (omx_base->input_fields_separately) {
+ // Halve the duration of output frame
+ omx_base->duration = omx_base->duration/2;
+ self->framerate_num *= 2;
+ }
+ }
+
+ /* set the output cap */
+ for (i=0 ; i<NUM_OUTPUTS; i++)
+ gst_pad_set_caps (omx_base->srcpad[i], create_src_caps (omx_base, i));
+
+ /* Setting Memory type at input port to Raw Memory */
+ GST_LOG_OBJECT (self, "Setting input port to Raw memory");
+
+ _G_OMX_INIT_PARAM (&memTypeCfg);
+ memTypeCfg.nPortIndex = omx_base->in_port->port_index;
+ memTypeCfg.eBufMemoryType = OMX_BUFFER_MEMORY_DEFAULT;
+ err = OMX_SetParameter (gomx->omx_handle, OMX_TI_IndexParamBuffMemType, &memTypeCfg);
+
+ if (err != OMX_ErrorNone)
+ return;
+
+ /* Setting Memory type at output port to Raw Memory */
+ GST_LOG_OBJECT (self, "Setting output port to Raw memory");
+
+ for (i=0 ; i<NUM_OUTPUTS; i++) {
+ _G_OMX_INIT_PARAM (&memTypeCfg);
+ memTypeCfg.nPortIndex = omx_base->out_port[i]->port_index;
+ memTypeCfg.eBufMemoryType = OMX_BUFFER_MEMORY_DEFAULT;
+ err = OMX_SetParameter (gomx->omx_handle, OMX_TI_IndexParamBuffMemType, &memTypeCfg);
+
+ if (err != OMX_ErrorNone)
+ return;
+ }
+
+ if (self->interlaced) shift = 1;
+ /* Input port configuration. */
+ GST_LOG_OBJECT (self, "Setting port definition (input)");
+
+ G_OMX_PORT_GET_DEFINITION (omx_base->in_port, &paramPort);
+ paramPort.format.video.nFrameWidth = self->in_width;
+ paramPort.format.video.nFrameHeight = self->in_height >> shift;
+ paramPort.format.video.nStride = self->in_stride;
+ paramPort.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+ paramPort.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+ paramPort.nBufferSize = self->in_stride * self->in_height * 1.5;
+ paramPort.nBufferAlignment = 0;
+ paramPort.bBuffersContiguous = 0;
+ G_OMX_PORT_SET_DEFINITION (omx_base->in_port, &paramPort);
+ g_omx_port_setup (omx_base->in_port, &paramPort);
+
+ /* Output port configuration. */
+ GST_LOG_OBJECT (self, "Setting port definition (output)");
+
+ for (i=0 ; i<NUM_OUTPUTS; i++) {
+ G_OMX_PORT_GET_DEFINITION (omx_base->out_port[i], &paramPort);
+ paramPort.format.video.nFrameWidth = self->out_width[i];
+ paramPort.format.video.nFrameHeight = self->out_height[i];
+ paramPort.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+ paramPort.format.video.nStride = self->out_stride[i];
+ paramPort.format.video.eColorFormat = omx_color_format_list[i];
+ paramPort.nBufferSize = self->out_stride[i] * self->out_height[i] * buffersize_multiplier_list[i];
+ paramPort.nBufferCountActual = 8;
+ paramPort.nBufferAlignment = 0;
+ paramPort.bBuffersContiguous = 0;
+ G_OMX_PORT_SET_DEFINITION (omx_base->out_port[i], &paramPort);
+ g_omx_port_setup (omx_base->out_port[i], &paramPort);
+ }
+
+ /* Set number of channles */
+ GST_LOG_OBJECT (self, "Setting number of channels");
+
+ _G_OMX_INIT_PARAM (&numChannels);
+ numChannels.nNumChannelsPerHandle = 1;
+ err = OMX_SetParameter (gomx->omx_handle,
+ (OMX_INDEXTYPE) OMX_TI_IndexParamVFPCNumChPerHandle, &numChannels);
+
+ if (err != OMX_ErrorNone)
+ return;
+
+ /* Set input channel resolution */
+ GST_LOG_OBJECT (self, "Setting channel resolution (input)");
+
+ _G_OMX_INIT_PARAM (&chResolution);
+ chResolution.Frm0Width = self->in_width;
+ chResolution.Frm0Height = self->in_height >> shift;
+ chResolution.Frm0Pitch = self->in_stride;
+ chResolution.Frm1Width = 0;
+ chResolution.Frm1Height = 0;
+ chResolution.Frm1Pitch = 0;
+ chResolution.FrmStartX = x;
+ chResolution.FrmStartY = y;
+ chResolution.FrmCropWidth = self->in_width;
+ chResolution.FrmCropHeight = self->in_height >> shift;
+ chResolution.eDir = OMX_DirInput;
+ chResolution.nChId = 0;
+ err = OMX_SetConfig (gomx->omx_handle, OMX_TI_IndexConfigVidChResolution, &chResolution);
+
+ if (err != OMX_ErrorNone)
+ return;
+
+#if 1
+ _G_OMX_INIT_PARAM(&sSubSamplinginfo);
+ sSubSamplinginfo.nSubSamplingFactor = (GST_OMX_DEISCALER(self))->framerate_divisor;
+ err = OMX_SetConfig ( gomx->omx_handle, ( OMX_INDEXTYPE )
+ ( OMX_TI_IndexConfigSubSamplingFactor ),
+ &sSubSamplinginfo );
+ if (err != OMX_ErrorNone)
+ return;
+#endif
+
+ /* Set output channel resolution */
+ GST_LOG_OBJECT (self, "Setting channel resolution (output)");
+
+ _G_OMX_INIT_PARAM (&chResolution);
+ chResolution.Frm0Width = self->out_width[0];
+ chResolution.Frm0Height = self->out_height[0];
+ chResolution.Frm0Pitch = self->out_stride[0];
+ chResolution.Frm1Width = self->out_width[1];
+ chResolution.Frm1Height = self->out_height[1];
+ chResolution.Frm1Pitch = self->out_stride[1];
+ chResolution.FrmStartX = 0;
+ chResolution.FrmStartY = 0;
+ chResolution.FrmCropWidth = 0;
+ chResolution.FrmCropHeight = 0;
+ chResolution.eDir = OMX_DirOutput;
+ chResolution.nChId = 0;
+ err = OMX_SetConfig (gomx->omx_handle, OMX_TI_IndexConfigVidChResolution, &chResolution);
+
+ if (err != OMX_ErrorNone)
+ return;
+
+ _G_OMX_INIT_PARAM (&algEnable);
+ algEnable.nPortIndex = 0;
+ algEnable.nChId = 0;
+ algEnable.bAlgBypass = (self->interlaced)?OMX_FALSE:OMX_TRUE;
+
+ err = OMX_SetConfig (gomx->omx_handle, (OMX_INDEXTYPE) OMX_TI_IndexConfigAlgEnable, &algEnable);
+
+ if (err != OMX_ErrorNone)
+ return;
+}
+
+enum
+{
+ ARG_0,
+ ARG_FRAMERATE_DIV,
+};
+
+static void
+set_property (GObject *obj,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id)
+ {
+ case ARG_FRAMERATE_DIV:
+ (GST_OMX_DEISCALER(obj))->framerate_divisor = g_value_get_uint (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+get_property (GObject *obj,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id)
+ {
+ case ARG_FRAMERATE_DIV:
+ g_value_set_uint (value, (GST_OMX_DEISCALER(obj))->framerate_divisor);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+type_class_init (gpointer g_class,
+ gpointer class_data)
+{
+ GObjectClass *gobject_class;
+
+ gobject_class = G_OBJECT_CLASS (g_class);
+ gobject_class->set_property = set_property;
+ gobject_class->get_property = get_property;
+
+ g_object_class_install_property (gobject_class, ARG_FRAMERATE_DIV,
+ g_param_spec_uint ("framerate-divisor", "Output framerate divisor",
+ "Output framerate = (2 * input_framerate) / framerate_divisor",
+ 1, 60, 1, G_PARAM_READWRITE));
+}
+
+static void
+type_instance_init (GTypeInstance *instance,
+ gpointer g_class)
+{
+ GstOmxBaseVfpc2 *self;
+
+ self = GST_OMX_BASE_VFPC2 (instance);
+
+ self->omx_setup = omx_setup;
+
+ (GST_OMX_DEISCALER(instance))->framerate_divisor = 1;
+}
+
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_deiscaler.h b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_deiscaler.h
new file mode 100644
index 0000000..35dd588
--- /dev/null
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_deiscaler.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2011-2012 Texas Instruments Inc.
+ *
+ * Author: Brijesh Singh <bksingh@ti.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef GSTOMX_DEISCALER_H
+#define GSTOMX_DEISCALER_H
+
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+
+#define GST_OMX_DEISCALER(obj) (struct GstOmxDeiScaler *) (obj)
+// #define GST_OMX_DEISCALER_TYPE (gst_omx_deiscaler_get_type ())
+
+typedef struct GstOmxDeiScaler GstOmxMDeiScaler;
+typedef struct GstOmxDeiScalerClass GstOmxMDeiScalerClass;
+typedef struct GstOmxDeiScaler GstOmxHDeiScaler;
+typedef struct GstOmxDeiScalerClass GstOmxHDeiScalerClass;
+
+#include "gstomx_base_vfpc2.h"
+
+struct GstOmxDeiScaler
+{
+ GstOmxBaseVfpc2 omx_base;
+ gint framerate_divisor;
+};
+
+struct GstOmxDeiScalerClass
+{
+ GstOmxBaseVfpc2Class parent_class;
+};
+
+GType gst_omx_hdeiscaler_get_type (void);
+GType gst_omx_mdeiscaler_get_type (void);
+
+G_END_DECLS
+
+#endif /* GSTOMX_DEISCALER_H */
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_h264dec.c b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_h264dec.c
index d59a278..4e4cbe3 100755
--- a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_h264dec.c
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_h264dec.c
@@ -99,12 +99,12 @@ initialize_port (GstOmxBaseFilter *omx_base)
height = self->extendedParams.height;
paramPort.nPortIndex = 1;
- paramPort.nBufferCountActual = 20;//15;//output_buffer_count
+ paramPort.nBufferCountActual = 8;//15;//output_buffer_count
paramPort.format.video.nFrameWidth = width;
paramPort.format.video.nFrameHeight = height;
paramPort.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
paramPort.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
- paramPort.format.video.xFramerate = (60) << 16;
+ paramPort.format.video.xFramerate = (30) << 16;
GST_DEBUG_OBJECT (self, "nFrameWidth = %ld, nFrameHeight = %ld, nBufferCountActual = %ld",
paramPort.format.video.nFrameWidth, paramPort.format.video.nFrameHeight,
@@ -112,11 +112,12 @@ initialize_port (GstOmxBaseFilter *omx_base)
GST_DEBUG_OBJECT (self, "G_OMX_PORT_SET_DEFINITION (output)");
G_OMX_PORT_SET_DEFINITION (omx_base->out_port, &paramPort);
-
+#if 0
G_OMX_PORT_GET_DEFINITION (omx_base->in_port, &paramPort);
//paramPort.nBufferCountActual = 8;
- paramPort.format.video.xFramerate = (60) << 16;
+ // paramPort.format.video.xFramerate = (30) << 16;
G_OMX_PORT_SET_DEFINITION (omx_base->in_port, &paramPort);
+#endif
#if 0
port = g_omx_core_get_port (gomx, "input", 0);
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_h264enc.c b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_h264enc.c
index 82a2d65..6d4e9c5 100644
--- a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_h264enc.c
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_h264enc.c
@@ -3,6 +3,9 @@
*
* Author: Felipe Contreras <felipe.contreras@nokia.com>
*
+ * Modified by: David Soto <david.soto@ridgerun.com>
+ * Copyright (C) 2011 RidgeRun
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation
@@ -21,6 +24,8 @@
#include "gstomx_h264enc.h"
#include "gstomx.h"
+#include <OMX_TI_Index.h>
+#include <OMX_TI_Video.h>
#include <string.h> /* for memset */
@@ -32,11 +37,18 @@ enum
ARG_BYTESTREAM,
ARG_PROFILE,
ARG_LEVEL,
+ ARG_I_PERIOD,
+ ARG_IDR_PERIOD,
+ ARG_FORCE_IDR,
+ ARG_ENCODING_PRESET,
+ ARG_RATECONTROL_PRESET,
};
#define DEFAULT_BYTESTREAM FALSE
-#define DEFAULT_PROFILE OMX_VIDEO_AVCProfileHigh
-#define DEFAULT_LEVEL OMX_VIDEO_AVCLevel4
+#define DEFAULT_PROFILE OMX_VIDEO_AVCProfileBaseline
+#define DEFAULT_LEVEL OMX_VIDEO_AVCLevel42
+#define DEFAULT_ENCODE_PRESET OMX_Video_Enc_High_Speed_Med_Quality
+#define DEFAULT_RATECONTROL_PRESET OMX_Video_RC_Low_Delay
#define GST_TYPE_OMX_VIDEO_AVCPROFILETYPE (gst_omx_video_avcprofiletype_get_type ())
static GType
@@ -99,6 +111,54 @@ gst_omx_video_avcleveltype_get_type ()
return type;
}
+#define GST_TYPE_OMX_VIDEO_ENCODE_PRESETTYPE (gst_omx_video_enocdepreset_get_type ())
+static GType
+gst_omx_video_enocdepreset_get_type ()
+{
+ static GType type = 0;
+
+ if (!type)
+ {
+ static const GEnumValue vals[] =
+ {
+ {OMX_Video_Enc_High_Quality, "High Quality", "hq"},
+ {OMX_Video_Enc_User_Defined, "User Defined", "user"},
+ {OMX_Video_Enc_High_Speed_Med_Quality, "High Speed Med Qual", "hsmq"},
+ {OMX_Video_Enc_Med_Speed_Med_Quality, "Med Speed Med Qaul", "msmq"},
+ {OMX_Video_Enc_Med_Speed_High_Quality, "Med Speed High Qaul", "mshq"},
+ {OMX_Video_Enc_High_Speed, "High Speed", "hs"},
+ {0, NULL, NULL },
+ };
+
+ type = g_enum_register_static ("GstOmxVideoEncoderPreset", vals);
+ }
+
+ return type;
+}
+
+#define GST_TYPE_OMX_VIDEO_RATECONTROL_PRESETTYPE (gst_omx_video_ratecontrolpreset_get_type ())
+static GType
+gst_omx_video_ratecontrolpreset_get_type ()
+{
+ static GType type = 0;
+
+ if (!type)
+ {
+ static const GEnumValue vals[] =
+ {
+ {OMX_Video_RC_Low_Delay, "Low Delay", "low-delay"},
+ {OMX_Video_RC_Storage, "Storage", "storage"},
+ {OMX_Video_RC_Twopass, "Two Pass", "two-pass"},
+ {OMX_Video_RC_None, "none", "none"},
+ {0, NULL, NULL },
+ };
+
+ type = g_enum_register_static ("GstOmxVideoRateControlPreset", vals);
+ }
+
+ return type;
+}
+
static GstCaps *
generate_src_template (void)
{
@@ -108,6 +168,8 @@ generate_src_template (void)
"width", GST_TYPE_INT_RANGE, 16, 4096,
"height", GST_TYPE_INT_RANGE, 16, 4096,
"framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1,
+ "stream-format", G_TYPE_STRING, "byte-stream",
+ "alignment", G_TYPE_STRING, "au",
NULL);
return caps;
@@ -150,11 +212,9 @@ set_property (GObject *obj,
{
GstOmxBaseFilter *omx_base;
GstOmxH264Enc *self;
- GOmxCore *gomx;
omx_base = GST_OMX_BASE_FILTER (obj);
self = GST_OMX_H264ENC (obj);
- gomx = (GOmxCore*) omx_base->gomx;
switch (prop_id)
{
@@ -162,15 +222,14 @@ set_property (GObject *obj,
self->bytestream = g_value_get_boolean (value);
break;
case ARG_PROFILE:
+ #if 0
{
OMX_VIDEO_PARAM_PROFILELEVELTYPE tProfileLevel;
- GOmxCore *gomx;
OMX_ERRORTYPE error_val = OMX_ErrorNone;
- gomx = (GOmxCore *) omx_base->gomx;
_G_OMX_INIT_PARAM (&tProfileLevel);
tProfileLevel.nPortIndex = omx_base->out_port->port_index;
- error_val = OMX_GetParameter (gomx->omx_handle,
+ error_val = OMX_GetParameter (g_omx_core_get_handle (omx_base->gomx),
OMX_IndexParamVideoProfileLevelCurrent,
&tProfileLevel);
g_assert (error_val == OMX_ErrorNone);
@@ -178,22 +237,25 @@ set_property (GObject *obj,
GST_DEBUG_OBJECT (self, "Profile: param=%d",
(gint)tProfileLevel.eProfile);
- error_val = OMX_SetParameter (gomx->omx_handle,
+ error_val = OMX_SetParameter (g_omx_core_get_handle (omx_base->gomx),
OMX_IndexParamVideoProfileLevelCurrent,
&tProfileLevel);
g_assert (error_val == OMX_ErrorNone);
break;
}
+ #else
+ self->profile = g_value_get_enum(value);
+ break;
+ #endif
case ARG_LEVEL:
+ #if 0
{
OMX_VIDEO_PARAM_PROFILELEVELTYPE tProfileLevel;
- GOmxCore *gomx;
OMX_ERRORTYPE error_val = OMX_ErrorNone;
- gomx = (GOmxCore *) omx_base->gomx;
_G_OMX_INIT_PARAM (&tProfileLevel);
tProfileLevel.nPortIndex = omx_base->out_port->port_index;
- error_val = OMX_GetParameter (gomx->omx_handle,
+ error_val = OMX_GetParameter (g_omx_core_get_handle (omx_base->gomx),
OMX_IndexParamVideoProfileLevelCurrent,
&tProfileLevel);
g_assert (error_val == OMX_ErrorNone);
@@ -201,12 +263,101 @@ set_property (GObject *obj,
GST_DEBUG_OBJECT (self, "Level: param=%d",
(gint)tProfileLevel.eLevel);
- error_val = OMX_SetParameter (gomx->omx_handle,
+ error_val = OMX_SetParameter (g_omx_core_get_handle (omx_base->gomx),
OMX_IndexParamVideoProfileLevelCurrent,
&tProfileLevel);
g_assert (error_val == OMX_ErrorNone);
break;
}
+ #else
+ self->level = g_value_get_enum(value);
+ break;
+ #endif
+ case ARG_I_PERIOD:
+ #if 0
+ {
+ OMX_VIDEO_CONFIG_AVCINTRAPERIOD avcIntraPeriod;
+ OMX_ERRORTYPE error_val = OMX_ErrorNone;
+
+ _G_OMX_INIT_PARAM (&avcIntraPeriod);
+ avcIntraPeriod.nPortIndex = omx_base->out_port->port_index;
+ error_val = OMX_GetConfig (g_omx_core_get_handle (omx_base->gomx),
+ OMX_IndexConfigVideoAVCIntraPeriod,
+ (OMX_PTR)&avcIntraPeriod);
+ g_assert (error_val == OMX_ErrorNone);
+ avcIntraPeriod.nPFrames = g_value_get_uint (value);
+
+ if(value>0)
+ {
+ error_val = OMX_SetConfig (g_omx_core_get_handle (omx_base->gomx),
+ OMX_IndexConfigVideoAVCIntraPeriod,
+ &avcIntraPeriod);
+ }
+ g_assert (error_val == OMX_ErrorNone);
+ break;
+ }
+ #else
+ self->i_period = g_value_get_uint (value);
+ break;
+ #endif
+ case ARG_IDR_PERIOD:
+ {
+ self->idr_period = g_value_get_uint (value);
+ break;
+ }
+ case ARG_FORCE_IDR:
+ {
+ self->force_idr = g_value_get_boolean (value);
+ break;
+ }
+ case ARG_ENCODING_PRESET:
+ {
+ #if 0
+ OMX_ERRORTYPE error_val = OMX_ErrorNone;
+ OMX_VIDEO_PARAM_ENCODER_PRESETTYPE tEncoderPreset;
+ _G_OMX_INIT_PARAM(&tEncoderPreset);
+ tEncoderPreset.nPortIndex = omx_base->out_port->port_index;
+
+ error_val =
+ OMX_GetParameter(g_omx_core_get_handle (omx_base->gomx),
+ OMX_TI_IndexParamVideoEncoderPreset,
+ &tEncoderPreset);
+ g_assert (error_val == OMX_ErrorNone);
+
+ tEncoderPreset.eEncodingModePreset = g_value_get_enum (value);
+ error_val = OMX_SetParameter(g_omx_core_get_handle (omx_base->gomx),
+ OMX_TI_IndexParamVideoEncoderPreset,
+ &tEncoderPreset);
+ g_assert (error_val == OMX_ErrorNone);
+ #else
+ self->encodingPreset = g_value_get_enum(value);
+ #endif
+ break;
+ }
+ case ARG_RATECONTROL_PRESET:
+ {
+ #if 0
+ OMX_ERRORTYPE error_val = OMX_ErrorNone;
+ OMX_VIDEO_PARAM_ENCODER_PRESETTYPE tEncoderPreset;
+ _G_OMX_INIT_PARAM(&tEncoderPreset);
+ tEncoderPreset.nPortIndex = omx_base->out_port->port_index;
+
+ error_val =
+ OMX_GetParameter(g_omx_core_get_handle (omx_base->gomx),
+ OMX_TI_IndexParamVideoEncoderPreset,
+ &tEncoderPreset);
+ g_assert (error_val == OMX_ErrorNone);
+
+ tEncoderPreset.eRateControlPreset = g_value_get_enum (value);
+ error_val = OMX_SetParameter(g_omx_core_get_handle (omx_base->gomx),
+ OMX_TI_IndexParamVideoEncoderPreset,
+ &tEncoderPreset);
+ g_assert (error_val == OMX_ErrorNone);
+ #else
+ self->ratecontrolPreset = g_value_get_enum(value);
+ #endif
+ break;
+ }
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
@@ -231,6 +382,7 @@ get_property (GObject *obj,
g_value_set_boolean (value, self->bytestream);
break;
case ARG_PROFILE:
+ #if 0
{
OMX_VIDEO_PARAM_PROFILELEVELTYPE tProfileLevel;
GOmxCore *gomx;
@@ -250,7 +402,12 @@ get_property (GObject *obj,
break;
}
+ #else
+ g_value_set_enum(value, self->profile);
+ break;
+ #endif
case ARG_LEVEL:
+ #if 0
{
OMX_VIDEO_PARAM_PROFILELEVELTYPE tProfileLevel;
GOmxCore *gomx;
@@ -270,6 +427,82 @@ get_property (GObject *obj,
break;
}
+ #else
+ g_value_set_enum(value, self->level);
+ break;
+ #endif
+ case ARG_I_PERIOD:
+ #if 0
+ {
+ OMX_VIDEO_CONFIG_AVCINTRAPERIOD avcIntraPeriod;
+ GOmxCore *gomx;
+
+ gomx = (GOmxCore *) omx_base->gomx;
+ _G_OMX_INIT_PARAM (&avcIntraPeriod);
+ avcIntraPeriod.nPortIndex = omx_base->out_port->port_index;
+ OMX_GetConfig (gomx->omx_handle,
+ OMX_IndexConfigVideoAVCIntraPeriod,
+ &avcIntraPeriod);
+ g_value_set_uint (value, (gint)avcIntraPeriod.nPFrames);
+
+ break;
+ }
+ #else
+ g_value_set_uint(value, self->i_period);
+ break;
+ #endif
+ case ARG_IDR_PERIOD:
+ {
+ g_value_set_uint (value, self->idr_period);
+
+ break;
+ }
+ case ARG_FORCE_IDR:
+ {
+ g_value_set_boolean (value, self->force_idr);
+
+ break;
+ }
+ case ARG_ENCODING_PRESET:
+ {
+ #if 0
+ OMX_VIDEO_PARAM_ENCODER_PRESETTYPE tEncoderPreset;
+ GOmxCore *gomx;
+ OMX_ERRORTYPE error_val = OMX_ErrorNone;
+
+ gomx = (GOmxCore *) omx_base->gomx;
+ error_val = OMX_GetParameter(gomx->omx_handle, OMX_TI_IndexParamVideoEncoderPreset,
+ &tEncoderPreset);
+
+ g_value_set_enum (value, tEncoderPreset.eEncodingModePreset);
+
+ GST_DEBUG_OBJECT (self, "Encoding Preset: param=%d",
+ (gint)tEncoderPreset.eEncodingModePreset);
+ #else
+ g_value_set_enum(value, self->encodingPreset);
+ #endif
+ break;
+ }
+ case ARG_RATECONTROL_PRESET:
+ {
+ #if 0
+ OMX_VIDEO_PARAM_ENCODER_PRESETTYPE tEncoderPreset;
+ GOmxCore *gomx;
+ OMX_ERRORTYPE error_val = OMX_ErrorNone;
+
+ gomx = (GOmxCore *) omx_base->gomx;
+ error_val = OMX_GetParameter(gomx->omx_handle, OMX_TI_IndexParamVideoEncoderPreset,
+ &tEncoderPreset);
+
+ g_value_set_enum (value, tEncoderPreset.eRateControlPreset);
+
+ GST_DEBUG_OBJECT (self, "RateControl Preset: param=%d",
+ (gint)tEncoderPreset.eRateControlPreset);
+ #else
+ g_value_set_enum(value, self->ratecontrolPreset);
+ #endif
+ break;
+ }
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
@@ -304,8 +537,73 @@ type_class_init (gpointer g_class,
GST_TYPE_OMX_VIDEO_AVCLEVELTYPE,
DEFAULT_LEVEL,
G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class, ARG_I_PERIOD,
+ g_param_spec_uint ("i-period", "Specifies periodicity of I frames",
+ "Specifies periodicity of I frames (0:Disable)",
+ 0, G_MAXINT32, 90, G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class, ARG_IDR_PERIOD,
+ g_param_spec_uint ("force-idr-period", "Specifies periodicity of IDR frames",
+ "Specifies periodicity of IDR frames (0:Disable)",
+ 0, G_MAXINT32, 0, G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class, ARG_FORCE_IDR,
+ g_param_spec_boolean ("force-idr", "force-idr", "force next frame to be IDR",
+ FALSE, G_PARAM_WRITABLE));
+ g_object_class_install_property (gobject_class, ARG_ENCODING_PRESET,
+ g_param_spec_enum ("encodingPreset", "Specifies which encoding preset to use",
+ "Specifies which encoding preset to use",
+ GST_TYPE_OMX_VIDEO_ENCODE_PRESETTYPE,
+ DEFAULT_ENCODE_PRESET,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class, ARG_RATECONTROL_PRESET,
+ g_param_spec_enum ("rateControlPreset", "Specifies what rate control preset to use",
+ "Specifies what rate control preset to use",
+ GST_TYPE_OMX_VIDEO_RATECONTROL_PRESETTYPE,
+ DEFAULT_RATECONTROL_PRESET,
+ G_PARAM_READWRITE));
+
+ }
+}
+
+static void
+omx_h264_push_cb (GstOmxBaseFilter *omx_base, GstBuffer *buf)
+{
+ GstOmxH264Enc *self;
+ self = GST_OMX_H264ENC (omx_base);
+ /* Currently we use this logic to handle IDR period since the latest
+ * EZSDK version doesn't have support for OMX_IndexConfigVideoAVCIntraPeriod
+ */
+ if ((self->idr_period > 0) || (self->force_idr))
+ {
+ if ((self->cont == self->idr_period) || (self->force_idr))
+ {
+ OMX_CONFIG_INTRAREFRESHVOPTYPE confIntraRefreshVOP;
+
+ _G_OMX_INIT_PARAM (&confIntraRefreshVOP);
+ confIntraRefreshVOP.nPortIndex = omx_base->out_port->port_index;
+
+ OMX_GetConfig (g_omx_core_get_handle (omx_base->gomx),
+ OMX_IndexConfigVideoIntraVOPRefresh,
+ &confIntraRefreshVOP);
+ confIntraRefreshVOP.IntraRefreshVOP = TRUE;
+
+ OMX_SetConfig (g_omx_core_get_handle (omx_base->gomx),
+ OMX_IndexConfigVideoIntraVOPRefresh,
+ &confIntraRefreshVOP);
+
+ if (self->cont == self->idr_period)
+ self->cont = 0;
+
+ if (self->force_idr)
+ {
+ self->force_idr = FALSE;
+ self->cont++;
+ }
+ } else {
+ self->cont++;
+ }
}
+ GST_BUFFER_CAPS(buf) = gst_caps_ref(GST_PAD_CAPS(omx_base->srcpad));
}
static void
@@ -313,7 +611,9 @@ omx_setup (GstOmxBaseFilter *omx_base)
{
GstOmxBaseVideoEnc *self;
GOmxCore *gomx;
+ GstOmxH264Enc *h264enc;
+ h264enc = GST_OMX_H264ENC (omx_base);
self = GST_OMX_BASE_VIDEOENC (omx_base);
gomx = (GOmxCore *) omx_base->gomx;
@@ -325,9 +625,7 @@ omx_setup (GstOmxBaseFilter *omx_base)
if (OMX_GetExtensionIndex (gomx->omx_handle, "OMX.TI.VideoEncode.Config.NALFormat", &index) == OMX_ErrorNone)
{
OMX_U32 nal_format;
- GstOmxH264Enc *h264enc;
- h264enc = GST_OMX_H264ENC (omx_base);
nal_format = h264enc->bytestream ? 0 : 1;
GST_DEBUG_OBJECT (omx_base, "setting 'OMX.TI.VideoEncode.Config.NALFormat' to %ld", nal_format);
@@ -339,6 +637,36 @@ omx_setup (GstOmxBaseFilter *omx_base)
}
}
+ {
+ OMX_VIDEO_PARAM_AVCTYPE tAVCParams;
+
+ _G_OMX_INIT_PARAM (&tAVCParams);
+
+ tAVCParams.nPortIndex = OMX_DirOutput;
+ OMX_GetParameter(gomx->omx_handle, OMX_IndexParamVideoAvc, &tAVCParams);
+
+ tAVCParams.eLevel = h264enc->level;
+ tAVCParams.eProfile = h264enc->profile;
+ tAVCParams.nPFrames = h264enc->i_period - 1;
+ tAVCParams.nBFrames = 0;
+
+ OMX_SetParameter(gomx->omx_handle, OMX_IndexParamVideoAvc, &tAVCParams);
+ }
+
+ {
+ OMX_VIDEO_PARAM_ENCODER_PRESETTYPE tEncoderPreset;
+
+ _G_OMX_INIT_PARAM(&tEncoderPreset);
+ tEncoderPreset.nPortIndex = omx_base->out_port->port_index;
+
+ OMX_GetParameter(gomx->omx_handle, OMX_TI_IndexParamVideoEncoderPreset, &tEncoderPreset);
+
+ tEncoderPreset.eEncodingModePreset = h264enc->encodingPreset;
+ tEncoderPreset.eRateControlPreset = h264enc->ratecontrolPreset;
+
+ OMX_SetParameter(gomx->omx_handle, OMX_TI_IndexParamVideoEncoderPreset, &tEncoderPreset);
+ }
+
GST_INFO_OBJECT (omx_base, "end");
}
@@ -371,6 +699,8 @@ settings_changed_cb (GOmxCore *core)
"height", G_TYPE_INT, height,
"framerate", GST_TYPE_FRACTION,
omx_base->framerate_num, omx_base->framerate_denom,
+ "stream-format", G_TYPE_STRING, "byte-stream",
+ "alignment", G_TYPE_STRING, "au",
NULL);
GST_INFO_OBJECT (omx_base, "caps are: %" GST_PTR_FORMAT, new_caps);
@@ -384,13 +714,29 @@ type_instance_init (GTypeInstance *instance,
{
GstOmxBaseFilter *omx_base_filter;
GstOmxBaseVideoEnc *omx_base;
+ GstOmxBaseFilterClass *bclass;
+ GstOmxH264Enc *self;
omx_base_filter = GST_OMX_BASE_FILTER (instance);
omx_base = GST_OMX_BASE_VIDEOENC (instance);
+ self = GST_OMX_H264ENC (instance);
+ bclass = GST_OMX_BASE_FILTER_CLASS (g_class);
omx_base->omx_setup = omx_setup;
+ omx_base_filter->push_cb = omx_h264_push_cb;
+
omx_base->compression_format = OMX_VIDEO_CodingAVC;
omx_base_filter->gomx->settings_changed_cb = settings_changed_cb;
+
+ self->idr_period = 0;
+ self->cont = 0;
+ self->force_idr = FALSE;
+
+ self->i_period = 90;
+ self->profile = DEFAULT_PROFILE;
+ self->level = DEFAULT_LEVEL;
+ self->encodingPreset = OMX_Video_Enc_High_Speed_Med_Quality;
+ self->ratecontrolPreset = OMX_Video_RC_Low_Delay;
}
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_h264enc.h b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_h264enc.h
index 9066092..a1966c0 100644
--- a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_h264enc.h
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_h264enc.h
@@ -38,6 +38,14 @@ struct GstOmxH264Enc
{
GstOmxBaseVideoEnc omx_base;
gboolean bytestream;
+ gint idr_period;
+ gint force_idr;
+ OMX_VIDEO_AVCPROFILETYPE profile;
+ OMX_VIDEO_AVCLEVELTYPE level;
+ gint i_period;
+ OMX_VIDEO_ENCODING_MODE_PRESETTYPE encodingPreset;
+ OMX_VIDEO_RATECONTROL_PRESETTYPE ratecontrolPreset;
+ gint cont;
};
struct GstOmxH264EncClass
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_mjpegdec.c b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_mjpegdec.c
new file mode 100755
index 0000000..0e3cf6c
--- /dev/null
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_mjpegdec.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2007-2009 Nokia Corporation.
+ *
+ * Author: Felipe Contreras <felipe.contreras@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "gstomx_mjpegdec.h"
+#include "gstomx.h"
+
+GSTOMX_BOILERPLATE (GstOmxMJPEGDec, gst_omx_mjpegdec, GstOmxBaseVideoDec, GST_OMX_BASE_VIDEODEC_TYPE);
+
+static GstCaps *
+generate_sink_template (void)
+{
+ GstCaps *caps;
+ GstStructure *struc;
+
+ caps = gst_caps_new_empty ();
+
+/*
+image/jpeg
+format: { I420, Y41B, UYVY, YV12 }
+width: [ 0, 2147483647 ]
+height: [ 0, 2147483647 ]
+interlaced: { true, false }
+framerate: [ 0/1, 2147483647/1 ]
+parsed: true
+*/
+ struc = gst_structure_new ("image/jpeg",
+ "width", GST_TYPE_INT_RANGE, 16, 4096,
+ "height", GST_TYPE_INT_RANGE, 16, 4096,
+ "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1,
+ NULL);
+
+ gst_caps_append_structure (caps, struc);
+
+ return caps;
+}
+
+static void
+type_base_init (gpointer g_class)
+{
+ GstElementClass *element_class;
+
+ element_class = GST_ELEMENT_CLASS (g_class);
+
+ {
+ GstElementDetails details;
+
+ details.longname = "OpenMAX IL JPEG/MJPEG decoder";
+ details.klass = "Codec/Decoder/Video";
+ details.description = "Decodes video/images in MJPEG/JPEG format with OpenMAX IL";
+ details.author = "Felipe Contreras";
+
+ gst_element_class_set_details (element_class, &details);
+ }
+
+ {
+ GstPadTemplate *template;
+
+ template = gst_pad_template_new ("sink", GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ generate_sink_template ());
+
+ gst_element_class_add_pad_template (element_class, template);
+ }
+}
+
+static void
+type_class_init (gpointer g_class,
+ gpointer class_data)
+{
+}
+
+static void
+initialize_port (GstOmxBaseFilter *omx_base)
+{
+ GstOmxBaseVideoDec *self;
+ GOmxCore *gomx;
+ OMX_PARAM_PORTDEFINITIONTYPE paramPort;
+ gint width, height;
+ GOmxPort *port;
+
+ self = GST_OMX_BASE_VIDEODEC (omx_base);
+ gomx = (GOmxCore *) omx_base->gomx;
+
+ GST_INFO_OBJECT (omx_base, "begin");
+
+ GST_DEBUG_OBJECT (self, "G_OMX_PORT_GET_DEFINITION (output)");
+ G_OMX_PORT_GET_DEFINITION (omx_base->out_port, &paramPort);
+
+ width = self->extendedParams.width;
+ height = self->extendedParams.height;
+
+ paramPort.nPortIndex = 1;
+ paramPort.nBufferCountActual = 20;//15;//output_buffer_count
+ paramPort.format.video.nFrameWidth = width;
+ paramPort.format.video.nFrameHeight = height;
+ paramPort.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+ paramPort.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+ paramPort.format.video.xFramerate = (60) << 16;
+
+ GST_DEBUG_OBJECT (self, "nFrameWidth = %ld, nFrameHeight = %ld, nBufferCountActual = %ld",
+ paramPort.format.video.nFrameWidth, paramPort.format.video.nFrameHeight,
+ paramPort.nBufferCountActual);
+
+ GST_DEBUG_OBJECT (self, "G_OMX_PORT_SET_DEFINITION (output)");
+ G_OMX_PORT_SET_DEFINITION (omx_base->out_port, &paramPort);
+
+ G_OMX_PORT_GET_DEFINITION (omx_base->in_port, &paramPort);
+ //paramPort.nBufferCountActual = 8;
+ paramPort.format.video.xFramerate = (60) << 16;
+ G_OMX_PORT_SET_DEFINITION (omx_base->in_port, &paramPort);
+#if 1
+ port = g_omx_core_get_port (gomx, "input", 0);
+
+ GST_DEBUG_OBJECT(self, "SendCommand(PortEnable, %d)", port->port_index);
+ OMX_SendCommand (g_omx_core_get_handle (port->core),
+ OMX_CommandPortEnable, port->port_index, NULL);
+ g_sem_down (port->core->port_sem);
+
+ port = g_omx_core_get_port (gomx, "output", 1);
+
+ GST_DEBUG_OBJECT(self, "SendCommand(PortEnable, %d)", port->port_index);
+ OMX_SendCommand (g_omx_core_get_handle (port->core),
+ OMX_CommandPortEnable, port->port_index, NULL);
+ g_sem_down (port->core->port_sem);
+#endif
+ GST_INFO_OBJECT (omx_base, "end");
+}
+
+static void
+type_instance_init (GTypeInstance *instance,
+ gpointer g_class)
+{
+ GstOmxBaseVideoDec *omx_base;
+
+ omx_base = GST_OMX_BASE_VIDEODEC (instance);
+
+ omx_base->compression_format = OMX_VIDEO_CodingMJPEG;
+ omx_base->initialize_port = initialize_port;
+}
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_mjpegdec.h b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_mjpegdec.h
new file mode 100644
index 0000000..63a99b7
--- /dev/null
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_mjpegdec.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2007-2009 Nokia Corporation.
+ *
+ * Author: Felipe Contreras <felipe.contreras@nokia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifndef GSTOMX_MJPEGDEC_H
+#define GSTOMX_MJPEGDEC_H
+
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+
+#define GST_OMX_MJPEGDEC(obj) (GstOmxMJPEGDec *) (obj)
+#define GST_OMX_MJPEGDEC_TYPE (gst_omx_mjpegdec_get_type ())
+
+typedef struct GstOmxMJPEGDec GstOmxMJPEGDec;
+typedef struct GstOmxMJPEGDecClass GstOmxMJPEGDecClass;
+
+#include "gstomx_base_videodec.h"
+
+struct GstOmxMJPEGDec
+{
+ GstOmxBaseVideoDec omx_base;
+};
+
+struct GstOmxMJPEGDecClass
+{
+ GstOmxBaseVideoDecClass parent_class;
+};
+
+GType gst_omx_mjpegdec_get_type (void);
+
+G_END_DECLS
+
+#endif /* GSTOMX_MJPEGDEC_H */
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_mpeg2dec.c b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_mpeg2dec.c
index 15c5071..8e6c35c 100755
--- a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_mpeg2dec.c
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_mpeg2dec.c
@@ -232,7 +232,7 @@ initialize_port (GstOmxBaseFilter *omx_base)
pOutPortDef.nBufferAlignment = 0x0;
/* OMX_VIDEO_PORTDEFINITION values for output port */
- pOutPortDef.format.video.cMIMEType = "H264";
+ pOutPortDef.format.video.cMIMEType = "MPEG2";
pOutPortDef.format.video.pNativeRender = NULL;
pOutPortDef.format.video.nFrameWidth = width;
pOutPortDef.format.video.nFrameHeight = height;
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_port.c b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_port.c
index 47aa8e2..f4c04b5 100755
--- a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_port.c
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_port.c
@@ -69,6 +69,7 @@ g_omx_port_new (GOmxCore *core, const gchar *name, guint index)
port->enabled = TRUE;
port->queue = async_queue_new ();
port->mutex = g_mutex_new ();
+ port->cond = g_cond_new();
port->ignore_count = 0;
port->n_offset = 0;
@@ -83,6 +84,7 @@ g_omx_port_free (GOmxPort *port)
DEBUG (port, "begin");
g_mutex_free (port->mutex);
+ g_cond_free(port->cond);
async_queue_free (port->queue);
g_free (port->name);
@@ -240,7 +242,7 @@ g_omx_port_allocate_buffers (GOmxPort *port)
if (!port->always_copy)
{
- buffer_data = port->share_buffer_info->pBuffer[i];
+ buffer_data = port->share_buffer_info->pBuffer[i];
}
else if (! port->share_buffer)
{
@@ -333,7 +335,7 @@ g_omx_port_start_buffers (GOmxPort *port)
* the queue, otherwise send to omx for processing (fill it up). */
if (port->type == GOMX_PORT_INPUT)
{
- if (port->always_copy)
+ /*if (port->always_copy)*/
g_omx_core_got_buffer (port->core, port, omx_buffer);
}
else
@@ -355,11 +357,14 @@ g_omx_port_push_buffer (GOmxPort *port,
/* Avoid a race condition of pAppPrivate getting set to null
after the buffer is submitted back again */
OMX_PTR appPrivate = omx_buffer->pAppPrivate;
- omx_buffer->pAppPrivate = NULL;
- gst_buffer_unref (appPrivate);
- }
-
- async_queue_push (port->queue, omx_buffer);
+ //omx_buffer->pAppPrivate = NULL;
+ g_mutex_lock(port->mutex);
+ GST_BUFFER_FLAG_UNSET(appPrivate,GST_BUFFER_FLAG_BUSY);
+ gst_buffer_unref (appPrivate);
+ g_cond_signal(port->cond);
+ g_mutex_unlock(port->mutex);
+ } else
+ async_queue_push (port->queue, omx_buffer);
}
static gint
@@ -724,7 +729,7 @@ send_prep_eos_event (GOmxPort *port, OMX_BUFFERHEADERTYPE *omx_buffer, GstEvent
static OMX_BUFFERHEADERTYPE *
get_input_buffer_header (GOmxPort *port, GstBuffer *src)
{
- OMX_BUFFERHEADERTYPE *omx_buffer;
+ OMX_BUFFERHEADERTYPE *omx_buffer,*tmp;
int index;
index = omxbuffer_index(port, GST_BUFFER_DATA (src));
@@ -732,7 +737,11 @@ get_input_buffer_header (GOmxPort *port, GstBuffer *src)
omx_buffer = port->buffers[index];
omx_buffer->pBuffer = GST_BUFFER_DATA(src);
- omx_buffer->nOffset = GST_GET_OMXBUFFER(src)->nOffset;
+ tmp = GST_GET_OMXBUFFER(src);
+ if(tmp)
+ omx_buffer->nOffset = tmp->nOffset;
+ else
+ omx_buffer->nOffset = 0;
omx_buffer->nFilledLen = GST_BUFFER_SIZE (src);
omx_buffer->pAppPrivate = gst_buffer_ref (src);
@@ -740,6 +749,60 @@ get_input_buffer_header (GOmxPort *port, GstBuffer *src)
}
/**
+ * Sends a buffer to the OMX component 2-fields separately
+ */
+gint g_omx_port_send_interlaced_fields(GOmxPort *port, GstBuffer *buf, gint second_field_offset)
+{
+ OMX_BUFFERHEADERTYPE *out1, *out2, *in, *first, *second;
+ gint ret;
+ OMX_U8 *pBuffer;
+ int index;
+
+ if (G_UNLIKELY((!GST_IS_OMXBUFFERTRANSPORT (buf)) || port->always_copy)) {
+ GST_ERROR_OBJECT(port->core->object,"Unexpected !!\n");
+ return -1; /* something went wrong */
+ }
+
+ in = GST_GET_OMXBUFFER(buf);
+
+ pBuffer = GST_BUFFER_DATA(buf);
+ index = omxbuffer_index(port, pBuffer);
+ out1 = port->buffers[index];
+ index = omxbuffer_index(port, pBuffer + second_field_offset);
+ out2 = port->buffers[index];
+
+ out1->pBuffer = pBuffer;
+ out2->pBuffer = out1->pBuffer + second_field_offset;
+ out1->nOffset = out2->nOffset = in->nOffset;
+ out1->nFlags = OMX_TI_BUFFERFLAG_VIDEO_FRAME_TYPE_INTERLACE;
+ out2->nFlags = out1->nFlags | OMX_TI_BUFFERFLAG_VIDEO_FRAME_TYPE_INTERLACE_BOTTOM;
+ ret = out1->nFilledLen = in->nFilledLen;
+ out2->nFilledLen = (((in->nFilledLen + in->nOffset) *3) >> 2) - in->nOffset;
+ out1->pAppPrivate = gst_buffer_ref(buf);
+ out2->pAppPrivate = gst_buffer_ref(buf);
+
+ if (in->nFlags & OMX_TI_BUFFERFLAG_VIDEO_FRAME_TYPE_INTERLACE_TOP_FIRST) {
+ first = out1; second = out2; }
+ else { first = out2; second = out1; }
+
+ if (port->core->use_timestamps) {
+ if (GST_CLOCK_TIME_NONE != GST_BUFFER_TIMESTAMP (buf)) {
+ first->nTimeStamp = gst_util_uint64_scale_int (
+ GST_BUFFER_TIMESTAMP (buf),
+ OMX_TICKS_PER_SECOND, GST_SECOND);
+ } else {
+ first->nTimeStamp = (OMX_TICKS)-1;
+ }
+ }
+ // Timestamp for the second field comes from adding duration to the
+ // First field timestamp
+ second->nTimeStamp = (OMX_TICKS)-1;
+ release_buffer (port, first);
+ release_buffer (port, second);
+ return ret;
+}
+
+/**
* Send a buffer/event to the OMX component. This handles conversion of
* GST buffer, codec-data, and EOS events to the equivalent OMX buffer.
*
@@ -750,103 +813,102 @@ get_input_buffer_header (GOmxPort *port, GstBuffer *src)
gint
g_omx_port_send (GOmxPort *port, gpointer obj)
{
-
- SendPrep send_prep = NULL;
-
- g_return_val_if_fail (port->type == GOMX_PORT_INPUT, -1);
+ SendPrep send_prep = NULL;
- GstOmxBaseVideoDec *self = GST_OMX_BASE_VIDEODEC (port->core->object);;
-
- if (GST_IS_BUFFER (obj))
- {
- if(self->compression_format == OMX_VIDEO_CodingWMV)
- {
-
- if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (obj, GST_BUFFER_FLAG_IN_CAPS)))
- send_prep = (SendPrep)send_prep_wmv_codec_data;
- else
- send_prep = (SendPrep)send_prep_wmv_buffer_data;
- }
+ g_return_val_if_fail (port->type == GOMX_PORT_INPUT, -1);
+
+
+ GstOmxBaseVideoDec *self = GST_OMX_BASE_VIDEODEC (port->core->object);;
+
+ if (GST_IS_BUFFER (obj))
+ {
+ if(self->compression_format == OMX_VIDEO_CodingWMV)
+ {
+
+ if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (obj, GST_BUFFER_FLAG_IN_CAPS)))
+ send_prep = (SendPrep)send_prep_wmv_codec_data;
+ else
+ send_prep = (SendPrep)send_prep_wmv_buffer_data;
+ }
else
if(self->compression_format == OMX_VIDEO_CodingMPEG4)
+ {
+
+ if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (obj, GST_BUFFER_FLAG_IN_CAPS)))
+ send_prep = (SendPrep)send_prep_wmv_codec_data;
+ else
+ send_prep = (SendPrep)send_prep_mpeg4_buffer_data;
+ }
+ else
+ {
+ if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (obj, GST_BUFFER_FLAG_IN_CAPS)))
+ send_prep = (SendPrep)send_prep_codec_data;
+ else
+ send_prep = (SendPrep)send_prep_buffer_data;
+ }
+ }
+ else if (GST_IS_EVENT (obj))
{
-
- if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (obj, GST_BUFFER_FLAG_IN_CAPS)))
- send_prep = (SendPrep)send_prep_wmv_codec_data;
- else
- send_prep = (SendPrep)send_prep_mpeg4_buffer_data;
+ if (G_LIKELY (GST_EVENT_TYPE (obj) == GST_EVENT_EOS))
+ send_prep = (SendPrep)send_prep_eos_event;
}
- else
- {
- if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (obj, GST_BUFFER_FLAG_IN_CAPS)))
- send_prep = (SendPrep)send_prep_codec_data;
- else
- send_prep = (SendPrep)send_prep_buffer_data;
- }
- }
- else if (GST_IS_EVENT (obj))
- {
- if (G_LIKELY (GST_EVENT_TYPE (obj) == GST_EVENT_EOS))
- send_prep = (SendPrep)send_prep_eos_event;
- }
- if (G_LIKELY (send_prep))
- {
- gint ret;
- OMX_BUFFERHEADERTYPE *omx_buffer = NULL;
+ if (G_LIKELY (send_prep))
+ {
+ gint ret;
+ OMX_BUFFERHEADERTYPE *omx_buffer = NULL;
- if (port->always_copy)
- {
-
- omx_buffer = request_buffer (port);
- if (!omx_buffer)
- {
- DEBUG (port, "null buffer");
- return -1;
- }
+ if (port->always_copy)
+ {
- /* don't assume OMX component clears flags!
- */
- omx_buffer->nFlags = 0;
+ omx_buffer = request_buffer (port);
+ if (!omx_buffer)
+ {
+ DEBUG (port, "null buffer");
+ return -1;
+ }
- /* if buffer sharing is enabled, pAppPrivate might hold the ref to
- * a buffer that is no longer required and should be unref'd. We
- * do this check here, rather than in send_prep_buffer_data() so
- * we don't keep the reference live in case, for example, this time
- * the buffer is used for an EOS event.
- */
- if (omx_buffer->pAppPrivate)
- {
- GstBuffer *old_buf = omx_buffer->pAppPrivate;
- gst_buffer_unref (old_buf);
- omx_buffer->pAppPrivate = NULL;
- omx_buffer->pBuffer = NULL; /* just to ease debugging */
- }
- }
- else
- {
-
- if (GST_IS_OMXBUFFERTRANSPORT (obj))
- omx_buffer = get_input_buffer_header (port, obj);
- else if(GST_IS_EVENT (obj) && (GST_EVENT_TYPE (obj) == GST_EVENT_EOS)) {
- omx_buffer = port->buffers[0];
- }
- else {
- GST_ERROR_OBJECT(port->core->object,"something went wrong!!\n");
- return -1; /* something went wrong */
- }
- }
+ /* don't assume OMX component clears flags!
+ */
+ omx_buffer->nFlags = 0;
+
+ /* if buffer sharing is enabled, pAppPrivate might hold the ref to
+ * a buffer that is no longer required and should be unref'd. We
+ * do this check here, rather than in send_prep_buffer_data() so
+ * we don't keep the reference live in case, for example, this time
+ * the buffer is used for an EOS event.
+ */
+ if (omx_buffer->pAppPrivate)
+ {
+ GstBuffer *old_buf = omx_buffer->pAppPrivate;
+ gst_buffer_unref (old_buf);
+ omx_buffer->pAppPrivate = NULL;
+ omx_buffer->pBuffer = NULL; /* just to ease debugging */
+ }
+ }
+ else
+ {
+ if (GST_IS_OMXBUFFERTRANSPORT (obj))
+ omx_buffer = get_input_buffer_header (port, obj);
+ else if(GST_IS_EVENT (obj) && (GST_EVENT_TYPE (obj) == GST_EVENT_EOS)) {
+ omx_buffer = port->buffers[0];
+ }
+ else {
+ GST_ERROR_OBJECT(port->core->object,"something went wrong!!\n");
+ return -1; /* something went wrong */
+ }
+ }
- send_prep (port, omx_buffer, obj);
+ send_prep (port, omx_buffer, obj);
- ret = omx_buffer->nFilledLen;
- release_buffer (port, omx_buffer);
- return ret;
- }
-
- WARNING (port, "unknown obj type");
- return -1;
+ ret = omx_buffer->nFilledLen;
+ release_buffer (port, omx_buffer);
+ return ret;
+ }
+
+ WARNING (port, "unknown obj type");
+ return -1;
}
/**
@@ -999,7 +1061,7 @@ g_omx_port_recv (GOmxPort *port)
#endif
{
setup_shared_buffer (port, omx_buffer);
- if (port->always_copy)
+ if ((NULL == ret) || port->always_copy)
release_buffer (port, omx_buffer);
}
}
@@ -1037,7 +1099,7 @@ g_omx_port_flush (GOmxPort *port)
{
omx_buffer->nFilledLen = 0;
-#ifdef USE_OMXTICORE
+#if 0
if (omx_buffer->nFlags & OMX_TI_BUFFERFLAG_READONLY)
{
/* For output buffer that is marked with READONLY, we
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_port.h b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_port.h
index e1ad8a9..563c70d 100644
--- a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_port.h
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_port.h
@@ -30,6 +30,8 @@
G_BEGIN_DECLS
+#define GST_BUFFER_FLAG_BUSY (GST_BUFFER_FLAG_LAST << 1)
+
/* Typedefs. */
typedef enum GOmxPortType GOmxPortType;
@@ -88,6 +90,8 @@ struct GOmxPort
/** if omx_allocate flag is not set then structure will contain upstream omx buffer pointer information */
OmxBufferInfo *share_buffer_info;
+
+ GCond *cond;
};
/* Macros. */
@@ -138,6 +142,7 @@ void g_omx_port_finish (GOmxPort *port);
void g_omx_port_push_buffer (GOmxPort *port, OMX_BUFFERHEADERTYPE *omx_buffer);
gint g_omx_port_send (GOmxPort *port, gpointer obj);
gpointer g_omx_port_recv (GOmxPort *port);
+gint g_omx_port_send_interlaced_fields(GOmxPort *port, GstBuffer *buf, gint second_field_offset);
/*
* Some domain specific port related utility functions:
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_scaler.c b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_scaler.c
index 33e3cff..67488e2 100644
--- a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_scaler.c
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_scaler.c
@@ -75,7 +75,7 @@ create_src_caps (GstOmxBaseFilter *omx_base)
self = GST_OMX_BASE_VFPC (omx_base);
caps = gst_pad_peer_get_caps (omx_base->srcpad);
- if (gst_caps_is_empty (caps))
+ if (NULL == caps || gst_caps_is_empty (caps))
{
width = self->in_width;
height = self->in_height;
@@ -93,6 +93,8 @@ create_src_caps (GstOmxBaseFilter *omx_base)
height = self->in_height;
}
}
+ /* Workaround: Make width multiple of 16, otherwise, scaler crashes */
+ width = (width+15) & 0xFFFFFFF0;
caps = gst_caps_new_empty ();
struc = gst_structure_new (("video/x-raw-yuv"),
@@ -218,10 +220,10 @@ omx_setup (GstOmxBaseFilter *omx_base)
chResolution.Frm1Width = 0;
chResolution.Frm1Height = 0;
chResolution.Frm1Pitch = 0;
- chResolution.FrmStartX = 0;//self->left;
- chResolution.FrmStartY = 0;//self->top;
- chResolution.FrmCropWidth = 0;//self->in_width - self->left;
- chResolution.FrmCropHeight = 0;//self->in_height - self->top;
+ chResolution.FrmStartX = 0;
+ chResolution.FrmStartY = 0;
+ chResolution.FrmCropWidth = 0;
+ chResolution.FrmCropHeight = 0;
chResolution.eDir = OMX_DirInput;
chResolution.nChId = 0;
err = OMX_SetConfig (gomx->omx_handle, OMX_TI_IndexConfigVidChResolution, &chResolution);
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_util.h b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_util.h
index 88dc0f1..453c407 100644
--- a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_util.h
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_util.h
@@ -99,7 +99,7 @@ static void type_base_init (gpointer g_class); \
static void type_class_init (gpointer g_class, gpointer class_data); \
static void type_instance_init (GTypeInstance *instance, gpointer g_class); \
static parent_type ## Class *parent_class; \
-static void type_class_init_trampoline (gpointer g_class, gpointer class_data)\
+static void type_class_init_trampoline ## type (gpointer g_class, gpointer class_data)\
{ \
parent_class = g_type_class_ref (parent_type_macro); \
type_class_init (g_class, class_data); \
@@ -116,7 +116,7 @@ GType type_as_function ## _get_type (void) \
type_info = g_new0 (GTypeInfo, 1); \
type_info->class_size = sizeof (type ## Class); \
type_info->base_init = type_base_init; \
- type_info->class_init = type_class_init_trampoline; \
+ type_info->class_init = type_class_init_trampoline ## type; \
type_info->instance_size = sizeof (type); \
type_info->instance_init = type_instance_init; \
_type = g_type_register_static (parent_type_macro, #type, type_info, 0);\
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_videomixer.c b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_videomixer.c
index 023a428..8fbab64 100755
--- a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_videomixer.c
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_videomixer.c
@@ -34,6 +34,7 @@ enum
ARG_NUM_INPUT_BUFFERS,
ARG_NUM_OUTPUT_BUFFERS,
ARG_PORT_INDEX,
+ ARG_FRAME_RATE
};
static void init_interfaces (GType type);
@@ -191,10 +192,12 @@ change_state (GstElement *element,
g_omx_port_finish (self->in_port[ii]);
g_omx_port_finish (self->out_port[ii]);
}
+ //printf("setting EOS to true\n");
+ self->eos = TRUE;
for(ii = 0; ii < NUM_PORTS; ii++)
async_queue_disable (self->chInfo[ii].queue);
-
- // printf("Waiting for ip thread to exit!!\n");
+ //printf("Waiting for ip thread to exit..semup!!\n");
+ g_sem_up(self->bufferSem);
pthread_join(self->input_loop, &thread_ret);
for(ii = 0; ii < NUM_PORTS; ii++)
@@ -303,6 +306,9 @@ set_property (GObject *obj,
if (!self->port_configured)
//gstomx_vfpc_set_port_index (obj, self->port_index);
break;
+ case ARG_FRAME_RATE:
+ self->framerate_num = g_value_get_uint (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
@@ -338,7 +344,7 @@ get_property (GObject *obj,
{
OMX_PARAM_PORTDEFINITIONTYPE param;
GOmxPort *port = (prop_id == ARG_NUM_INPUT_BUFFERS) ?
- self->in_port : self->out_port;
+ self->in_port[0] : self->out_port[0];
G_OMX_PORT_GET_DEFINITION (port, &param);
@@ -440,6 +446,11 @@ type_class_init (gpointer g_class,
g_param_spec_uint ("port-index", "port index",
"input/output start port index",
0, 8, 0, G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class, ARG_FRAME_RATE,
+ g_param_spec_uint ("framerate", "Frame Rate",
+ "The rate at which the mixer ocmponent would operate",
+ 1, 60, 15, G_PARAM_WRITABLE));
}
}
@@ -721,7 +732,7 @@ vidmix_port_recv (GstOmxVideoMixer *self)
omx_bufferHdr[ii-1] = NULL;
continue;
}
- //printf("Request buffer:%d!!\n",ii);
+ // printf("Request buffer:%d!!\n",ii);
omx_buffer1 = request_buffer (port);
//printf("got buffer:%d!!\n",ii);
@@ -755,13 +766,16 @@ vidmix_port_recv (GstOmxVideoMixer *self)
GST_BUFFER_SIZE(buf) = GST_BUFFER_SIZE(buf)*2;
if (port->core->use_timestamps)
{
- GST_BUFFER_TIMESTAMP (buf) = gst_util_uint64_scale_int (
+ /*GST_BUFFER_TIMESTAMP (buf) = gst_util_uint64_scale_int (
omx_buffer->nTimeStamp,
- GST_SECOND, OMX_TICKS_PER_SECOND);
+ GST_SECOND, OMX_TICKS_PER_SECOND);*/
+ GST_BUFFER_TIMESTAMP (buf) = self->timestamp;
+ GST_BUFFER_DURATION (buf) = self->duration;
+ self->timestamp += self->duration;
}
gst_omxbuffertransport_set_additional_headers (buf ,NUM_PORTS -1,&omx_bufferHdr);
-
+ gst_omxbuffertransport_set_bufsem (buf ,self->bufferSem);
port->n_offset = omx_buffer->nOffset;
ret = buf;
@@ -810,6 +824,10 @@ output_loop (gpointer data)
{
GstBuffer *buf = GST_BUFFER (obj);
+ /*printf("push : %"
+ GST_TIME_FORMAT ", duration: %" GST_TIME_FORMAT"\n",
+ GST_TIME_ARGS (GST_BUFFER_TIMESTAMP(buf)),
+ GST_TIME_ARGS (GST_BUFFER_DURATION(buf)));*/
ret = bclass->push_buffer (self, buf);
GST_DEBUG_OBJECT (self, "ret=%s", gst_flow_get_name (ret));
@@ -986,7 +1004,7 @@ vidmix_port_allocate_buffers (GstOmxVideoMixer *self)
size = param.nBufferSize;
port->buffers = g_new0 (OMX_BUFFERHEADERTYPE *, port->num_buffers);
-
+ printf("Input num bufffers:%d\n",port->num_buffers);
for (i = 0; i < port->num_buffers; i++)
{
gpointer buffer_data = NULL;
@@ -1039,6 +1057,7 @@ vidmix_port_allocate_buffers (GstOmxVideoMixer *self)
g_return_if_fail (port->buffers[i]);
//printf("allocated buffer:%p\n",port->buffers[i]->pBuffer);
}
+ self->bufferSem = g_sem_new_with_value(port->num_buffers);
}else {
G_OMX_PORT_GET_DEFINITION (port, &param);
size = param.nBufferSize;
@@ -1105,6 +1124,9 @@ static void* vidmix_input_loop(void *arg) {
GOmxCore *gomx;
int kk=0;
gint sent;
+ struct timeval tv;
+ guint64 afttime;
+ guint64 beftime;
port = self->in_port[0];
gomx = port->core;
@@ -1122,9 +1144,9 @@ static void* vidmix_input_loop(void *arg) {
scaler_setup(self);
- //printf("calline prepare!!\n");
+ printf("calline prepare!!\n");
videomixer_prepare (self,self->gomx);
- //printf("calline prepare returned!!\n");
+ printf("calline prepare returned!!\n");
if (gomx->omx_state == OMX_StateIdle)
{
@@ -1160,32 +1182,74 @@ static void* vidmix_input_loop(void *arg) {
{
printf("port not ennabled!!\n");
}
-
+ //printf("Init done!!\n");
while(TRUE) {
+ OMX_BUFFERHEADERTYPE *omx_buffer;
+ //printf("sem cnt:%d\n",self->bufferSem->counter);
+
+ /*gettimeofday(&tv, NULL);
+ beftime = (tv.tv_sec * 1000000 + tv.tv_usec);*/
+ g_sem_down(self->bufferSem);
+ /*gettimeofday(&tv, NULL);
+ afttime = (tv.tv_sec * 1000000 + tv.tv_usec);
+ printf("Wait:%lld\n",(afttime-beftime));*/
for(ii = 0; ii < NUM_PORTS; ii++) {
port = self->in_port[ii];
gomx = port->core;
buf = NULL;
//printf("pop queue:%d\n",ii);
if(self->chInfo[ii].eos == FALSE) {
- buf = (GstBuffer *)async_queue_pop_full(self->chInfo[ii].queue,TRUE,FALSE);
+ //printf("force is FALSE\n");
+ buf = (GstBuffer *)async_queue_pop_full(self->chInfo[ii].queue,FALSE,FALSE);
if(buf == NULL) {
+
+ if(self->eos == TRUE) {
+ printf("goto leave!!\n");
+ goto leave;
+ }
+
//printf("NULL buffer...ip exiting!!\n");
- goto leave;
+ //printf("reuse:%d, buffer:%p!!\n",ii,self->chInfo[ii].lastBuf);
+ //buf = gst_buffer_ref(self->chInfo[ii].lastBuf);
+ //omx_buffer = GST_GET_OMXBUFFER(self->chInfo[ii].lastBuf);
+ g_mutex_lock(port->mutex);
+ //printf("wait:%d,buffer:%p\n",ii,self->chInfo[ii].lastBuf);
+ while(GST_BUFFER_FLAG_IS_SET(self->chInfo[ii].lastBuf,GST_BUFFER_FLAG_BUSY))
+ g_cond_wait(port->cond,port->mutex);
+ //printf("wait done:%d\n",ii);
+ g_mutex_unlock(port->mutex);
+
+ buf = (self->chInfo[ii].lastBuf);
+ //goto leave;
+ }else {
+ if(self->chInfo[ii].lastBuf) {
+ //printf("unref buffer:%p, refcnt:%d!!\n",self->chInfo[ii].lastBuf,GST_MINI_OBJECT_CAST(self->chInfo[ii].lastBuf)->refcount);
+ gst_buffer_unref(self->chInfo[ii].lastBuf);
+ }
+ //self->chInfo[ii].lastBuf = gst_buffer_ref(buf);
+ self->chInfo[ii].lastBuf = buf;
}
+
+ /*omx_buffer = GST_GET_OMXBUFFER(buf);
+ omx_buffer->nFlags |= OMX_BUFFERFLAG_BUSY;*/
//printf("send: %d:%p!!\n",ii,buf);
+ GST_BUFFER_FLAG_SET(buf,GST_BUFFER_FLAG_BUSY);
sent = g_omx_port_send (port, buf);
- gst_buffer_unref (buf);
+ //gst_buffer_unref (buf);
}
-
+ //sched_yield();
}
}
leave:
- //printf("leaving ip thread!!\n");
+ printf("leaving ip thread!!\n");
+ for(ii = 0; ii < NUM_PORTS; ii++)
+ if(self->chInfo[ii].lastBuf)
+ gst_buffer_unref(self->chInfo[ii].lastBuf);
+
return NULL;
}
@@ -1208,7 +1272,7 @@ pad_chain (GstPad *pad,
return ret;
}
PRINT_BUFFER (self, buf);
- //printf("ip for channel %d\n",ch_info->idx);
+ // printf("ip for channel %d\n",ch_info->idx);
gomx = self->gomx;
GST_LOG_OBJECT (self, "begin: size=%u, state=%d", GST_BUFFER_SIZE (buf), gomx->omx_state);
@@ -1229,7 +1293,7 @@ pad_chain (GstPad *pad,
leave:
GST_LOG_OBJECT (self, "end");
- //printf("leaving!!\n");
+ // printf("leaving :%d!!\n",ch_info->idx);
return ret;
/* special conditions */
@@ -1513,7 +1577,7 @@ sink_setcaps (GstPad *pad,
{
ch_info->in_stride = gstomx_calculate_stride (ch_info->in_width, format);
}
-
+#if 0
{
const GValue *framerate = NULL;
framerate = gst_structure_get_value (structure, "framerate");
@@ -1522,13 +1586,15 @@ sink_setcaps (GstPad *pad,
self->framerate_num = gst_value_get_fraction_numerator (framerate);
self->framerate_denom = gst_value_get_fraction_denominator (framerate);
- omx_base->duration = gst_util_uint64_scale_int(GST_SECOND,
+ /* omx_base->duration = gst_util_uint64_scale_int(GST_SECOND,
gst_value_get_fraction_denominator (framerate),
gst_value_get_fraction_numerator (framerate));
GST_DEBUG_OBJECT (self, "Nominal frame duration =%"GST_TIME_FORMAT,
- GST_TIME_ARGS (omx_base->duration));
+ GST_TIME_ARGS (omx_base->duration));*/
}
}
+#endif
+ self->duration = ((guint64)GST_SECOND/self->framerate_num);
if (self->sink_setcaps)
self->sink_setcaps (pad, caps);
@@ -1630,6 +1696,7 @@ type_instance_init (GTypeInstance *instance,
self->chInfo[ii].queue = async_queue_new ();
self->chInfo[ii].idx = ii;
self->chInfo[ii].eos = FALSE;
+ self->chInfo[ii].lastBuf = NULL;
printf("queue_%d : %p\n",ii,self->chInfo[ii].queue);
gst_pad_set_element_private(self->sinkpad[ii], &(self->chInfo[ii]));
@@ -1650,9 +1717,13 @@ type_instance_init (GTypeInstance *instance,
gst_pad_set_setcaps_function (self->srcpad,
GST_DEBUG_FUNCPTR (src_setcaps));
-
- self->duration = GST_CLOCK_TIME_NONE;
- printf("In instance init/...done!!\n");
+
+ self->framerate_num = 15;
+ self->framerate_denom = 1;
+ self->timestamp = 0;
+ /*printf("duration:%lld, in time : %"
+ GST_TIME_FORMAT "\n",self->duration,GST_TIME_ARGS(self->duration));
+ printf("In instance init/...done!!\n");*/
GST_LOG_OBJECT (self, "end");
}
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_videomixer.h b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_videomixer.h
index 9255e08..7adf186 100755
--- a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_videomixer.h
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomx_videomixer.h
@@ -49,6 +49,7 @@ typedef struct ip_params {
gint in_width, in_height, in_stride;
AsyncQueue *queue;
gboolean eos;
+ GstBuffer *lastBuf;
} ip_params ;
@@ -88,9 +89,10 @@ struct GstOmxVideoMixer
//gpointer g_class;
ip_params chInfo[NUM_PORTS];
guint numEosPending;
+ GSem *bufferSem;
+ GstClockTime timestamp;
};
-
struct GstOmxVideoMixerClass
{
GstElementClass parent_class;
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomxbufferalloc.c b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomxbufferalloc.c
new file mode 100755
index 0000000..e92fd9d
--- /dev/null
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomxbufferalloc.c
@@ -0,0 +1,348 @@
+/*
+ * GStreamer
+ * Copyright (C) 2005 Thomas Vander Stichele <thomas@apestaart.org>
+ * Copyright (C) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
+ * Copyright (C) 2011 prashant <<user@hostname.org>>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Alternatively, the contents of this file may be used under the
+ * GNU Lesser General Public License Version 2.1 (the "LGPL"), in
+ * which case the following provisions apply instead of the ones
+ * mentioned above:
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * SECTION:element-omxbufferalloc
+ *
+ * FIXME:Describe omxbufferalloc here.
+ *
+ * <refsect2>
+ * <title>Example launch line</title>
+ * |[
+ * gst-launch -v -m fakesrc ! omxbufferalloc ! fakesink silent=TRUE
+ * ]|
+ * </refsect2>
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <gst/gst.h>
+#include "gstomx.h"
+#include "gstomx_interface.h"
+
+#include "gstomxbufferalloc.h"
+
+
+GST_DEBUG_CATEGORY_STATIC (gst_omx_buffer_alloc_debug);
+//#define GST_CAT_DEFAULT gst_omx_buffer_alloc_debug
+
+/* Filter signals and args */
+enum
+{
+ /* FILL ME */
+ LAST_SIGNAL
+};
+
+enum
+{
+ PROP_0,
+ PROP_SILENT,
+ PROP_NUMBUFFERS
+};
+
+/* the capabilities of the inputs and outputs.
+ *
+ * describe the real formats here.
+ */
+static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS ("ANY")
+ );
+
+static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS ("ANY")
+ );
+
+GST_BOILERPLATE (GstomxBufferAlloc, gst_omx_buffer_alloc, GstElement,
+ GST_TYPE_ELEMENT);
+
+static void gst_omx_buffer_alloc_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec);
+static void gst_omx_buffer_alloc_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec);
+
+static gboolean gst_omx_buffer_alloc_set_caps (GstPad * pad, GstCaps * caps);
+static GstFlowReturn gst_omx_buffer_alloc_chain (GstPad * pad, GstBuffer * buf);
+
+GstFlowReturn
+gst_omx_buffer_alloc_bufferalloc (GstPad *pad, guint64 offset, guint size,
+ GstCaps *caps, GstBuffer **buf);
+
+static GstStateChangeReturn
+gst_omx_buffer_alloc_change_state (GstElement *element,
+ GstStateChange transition);
+
+
+
+/* GObject vmethod implementations */
+
+static void
+gst_omx_buffer_alloc_base_init (gpointer gclass)
+{
+ GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
+
+ gst_element_class_set_details_simple(element_class,
+ "omxBufferAlloc",
+ "FIXME:Generic",
+ "FIXME:Generic Template Element",
+ "prashant <<user@hostname.org>>");
+
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&src_factory));
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&sink_factory));
+}
+
+/* initialize the omxbufferalloc's class */
+static void
+gst_omx_buffer_alloc_class_init (GstomxBufferAllocClass * klass)
+{
+ GObjectClass *gobject_class;
+ GstElementClass *gstelement_class;
+
+ gobject_class = (GObjectClass *) klass;
+ gstelement_class = (GstElementClass *) klass;
+
+ gobject_class->set_property = gst_omx_buffer_alloc_set_property;
+ gobject_class->get_property = gst_omx_buffer_alloc_get_property;
+ gstelement_class->change_state = gst_omx_buffer_alloc_change_state;
+
+ g_object_class_install_property (gobject_class, PROP_NUMBUFFERS,
+ g_param_spec_uint ("numBuffers", "number of buffers",
+ "Number of buffers to be allocated by component",
+ 1, 16, 10, G_PARAM_WRITABLE));
+
+ g_object_class_install_property (gobject_class, PROP_SILENT,
+ g_param_spec_boolean ("silent", "Silent", "Produce verbose output ?",
+ FALSE, G_PARAM_READWRITE));
+
+}
+
+/* initialize the new element
+ * instantiate pads and add them to element
+ * set pad calback functions
+ * initialize instance structure
+ */
+static void
+gst_omx_buffer_alloc_init (GstomxBufferAlloc * filter,
+ GstomxBufferAllocClass * gclass)
+{
+ filter->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink");
+ gst_pad_set_setcaps_function (filter->sinkpad,
+ GST_DEBUG_FUNCPTR(gst_omx_buffer_alloc_set_caps));
+ gst_pad_set_getcaps_function (filter->sinkpad,
+ GST_DEBUG_FUNCPTR(gst_pad_proxy_getcaps));
+ gst_pad_set_chain_function (filter->sinkpad,
+ GST_DEBUG_FUNCPTR(gst_omx_buffer_alloc_chain));
+
+ gst_pad_set_bufferalloc_function(filter->sinkpad,GST_DEBUG_FUNCPTR(gst_omx_buffer_alloc_bufferalloc));
+
+ filter->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
+ gst_pad_set_getcaps_function (filter->srcpad,
+ GST_DEBUG_FUNCPTR(gst_pad_proxy_getcaps));
+
+ gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);
+ gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad);
+ filter->silent = FALSE;
+ filter->out_port.num_buffers = 10;
+ filter->out_port.always_copy = FALSE;
+ filter->cnt = 0;
+ filter->out_port.buffers = NULL;
+}
+
+static void
+gst_omx_buffer_alloc_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ GstomxBufferAlloc *filter = GST_OMXBUFFERALLOC (object);
+
+ switch (prop_id) {
+ case PROP_SILENT:
+ filter->silent = g_value_get_boolean (value);
+ break;
+ case PROP_NUMBUFFERS:
+ filter->out_port.num_buffers = g_value_get_uint (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_omx_buffer_alloc_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec)
+{
+ GstomxBufferAlloc *filter = GST_OMXBUFFERALLOC (object);
+
+ switch (prop_id) {
+ case PROP_SILENT:
+ g_value_set_boolean (value, filter->silent);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/* GstElement vmethod implementations */
+
+/* this function handles the link with other elements */
+static gboolean
+gst_omx_buffer_alloc_set_caps (GstPad * pad, GstCaps * caps)
+{
+ GstomxBufferAlloc *filter;
+ GstPad *otherpad;
+
+ filter = GST_OMXBUFFERALLOC (gst_pad_get_parent (pad));
+ otherpad = (pad == filter->srcpad) ? filter->sinkpad : filter->srcpad;
+ gst_object_unref (filter);
+
+ return gst_pad_set_caps (otherpad, caps);
+}
+
+/* chain function
+ * this function does the actual processing
+ */
+static GstFlowReturn
+gst_omx_buffer_alloc_chain (GstPad * pad, GstBuffer * buf)
+{
+ GstomxBufferAlloc *filter;
+
+ filter = GST_OMXBUFFERALLOC (GST_OBJECT_PARENT (pad));
+
+ buf = gst_omxbuffertransport_clone (buf, &(filter->out_port));
+
+ /* just push out the incoming buffer without touching it */
+ return gst_pad_push (filter->srcpad, buf);
+}
+
+void
+gst_omx_buffer_alloc_allocate_buffers (GstomxBufferAlloc *filter, guint size)
+{
+ guint ii;
+ guint numBufs;
+
+ numBufs = filter->out_port.num_buffers;
+ printf("allocating %d buffers of size:%d!!\n",numBufs,size);
+ filter->out_port.buffers = g_new0 (OMX_BUFFERHEADERTYPE *, numBufs);
+ filter->heap = SharedRegion_getHeap(2);
+
+ for(ii = 0; ii < numBufs; ii++) {
+ filter->out_port.buffers[ii] = malloc(sizeof(OMX_BUFFERHEADERTYPE));
+ filter->out_port.buffers[ii]->pBuffer = Memory_alloc (filter->heap, size, 128, NULL);
+ printf("allocated outbuf:%p\n",filter->out_port.buffers[ii]->pBuffer);
+ }
+ filter->allocSize = size;
+
+ return;
+}
+
+GstFlowReturn
+gst_omx_buffer_alloc_bufferalloc (GstPad *pad, guint64 offset, guint size,
+ GstCaps *caps, GstBuffer **buf)
+{
+ GstomxBufferAlloc *filter;
+ filter = GST_OMXBUFFERALLOC (GST_OBJECT_PARENT (pad));
+ if(filter->out_port.buffers == NULL)
+ gst_omx_buffer_alloc_allocate_buffers (filter,size);
+
+ *buf = gst_buffer_new();
+ GST_BUFFER_DATA(*buf) = filter->out_port.buffers[filter->cnt++]->pBuffer;
+ GST_BUFFER_SIZE(*buf) = size;
+ GST_BUFFER_CAPS(*buf) = caps;
+ return;
+}
+
+static GstStateChangeReturn
+gst_omx_buffer_alloc_change_state (GstElement *element,
+ GstStateChange transition)
+{
+ GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
+ GstomxBufferAlloc *filter = GST_OMXBUFFERALLOC (element);
+ guint ii;
+ switch (transition)
+ {
+ case GST_STATE_CHANGE_NULL_TO_READY:
+ OMX_Init ();
+ break;
+
+ default:
+ break;
+ }
+
+ ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+
+ if (ret == GST_STATE_CHANGE_FAILURE)
+ goto leave;
+
+ switch (transition)
+ {
+ case GST_STATE_CHANGE_PAUSED_TO_READY:
+ break;
+ case GST_STATE_CHANGE_READY_TO_NULL:
+ for(ii = 0; ii < filter->out_port.num_buffers; ii++) {
+ Memory_free(filter->heap,filter->out_port.buffers[ii]->pBuffer,filter->allocSize);
+ }
+ g_free(filter->out_port.buffers);
+ OMX_Deinit();
+ break;
+
+ default:
+ break;
+ }
+
+leave:
+ return ret;
+}
+
+
+
+
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomxbufferalloc.h b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomxbufferalloc.h
new file mode 100755
index 0000000..fbd9573
--- /dev/null
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstomxbufferalloc.h
@@ -0,0 +1,96 @@
+/*
+ * GStreamer
+ * Copyright (C) 2005 Thomas Vander Stichele <thomas@apestaart.org>
+ * Copyright (C) 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
+ * Copyright (C) 2011 prashant <<user@hostname.org>>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Alternatively, the contents of this file may be used under the
+ * GNU Lesser General Public License Version 2.1 (the "LGPL"), in
+ * which case the following provisions apply instead of the ones
+ * mentioned above:
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GST_OMXBUFFERALLOC_H__
+#define __GST_OMXBUFFERALLOC_H__
+
+#include <gst/gst.h>
+#include "gstomx_util.h"
+
+#include <xdc/std.h>
+#include <ti/syslink/utils/IHeap.h>
+
+
+G_BEGIN_DECLS
+
+/* #defines don't like whitespacey bits */
+#define GST_TYPE_OMXBUFFERALLOC \
+ (gst_omx_buffer_alloc_get_type())
+#define GST_OMXBUFFERALLOC(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OMXBUFFERALLOC,GstomxBufferAlloc))
+#define GST_OMXBUFFERALLOC_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OMXBUFFERALLOC,GstomxBufferAllocClass))
+#define GST_IS_OMXBUFFERALLOC(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OMXBUFFERALLOC))
+#define GST_IS_OMXBUFFERALLOC_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OMXBUFFERALLOC))
+
+typedef struct _GstomxBufferAlloc GstomxBufferAlloc;
+typedef struct _GstomxBufferAllocClass GstomxBufferAllocClass;
+
+struct _GstomxBufferAlloc
+{
+ GstElement element;
+
+ GstPad *sinkpad, *srcpad;
+
+ gboolean silent;
+
+ GOmxPort out_port;
+ guint cnt;
+ IHeap_Handle heap;
+ guint allocSize;
+};
+
+struct _GstomxBufferAllocClass
+{
+ GstElementClass parent_class;
+};
+
+GType gst_omx_buffer_alloc_get_type (void);
+
+G_END_DECLS
+
+#endif /* __GST_OMXBUFFERALLOC_H__ */
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstperf.c b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstperf.c
index 5fb6084..13e77ca 100644
--- a/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstperf.c
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/omx/gstperf.c
@@ -83,6 +83,7 @@ display_current_fps (gpointer data)
gchar fps_message[256];
gdouble time_diff, time_elapsed;
GstClockTime current_ts = gst_util_get_timestamp ();
+ char *name = GST_OBJECT_NAME(self);
frames_count = self->frames_count;
@@ -93,8 +94,8 @@ display_current_fps (gpointer data)
average_fps = (gdouble) frames_count / time_elapsed;
- g_snprintf (fps_message, 255, "frames: %" G_GUINT64_FORMAT " \tcurrent: %.2f\t average: %.2f",
- frames_count, rr, average_fps);
+ g_snprintf (fps_message, 255, "%s: frames: %" G_GUINT64_FORMAT " \tcurrent: %.2f\t average: %.2f",
+ name, frames_count, rr, average_fps);
g_print ("%s", fps_message);
self->last_frames_count = frames_count;
diff --git a/gstreamer_ti_dm81xx/ti_build/gst-openmax/util/sem.c b/gstreamer_ti_dm81xx/ti_build/gst-openmax/util/sem.c
index 2ac6fac..fac8282 100644
--- a/gstreamer_ti_dm81xx/ti_build/gst-openmax/util/sem.c
+++ b/gstreamer_ti_dm81xx/ti_build/gst-openmax/util/sem.c
@@ -36,6 +36,19 @@ g_sem_new (void)
return sem;
}
+GSem *
+g_sem_new_with_value (gint value)
+{
+ GSem *sem;
+
+ sem = g_new (GSem, 1);
+ sem->condition = g_cond_new ();
+ sem->mutex = g_mutex_new ();
+ sem->counter = value;
+
+ return sem;
+}
+
void
g_sem_free (GSem *sem)
{