summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'media-libs/gst-plugins-base')
-rw-r--r--media-libs/gst-plugins-base/Manifest26
-rw-r--r--media-libs/gst-plugins-base/files/gst-0.10.32-0001-add-rowstride-support-to-video-utility-functions.patch536
-rw-r--r--media-libs/gst-plugins-base/files/gst-0.10.32-0002-stridetransform-skeletal-implementation-of-stridetra.patch368
-rw-r--r--media-libs/gst-plugins-base/files/gst-0.10.32-0003-stridetransform-implement-caps-negotiation-and-relat.patch379
-rw-r--r--media-libs/gst-plugins-base/files/gst-0.10.32-0004-stridetransform-implement-transform-function.patch215
-rw-r--r--media-libs/gst-plugins-base/files/gst-0.10.32-0005-add-gst_stride_transform_transform_size.patch143
-rw-r--r--media-libs/gst-plugins-base/files/gst-0.10.32-0006-fix-a-small-typo.-need-to-use-the-smaller-of-new_wid.patch36
-rw-r--r--media-libs/gst-plugins-base/files/gst-0.10.32-0007-Add-NV12-support-in-stridetransform.patch77
-rw-r--r--media-libs/gst-plugins-base/files/gst-0.10.32-0008-add-basic-support-for-I420-NV12-colorspace-conversio.patch186
-rw-r--r--media-libs/gst-plugins-base/files/gst-0.10.32-0009-fix-to-avoid-parsing-caps-on-every-frame.patch35
-rw-r--r--media-libs/gst-plugins-base/files/gst-0.10.32-0010-refactor-stridetransform-to-make-it-easier-to-add-ne.patch759
-rw-r--r--media-libs/gst-plugins-base/files/gst-0.10.32-0011-add-some-neon.patch293
-rw-r--r--media-libs/gst-plugins-base/files/gst-0.10.32-0012-add-support-to-convert-to-YUY2-YUYV-color-format.patch197
-rw-r--r--media-libs/gst-plugins-base/files/gst-0.10.32-0013-Add-support-for-RGB565-to-stridetransform.patch336
-rw-r--r--media-libs/gst-plugins-base/files/gst-0.10.32-0014-stridetransform-updates-for-new-extra-anal-compiler-.patch61
-rw-r--r--media-libs/gst-plugins-base/files/gst-0.10.32-0015-stridetransform-fix-problem-transforming-caps-with-l.patch544
-rw-r--r--media-libs/gst-plugins-base/files/gst-0.10.32-0016-modify-playbin-to-use-stridetransform.patch62
-rw-r--r--media-libs/gst-plugins-base/files/gst-0.10.32-0017-playbin-disable-interlaced-support.patch33
-rw-r--r--media-libs/gst-plugins-base/files/gst-0.10.32-0018-textoverlay-add-stride-support.patch132
-rw-r--r--media-libs/gst-plugins-base/files/gst-0.10.32-0019-video-more-flexible-video-caps-utility.patch228
-rw-r--r--media-libs/gst-plugins-base/files/gst-0.10.32-0020-video-fix-endianess-issue-for-16bit-RGB-formats.patch41
-rw-r--r--media-libs/gst-plugins-base/files/gst-0.10.32-0021-stride-more-flexible-stride-color-conversion.patch1131
-rw-r--r--media-libs/gst-plugins-base/files/gst-0.10.32-0022-stride-support-for-32bit-RGB-formats.patch54
-rw-r--r--media-libs/gst-plugins-base/files/gst-0.10.32-0023-ffmpegcolorspace-support-for-rowstride.patch410
-rw-r--r--media-libs/gst-plugins-base/files/gst-0.10.32-0024-discoverer-rowstride-support.patch45
-rw-r--r--media-libs/gst-plugins-base/gst-plugins-base-0.10.32_p20110127.ebuild78
26 files changed, 6405 insertions, 0 deletions
diff --git a/media-libs/gst-plugins-base/Manifest b/media-libs/gst-plugins-base/Manifest
new file mode 100644
index 0000000..0cba68e
--- /dev/null
+++ b/media-libs/gst-plugins-base/Manifest
@@ -0,0 +1,26 @@
+AUX gst-0.10.32-0001-add-rowstride-support-to-video-utility-functions.patch 19478 RMD160 3314aa44215803242a9cd1b2f33987066b2d9255 SHA1 960ce8f2c0c12c1d79cac4ba667236ab5dc9c4a9 SHA256 453f54b8b2a00df3038b96096f65720ad09f78a83db356bbd3018a6dae519c56
+AUX gst-0.10.32-0002-stridetransform-skeletal-implementation-of-stridetra.patch 12038 RMD160 ae601020715b8049423418dd51c97ffd4cd84da6 SHA1 b0210b381c97a94b7542b3e103a0071bbce14cf6 SHA256 a8cbdef59063369c4bae3c87dc9d197fc950c9fb588ad9a3dcfcbca7f1ea02c9
+AUX gst-0.10.32-0003-stridetransform-implement-caps-negotiation-and-relat.patch 13666 RMD160 cd97b88ec464c8e8055c93a443ff7a0d31aa0d41 SHA1 500b157dca39a60751fd89edd29d23224b287fd9 SHA256 a2685bd2928796756e5217d10bee09679b99458e5c33ea90498725b379c060a6
+AUX gst-0.10.32-0004-stridetransform-implement-transform-function.patch 7985 RMD160 f246b2f9a27a6d94a7d21f2594bbb65f9dba08be SHA1 62174bf74b1b1086a3585df0178db703c8ddb108 SHA256 efcf08ac81ce74fedab80318db7e20eef0abda36ef9e03aed6c823426199bad8
+AUX gst-0.10.32-0005-add-gst_stride_transform_transform_size.patch 5629 RMD160 01a147ca359509d478aa69c40697735f3b339d4d SHA1 1e7a520e85b9364797764be5a755478e4becbb3b SHA256 3ca3bfac1d14ce43c2c1211038275a22b41b370bbfcadd06224bd68b6f79608b
+AUX gst-0.10.32-0006-fix-a-small-typo.-need-to-use-the-smaller-of-new_wid.patch 1398 RMD160 fff110733e415d3a62b887ac5155d3200f821daa SHA1 0e331030afdf5be917c71f7b2d0a3961450159ef SHA256 e4ffd2ceefcb6bdf851d897ca63f57f5b33bc80210fcd2e70e8337738857a823
+AUX gst-0.10.32-0007-Add-NV12-support-in-stridetransform.patch 2909 RMD160 f77e0f781af75021ba4dbbc19fc181c38f5e7a7d SHA1 8eebe554050a4e7239e2d3c886f2d71e92c481ad SHA256 ee77cd62a3af64ab453d14e563ac142e1cc9a78422158d548fa412c3e6a5c6e1
+AUX gst-0.10.32-0008-add-basic-support-for-I420-NV12-colorspace-conversio.patch 6976 RMD160 e8c645b0a55e39cc70547eeb6eaed361b93f7770 SHA1 2fb572546b90b9e1566f8dd38854d307ea5fa897 SHA256 55c669534771130dbaf5bdd94a4a08031faf27900fb3d7981d4b5934510c5f11
+AUX gst-0.10.32-0009-fix-to-avoid-parsing-caps-on-every-frame.patch 1087 RMD160 ee3a3bbf77ad5c5726a30115caeb373c430553f9 SHA1 cfb3b914b88a278131d91e2dd48865765302d947 SHA256 52f163890b09cc2133739adb18788441329c71c10359a0a1a2e5bcee918bff1c
+AUX gst-0.10.32-0010-refactor-stridetransform-to-make-it-easier-to-add-ne.patch 26534 RMD160 ccc77aef354ecc2f506dfe73d485a1edd5910e2a SHA1 837fdc52c72c09105356c12b361480b1ff03eb54 SHA256 1abf8e19bdbd7d4b404cc8803dce83da77be4fd98e1c940d6842f2ae3c6e29fd
+AUX gst-0.10.32-0011-add-some-neon.patch 9024 RMD160 48388eea9e42f4a156cae6090f34c1732eec717f SHA1 dfe6de8382322ccab6889c3afb228fc3512f9816 SHA256 d9f3e1fbb8cfbcda0fa49cf976e7b318c55780a3f4216c030e4a6b1e1ec207c1
+AUX gst-0.10.32-0012-add-support-to-convert-to-YUY2-YUYV-color-format.patch 6307 RMD160 37c8cfdc0850f8b163747b029ce6ef7125a92bcf SHA1 5385dfa1622cc4b8639e03adc99dbb91d6de8b49 SHA256 f26b61b6c92bd064c423eadcc7b35dcd3573c7e313b0ecc142473124f37240ec
+AUX gst-0.10.32-0013-Add-support-for-RGB565-to-stridetransform.patch 13641 RMD160 51386f4ebb999d90eff5ef786e27d07fa37e159a SHA1 1b0f6ee44a24c32247e165f357100d9a6a0cac6b SHA256 f8013cdb9943559fa14491c8e253f7c51a7a061e16c76acabe10f057f9066b6a
+AUX gst-0.10.32-0014-stridetransform-updates-for-new-extra-anal-compiler-.patch 2398 RMD160 2fc97ee99088fb484f728d9d0c6ea0ae2509c32d SHA1 0b5aed4e09b7dad068d7048e9960ca980e46fd18 SHA256 749859c06913a633ead030f69d9cc5076d9425a95e720111876c8abf464a3d57
+AUX gst-0.10.32-0015-stridetransform-fix-problem-transforming-caps-with-l.patch 20488 RMD160 f5d8a82c2313dcde45b2220ead8bd2f1c356a2dd SHA1 c02b4ee4468134fd9eb27a755a031a0e113a509e SHA256 6313ea19aa2496f2e14e91c2d3812d6f9d9c82035635d4a978a8e7b963a8be6a
+AUX gst-0.10.32-0016-modify-playbin-to-use-stridetransform.patch 2485 RMD160 cb93726b58319d71c95abc8195d1535785fbde85 SHA1 afcc848f8ab059452a68b1eea13735c5c431de89 SHA256 9e55a7d20b269d947875aba1e3ed66579a866696afda99e754093ff74b5d4fe5
+AUX gst-0.10.32-0017-playbin-disable-interlaced-support.patch 1108 RMD160 9d759f6f3028811150df8aa01ccb114e73b3f2df SHA1 63802de92a41aec3a210615f9c7750621c9cd20c SHA256 31d306b25a4edf00b65146a92c74f8f1f6bf6aaf001b81b8df70affdddd2b5ab
+AUX gst-0.10.32-0018-textoverlay-add-stride-support.patch 5213 RMD160 f1a10c218e9cc25b232f48e1cf890cf6a108dce4 SHA1 3d79d8b3f2037c807d61c427943e3a2cb1a0cf1d SHA256 cf0facafdf762e114c5ea56a5ad6420dd6a6269c674eb2f06af0eec17a4a0d9d
+AUX gst-0.10.32-0019-video-more-flexible-video-caps-utility.patch 8691 RMD160 5b22d8a8f74bcf46e08671a160b6bce314f50b82 SHA1 862be817be2a3a6fdac3073efa2d6e53b161aa00 SHA256 a6b85a91555daf21c4228ea708be91de875997158b393b8e99422bc02c05f835
+AUX gst-0.10.32-0020-video-fix-endianess-issue-for-16bit-RGB-formats.patch 1343 RMD160 4fa95c02bfaf97dadf504f3aee2a7397afd4ac41 SHA1 bdc1d37a88cd3ce562a411474474608d7d1b9084 SHA256 3f8a7bf670e54af9bd3fdf8d56b22f5c9e6ff00616472e1c0b0b2493f6a561c8
+AUX gst-0.10.32-0021-stride-more-flexible-stride-color-conversion.patch 40158 RMD160 1d45d8b1e3084ac125b733e57bece2b1de01b096 SHA1 621a2f39835043114e08b4420c1d6e3731b568b9 SHA256 a38d4f60b3e38d45c38044133fe2ad1e799dc966e53c1dd292e63ad897101037
+AUX gst-0.10.32-0022-stride-support-for-32bit-RGB-formats.patch 1818 RMD160 d5a3ade8595272586ab934cc10ba7658fbc9121a SHA1 42f14b868bc68e2554e96d4ff8d94faa79863fbf SHA256 a74ac22cb796fc175fa2362fe48b7d2554f41e39228a993197a09e5002fc4fe1
+AUX gst-0.10.32-0023-ffmpegcolorspace-support-for-rowstride.patch 15546 RMD160 c389743544f5881bf7be1ce8df5682a0a8556285 SHA1 975b92fa352e3210b1013f5c6e98f6994b5737e7 SHA256 3843c61f9d49ba75dc6a20c9b7d57bcdc3bfbdf784ea93619ee68dd8bab72c6c
+AUX gst-0.10.32-0024-discoverer-rowstride-support.patch 1552 RMD160 4e662a66b724a19dcb71e614a71198edd9d5fe5b SHA1 153a14d26dc2f90e0d060d78244e10ab54d7912d SHA256 434643810dde2d6afc8d712563afbcd588d49cdb6bec7edec9545d2c7e375ee8
+DIST gst-plugins-base-0.10.32.tar.bz2 2720103 RMD160 b267e3138e40e3646efed0baa662d40775eca1ea SHA1 c1c149272b7ab6cbe5f648532f74525c6541eea5 SHA256 e9aabfac83f6480896da0686e9c911989f896fbad634821b7771ed84a446172b
+EBUILD gst-plugins-base-0.10.32_p20110127.ebuild 3386 RMD160 366819facffe23ed35617ff106ac81411824103c SHA1 2efdfad7c81709078ff142410917d092b34ad112 SHA256 8fa605d70e03f9f52680a5d46334a9ad9cc055e84578fb440ddc74174670fa64
diff --git a/media-libs/gst-plugins-base/files/gst-0.10.32-0001-add-rowstride-support-to-video-utility-functions.patch b/media-libs/gst-plugins-base/files/gst-0.10.32-0001-add-rowstride-support-to-video-utility-functions.patch
new file mode 100644
index 0000000..6f25b71
--- /dev/null
+++ b/media-libs/gst-plugins-base/files/gst-0.10.32-0001-add-rowstride-support-to-video-utility-functions.patch
@@ -0,0 +1,536 @@
+From 481cda8686336999ccccbdbf239bcbd520bcdfc7 Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Thu, 30 Jul 2009 14:50:05 -0500
+Subject: [PATCH 01/24] add rowstride support to video utility functions
+
+---
+ gst-libs/gst/video/gstvideofilter.c | 8 +-
+ gst-libs/gst/video/video.c | 244 ++++++++++++++++++++++++++++-------
+ gst-libs/gst/video/video.h | 27 +++--
+ 3 files changed, 220 insertions(+), 59 deletions(-)
+
+diff --git a/gst-libs/gst/video/gstvideofilter.c b/gst-libs/gst/video/gstvideofilter.c
+index 2d08a60..6b2d7b7 100644
+--- a/gst-libs/gst/video/gstvideofilter.c
++++ b/gst-libs/gst/video/gstvideofilter.c
+@@ -21,7 +21,7 @@
+ /**
+ * SECTION:gstvideofilter
+ * @short_description: Base class for video filters
+- *
++ *
+ * <refsect2>
+ * <para>
+ * Provides useful functions and a base class for video filters.
+@@ -78,14 +78,14 @@ gst_video_filter_get_unit_size (GstBaseTransform * btrans, GstCaps * caps,
+ guint * size)
+ {
+ GstVideoFormat fmt;
+- gint width, height;
++ gint width, height, rowstride;
+
+- if (!gst_video_format_parse_caps (caps, &fmt, &width, &height)) {
++ if (!gst_video_format_parse_caps_strided (caps, &fmt, &width, &height, &rowstride)) {
+ GST_WARNING_OBJECT (btrans, "Failed to parse caps %" GST_PTR_FORMAT, caps);
+ return FALSE;
+ }
+
+- *size = gst_video_format_get_size (fmt, width, height);
++ *size = gst_video_format_get_size_strided (fmt, width, height, rowstride);
+
+ GST_DEBUG_OBJECT (btrans, "Returning size %u bytes for caps %"
+ GST_PTR_FORMAT, *size, caps);
+diff --git a/gst-libs/gst/video/video.c b/gst-libs/gst/video/video.c
+index d9fa50b..24f1ac8 100644
+--- a/gst-libs/gst/video/video.c
++++ b/gst-libs/gst/video/video.c
+@@ -31,7 +31,7 @@
+ *
+ * <refsect2>
+ * <para>
+- * This library contains some helper functions and includes the
++ * This library contains some helper functions and includes the
+ * videosink and videofilter base classes.
+ * </para>
+ * </refsect2>
+@@ -53,7 +53,7 @@ static GstVideoFormat gst_video_format_from_rgb16_masks (int red_mask,
+ *
+ * A convenience function to retrieve a GValue holding the framerate
+ * from the caps on a pad.
+- *
++ *
+ * The pad needs to have negotiated caps containing a framerate property.
+ *
+ * Returns: NULL if the pad has no configured caps or the configured caps
+@@ -106,7 +106,7 @@ gst_video_frame_rate (GstPad * pad)
+ *
+ * Inspect the caps of the provided pad and retrieve the width and height of
+ * the video frames it is configured for.
+- *
++ *
+ * The pad needs to have negotiated caps containing width and height properties.
+ *
+ * Returns: TRUE if the width and height could be retrieved.
+@@ -158,13 +158,13 @@ gst_video_get_size (GstPad * pad, gint * width, gint * height)
+ * @display_par_n: Numerator of the pixel aspect ratio of the display device
+ * @display_par_d: Denominator of the pixel aspect ratio of the display device
+ *
+- * Given the Pixel Aspect Ratio and size of an input video frame, and the
+- * pixel aspect ratio of the intended display device, calculates the actual
++ * Given the Pixel Aspect Ratio and size of an input video frame, and the
++ * pixel aspect ratio of the intended display device, calculates the actual
+ * display ratio the video will be rendered with.
+ *
+- * Returns: A boolean indicating success and a calculated Display Ratio in the
+- * dar_n and dar_d parameters.
+- * The return value is FALSE in the case of integer overflow or other error.
++ * Returns: A boolean indicating success and a calculated Display Ratio in the
++ * dar_n and dar_d parameters.
++ * The return value is FALSE in the case of integer overflow or other error.
+ *
+ * Since: 0.10.7
+ */
+@@ -308,28 +308,15 @@ gst_video_parse_caps_chroma_site (GstCaps * caps)
+ }
+
+ /**
+- * gst_video_format_parse_caps:
+- * @caps: the #GstCaps to parse
+- * @format: the #GstVideoFormat of the video represented by @caps (output)
+- * @width: the width of the video represented by @caps, may be NULL (output)
+- * @height: the height of the video represented by @caps, may be NULL (output)
+- *
+- * Determines the #GstVideoFormat of @caps and places it in the location
+- * pointed to by @format. Extracts the size of the video and places it
+- * in the location pointed to by @width and @height. If @caps does not
+- * represent one of the raw video formats listed in #GstVideoFormat, the
+- * function will fail and return FALSE.
+- *
+- * Since: 0.10.16
+- *
+- * Returns: TRUE if @caps was parsed correctly.
++ * see gst_video_format_parse_caps_strided and gst_video_format_parse_caps
+ */
+-gboolean
+-gst_video_format_parse_caps (GstCaps * caps, GstVideoFormat * format,
+- int *width, int *height)
++static gboolean
++parse_caps (GstCaps * caps, GstVideoFormat * format, gint *width, gint *height,
++ gboolean stride_ok, gint *rowstride)
+ {
+ GstStructure *structure;
+ gboolean ok = TRUE;
++ gboolean strided = FALSE;
+
+ if (!gst_caps_is_fixed (caps))
+ return FALSE;
+@@ -337,7 +324,10 @@ gst_video_format_parse_caps (GstCaps * caps, GstVideoFormat * format,
+ structure = gst_caps_get_structure (caps, 0);
+
+ if (format) {
+- if (gst_structure_has_name (structure, "video/x-raw-yuv")) {
++ if (gst_structure_has_name (structure, "video/x-raw-yuv") ||
++ (stride_ok &&
++ gst_structure_has_name (structure, "video/x-raw-yuv-strided") &&
++ (strided=TRUE) /* single '=' intentional */)) {
+ guint32 fourcc;
+
+ ok &= gst_structure_get_fourcc (structure, "format", &fourcc);
+@@ -346,7 +336,10 @@ gst_video_format_parse_caps (GstCaps * caps, GstVideoFormat * format,
+ if (*format == GST_VIDEO_FORMAT_UNKNOWN) {
+ ok = FALSE;
+ }
+- } else if (gst_structure_has_name (structure, "video/x-raw-rgb")) {
++ } else if (gst_structure_has_name (structure, "video/x-raw-rgb") ||
++ (stride_ok &&
++ gst_structure_has_name (structure, "video/x-raw-rgb-strided") &&
++ (strided=TRUE) /* single '=' intentional */)) {
+ int depth;
+ int bpp;
+ int endianness = 0;
+@@ -423,6 +416,10 @@ gst_video_format_parse_caps (GstCaps * caps, GstVideoFormat * format,
+ }
+ }
+
++ /* note: should we require that the caps have these fields, even if
++ * the caller does not particularly request them??
++ */
++
+ if (width) {
+ ok &= gst_structure_get_int (structure, "width", width);
+ }
+@@ -431,11 +428,70 @@ gst_video_format_parse_caps (GstCaps * caps, GstVideoFormat * format,
+ ok &= gst_structure_get_int (structure, "height", height);
+ }
+
++ if (rowstride) {
++ if (strided) {
++ ok &= gst_structure_get_int (structure, "rowstride", rowstride);
++ } else {
++ *rowstride = 0; /* not a strided format */
++ }
++ }
++
+ return ok;
+ }
+
+
+ /**
++ * gst_video_format_parse_caps_strided:
++ * @caps: the #GstCaps to parse
++ * @format: the #GstVideoFormat of the video represented by @caps (output)
++ * @width: the width of the video represented by @caps, may be NULL (output)
++ * @height: the height of the video represented by @caps, may be NULL (output)
++ * @rowstride: the rowstride (in bytes) represented by @caps, or 0 if there
++ * is no rowstride, may be NULL (output)
++ *
++ * Determines the #GstVideoFormat of @caps and places it in the location
++ * pointed to by @format. Extracts the size of the video and places it
++ * in the location pointed to by @width and @height. Extracts the row-
++ * stride and places it in the location pointed to by @rowstride. If
++ * @caps does not represent one of the raw video formats listed in
++ * #GstVideoFormat, the function will fail and return FALSE.
++ *
++ * Since: ???
++ *
++ * Returns: TRUE if @caps was parsed correctly.
++ */
++gboolean
++gst_video_format_parse_caps_strided (GstCaps * caps, GstVideoFormat * format,
++ int *width, int *height, int *rowstride)
++{
++ return parse_caps (caps, format, width, height, TRUE, rowstride);
++}
++
++/**
++ * gst_video_format_parse_caps:
++ * @caps: the #GstCaps to parse
++ * @format: the #GstVideoFormat of the video represented by @caps (output)
++ * @width: the width of the video represented by @caps, may be NULL (output)
++ * @height: the height of the video represented by @caps, may be NULL (output)
++ *
++ * Determines the #GstVideoFormat of @caps and places it in the location
++ * pointed to by @format. Extracts the size of the video and places it
++ * in the location pointed to by @width and @height. If @caps does not
++ * represent one of the raw video formats listed in #GstVideoFormat, the
++ * function will fail and return FALSE.
++ *
++ * Since: 0.10.16
++ *
++ * Returns: TRUE if @caps was parsed correctly.
++ */
++gboolean
++gst_video_format_parse_caps (GstCaps * caps, GstVideoFormat * format,
++ int *width, int *height)
++{
++ return parse_caps (caps, format, width, height, FALSE, NULL);
++}
++
++/**
+ * gst_video_parse_caps_framerate:
+ * @caps: pointer to a #GstCaps instance
+ * @fps_n: pointer to integer to hold numerator of frame rate (output)
+@@ -534,10 +590,11 @@ gst_video_format_new_caps_interlaced (GstVideoFormat format,
+ }
+
+ /**
+- * gst_video_format_new_caps:
++ * gst_video_format_new_caps_strided:
+ * @format: the #GstVideoFormat describing the raw video format
+ * @width: width of video
+ * @height: height of video
++ * @rowstride: the rowstride (in bytes), or 0 if no rowstride
+ * @framerate_n: numerator of frame rate
+ * @framerate_d: denominator of frame rate
+ * @par_n: numerator of pixel aspect ratio
+@@ -545,26 +602,29 @@ gst_video_format_new_caps_interlaced (GstVideoFormat format,
+ *
+ * Creates a new #GstCaps object based on the parameters provided.
+ *
+- * Since: 0.10.16
++ * Since: ???
+ *
+ * Returns: a new #GstCaps object, or NULL if there was an error
+ */
+ GstCaps *
+-gst_video_format_new_caps (GstVideoFormat format, int width,
+- int height, int framerate_n, int framerate_d, int par_n, int par_d)
++gst_video_format_new_caps_strided (GstVideoFormat format,
++ int width, int height, int rowstride,
++ int framerate_n, int framerate_d, int par_n, int par_d)
+ {
++ GstCaps *caps = NULL;
++
+ g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, NULL);
+ g_return_val_if_fail (width > 0 && height > 0, NULL);
+
+ if (gst_video_format_is_yuv (format)) {
+- return gst_caps_new_simple ("video/x-raw-yuv",
++ caps = gst_caps_new_simple (
++ rowstride ? "video/x-raw-yuv-strided" : "video/x-raw-yuv",
+ "format", GST_TYPE_FOURCC, gst_video_format_to_fourcc (format),
+ "width", G_TYPE_INT, width,
+ "height", G_TYPE_INT, height,
+ "framerate", GST_TYPE_FRACTION, framerate_n, framerate_d,
+ "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d, NULL);
+- }
+- if (gst_video_format_is_rgb (format)) {
++ } else if (gst_video_format_is_rgb (format)) {
+ GstCaps *caps;
+ int red_mask = 0;
+ int blue_mask = 0;
+@@ -663,7 +723,8 @@ gst_video_format_new_caps (GstVideoFormat format, int width,
+ return NULL;
+ }
+
+- caps = gst_caps_new_simple ("video/x-raw-rgb",
++ caps = gst_caps_new_simple (
++ rowstride ? "video/x-raw-rgb-strided" : "video/x-raw-rgb",
+ "bpp", G_TYPE_INT, bpp,
+ "depth", G_TYPE_INT, depth,
+ "width", G_TYPE_INT, width,
+@@ -685,11 +746,7 @@ gst_video_format_new_caps (GstVideoFormat format, int width,
+ width, height));
+ gst_caps_set_simple (caps, "alpha_mask", G_TYPE_INT, alpha_mask, NULL);
+ }
+- return caps;
+- }
+-
+- if (gst_video_format_is_gray (format)) {
+- GstCaps *caps;
++ } else if (gst_video_format_is_gray (format)) {
+ int bpp;
+ int depth;
+ int endianness;
+@@ -730,11 +787,39 @@ gst_video_format_new_caps (GstVideoFormat format, int width,
+ "framerate", GST_TYPE_FRACTION, framerate_n, framerate_d,
+ "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d, NULL);
+ }
++ } else {
++ return NULL;
++ }
+
+- return caps;
++ if (rowstride) {
++ gst_caps_set_simple (caps, "rowstride", G_TYPE_INT, rowstride, NULL);
+ }
+
+- return NULL;
++ return caps;
++}
++
++/**
++ * gst_video_format_new_caps:
++ * @format: the #GstVideoFormat describing the raw video format
++ * @width: width of video
++ * @height: height of video
++ * @framerate_n: numerator of frame rate
++ * @framerate_d: denominator of frame rate
++ * @par_n: numerator of pixel aspect ratio
++ * @par_d: denominator of pixel aspect ratio
++ *
++ * Creates a new #GstCaps object based on the parameters provided.
++ *
++ * Since: 0.10.16
++ *
++ * Returns: a new #GstCaps object, or NULL if there was an error
++ */
++GstCaps *
++gst_video_format_new_caps (GstVideoFormat format, int width, int height,
++ int framerate_n, int framerate_d, int par_n, int par_d)
++{
++ return gst_video_format_new_caps_strided (format, width, height, 0,
++ framerate_n, framerate_d, par_n, par_d);
+ }
+
+ /**
+@@ -874,7 +959,7 @@ gst_video_format_to_fourcc (GstVideoFormat format)
+ * @blue_mask: blue bit mask
+ *
+ * Converts red, green, blue bit masks into the corresponding
+- * #GstVideoFormat.
++ * #GstVideoFormat.
+ *
+ * Since: 0.10.16
+ *
+@@ -1107,7 +1192,7 @@ gst_video_format_is_gray (GstVideoFormat format)
+ /**
+ * gst_video_format_has_alpha:
+ * @format: a #GstVideoFormat
+- *
++ *
+ * Returns TRUE or FALSE depending on if the video format provides an
+ * alpha channel.
+ *
+@@ -1877,6 +1962,75 @@ gst_video_format_get_size (GstVideoFormat format, int width, int height)
+ }
+
+ /**
++ * gst_video_format_get_size_strided:
++ * @format: a #GstVideoFormat
++ * @width: the width of video (in pixels)
++ * @height: the height of video (in pixels)
++ * @rowstride: the rowstride (in bytes), or 0 if no rowstride (in which
++ * case the returned value is same as #gst_video_format_get_size())
++ *
++ * Calculates the total number of bytes in the raw video format, for a buffer
++ * which may have a rowstride in bytes
++ *
++ * Since: ???
++ *
++ * Returns: size (in bytes) of raw video format
++ */
++int
++gst_video_format_get_size_strided (GstVideoFormat format,
++ int width, int height, int rowstride)
++{
++ if(!rowstride)
++ return gst_video_format_get_size (format, width, height);
++
++ g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, 0);
++ g_return_val_if_fail (width > 0 && height > 0, 0);
++
++ switch (format) {
++ /* all packed formats have the same calculation, ie. rowstride * height
++ */
++ case GST_VIDEO_FORMAT_RGBx:
++ case GST_VIDEO_FORMAT_BGRx:
++ case GST_VIDEO_FORMAT_xRGB:
++ case GST_VIDEO_FORMAT_xBGR:
++ case GST_VIDEO_FORMAT_RGBA:
++ case GST_VIDEO_FORMAT_BGRA:
++ case GST_VIDEO_FORMAT_ARGB:
++ case GST_VIDEO_FORMAT_ABGR:
++ case GST_VIDEO_FORMAT_RGB16:
++ case GST_VIDEO_FORMAT_BGR16:
++ case GST_VIDEO_FORMAT_RGB15:
++ case GST_VIDEO_FORMAT_BGR15:
++ case GST_VIDEO_FORMAT_RGB:
++ case GST_VIDEO_FORMAT_BGR:
++ case GST_VIDEO_FORMAT_YUY2:
++ case GST_VIDEO_FORMAT_YVYU:
++ case GST_VIDEO_FORMAT_UYVY:
++ case GST_VIDEO_FORMAT_AYUV:
++ case GST_VIDEO_FORMAT_v210:
++ case GST_VIDEO_FORMAT_v216:
++ return GST_ROUND_UP_4 (rowstride * height);
++
++ /* these planar formats have 2x sub-sampling in the vertical direction,
++ * so U/V have half as many rows as Y:
++ */
++ case GST_VIDEO_FORMAT_I420:
++ case GST_VIDEO_FORMAT_YV12:
++ return GST_ROUND_UP_4 (2 * rowstride * height);
++
++ /* these planar formats have no sub-sampling in the vertical direction,
++ * so each plane has 'height' number of rows
++ */
++ case GST_VIDEO_FORMAT_Y41B:
++ case GST_VIDEO_FORMAT_Y42B:
++ case GST_VIDEO_FORMAT_Y444:
++ return GST_ROUND_UP_4 (3 * rowstride * height);
++ default:
++ return 0;
++ }
++}
++
++/**
+ * gst_video_format_convert:
+ * @format: a #GstVideoFormat
+ * @width: the width of video
+diff --git a/gst-libs/gst/video/video.h b/gst-libs/gst/video/video.h
+index 96c5a85..a6a2293 100644
+--- a/gst-libs/gst/video/video.h
++++ b/gst-libs/gst/video/video.h
+@@ -33,7 +33,7 @@ G_BEGIN_DECLS
+ * @GST_VIDEO_FORMAT_I420: planar 4:2:0 YUV
+ * @GST_VIDEO_FORMAT_YV12: planar 4:2:0 YVU (like I420 but UV planes swapped)
+ * @GST_VIDEO_FORMAT_YUY2: packed 4:2:2 YUV (Y0-U0-Y1-V0 Y2-U2-Y3-V2 Y4 ...)
+- * @GST_VIDEO_FORMAT_UYVY: packed 4:2:2 YUV (U0-Y0-V0-Y1 U2-Y2-V2-Y3 U4 ...)
++ * @GST_VIDEO_FORMAT_UYVY: packed 4:2:2 YUV (U0-Y0-V0-Y1 U2-Y2-V2-Y3 U4 ...)
+ * @GST_VIDEO_FORMAT_AYUV: packed 4:4:4 YUV with alpha channel (A0-Y0-U0-V0 ...)
+ * @GST_VIDEO_FORMAT_RGBx: sparse rgb packed into 32 bit, space last
+ * @GST_VIDEO_FORMAT_BGRx: sparse reverse rgb packed into 32 bit, space last
+@@ -245,13 +245,13 @@ typedef enum {
+
+ #define GST_VIDEO_CAPS_RGBx \
+ __GST_VIDEO_CAPS_MAKE_32 (1, 2, 3)
+-
++
+ #define GST_VIDEO_CAPS_xRGB \
+ __GST_VIDEO_CAPS_MAKE_32 (2, 3, 4)
+-
++
+ #define GST_VIDEO_CAPS_BGRx \
+ __GST_VIDEO_CAPS_MAKE_32 (3, 2, 1)
+-
++
+ #define GST_VIDEO_CAPS_xBGR \
+ __GST_VIDEO_CAPS_MAKE_32 (4, 3, 2)
+
+@@ -259,13 +259,13 @@ typedef enum {
+
+ #define GST_VIDEO_CAPS_RGBA \
+ __GST_VIDEO_CAPS_MAKE_32A (1, 2, 3, 4)
+-
++
+ #define GST_VIDEO_CAPS_ARGB \
+ __GST_VIDEO_CAPS_MAKE_32A (2, 3, 4, 1)
+-
++
+ #define GST_VIDEO_CAPS_BGRA \
+ __GST_VIDEO_CAPS_MAKE_32A (3, 2, 1, 4)
+-
++
+ #define GST_VIDEO_CAPS_ABGR \
+ __GST_VIDEO_CAPS_MAKE_32A (4, 3, 2, 1)
+
+@@ -281,7 +281,7 @@ typedef enum {
+ #define GST_VIDEO_CAPS_BGRx_HOST_ENDIAN \
+ GST_VIDEO_CAPS_xRGB
+ #endif
+-
++
+ /* 15/16 bit */
+
+ #define GST_VIDEO_CAPS_RGB_16 \
+@@ -395,13 +395,15 @@ gboolean gst_video_get_size (GstPad *pad,
+ gint *height);
+
+ gboolean gst_video_calculate_display_ratio (guint *dar_n, guint *dar_d,
+- guint video_width, guint video_height,
+- guint video_par_n, guint video_par_d,
++ guint video_width, guint video_height,
++ guint video_par_n, guint video_par_d,
+ guint display_par_n, guint display_par_d);
+
+ gboolean gst_video_format_parse_caps (GstCaps *caps, GstVideoFormat *format,
+ int *width, int *height);
+ gboolean gst_video_format_parse_caps_interlaced (GstCaps *caps, gboolean *interlaced);
++gboolean gst_video_format_parse_caps_strided (GstCaps * caps, GstVideoFormat * format,
++ int *width, int *height, int *rowstride);
+ gboolean gst_video_parse_caps_framerate (GstCaps *caps,
+ int *fps_n, int *fps_d);
+ gboolean gst_video_parse_caps_pixel_aspect_ratio (GstCaps *caps,
+@@ -415,6 +417,9 @@ GstCaps * gst_video_format_new_caps (GstVideoFormat format,
+ GstCaps * gst_video_format_new_caps_interlaced (GstVideoFormat format,
+ int width, int height, int framerate_n, int framerate_d,
+ int par_n, int par_d, gboolean interlaced);
++GstCaps * gst_video_format_new_caps_strided (GstVideoFormat format,
++ int width, int height, int rowstride,
++ int framerate_n, int framerate_d, int par_n, int par_d);
+ GstVideoFormat gst_video_format_from_fourcc (guint32 fourcc);
+ guint32 gst_video_format_to_fourcc (GstVideoFormat format);
+ gboolean gst_video_format_is_rgb (GstVideoFormat format);
+@@ -431,6 +436,8 @@ int gst_video_format_get_component_height (GstVideoFormat format, int component,
+ int gst_video_format_get_component_offset (GstVideoFormat format, int component,
+ int width, int height);
+ int gst_video_format_get_size (GstVideoFormat format, int width, int height);
++int gst_video_format_get_size_strided (GstVideoFormat format,
++ int width, int height, int rowstride);
+ gboolean gst_video_format_convert (GstVideoFormat format, int width, int height,
+ int fps_n, int fps_d,
+ GstFormat src_format, gint64 src_value,
+--
+1.7.1
+
diff --git a/media-libs/gst-plugins-base/files/gst-0.10.32-0002-stridetransform-skeletal-implementation-of-stridetra.patch b/media-libs/gst-plugins-base/files/gst-0.10.32-0002-stridetransform-skeletal-implementation-of-stridetra.patch
new file mode 100644
index 0000000..6e88172
--- /dev/null
+++ b/media-libs/gst-plugins-base/files/gst-0.10.32-0002-stridetransform-skeletal-implementation-of-stridetra.patch
@@ -0,0 +1,368 @@
+From 9820616aad713a23aa9d0e2afe44835d9e9278e5 Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Thu, 30 Jul 2009 20:41:18 -0500
+Subject: [PATCH 02/24] stridetransform: skeletal implementation of stridetransform element
+
+---
+ configure.ac | 2 +
+ gst/stride/Makefile.am | 15 ++++
+ gst/stride/gststridetransform.c | 178 +++++++++++++++++++++++++++++++++++++++
+ gst/stride/gststridetransform.h | 66 ++++++++++++++
+ gst/stride/plugin.c | 45 ++++++++++
+ 5 files changed, 306 insertions(+), 0 deletions(-)
+ create mode 100644 gst/stride/Makefile.am
+ create mode 100644 gst/stride/gststridetransform.c
+ create mode 100644 gst/stride/gststridetransform.h
+ create mode 100644 gst/stride/plugin.c
+
+diff --git a/configure.ac b/configure.ac
+index 3325abc..af6cd52 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -427,6 +427,7 @@ AG_GST_CHECK_PLUGIN(ffmpegcolorspace)
+ AG_GST_CHECK_PLUGIN(gdp)
+ AG_GST_CHECK_PLUGIN(playback)
+ AG_GST_CHECK_PLUGIN(audioresample)
++AG_GST_CHECK_PLUGIN(stride)
+ AG_GST_CHECK_PLUGIN(subparse)
+ AG_GST_CHECK_PLUGIN(tcp)
+ AG_GST_CHECK_PLUGIN(typefind)
+@@ -925,6 +926,7 @@ gst/ffmpegcolorspace/Makefile
+ gst/gdp/Makefile
+ gst/playback/Makefile
+ gst/audioresample/Makefile
++gst/stride/Makefile
+ gst/subparse/Makefile
+ gst/tcp/Makefile
+ gst/typefind/Makefile
+diff --git a/gst/stride/Makefile.am b/gst/stride/Makefile.am
+new file mode 100644
+index 0000000..1adc197
+--- /dev/null
++++ b/gst/stride/Makefile.am
+@@ -0,0 +1,15 @@
++plugin_LTLIBRARIES = libgststridetransform.la
++
++libgststridetransform_la_SOURCES = \
++ gststridetransform.c \
++ plugin.c
++
++libgststridetransform_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS)
++libgststridetransform_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
++libgststridetransform_la_LIBADD = \
++ $(top_builddir)/gst-libs/gst/video/libgstvideo-@GST_MAJORMINOR@.la \
++ $(GST_BASE_LIBS) $(GST_LIBS) $(LIBM)
++libgststridetransform_la_LIBTOOLFLAGS = --tag=disable-static
++
++noinst_HEADERS = \
++ gststridetransform.h
+diff --git a/gst/stride/gststridetransform.c b/gst/stride/gststridetransform.c
+new file mode 100644
+index 0000000..21f2d6e
+--- /dev/null
++++ b/gst/stride/gststridetransform.c
+@@ -0,0 +1,178 @@
++/* GStreamer
++ *
++ * Copyright (C) 2009 Texas Instruments, Inc - http://www.ti.com/
++ *
++ * Description: V4L2 sink element
++ * Created on: Jul 30, 2009
++ * Author: Rob Clark <rob@ti.com>
++ *
++ * 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-stridetransform
++ *
++ * stridetransform can be used to convert between video buffers
++ * with and without stride, or between buffers with differing
++ * stride
++ *
++ * <refsect2>
++ * <title>Example launch lines</title>
++ * |[
++ * gst-launch ???? TODO
++ * ]| This pipeline ???? TODO
++ * </refsect2>
++ */
++
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include "gststridetransform.h"
++#include "gst/gst-i18n-plugin.h"
++
++
++static const GstElementDetails stridetransform_details =
++GST_ELEMENT_DETAILS ("Stride transform",
++ "Filter/Converter/Video",
++ "Convert between video buffers with and without stride, or with differing stride",
++ "Rob Clark <rob@ti.com>,");
++
++GST_DEBUG_CATEGORY (stridetransform_debug);
++#define GST_CAT_DEFAULT stridetransform_debug
++
++/* type functions */
++static void gst_stride_transform_dispose (GObject * obj);
++
++/* GstBaseTransform functions */
++static gboolean gst_stride_transform_get_unit_size (GstBaseTransform * base,
++ GstCaps * caps, guint * size);
++static GstCaps *gst_stride_transform_transform_caps (GstBaseTransform * base,
++ GstPadDirection direction, GstCaps * caps);
++static void gst_stride_transform_fixate_caps (GstBaseTransform * base,
++ GstPadDirection direction, GstCaps * caps, GstCaps * othercaps);
++static gboolean gst_stride_transform_set_caps (GstBaseTransform * base,
++ GstCaps * incaps, GstCaps * outcaps);
++static GstFlowReturn gst_stride_transform_transform (GstBaseTransform * base,
++ GstBuffer * inbuf, GstBuffer * outbuf);
++static GstFlowReturn gst_stride_transform_transform_ip (GstBaseTransform * base,
++ GstBuffer * buf);
++
++GST_BOILERPLATE (GstStrideTransform, gst_stride_transform, GstVideoFilter, GST_TYPE_VIDEO_FILTER);
++
++
++static void
++gst_stride_transform_base_init (gpointer g_class)
++{
++ GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
++
++ GST_DEBUG_CATEGORY_INIT (stridetransform_debug, "stride", 0, "stride transform element");
++
++ gst_element_class_set_details (gstelement_class, &stridetransform_details);
++}
++
++static void
++gst_stride_transform_class_init (GstStrideTransformClass * klass)
++{
++ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
++ GstBaseTransformClass *basetransform_class = GST_BASE_TRANSFORM_CLASS (klass);
++
++ gobject_class->dispose = gst_stride_transform_dispose;
++
++ basetransform_class->get_unit_size =
++ GST_DEBUG_FUNCPTR (gst_stride_transform_get_unit_size);
++ basetransform_class->transform_caps =
++ GST_DEBUG_FUNCPTR (gst_stride_transform_transform_caps);
++ basetransform_class->fixate_caps =
++ GST_DEBUG_FUNCPTR (gst_stride_transform_fixate_caps);
++ basetransform_class->set_caps =
++ GST_DEBUG_FUNCPTR (gst_stride_transform_set_caps);
++ basetransform_class->transform_ip =
++ GST_DEBUG_FUNCPTR (gst_stride_transform_transform_ip);
++ basetransform_class->transform =
++ GST_DEBUG_FUNCPTR (gst_stride_transform_transform);
++
++ basetransform_class->passthrough_on_same_caps = TRUE;
++}
++
++static void
++gst_stride_transform_init (GstStrideTransform * self, GstStrideTransformClass * klass)
++{
++ GST_DEBUG_OBJECT (self, "not implemented");
++}
++
++
++static void
++gst_stride_transform_dispose (GObject * object)
++{
++ GstStrideTransform *self = GST_STRIDE_TRANSFORM (object);
++ GST_DEBUG_OBJECT (self, "not implemented");
++ G_OBJECT_CLASS (parent_class)->dispose (object);
++}
++
++static gboolean
++gst_stride_transform_get_unit_size (GstBaseTransform * base,
++ GstCaps * caps, guint * size)
++{
++ GstStrideTransform *self = GST_STRIDE_TRANSFORM (base);
++ GST_DEBUG_OBJECT (self, "not implemented");
++ return FALSE;
++}
++
++static GstCaps *
++gst_stride_transform_transform_caps (GstBaseTransform * base,
++ GstPadDirection direction, GstCaps * caps)
++{
++ GstStrideTransform *self = GST_STRIDE_TRANSFORM (base);
++ GST_DEBUG_OBJECT (self, "not implemented");
++ return NULL;
++}
++
++static void
++gst_stride_transform_fixate_caps (GstBaseTransform * base,
++ GstPadDirection direction, GstCaps * caps, GstCaps * othercaps)
++{
++ GstStrideTransform *self = GST_STRIDE_TRANSFORM (base);
++ GST_DEBUG_OBJECT (self, "not implemented");
++}
++
++static gboolean
++gst_stride_transform_set_caps (GstBaseTransform * base,
++ GstCaps * incaps, GstCaps * outcaps)
++{
++ GstStrideTransform *self = GST_STRIDE_TRANSFORM (base);
++ GST_DEBUG_OBJECT (self, "not implemented");
++ return FALSE;
++}
++
++static GstFlowReturn gst_stride_transform_transform (GstBaseTransform * base,
++ GstBuffer * inbuf, GstBuffer * outbuf)
++{
++ GstStrideTransform *self = GST_STRIDE_TRANSFORM (base);
++ GST_DEBUG_OBJECT (self, "not implemented");
++ return GST_FLOW_ERROR;
++}
++
++static GstFlowReturn
++gst_stride_transform_transform_ip (GstBaseTransform * base,
++ GstBuffer * buf)
++{
++ GstStrideTransform *self = GST_STRIDE_TRANSFORM (base);
++ GST_DEBUG_OBJECT (self, "not implemented");
++ return GST_FLOW_ERROR;
++}
+diff --git a/gst/stride/gststridetransform.h b/gst/stride/gststridetransform.h
+new file mode 100644
+index 0000000..b4f7d59
+--- /dev/null
++++ b/gst/stride/gststridetransform.h
+@@ -0,0 +1,66 @@
++/* GStreamer
++ *
++ * Copyright (C) 2009 Texas Instruments, Inc - http://www.ti.com/
++ *
++ * Description: V4L2 sink element
++ * Created on: Jul 2, 2009
++ * Author: Rob Clark <rob@ti.com>
++ *
++ * 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 __GSTSTRIDETRANSFORM_H__
++#define __GSTSTRIDETRANSFORM_H__
++
++
++#include <gst/video/gstvideofilter.h>
++
++G_BEGIN_DECLS
++
++#define GST_TYPE_STRIDE_TRANSFORM \
++ (gst_stride_transform_get_type())
++#define GST_STRIDE_TRANSFORM(obj) \
++ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_STRIDE_TRANSFORM,GstStrideTransform))
++#define GST_STRIDE_TRANSFORM_CLASS(klass) \
++ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_STRIDE_TRANSFORM,GstStrideTransformClass))
++#define GST_IS_STRIDE_TRANSFORM(obj) \
++ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_STRIDE_TRANSFORM))
++#define GST_IS_STRIDE_TRANSFORM_CLASS(klass) \
++ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_STRIDE_TRANSFORM))
++
++typedef struct _GstStrideTransform GstStrideTransform;
++typedef struct _GstStrideTransformClass GstStrideTransformClass;
++
++/**
++ * GstStrideTransform:
++ *
++ * Opaque datastructure.
++ */
++struct _GstStrideTransform {
++ GstVideoFilter videofilter;
++
++};
++
++struct _GstStrideTransformClass {
++ GstVideoFilterClass parent_class;
++};
++
++GType gst_stride_transform_get_type (void);
++
++G_END_DECLS
++
++
++#endif /* __GSTSTRIDETRANSFORM_H__ */
+diff --git a/gst/stride/plugin.c b/gst/stride/plugin.c
+new file mode 100644
+index 0000000..7672bdc
+--- /dev/null
++++ b/gst/stride/plugin.c
+@@ -0,0 +1,45 @@
++/* GStreamer
++ *
++ * Copyright (C) 2009 Texas Instruments, Inc - http://www.ti.com/
++ *
++ * Description: V4L2 sink element
++ * Created on: Jul 30, 2009
++ * Author: Rob Clark <rob@ti.com>
++ *
++ * 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.
++ */
++
++#ifdef HAVE_CONFIG_H
++#include "config.h"
++#endif
++
++#include "gststridetransform.h"
++
++static gboolean
++plugin_init (GstPlugin * plugin)
++{
++ if (!gst_element_register (plugin, "stridetransform",
++ GST_RANK_PRIMARY, gst_stride_transform_get_type ()))
++ return FALSE;
++
++ return TRUE;
++}
++
++GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
++ GST_VERSION_MINOR,
++ "stridetransform",
++ "Convert video from strided to non-strided, or between different row-strides",
++ plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
+--
+1.7.1
+
diff --git a/media-libs/gst-plugins-base/files/gst-0.10.32-0003-stridetransform-implement-caps-negotiation-and-relat.patch b/media-libs/gst-plugins-base/files/gst-0.10.32-0003-stridetransform-implement-caps-negotiation-and-relat.patch
new file mode 100644
index 0000000..faf97a1
--- /dev/null
+++ b/media-libs/gst-plugins-base/files/gst-0.10.32-0003-stridetransform-implement-caps-negotiation-and-relat.patch
@@ -0,0 +1,379 @@
+From c235770f9e1c73dc75d6873166bc1ef69770a6c1 Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Fri, 31 Jul 2009 16:31:42 -0500
+Subject: [PATCH 03/24] stridetransform: implement caps negotiation and related parts
+
+now all that is left is to implement the actual transform functions
+---
+ gst-libs/gst/video/video.h | 10 ++
+ gst/stride/gststridetransform.c | 190 ++++++++++++++++++++++++++++++---------
+ gst/stride/gststridetransform.h | 38 ++++++++
+ 3 files changed, 196 insertions(+), 42 deletions(-)
+
+diff --git a/gst-libs/gst/video/video.h b/gst-libs/gst/video/video.h
+index a6a2293..5bac21f 100644
+--- a/gst-libs/gst/video/video.h
++++ b/gst-libs/gst/video/video.h
+@@ -356,6 +356,16 @@ typedef enum {
+ "height = " GST_VIDEO_SIZE_RANGE ", " \
+ "framerate = " GST_VIDEO_FPS_RANGE
+
++
++#define GST_VIDEO_CAPS_YUV_STRIDED(fourcc, rowstride) \
++ GST_VIDEO_CAPS_YUV(fourcc) "; " \
++ "video/x-raw-yuv-strided, " \
++ "format = (fourcc) " fourcc ", " \
++ "rowstride = (int) " rowstride ", " \
++ "width = " GST_VIDEO_SIZE_RANGE ", " \
++ "height = " GST_VIDEO_SIZE_RANGE ", " \
++ "framerate = " GST_VIDEO_FPS_RANGE
++
+ /* buffer flags */
+
+ /**
+diff --git a/gst/stride/gststridetransform.c b/gst/stride/gststridetransform.c
+index 21f2d6e..e31bf11 100644
+--- a/gst/stride/gststridetransform.c
++++ b/gst/stride/gststridetransform.c
+@@ -33,7 +33,10 @@
+ * <refsect2>
+ * <title>Example launch lines</title>
+ * |[
+- * gst-launch ???? TODO
++ * gst-launch videotestsrc ! video/x-raw-yuv,format=(fourcc)YUY2,width=320,height=240,framerate=30/1 !
++ * stridetransform ! video/x-raw-yuv-strided,format=(fourcc)YUY2,width=320,height=240,rowstride=700,framerate=30/1 !
++ * stridetransform ! video/x-raw-yuv,format=(fourcc)YUY2,width=320,height=240,framerate=30/1 !
++ * v4l2sink
+ * ]| This pipeline ???? TODO
+ * </refsect2>
+ */
+@@ -43,8 +46,11 @@
+ #include <config.h>
+ #endif
+
+-#include "gststridetransform.h"
++#include <string.h>
++#include <gst/video/video.h>
++
+ #include "gst/gst-i18n-plugin.h"
++#include "gststridetransform.h"
+
+
+ static const GstElementDetails stridetransform_details =
+@@ -53,25 +59,44 @@ GST_ELEMENT_DETAILS ("Stride transform",
+ "Convert between video buffers with and without stride, or with differing stride",
+ "Rob Clark <rob@ti.com>,");
+
++
++/* TODO: add rgb formats too! */
++#define SUPPORTED_CAPS \
++ GST_VIDEO_CAPS_YUV_STRIDED ("{ I420, YV12, YUY2 }", "[ 0, max ]")
++
++
++static GstStaticPadTemplate src_template =
++GST_STATIC_PAD_TEMPLATE ("src",
++ GST_PAD_SRC,
++ GST_PAD_ALWAYS,
++ GST_STATIC_CAPS (SUPPORTED_CAPS)
++ );
++
++static GstStaticPadTemplate sink_template =
++GST_STATIC_PAD_TEMPLATE ("sink",
++ GST_PAD_SINK,
++ GST_PAD_ALWAYS,
++ GST_STATIC_CAPS (SUPPORTED_CAPS)
++ );
++
++
+ GST_DEBUG_CATEGORY (stridetransform_debug);
+ #define GST_CAT_DEFAULT stridetransform_debug
+
+ /* type functions */
+-static void gst_stride_transform_dispose (GObject * obj);
++static void gst_stride_transform_dispose (GObject *obj);
+
+ /* GstBaseTransform functions */
+-static gboolean gst_stride_transform_get_unit_size (GstBaseTransform * base,
+- GstCaps * caps, guint * size);
+-static GstCaps *gst_stride_transform_transform_caps (GstBaseTransform * base,
+- GstPadDirection direction, GstCaps * caps);
+-static void gst_stride_transform_fixate_caps (GstBaseTransform * base,
+- GstPadDirection direction, GstCaps * caps, GstCaps * othercaps);
+-static gboolean gst_stride_transform_set_caps (GstBaseTransform * base,
+- GstCaps * incaps, GstCaps * outcaps);
+-static GstFlowReturn gst_stride_transform_transform (GstBaseTransform * base,
+- GstBuffer * inbuf, GstBuffer * outbuf);
+-static GstFlowReturn gst_stride_transform_transform_ip (GstBaseTransform * base,
+- GstBuffer * buf);
++static gboolean gst_stride_transform_get_unit_size (GstBaseTransform *base,
++ GstCaps *caps, guint *size);
++static GstCaps *gst_stride_transform_transform_caps (GstBaseTransform *base,
++ GstPadDirection direction, GstCaps *caps);
++static gboolean gst_stride_transform_set_caps (GstBaseTransform *base,
++ GstCaps *incaps, GstCaps *outcaps);
++static GstFlowReturn gst_stride_transform_transform (GstBaseTransform *base,
++ GstBuffer *inbuf, GstBuffer *outbuf);
++static GstFlowReturn gst_stride_transform_transform_ip (GstBaseTransform *base,
++ GstBuffer *buf);
+
+ GST_BOILERPLATE (GstStrideTransform, gst_stride_transform, GstVideoFilter, GST_TYPE_VIDEO_FILTER);
+
+@@ -84,10 +109,15 @@ gst_stride_transform_base_init (gpointer g_class)
+ GST_DEBUG_CATEGORY_INIT (stridetransform_debug, "stride", 0, "stride transform element");
+
+ gst_element_class_set_details (gstelement_class, &stridetransform_details);
++
++ gst_element_class_add_pad_template (gstelement_class,
++ gst_static_pad_template_get (&sink_template));
++ gst_element_class_add_pad_template (gstelement_class,
++ gst_static_pad_template_get (&src_template));
+ }
+
+ static void
+-gst_stride_transform_class_init (GstStrideTransformClass * klass)
++gst_stride_transform_class_init (GstStrideTransformClass *klass)
+ {
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GstBaseTransformClass *basetransform_class = GST_BASE_TRANSFORM_CLASS (klass);
+@@ -98,8 +128,6 @@ gst_stride_transform_class_init (GstStrideTransformClass * klass)
+ GST_DEBUG_FUNCPTR (gst_stride_transform_get_unit_size);
+ basetransform_class->transform_caps =
+ GST_DEBUG_FUNCPTR (gst_stride_transform_transform_caps);
+- basetransform_class->fixate_caps =
+- GST_DEBUG_FUNCPTR (gst_stride_transform_fixate_caps);
+ basetransform_class->set_caps =
+ GST_DEBUG_FUNCPTR (gst_stride_transform_set_caps);
+ basetransform_class->transform_ip =
+@@ -111,57 +139,135 @@ gst_stride_transform_class_init (GstStrideTransformClass * klass)
+ }
+
+ static void
+-gst_stride_transform_init (GstStrideTransform * self, GstStrideTransformClass * klass)
++gst_stride_transform_init (GstStrideTransform *self, GstStrideTransformClass *klass)
+ {
+ GST_DEBUG_OBJECT (self, "not implemented");
+ }
+
+
+ static void
+-gst_stride_transform_dispose (GObject * object)
++gst_stride_transform_dispose (GObject *object)
+ {
+ GstStrideTransform *self = GST_STRIDE_TRANSFORM (object);
+ GST_DEBUG_OBJECT (self, "not implemented");
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+ }
+
++/**
++ * figure out the required buffer size based on @caps
++ */
+ static gboolean
+-gst_stride_transform_get_unit_size (GstBaseTransform * base,
+- GstCaps * caps, guint * size)
++gst_stride_transform_get_unit_size (GstBaseTransform *base,
++ GstCaps *caps, guint *size)
+ {
+ GstStrideTransform *self = GST_STRIDE_TRANSFORM (base);
+- GST_DEBUG_OBJECT (self, "not implemented");
+- return FALSE;
++ GstVideoFormat format;
++ gint width, height, rowstride;
++
++ g_return_val_if_fail (gst_video_format_parse_caps_strided (
++ caps, &format, &width, &height, &rowstride), FALSE);
++
++ *size = gst_video_format_get_size_strided (format, width, height, rowstride);
++
++ GST_DEBUG_OBJECT (self,
++ "format=%d, width=%d, height=%d, rowstride=%d -> size=%d",
++ format, width, height, rowstride, *size);
++
++ return TRUE;
+ }
+
+-static GstCaps *
+-gst_stride_transform_transform_caps (GstBaseTransform * base,
+- GstPadDirection direction, GstCaps * caps)
++
++/**
++ * helper to add all fields, other than rowstride to @caps, copied from @s.
++ */
++static void
++add_all_fields (GstCaps *caps, const gchar *name, GstStructure *s, gboolean rowstride)
+ {
+- GstStrideTransform *self = GST_STRIDE_TRANSFORM (base);
+- GST_DEBUG_OBJECT (self, "not implemented");
+- return NULL;
++ gint idx;
++ GstStructure *new_s = gst_structure_new (name, NULL);
++
++ if (rowstride) {
++ gst_structure_set (new_s, "rowstride", GST_TYPE_INT_RANGE, 1, 1000, NULL); // XXX
++ }
++
++ idx = gst_structure_n_fields (s) - 1;
++ while (idx >= 0) {
++ const gchar *name = gst_structure_nth_field_name (s, idx);
++ if (strcmp ("rowstride", name)) {
++ const GValue *val = gst_structure_get_value (s, name);
++ gst_structure_set_value (new_s, name, val);
++ }
++ idx--;
++ }
++
++ gst_caps_merge_structure (caps, new_s);
+ }
+
+-static void
+-gst_stride_transform_fixate_caps (GstBaseTransform * base,
+- GstPadDirection direction, GstCaps * caps, GstCaps * othercaps)
++
++/**
++ * we can transform @caps to strided or non-strided caps with otherwise
++ * identical parameters
++ */
++static GstCaps *
++gst_stride_transform_transform_caps (GstBaseTransform *base,
++ GstPadDirection direction, GstCaps *caps)
+ {
+ GstStrideTransform *self = GST_STRIDE_TRANSFORM (base);
+- GST_DEBUG_OBJECT (self, "not implemented");
++ GstCaps *ret;
++ GstStructure *s;
++
++ g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), NULL);
++
++ GST_DEBUG_OBJECT (self, "direction=%d, caps=%p", direction, caps);
++ LOG_CAPS (self, caps);
++
++ ret = gst_caps_new_empty ();
++ s = gst_caps_get_structure (caps, 0);
++
++ if (gst_structure_has_name (s, "video/x-raw-yuv") ||
++ gst_structure_has_name (s, "video/x-raw-yuv-strided")) {
++
++ add_all_fields (ret, "video/x-raw-yuv", s, FALSE);
++ add_all_fields (ret, "video/x-raw-yuv-strided", s, TRUE);
++
++ } else if (gst_structure_has_name (s, "video/x-raw-rgb") ||
++ gst_structure_has_name (s, "video/x-raw-rgb-strided")) {
++
++ add_all_fields (ret, "video/x-raw-rgb", s, FALSE);
++ add_all_fields (ret, "video/x-raw-rgb-strided", s, TRUE);
++
++ }
++
++ LOG_CAPS (self, ret);
++
++ return ret;
+ }
+
++/**
++ * at this point, we have identical fourcc, width, and height for @incaps
++ * and @outcaps.. so we need to extract these to use for transforming,
++ * plus the requested rowstride of the @incaps and @outcaps
++ */
+ static gboolean
+-gst_stride_transform_set_caps (GstBaseTransform * base,
+- GstCaps * incaps, GstCaps * outcaps)
++gst_stride_transform_set_caps (GstBaseTransform *base,
++ GstCaps *incaps, GstCaps *outcaps)
+ {
+ GstStrideTransform *self = GST_STRIDE_TRANSFORM (base);
+- GST_DEBUG_OBJECT (self, "not implemented");
+- return FALSE;
++
++ LOG_CAPS (self, incaps);
++ LOG_CAPS (self, outcaps);
++
++ g_return_val_if_fail (gst_video_format_parse_caps_strided (incaps,
++ &self->format, &self->width, &self->height, &self->in_rowstride), FALSE);
++ g_return_val_if_fail (gst_video_format_parse_caps_strided (outcaps,
++ NULL, NULL, NULL, &self->out_rowstride), FALSE);
++
++ return TRUE;
+ }
+
+-static GstFlowReturn gst_stride_transform_transform (GstBaseTransform * base,
+- GstBuffer * inbuf, GstBuffer * outbuf)
++static GstFlowReturn
++gst_stride_transform_transform (GstBaseTransform *base,
++ GstBuffer *inbuf, GstBuffer *outbuf)
+ {
+ GstStrideTransform *self = GST_STRIDE_TRANSFORM (base);
+ GST_DEBUG_OBJECT (self, "not implemented");
+@@ -169,8 +275,8 @@ static GstFlowReturn gst_stride_transform_transform (GstBaseTransform * base,
+ }
+
+ static GstFlowReturn
+-gst_stride_transform_transform_ip (GstBaseTransform * base,
+- GstBuffer * buf)
++gst_stride_transform_transform_ip (GstBaseTransform *base,
++ GstBuffer *buf)
+ {
+ GstStrideTransform *self = GST_STRIDE_TRANSFORM (base);
+ GST_DEBUG_OBJECT (self, "not implemented");
+diff --git a/gst/stride/gststridetransform.h b/gst/stride/gststridetransform.h
+index b4f7d59..d80197f 100644
+--- a/gst/stride/gststridetransform.h
++++ b/gst/stride/gststridetransform.h
+@@ -27,6 +27,8 @@
+
+
+ #include <gst/video/gstvideofilter.h>
++#include <gst/video/video.h>
++
+
+ G_BEGIN_DECLS
+
+@@ -52,6 +54,11 @@ typedef struct _GstStrideTransformClass GstStrideTransformClass;
+ struct _GstStrideTransform {
+ GstVideoFilter videofilter;
+
++ /*< private >*/
++ GstVideoFormat format;
++ gint width, height;
++ gint in_rowstride;
++ gint out_rowstride;
+ };
+
+ struct _GstStrideTransformClass {
+@@ -63,4 +70,35 @@ GType gst_stride_transform_get_type (void);
+ G_END_DECLS
+
+
++
++
++/* note: in case this is a build with TTIF logging, we can optimize slightly
++ * and avoid the gst_caps_to_string() in case logging isn't enabled by using
++ * the TTIF_TRACE_ARG_PROCESSOR feature of ttif_trace_fprintf():
++ */
++#ifdef GST_LOG_OVER_TTIF
++# define LOG_CAPS(obj, caps) G_STMT_START { \
++ if (caps) { \
++ static TTIF_TRACE_ARG_PROCESSOR proc = { \
++ .convert = (char (*)(void *))gst_caps_to_string, \
++ .free = (void (*)(char *))g_free \
++ }; \
++ GST_DEBUG_OBJECT (obj, "%s: %qs", #caps, &proc, (caps)); \
++ } else { \
++ GST_DEBUG_OBJECT (obj, "null"); \
++ } \
++ } G_STMT_END
++#else
++# define LOG_CAPS(obj, caps) G_STMT_START { \
++ if (caps) { \
++ gchar *capstr = gst_caps_to_string (caps); \
++ GST_DEBUG_OBJECT (obj, "%s: %s", #caps, capstr); \
++ g_free (capstr); \
++ } else { \
++ GST_DEBUG_OBJECT (obj, "null"); \
++ } \
++ } G_STMT_END
++#endif
++
++
+ #endif /* __GSTSTRIDETRANSFORM_H__ */
+--
+1.7.1
+
diff --git a/media-libs/gst-plugins-base/files/gst-0.10.32-0004-stridetransform-implement-transform-function.patch b/media-libs/gst-plugins-base/files/gst-0.10.32-0004-stridetransform-implement-transform-function.patch
new file mode 100644
index 0000000..b948c02
--- /dev/null
+++ b/media-libs/gst-plugins-base/files/gst-0.10.32-0004-stridetransform-implement-transform-function.patch
@@ -0,0 +1,215 @@
+From 44d68a183355bce2dd7b6c890f67420ab300e0b4 Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Fri, 31 Jul 2009 17:39:47 -0500
+Subject: [PATCH 04/24] stridetransform: implement transform function
+
+Still needed are a few details, like conversion from one stride to another (instead of just strided->nonstrided or visa versa), and support for RGB and more YUV color formats.
+---
+ gst/stride/gststridetransform.c | 163 +++++++++++++++++++++++++++++++++++++--
+ 1 files changed, 157 insertions(+), 6 deletions(-)
+
+diff --git a/gst/stride/gststridetransform.c b/gst/stride/gststridetransform.c
+index e31bf11..a911cd0 100644
+--- a/gst/stride/gststridetransform.c
++++ b/gst/stride/gststridetransform.c
+@@ -187,7 +187,7 @@ add_all_fields (GstCaps *caps, const gchar *name, GstStructure *s, gboolean rows
+ GstStructure *new_s = gst_structure_new (name, NULL);
+
+ if (rowstride) {
+- gst_structure_set (new_s, "rowstride", GST_TYPE_INT_RANGE, 1, 1000, NULL); // XXX
++ gst_structure_set (new_s, "rowstride", GST_TYPE_INT_RANGE, 1, 1000, NULL); // TODO
+ }
+
+ idx = gst_structure_n_fields (s) - 1;
+@@ -253,6 +253,8 @@ gst_stride_transform_set_caps (GstBaseTransform *base,
+ GstCaps *incaps, GstCaps *outcaps)
+ {
+ GstStrideTransform *self = GST_STRIDE_TRANSFORM (base);
++ GstVideoFormat format;
++ gint width, height;
+
+ LOG_CAPS (self, incaps);
+ LOG_CAPS (self, outcaps);
+@@ -260,17 +262,166 @@ gst_stride_transform_set_caps (GstBaseTransform *base,
+ g_return_val_if_fail (gst_video_format_parse_caps_strided (incaps,
+ &self->format, &self->width, &self->height, &self->in_rowstride), FALSE);
+ g_return_val_if_fail (gst_video_format_parse_caps_strided (outcaps,
+- NULL, NULL, NULL, &self->out_rowstride), FALSE);
++ &format, &width, &height, &self->out_rowstride), FALSE);
++
++ g_return_val_if_fail (self->format == format, FALSE);
++ g_return_val_if_fail (self->width == width, FALSE);
++ g_return_val_if_fail (self->height == height, FALSE);
+
+ return TRUE;
+ }
+
++/* ************************************************************************* */
++
++/**
++ * Convert from one stride to another... like memmove, but can convert stride in
++ * the process. This function is not aware of pixels, only of bytes. So widths
++ * are given in bytes, not pixels. The new_buf and orig_buf can point to the
++ * same buffers to do an in-place conversion, but the buffer should be large
++ * enough.
++ */
++static void
++stridemove (guchar *new_buf, guchar *orig_buf, gint new_width, gint orig_width, gint height)
++{
++ int row;
++
++ GST_DEBUG ("new_buf=%p, orig_buf=%p, new_width=%d, orig_width=%d, height=%d",
++ new_buf, orig_buf, new_width, orig_width, height);
++ /* if increasing the stride, work from bottom-up to avoid overwriting data
++ * that has not been moved yet.. otherwise, work in the opposite order,
++ * for the same reason.
++ */
++ if (new_width > orig_width) {
++ for (row=height-1; row>=0; row--) {
++ memmove (new_buf+(new_width*row), orig_buf+(orig_width*row), orig_width);
++ }
++ } else {
++ for (row=0; row<height; row++) {
++ memmove (new_buf+(new_width*row), orig_buf+(orig_width*row), orig_width);
++ }
++ }
++}
++
++
++/**
++ * Convert from a non-strided buffer to strided. The two buffer pointers could
++ * be pointing to the same memory block for in-place transform.. assuming that
++ * the buffer is large enough
++ *
++ * @strided: the pointer to the resulting strided buffer
++ * @unstrided: the pointer to the initial unstrided buffer
++ * @fourcc: the color format
++ * @stride: the stride, in bytes
++ * @width: the width in pixels
++ * @height: the height in pixels
++ */
++static GstFlowReturn
++stridify (GstStrideTransform *self, guchar *strided, guchar *unstrided)
++{
++ gint width = self->width;
++ gint height = self->height;
++ gint stride = self->out_rowstride;
++
++ switch (self->format) {
++#if 0 /* TODO */
++ case GST_VIDEO_FORMAT_NV12:
++ g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
++ stridemove (strided, unstrided, stride, width, height * 1.5);
++ return GST_FLOW_OK;
++#endif
++ case GST_VIDEO_FORMAT_I420:
++ case GST_VIDEO_FORMAT_YV12:
++ g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
++ stridemove (
++ strided + (int)(height*stride*1.5),
++ unstrided + (int)(height*width*1.5),
++ stride, width/2, height); /* move U/V */
++ stridemove (
++ strided + (height*stride),
++ unstrided + (height*width),
++ stride, width/2, height); /* move V/U */
++ stridemove (strided, unstrided, stride, width, height); /* move Y */
++ return GST_FLOW_OK;
++ case GST_VIDEO_FORMAT_YUY2:
++ case GST_VIDEO_FORMAT_UYVY:
++ g_return_val_if_fail (stride >= (width*2), GST_FLOW_ERROR);
++ stridemove (strided, unstrided, stride, width*2, height);
++ return GST_FLOW_OK;
++ default:
++ GST_WARNING ("unknown color format!\n");
++ return GST_FLOW_ERROR;
++ }
++}
++
++
++/**
++ * Convert from a strided buffer to non-strided. The two buffer pointers could
++ * be pointing to the same memory block for in-place transform..
++ *
++ * @unstrided: the pointer to the resulting unstrided buffer
++ * @strided: the pointer to the initial strided buffer
++ */
++static GstFlowReturn
++unstridify (GstStrideTransform *self, guchar *unstrided, guchar *strided)
++{
++ gint width = self->width;
++ gint height = self->height;
++ gint stride = self->in_rowstride;
++
++ switch (self->format) {
++#if 0 /* TODO */
++ case GST_VIDEO_FORMAT_NV12:
++ g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
++ stridemove (unstrided, strided, width, stride, height * 1.5);
++ return GST_FLOW_OK;
++#endif
++ case GST_VIDEO_FORMAT_I420:
++ case GST_VIDEO_FORMAT_YV12:
++ g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
++ stridemove (unstrided, strided, width, stride, height); /* move Y */
++ stridemove (
++ unstrided + (height*width),
++ strided + (height*stride),
++ width/2, stride, height); /* move V/U */
++ stridemove (
++ unstrided + (int)(height*width*1.5),
++ strided + (int)(height*stride*1.5),
++ width/2, stride, height); /* move U/V */
++ return GST_FLOW_OK;
++ case GST_VIDEO_FORMAT_YUY2:
++ case GST_VIDEO_FORMAT_UYVY:
++ g_return_val_if_fail (stride >= (width*2), GST_FLOW_ERROR);
++ stridemove (unstrided, strided, width*2, stride, height);
++ return GST_FLOW_OK;
++ default:
++ GST_WARNING ("unknown color format!\n");
++ return GST_FLOW_ERROR;
++ }
++}
++
++
+ static GstFlowReturn
+ gst_stride_transform_transform (GstBaseTransform *base,
+ GstBuffer *inbuf, GstBuffer *outbuf)
+ {
+ GstStrideTransform *self = GST_STRIDE_TRANSFORM (base);
+- GST_DEBUG_OBJECT (self, "not implemented");
++
++ GST_DEBUG_OBJECT (self, "inbuf=%p, outbuf=%p", inbuf, outbuf);
++
++ if (self->in_rowstride && self->out_rowstride) {
++ GST_DEBUG_OBJECT (self, "not implemented"); // TODO
++ return GST_FLOW_ERROR;
++ } else if (self->in_rowstride) {
++ return unstridify (self,
++ GST_BUFFER_DATA (outbuf), GST_BUFFER_DATA (inbuf));
++ } else if (self->out_rowstride) {
++ return stridify (self,
++ GST_BUFFER_DATA (outbuf), GST_BUFFER_DATA (inbuf));
++ }
++
++ GST_DEBUG_OBJECT (self, "this shouldn't happen! in_rowstride=%d, out_rowstride=%d",
++ self->in_rowstride, self->out_rowstride);
++
+ return GST_FLOW_ERROR;
+ }
+
+@@ -278,7 +429,7 @@ static GstFlowReturn
+ gst_stride_transform_transform_ip (GstBaseTransform *base,
+ GstBuffer *buf)
+ {
+- GstStrideTransform *self = GST_STRIDE_TRANSFORM (base);
+- GST_DEBUG_OBJECT (self, "not implemented");
+- return GST_FLOW_ERROR;
++ /* transform function is safe to call with same buffer ptr:
++ */
++ return gst_stride_transform_transform (base, buf, buf);
+ }
+--
+1.7.1
+
diff --git a/media-libs/gst-plugins-base/files/gst-0.10.32-0005-add-gst_stride_transform_transform_size.patch b/media-libs/gst-plugins-base/files/gst-0.10.32-0005-add-gst_stride_transform_transform_size.patch
new file mode 100644
index 0000000..2a791d0
--- /dev/null
+++ b/media-libs/gst-plugins-base/files/gst-0.10.32-0005-add-gst_stride_transform_transform_size.patch
@@ -0,0 +1,143 @@
+From c1b33e01fa6fa867b950ba0e6f4426e5a878cbe7 Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Sun, 16 Aug 2009 21:04:40 -0500
+Subject: [PATCH 05/24] add gst_stride_transform_transform_size()
+
+input buffer size and output buffer size many not be multiples of a common unit size, so the transform_size() method should be used
+---
+ gst/stride/gststridetransform.c | 38 ++++++++++++++++++++++++++++++++++++--
+ gst/stride/gststridetransform.h | 34 +++++-----------------------------
+ 2 files changed, 41 insertions(+), 31 deletions(-)
+
+diff --git a/gst/stride/gststridetransform.c b/gst/stride/gststridetransform.c
+index a911cd0..adc22ce 100644
+--- a/gst/stride/gststridetransform.c
++++ b/gst/stride/gststridetransform.c
+@@ -62,7 +62,7 @@ GST_ELEMENT_DETAILS ("Stride transform",
+
+ /* TODO: add rgb formats too! */
+ #define SUPPORTED_CAPS \
+- GST_VIDEO_CAPS_YUV_STRIDED ("{ I420, YV12, YUY2 }", "[ 0, max ]")
++ GST_VIDEO_CAPS_YUV_STRIDED ("{ I420, YV12, YUY2, UYVY }", "[ 0, max ]")
+
+
+ static GstStaticPadTemplate src_template =
+@@ -89,6 +89,10 @@ static void gst_stride_transform_dispose (GObject *obj);
+ /* GstBaseTransform functions */
+ static gboolean gst_stride_transform_get_unit_size (GstBaseTransform *base,
+ GstCaps *caps, guint *size);
++static gboolean gst_stride_transform_transform_size (GstBaseTransform *base,
++ GstPadDirection direction,
++ GstCaps *caps, guint size,
++ GstCaps *othercaps, guint *othersize);
+ static GstCaps *gst_stride_transform_transform_caps (GstBaseTransform *base,
+ GstPadDirection direction, GstCaps *caps);
+ static gboolean gst_stride_transform_set_caps (GstBaseTransform *base,
+@@ -126,6 +130,8 @@ gst_stride_transform_class_init (GstStrideTransformClass *klass)
+
+ basetransform_class->get_unit_size =
+ GST_DEBUG_FUNCPTR (gst_stride_transform_get_unit_size);
++ basetransform_class->transform_size =
++ GST_DEBUG_FUNCPTR (gst_stride_transform_transform_size);
+ basetransform_class->transform_caps =
+ GST_DEBUG_FUNCPTR (gst_stride_transform_transform_caps);
+ basetransform_class->set_caps =
+@@ -176,6 +182,34 @@ gst_stride_transform_get_unit_size (GstBaseTransform *base,
+ return TRUE;
+ }
+
++/**
++ * Default transform_size function is no good, as it assumes that the output
++ * buffer size is a multiple of the unit size.. which doesn't hold true.
++ */
++static gboolean
++gst_stride_transform_transform_size (GstBaseTransform *base,
++ GstPadDirection direction,
++ GstCaps *caps, guint size,
++ GstCaps *othercaps, guint *othersize)
++{
++ GstStrideTransform *self = GST_STRIDE_TRANSFORM (base);
++ guint idx = (direction == GST_PAD_SINK) ? 0 : 1;
++
++ if (self->cached_caps[idx] != othercaps)
++ {
++ if (!gst_stride_transform_get_unit_size (base, othercaps,
++ &(self->cached_size[idx])))
++ {
++ return FALSE;
++ }
++ }
++
++ *othersize = self->cached_size[idx];
++
++ return TRUE;
++}
++
++
+
+ /**
+ * helper to add all fields, other than rowstride to @caps, copied from @s.
+@@ -187,7 +221,7 @@ add_all_fields (GstCaps *caps, const gchar *name, GstStructure *s, gboolean rows
+ GstStructure *new_s = gst_structure_new (name, NULL);
+
+ if (rowstride) {
+- gst_structure_set (new_s, "rowstride", GST_TYPE_INT_RANGE, 1, 1000, NULL); // TODO
++ gst_structure_set (new_s, "rowstride", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
+ }
+
+ idx = gst_structure_n_fields (s) - 1;
+diff --git a/gst/stride/gststridetransform.h b/gst/stride/gststridetransform.h
+index d80197f..481959e 100644
+--- a/gst/stride/gststridetransform.h
++++ b/gst/stride/gststridetransform.h
+@@ -59,6 +59,10 @@ struct _GstStrideTransform {
+ gint width, height;
+ gint in_rowstride;
+ gint out_rowstride;
++
++ /* for caching the tranform_size() results.. */
++ GstCaps *cached_caps[2];
++ guint cached_size[2];
+ };
+
+ struct _GstStrideTransformClass {
+@@ -70,35 +74,7 @@ GType gst_stride_transform_get_type (void);
+ G_END_DECLS
+
+
+-
+-
+-/* note: in case this is a build with TTIF logging, we can optimize slightly
+- * and avoid the gst_caps_to_string() in case logging isn't enabled by using
+- * the TTIF_TRACE_ARG_PROCESSOR feature of ttif_trace_fprintf():
+- */
+-#ifdef GST_LOG_OVER_TTIF
+-# define LOG_CAPS(obj, caps) G_STMT_START { \
+- if (caps) { \
+- static TTIF_TRACE_ARG_PROCESSOR proc = { \
+- .convert = (char (*)(void *))gst_caps_to_string, \
+- .free = (void (*)(char *))g_free \
+- }; \
+- GST_DEBUG_OBJECT (obj, "%s: %qs", #caps, &proc, (caps)); \
+- } else { \
+- GST_DEBUG_OBJECT (obj, "null"); \
+- } \
+- } G_STMT_END
+-#else
+-# define LOG_CAPS(obj, caps) G_STMT_START { \
+- if (caps) { \
+- gchar *capstr = gst_caps_to_string (caps); \
+- GST_DEBUG_OBJECT (obj, "%s: %s", #caps, capstr); \
+- g_free (capstr); \
+- } else { \
+- GST_DEBUG_OBJECT (obj, "null"); \
+- } \
+- } G_STMT_END
+-#endif
++#define LOG_CAPS(obj, caps) GST_DEBUG_OBJECT (obj, "%s: %"GST_PTR_FORMAT, #caps, caps)
+
+
+ #endif /* __GSTSTRIDETRANSFORM_H__ */
+--
+1.7.1
+
diff --git a/media-libs/gst-plugins-base/files/gst-0.10.32-0006-fix-a-small-typo.-need-to-use-the-smaller-of-new_wid.patch b/media-libs/gst-plugins-base/files/gst-0.10.32-0006-fix-a-small-typo.-need-to-use-the-smaller-of-new_wid.patch
new file mode 100644
index 0000000..14f7d3f
--- /dev/null
+++ b/media-libs/gst-plugins-base/files/gst-0.10.32-0006-fix-a-small-typo.-need-to-use-the-smaller-of-new_wid.patch
@@ -0,0 +1,36 @@
+From db7698656e71dc4a898fec9e46ae6c9d04352447 Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Wed, 19 Aug 2009 15:33:50 -0500
+Subject: [PATCH 06/24] fix a small typo.. need to use the smaller of {new_width, orig_width} for the line-by-line copy to avoid overwriting past end of buffer
+
+---
+ gst/stride/gststridetransform.c | 6 ++++--
+ 1 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/gst/stride/gststridetransform.c b/gst/stride/gststridetransform.c
+index adc22ce..ea52500 100644
+--- a/gst/stride/gststridetransform.c
++++ b/gst/stride/gststridetransform.c
+@@ -331,7 +331,7 @@ stridemove (guchar *new_buf, guchar *orig_buf, gint new_width, gint orig_width,
+ }
+ } else {
+ for (row=0; row<height; row++) {
+- memmove (new_buf+(new_width*row), orig_buf+(orig_width*row), orig_width);
++ memmove (new_buf+(new_width*row), orig_buf+(orig_width*row), new_width);
+ }
+ }
+ }
+@@ -440,7 +440,9 @@ gst_stride_transform_transform (GstBaseTransform *base,
+ {
+ GstStrideTransform *self = GST_STRIDE_TRANSFORM (base);
+
+- GST_DEBUG_OBJECT (self, "inbuf=%p, outbuf=%p", inbuf, outbuf);
++ GST_DEBUG_OBJECT (self, "inbuf=%p (size=%d), outbuf=%p (size=%d)",
++ inbuf, GST_BUFFER_SIZE (inbuf),
++ outbuf, GST_BUFFER_SIZE (outbuf));
+
+ if (self->in_rowstride && self->out_rowstride) {
+ GST_DEBUG_OBJECT (self, "not implemented"); // TODO
+--
+1.7.1
+
diff --git a/media-libs/gst-plugins-base/files/gst-0.10.32-0007-Add-NV12-support-in-stridetransform.patch b/media-libs/gst-plugins-base/files/gst-0.10.32-0007-Add-NV12-support-in-stridetransform.patch
new file mode 100644
index 0000000..fae77f7
--- /dev/null
+++ b/media-libs/gst-plugins-base/files/gst-0.10.32-0007-Add-NV12-support-in-stridetransform.patch
@@ -0,0 +1,77 @@
+From f392c3f35052b57343e814d8f2d52b4f788d5d45 Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Fri, 20 Nov 2009 18:43:12 -0600
+Subject: [PATCH 07/24] Add NV12 support in stridetransform
+
+---
+ gst-libs/gst/video/video.c | 3 +++
+ gst/stride/gststridetransform.c | 12 ++++--------
+ 2 files changed, 7 insertions(+), 8 deletions(-)
+
+diff --git a/gst-libs/gst/video/video.c b/gst-libs/gst/video/video.c
+index 24f1ac8..ff9c4fb 100644
+--- a/gst-libs/gst/video/video.c
++++ b/gst-libs/gst/video/video.c
+@@ -2025,6 +2025,9 @@ gst_video_format_get_size_strided (GstVideoFormat format,
+ case GST_VIDEO_FORMAT_Y42B:
+ case GST_VIDEO_FORMAT_Y444:
+ return GST_ROUND_UP_4 (3 * rowstride * height);
++ case GST_VIDEO_FORMAT_NV12:
++ case GST_VIDEO_FORMAT_NV21:
++ return GST_ROUND_UP_4 (rowstride) * GST_ROUND_UP_2 (height) * 3 / 2;
+ default:
+ return 0;
+ }
+diff --git a/gst/stride/gststridetransform.c b/gst/stride/gststridetransform.c
+index ea52500..56207d0 100644
+--- a/gst/stride/gststridetransform.c
++++ b/gst/stride/gststridetransform.c
+@@ -2,7 +2,7 @@
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc - http://www.ti.com/
+ *
+- * Description: V4L2 sink element
++ * Description: stride transform element
+ * Created on: Jul 30, 2009
+ * Author: Rob Clark <rob@ti.com>
+ *
+@@ -62,7 +62,7 @@ GST_ELEMENT_DETAILS ("Stride transform",
+
+ /* TODO: add rgb formats too! */
+ #define SUPPORTED_CAPS \
+- GST_VIDEO_CAPS_YUV_STRIDED ("{ I420, YV12, YUY2, UYVY }", "[ 0, max ]")
++ GST_VIDEO_CAPS_YUV_STRIDED ("{ I420, YV12, YUY2, UYVY, NV12 }", "[ 0, max ]")
+
+
+ static GstStaticPadTemplate src_template =
+@@ -357,12 +357,10 @@ stridify (GstStrideTransform *self, guchar *strided, guchar *unstrided)
+ gint stride = self->out_rowstride;
+
+ switch (self->format) {
+-#if 0 /* TODO */
+ case GST_VIDEO_FORMAT_NV12:
+ g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
+- stridemove (strided, unstrided, stride, width, height * 1.5);
++ stridemove (strided, unstrided, stride, width, (GST_ROUND_UP_2 (height) * 3) / 2);
+ return GST_FLOW_OK;
+-#endif
+ case GST_VIDEO_FORMAT_I420:
+ case GST_VIDEO_FORMAT_YV12:
+ g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
+@@ -403,12 +401,10 @@ unstridify (GstStrideTransform *self, guchar *unstrided, guchar *strided)
+ gint stride = self->in_rowstride;
+
+ switch (self->format) {
+-#if 0 /* TODO */
+ case GST_VIDEO_FORMAT_NV12:
+ g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
+- stridemove (unstrided, strided, width, stride, height * 1.5);
++ stridemove (unstrided, strided, width, stride, (GST_ROUND_UP_2 (height) * 3) / 2);
+ return GST_FLOW_OK;
+-#endif
+ case GST_VIDEO_FORMAT_I420:
+ case GST_VIDEO_FORMAT_YV12:
+ g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
+--
+1.7.1
+
diff --git a/media-libs/gst-plugins-base/files/gst-0.10.32-0008-add-basic-support-for-I420-NV12-colorspace-conversio.patch b/media-libs/gst-plugins-base/files/gst-0.10.32-0008-add-basic-support-for-I420-NV12-colorspace-conversio.patch
new file mode 100644
index 0000000..5898e0a
--- /dev/null
+++ b/media-libs/gst-plugins-base/files/gst-0.10.32-0008-add-basic-support-for-I420-NV12-colorspace-conversio.patch
@@ -0,0 +1,186 @@
+From 4b74d1b679855e8c709fde124fd9f0027ba8d916 Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Fri, 27 Nov 2009 11:13:47 -0600
+Subject: [PATCH 08/24] add basic support for I420->NV12 colorspace conversion
+
+---
+ gst/stride/gststridetransform.c | 109 ++++++++++++++++++++++++++++++++++++---
+ gst/stride/gststridetransform.h | 2 +-
+ 2 files changed, 103 insertions(+), 8 deletions(-)
+
+diff --git a/gst/stride/gststridetransform.c b/gst/stride/gststridetransform.c
+index 56207d0..03deeb1 100644
+--- a/gst/stride/gststridetransform.c
++++ b/gst/stride/gststridetransform.c
+@@ -227,11 +227,43 @@ add_all_fields (GstCaps *caps, const gchar *name, GstStructure *s, gboolean rows
+ idx = gst_structure_n_fields (s) - 1;
+ while (idx >= 0) {
+ const gchar *name = gst_structure_nth_field_name (s, idx);
++ idx--;
++ if (!strcmp ("format", name)) {
++ // we can do simple color format translations, such as converting from one
++ // YUV420 format to another:
++ GValue formats = {0};
++ GValue fourccval = {0};
++ guint fourcc;
++ if (gst_structure_get_fourcc (s, name, &fourcc)) {
++ switch (gst_video_format_from_fourcc (fourcc)) {
++ case GST_VIDEO_FORMAT_NV12:
++ case GST_VIDEO_FORMAT_I420:
++GST_DEBUG ("Hmm, let's say I can convert I420<-->NV12..");
++ g_value_init (&formats, GST_TYPE_LIST);
++ g_value_init (&fourccval, GST_TYPE_FOURCC);
++ gst_value_set_fourcc (&fourccval,
++ GST_MAKE_FOURCC ('I', '4', '2', '0'));
++ gst_value_list_append_value (&formats, &fourccval);
++ gst_value_set_fourcc (&fourccval,
++ GST_MAKE_FOURCC ('N', 'V', '1', '2'));
++ gst_value_list_append_value (&formats, &fourccval);
++ gst_structure_set_value (new_s, "format", &formats);
++ continue;
++/* maybe handle other cases later..
++ case GST_VIDEO_FORMAT_YV12:
++ case GST_VIDEO_FORMAT_YUY2:
++ case GST_VIDEO_FORMAT_UYVY:
++*/
++ default:
++ break;
++ }
++ }
++ }
++
+ if (strcmp ("rowstride", name)) {
+ const GValue *val = gst_structure_get_value (s, name);
+ gst_structure_set_value (new_s, name, val);
+ }
+- idx--;
+ }
+
+ gst_caps_merge_structure (caps, new_s);
+@@ -287,18 +319,16 @@ gst_stride_transform_set_caps (GstBaseTransform *base,
+ GstCaps *incaps, GstCaps *outcaps)
+ {
+ GstStrideTransform *self = GST_STRIDE_TRANSFORM (base);
+- GstVideoFormat format;
+ gint width, height;
+
+ LOG_CAPS (self, incaps);
+ LOG_CAPS (self, outcaps);
+
+ g_return_val_if_fail (gst_video_format_parse_caps_strided (incaps,
+- &self->format, &self->width, &self->height, &self->in_rowstride), FALSE);
++ &self->in_format, &self->width, &self->height, &self->in_rowstride), FALSE);
+ g_return_val_if_fail (gst_video_format_parse_caps_strided (outcaps,
+- &format, &width, &height, &self->out_rowstride), FALSE);
++ &self->out_format, &width, &height, &self->out_rowstride), FALSE);
+
+- g_return_val_if_fail (self->format == format, FALSE);
+ g_return_val_if_fail (self->width == width, FALSE);
+ g_return_val_if_fail (self->height == height, FALSE);
+
+@@ -307,6 +337,49 @@ gst_stride_transform_set_caps (GstBaseTransform *base,
+
+ /* ************************************************************************* */
+
++static void
++memmove_demux (guchar *new_buf, guchar *orig_buf, gint sz, gint pxstride)
++{
++ if (new_buf > orig_buf) {
++ /* copy backwards */
++ new_buf += (sz * pxstride);
++ orig_buf += sz;
++ while(sz--) {
++ *new_buf = *orig_buf;
++ new_buf -= pxstride;
++ orig_buf--;
++ }
++ } else {
++ while(sz--) {
++ *new_buf = *orig_buf;
++ new_buf += pxstride;
++ orig_buf++;
++ }
++ }
++}
++
++static void
++stridemove_demux (guchar *new_buf, guchar *orig_buf, gint new_width, gint orig_width, gint height, gint pxstride)
++{
++ int row;
++
++ GST_DEBUG ("new_buf=%p, orig_buf=%p, new_width=%d, orig_width=%d, height=%d",
++ new_buf, orig_buf, new_width, orig_width, height);
++ /* if increasing the stride, work from bottom-up to avoid overwriting data
++ * that has not been moved yet.. otherwise, work in the opposite order,
++ * for the same reason.
++ */
++ if (new_width > orig_width) {
++ for (row=height-1; row>=0; row--) {
++ memmove_demux (new_buf+(new_width*row), orig_buf+(orig_width*row), orig_width, pxstride);
++ }
++ } else {
++ for (row=0; row<height; row++) {
++ memmove_demux (new_buf+(new_width*row), orig_buf+(orig_width*row), new_width, pxstride);
++ }
++ }
++}
++
+ /**
+ * Convert from one stride to another... like memmove, but can convert stride in
+ * the process. This function is not aware of pixels, only of bytes. So widths
+@@ -356,7 +429,29 @@ stridify (GstStrideTransform *self, guchar *strided, guchar *unstrided)
+ gint height = self->height;
+ gint stride = self->out_rowstride;
+
+- switch (self->format) {
++ if (self->out_format != self->in_format) {
++
++ if ((self->in_format == GST_VIDEO_FORMAT_I420) &&
++ (self->out_format == GST_VIDEO_FORMAT_NV12)) {
++ /* note: if not an in-place conversion, then doing the U&V in one pass
++ * would be more efficient... but if it is an in-place conversion, I'd
++ * need to think about whether it is potential for the new UV plane to
++ * corrupt the V plane before it is done copying..
++ */
++ stridemove_demux (
++ strided + (height*stride) + 1,
++ unstrided + (int)(height*width*1.25),
++ stride, width/2, height/2, 2); /* move V */
++ stridemove_demux (
++ strided + (height*stride),
++ unstrided + (height*width),
++ stride, width/2, height/2, 2); /* move U */
++ stridemove (strided, unstrided, stride, width, height); /* move Y */
++ return GST_FLOW_OK;
++ }
++ }
++
++ switch (self->out_format) {
+ case GST_VIDEO_FORMAT_NV12:
+ g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
+ stridemove (strided, unstrided, stride, width, (GST_ROUND_UP_2 (height) * 3) / 2);
+@@ -400,7 +495,7 @@ unstridify (GstStrideTransform *self, guchar *unstrided, guchar *strided)
+ gint height = self->height;
+ gint stride = self->in_rowstride;
+
+- switch (self->format) {
++ switch (self->out_format) {
+ case GST_VIDEO_FORMAT_NV12:
+ g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
+ stridemove (unstrided, strided, width, stride, (GST_ROUND_UP_2 (height) * 3) / 2);
+diff --git a/gst/stride/gststridetransform.h b/gst/stride/gststridetransform.h
+index 481959e..0141571 100644
+--- a/gst/stride/gststridetransform.h
++++ b/gst/stride/gststridetransform.h
+@@ -55,7 +55,7 @@ struct _GstStrideTransform {
+ GstVideoFilter videofilter;
+
+ /*< private >*/
+- GstVideoFormat format;
++ GstVideoFormat in_format, out_format;
+ gint width, height;
+ gint in_rowstride;
+ gint out_rowstride;
+--
+1.7.1
+
diff --git a/media-libs/gst-plugins-base/files/gst-0.10.32-0009-fix-to-avoid-parsing-caps-on-every-frame.patch b/media-libs/gst-plugins-base/files/gst-0.10.32-0009-fix-to-avoid-parsing-caps-on-every-frame.patch
new file mode 100644
index 0000000..b67789f
--- /dev/null
+++ b/media-libs/gst-plugins-base/files/gst-0.10.32-0009-fix-to-avoid-parsing-caps-on-every-frame.patch
@@ -0,0 +1,35 @@
+From 8132aecf99071faab59739ebabd7bcd41a2ab581 Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Fri, 27 Nov 2009 11:14:58 -0600
+Subject: [PATCH 09/24] fix to avoid parsing caps on every frame
+
+---
+ gst/stride/gststridetransform.c | 10 +++++++---
+ 1 files changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/gst/stride/gststridetransform.c b/gst/stride/gststridetransform.c
+index 03deeb1..143a9f7 100644
+--- a/gst/stride/gststridetransform.c
++++ b/gst/stride/gststridetransform.c
+@@ -197,11 +197,15 @@ gst_stride_transform_transform_size (GstBaseTransform *base,
+
+ if (self->cached_caps[idx] != othercaps)
+ {
+- if (!gst_stride_transform_get_unit_size (base, othercaps,
+- &(self->cached_size[idx])))
+- {
++ guint sz;
++ if (!gst_stride_transform_get_unit_size (base, othercaps, &sz)) {
+ return FALSE;
+ }
++ if (self->cached_caps[idx]) {
++ gst_caps_unref (self->cached_caps[idx]);
++ }
++ self->cached_size[idx] = sz;
++ self->cached_caps[idx] = gst_caps_ref (othercaps);
+ }
+
+ *othersize = self->cached_size[idx];
+--
+1.7.1
+
diff --git a/media-libs/gst-plugins-base/files/gst-0.10.32-0010-refactor-stridetransform-to-make-it-easier-to-add-ne.patch b/media-libs/gst-plugins-base/files/gst-0.10.32-0010-refactor-stridetransform-to-make-it-easier-to-add-ne.patch
new file mode 100644
index 0000000..f8c3612
--- /dev/null
+++ b/media-libs/gst-plugins-base/files/gst-0.10.32-0010-refactor-stridetransform-to-make-it-easier-to-add-ne.patch
@@ -0,0 +1,759 @@
+From c854bfe87a39d640dfd3381bcba83281d9316b50 Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Fri, 27 Nov 2009 15:05:56 -0600
+Subject: [PATCH 10/24] refactor stridetransform to make it easier to add new transforms (stride and/or colorspace)
+
+---
+ gst/stride/Makefile.am | 1 +
+ gst/stride/convert.c | 267 +++++++++++++++++++++++++++++++++++
+ gst/stride/gststridetransform.c | 295 ++++++++-------------------------------
+ gst/stride/gststridetransform.h | 18 ++-
+ 4 files changed, 340 insertions(+), 241 deletions(-)
+ create mode 100644 gst/stride/convert.c
+
+diff --git a/gst/stride/Makefile.am b/gst/stride/Makefile.am
+index 1adc197..0b61d55 100644
+--- a/gst/stride/Makefile.am
++++ b/gst/stride/Makefile.am
+@@ -2,6 +2,7 @@ plugin_LTLIBRARIES = libgststridetransform.la
+
+ libgststridetransform_la_SOURCES = \
+ gststridetransform.c \
++ convert.c \
+ plugin.c
+
+ libgststridetransform_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS)
+diff --git a/gst/stride/convert.c b/gst/stride/convert.c
+new file mode 100644
+index 0000000..860f16c
+--- /dev/null
++++ b/gst/stride/convert.c
+@@ -0,0 +1,267 @@
++/* GStreamer
++ *
++ * Copyright (C) 2009 Texas Instruments, Inc - http://www.ti.com/
++ *
++ * Description: stride transform conversion utilities
++ * Created on: Nov 27, 2009
++ * Author: Rob Clark <rob@ti.com>
++ *
++ * 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.
++ */
++
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include <string.h>
++#include <gst/video/video.h>
++
++#include "gststridetransform.h"
++
++
++GST_DEBUG_CATEGORY_EXTERN (stridetransform_debug);
++#define GST_CAT_DEFAULT stridetransform_debug
++
++
++/*
++ * Conversion utilities:
++ */
++
++static void
++memmove_demux (guchar *new_buf, guchar *orig_buf, gint sz, gint pxstride)
++{
++ if (new_buf > orig_buf) {
++ /* copy backwards */
++ new_buf += ((sz - 1) * pxstride);
++ orig_buf += sz - 1;
++ while(sz--) {
++ *new_buf = *orig_buf;
++ new_buf -= pxstride;
++ orig_buf--;
++ }
++ } else {
++ while(sz--) {
++ *new_buf = *orig_buf;
++ new_buf += pxstride;
++ orig_buf++;
++ }
++ }
++}
++
++static void
++stridemove_demux (guchar *new_buf, guchar *orig_buf, gint new_width, gint orig_width, gint height, gint pxstride)
++{
++ int row;
++
++ GST_DEBUG ("new_buf=%p, orig_buf=%p, new_width=%d, orig_width=%d, height=%d",
++ new_buf, orig_buf, new_width, orig_width, height);
++
++ /* if increasing the stride, work from bottom-up to avoid overwriting data
++ * that has not been moved yet.. otherwise, work in the opposite order,
++ * for the same reason.
++ */
++ if (new_width > orig_width) {
++ for (row=height-1; row>=0; row--) {
++ memmove_demux (new_buf+(new_width*row), orig_buf+(orig_width*row), orig_width, pxstride);
++ }
++ } else {
++ for (row=0; row<height; row++) {
++ memmove_demux (new_buf+(new_width*row), orig_buf+(orig_width*row), new_width, pxstride);
++ }
++ }
++}
++
++/**
++ * Convert from one stride to another... like memmove, but can convert stride in
++ * the process. This function is not aware of pixels, only of bytes. So widths
++ * are given in bytes, not pixels. The new_buf and orig_buf can point to the
++ * same buffers to do an in-place conversion, but the buffer should be large
++ * enough.
++ */
++static void
++stridemove (guchar *new_buf, guchar *orig_buf, gint new_width, gint orig_width, gint height)
++{
++ int row;
++
++ GST_DEBUG ("new_buf=%p, orig_buf=%p, new_width=%d, orig_width=%d, height=%d",
++ new_buf, orig_buf, new_width, orig_width, height);
++
++ /* if increasing the stride, work from bottom-up to avoid overwriting data
++ * that has not been moved yet.. otherwise, work in the opposite order,
++ * for the same reason.
++ */
++ if (new_width > orig_width) {
++ for (row=height-1; row>=0; row--) {
++ memmove (new_buf+(new_width*row), orig_buf+(orig_width*row), orig_width);
++ }
++ } else {
++ for (row=0; row<height; row++) {
++ memmove (new_buf+(new_width*row), orig_buf+(orig_width*row), new_width);
++ }
++ }
++}
++
++/*
++ * Conversion Functions:
++ */
++
++/** convert 4:2:0 semiplanar to same 4:2:0 semiplanar */
++static GstFlowReturn
++unstridify_420sp_420sp (GstStrideTransform *self, guchar *unstrided, guchar *strided)
++{
++ gint width = self->width;
++ gint height = self->height;
++ gint stride = self->in_rowstride;
++
++ g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
++
++ stridemove (unstrided, strided, width, stride,
++ (GST_ROUND_UP_2 (height) * 3) / 2);
++
++ return GST_FLOW_OK;
++}
++static GstFlowReturn
++stridify_420sp_420sp (GstStrideTransform *self, guchar *strided, guchar *unstrided)
++{
++ gint width = self->width;
++ gint height = self->height;
++ gint stride = self->out_rowstride;
++
++ g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
++
++ g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
++ stridemove (strided, unstrided, stride, width,
++ (GST_ROUND_UP_2 (height) * 3) / 2);
++
++ return GST_FLOW_OK;
++}
++
++/** convert 4:2:0 planar to same 4:2:0 planar */
++static GstFlowReturn
++unstridify_420p_420p (GstStrideTransform *self, guchar *unstrided, guchar *strided)
++{
++ gint width = self->width;
++ gint height = self->height;
++ gint stride = self->in_rowstride;
++
++ g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
++
++ stridemove (unstrided, strided, width, stride, height); /* move Y */
++ stridemove (
++ unstrided + (height*width),
++ strided + (height*stride),
++ width/2, stride, height); /* move V/U */
++ /* XXX odd widths/heights/strides: */
++ stridemove (
++ unstrided + (int)(height*width*1.5),
++ strided + (int)(height*stride*1.5),
++ width/2, stride, height); /* move U/V */
++
++ return GST_FLOW_OK;
++}
++static GstFlowReturn
++stridify_420p_420p (GstStrideTransform *self, guchar *strided, guchar *unstrided)
++{
++ gint width = self->width;
++ gint height = self->height;
++ gint stride = self->out_rowstride;
++
++ g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
++
++ /* XXX odd widths/heights/strides: */
++ stridemove (
++ strided + (int)(height*stride*1.5),
++ unstrided + (int)(height*width*1.5),
++ stride, width/2, height); /* move U/V */
++ stridemove (
++ strided + (height*stride),
++ unstrided + (height*width),
++ stride, width/2, height); /* move V/U */
++ stridemove (strided, unstrided, stride, width, height); /* move Y */
++
++ return GST_FLOW_OK;
++}
++
++/** convert 4:2:2 packed to same 4:2:2 packed */
++static GstFlowReturn
++unstridify_422i_422i (GstStrideTransform *self, guchar *unstrided, guchar *strided)
++{
++ gint width = self->width;
++ gint height = self->height;
++ gint stride = self->in_rowstride;
++
++ g_return_val_if_fail (stride >= (width*2), GST_FLOW_ERROR);
++
++ stridemove (unstrided, strided, width*2, stride, height);
++
++ return GST_FLOW_OK;
++}
++static GstFlowReturn
++stridify_422i_422i (GstStrideTransform *self, guchar *strided, guchar *unstrided)
++{
++ gint width = self->width;
++ gint height = self->height;
++ gint stride = self->out_rowstride;
++
++ g_return_val_if_fail (stride >= (width*2), GST_FLOW_ERROR);
++
++ stridemove (strided, unstrided, stride, width*2, height);
++
++ return GST_FLOW_OK;
++}
++
++/** convert I420 unstrided to NV12 strided */
++static GstFlowReturn
++stridify_i420_nv12 (GstStrideTransform *self, guchar *strided, guchar *unstrided)
++{
++ gint width = self->width;
++ gint height = self->height;
++ gint stride = self->out_rowstride;
++
++ g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
++
++ /* note: if not an in-place conversion, then doing the U&V in one pass
++ * would be more efficient... but if it is an in-place conversion, I'd
++ * need to think about whether it is potential for the new UV plane to
++ * corrupt the V plane before it is done copying..
++ */
++ stridemove_demux (
++ strided + (height*stride) + 1,
++ unstrided + (int)(height*width*1.25),
++ stride, width/2, height/2, 2); /* move V */
++ stridemove_demux (
++ strided + (height*stride),
++ unstrided + (height*width),
++ stride, width/2, height/2, 2); /* move U */
++ stridemove (strided, unstrided, stride, width, height); /* move Y */
++
++ return GST_FLOW_OK;
++}
++
++/* last entry has GST_VIDEO_FORMAT_UNKNOWN for in/out formats */
++Conversion stride_conversions[] = {
++ { { GST_VIDEO_FORMAT_NV12, GST_VIDEO_FORMAT_NV12 }, stridify_420sp_420sp, unstridify_420sp_420sp },
++ { { GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_I420 }, stridify_420p_420p, unstridify_420p_420p },
++ { { GST_VIDEO_FORMAT_YV12, GST_VIDEO_FORMAT_YV12 }, stridify_420p_420p, unstridify_420p_420p },
++ { { GST_VIDEO_FORMAT_YUY2, GST_VIDEO_FORMAT_YUY2 }, stridify_422i_422i, unstridify_422i_422i },
++ { { GST_VIDEO_FORMAT_UYVY, GST_VIDEO_FORMAT_UYVY }, stridify_422i_422i, unstridify_422i_422i },
++ { { GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_NV12 }, stridify_i420_nv12, NULL },
++ /* add new entries before here */
++ { { GST_VIDEO_FORMAT_UNKNOWN } }
++};
++
++
+diff --git a/gst/stride/gststridetransform.c b/gst/stride/gststridetransform.c
+index 143a9f7..6ab0479 100644
+--- a/gst/stride/gststridetransform.c
++++ b/gst/stride/gststridetransform.c
+@@ -47,12 +47,17 @@
+ #endif
+
+ #include <string.h>
++
+ #include <gst/video/video.h>
+
+ #include "gst/gst-i18n-plugin.h"
+ #include "gststridetransform.h"
+
+
++/* last entry has GST_VIDEO_FORMAT_UNKNOWN for in/out formats */
++extern const Conversion stride_conversions[];
++
++
+ static const GstElementDetails stridetransform_details =
+ GST_ELEMENT_DETAILS ("Stride transform",
+ "Filter/Converter/Video",
+@@ -70,14 +75,14 @@ GST_STATIC_PAD_TEMPLATE ("src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (SUPPORTED_CAPS)
+- );
++);
+
+ static GstStaticPadTemplate sink_template =
+ GST_STATIC_PAD_TEMPLATE ("sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (SUPPORTED_CAPS)
+- );
++);
+
+
+ GST_DEBUG_CATEGORY (stridetransform_debug);
+@@ -99,8 +104,6 @@ static gboolean gst_stride_transform_set_caps (GstBaseTransform *base,
+ GstCaps *incaps, GstCaps *outcaps);
+ static GstFlowReturn gst_stride_transform_transform (GstBaseTransform *base,
+ GstBuffer *inbuf, GstBuffer *outbuf);
+-static GstFlowReturn gst_stride_transform_transform_ip (GstBaseTransform *base,
+- GstBuffer *buf);
+
+ GST_BOILERPLATE (GstStrideTransform, gst_stride_transform, GstVideoFilter, GST_TYPE_VIDEO_FILTER);
+
+@@ -136,8 +139,6 @@ gst_stride_transform_class_init (GstStrideTransformClass *klass)
+ GST_DEBUG_FUNCPTR (gst_stride_transform_transform_caps);
+ basetransform_class->set_caps =
+ GST_DEBUG_FUNCPTR (gst_stride_transform_set_caps);
+- basetransform_class->transform_ip =
+- GST_DEBUG_FUNCPTR (gst_stride_transform_transform_ip);
+ basetransform_class->transform =
+ GST_DEBUG_FUNCPTR (gst_stride_transform_transform);
+
+@@ -219,7 +220,7 @@ gst_stride_transform_transform_size (GstBaseTransform *base,
+ * helper to add all fields, other than rowstride to @caps, copied from @s.
+ */
+ static void
+-add_all_fields (GstCaps *caps, const gchar *name, GstStructure *s, gboolean rowstride)
++add_all_fields (GstCaps *caps, const gchar *name, GstStructure *s, gboolean rowstride, GstPadDirection direction)
+ {
+ gint idx;
+ GstStructure *new_s = gst_structure_new (name, NULL);
+@@ -232,38 +233,39 @@ add_all_fields (GstCaps *caps, const gchar *name, GstStructure *s, gboolean rows
+ while (idx >= 0) {
+ const gchar *name = gst_structure_nth_field_name (s, idx);
+ idx--;
++
++ /* for format field, check the stride_conversions table to see what
++ * we can support:
++ */
+ if (!strcmp ("format", name)) {
+- // we can do simple color format translations, such as converting from one
+- // YUV420 format to another:
+- GValue formats = {0};
+- GValue fourccval = {0};
+ guint fourcc;
+- if (gst_structure_get_fourcc (s, name, &fourcc)) {
+- switch (gst_video_format_from_fourcc (fourcc)) {
+- case GST_VIDEO_FORMAT_NV12:
+- case GST_VIDEO_FORMAT_I420:
+-GST_DEBUG ("Hmm, let's say I can convert I420<-->NV12..");
+- g_value_init (&formats, GST_TYPE_LIST);
+- g_value_init (&fourccval, GST_TYPE_FOURCC);
+- gst_value_set_fourcc (&fourccval,
+- GST_MAKE_FOURCC ('I', '4', '2', '0'));
+- gst_value_list_append_value (&formats, &fourccval);
+- gst_value_set_fourcc (&fourccval,
+- GST_MAKE_FOURCC ('N', 'V', '1', '2'));
++
++ /* XXX double check this: */
++ gint to_format = (direction == GST_PAD_SINK) ? 1 : 0;
++ gint from_format = (direction == GST_PAD_SRC) ? 1 : 0;
++
++ if (gst_structure_get_fourcc (s, "format", &fourcc)) {
++ GValue formats = {0};
++ GValue fourccval = {0};
++ gint i;
++ GstVideoFormat format = gst_video_format_from_fourcc (fourcc);
++
++ g_value_init (&formats, GST_TYPE_LIST);
++ g_value_init (&fourccval, GST_TYPE_FOURCC);
++
++ for (i=0; stride_conversions[i].format[0]!=GST_VIDEO_FORMAT_UNKNOWN; i++) {
++ if (stride_conversions[i].format[from_format] == format) {
++ gst_value_set_fourcc (&fourccval, gst_video_format_to_fourcc
++ (stride_conversions[i].format[to_format]));
+ gst_value_list_append_value (&formats, &fourccval);
+- gst_structure_set_value (new_s, "format", &formats);
+- continue;
+-/* maybe handle other cases later..
+- case GST_VIDEO_FORMAT_YV12:
+- case GST_VIDEO_FORMAT_YUY2:
+- case GST_VIDEO_FORMAT_UYVY:
+-*/
+- default:
+- break;
++ }
+ }
++
++ continue;
+ }
+ }
+
++ /* copy over all other non-rowstride fields: */
+ if (strcmp ("rowstride", name)) {
+ const GValue *val = gst_structure_get_value (s, name);
+ gst_structure_set_value (new_s, name, val);
+@@ -297,14 +299,14 @@ gst_stride_transform_transform_caps (GstBaseTransform *base,
+ if (gst_structure_has_name (s, "video/x-raw-yuv") ||
+ gst_structure_has_name (s, "video/x-raw-yuv-strided")) {
+
+- add_all_fields (ret, "video/x-raw-yuv", s, FALSE);
+- add_all_fields (ret, "video/x-raw-yuv-strided", s, TRUE);
++ add_all_fields (ret, "video/x-raw-yuv", s, FALSE, direction);
++ add_all_fields (ret, "video/x-raw-yuv-strided", s, TRUE, direction);
+
+ } else if (gst_structure_has_name (s, "video/x-raw-rgb") ||
+ gst_structure_has_name (s, "video/x-raw-rgb-strided")) {
+
+- add_all_fields (ret, "video/x-raw-rgb", s, FALSE);
+- add_all_fields (ret, "video/x-raw-rgb-strided", s, TRUE);
++ add_all_fields (ret, "video/x-raw-rgb", s, FALSE, direction);
++ add_all_fields (ret, "video/x-raw-rgb-strided", s, TRUE, direction);
+
+ }
+
+@@ -324,211 +326,37 @@ gst_stride_transform_set_caps (GstBaseTransform *base,
+ {
+ GstStrideTransform *self = GST_STRIDE_TRANSFORM (base);
+ gint width, height;
++ GstVideoFormat in_format, out_format;
++ gint i;
+
+ LOG_CAPS (self, incaps);
+ LOG_CAPS (self, outcaps);
+
+ g_return_val_if_fail (gst_video_format_parse_caps_strided (incaps,
+- &self->in_format, &self->width, &self->height, &self->in_rowstride), FALSE);
++ &in_format, &self->width, &self->height, &self->in_rowstride), FALSE);
+ g_return_val_if_fail (gst_video_format_parse_caps_strided (outcaps,
+- &self->out_format, &width, &height, &self->out_rowstride), FALSE);
+-
+- g_return_val_if_fail (self->width == width, FALSE);
+- g_return_val_if_fail (self->height == height, FALSE);
+-
+- return TRUE;
+-}
+-
+-/* ************************************************************************* */
+-
+-static void
+-memmove_demux (guchar *new_buf, guchar *orig_buf, gint sz, gint pxstride)
+-{
+- if (new_buf > orig_buf) {
+- /* copy backwards */
+- new_buf += (sz * pxstride);
+- orig_buf += sz;
+- while(sz--) {
+- *new_buf = *orig_buf;
+- new_buf -= pxstride;
+- orig_buf--;
+- }
+- } else {
+- while(sz--) {
+- *new_buf = *orig_buf;
+- new_buf += pxstride;
+- orig_buf++;
+- }
+- }
+-}
+-
+-static void
+-stridemove_demux (guchar *new_buf, guchar *orig_buf, gint new_width, gint orig_width, gint height, gint pxstride)
+-{
+- int row;
+-
+- GST_DEBUG ("new_buf=%p, orig_buf=%p, new_width=%d, orig_width=%d, height=%d",
+- new_buf, orig_buf, new_width, orig_width, height);
+- /* if increasing the stride, work from bottom-up to avoid overwriting data
+- * that has not been moved yet.. otherwise, work in the opposite order,
+- * for the same reason.
+- */
+- if (new_width > orig_width) {
+- for (row=height-1; row>=0; row--) {
+- memmove_demux (new_buf+(new_width*row), orig_buf+(orig_width*row), orig_width, pxstride);
+- }
+- } else {
+- for (row=0; row<height; row++) {
+- memmove_demux (new_buf+(new_width*row), orig_buf+(orig_width*row), new_width, pxstride);
+- }
+- }
+-}
++ &out_format, &width, &height, &self->out_rowstride), FALSE);
+
+-/**
+- * Convert from one stride to another... like memmove, but can convert stride in
+- * the process. This function is not aware of pixels, only of bytes. So widths
+- * are given in bytes, not pixels. The new_buf and orig_buf can point to the
+- * same buffers to do an in-place conversion, but the buffer should be large
+- * enough.
+- */
+-static void
+-stridemove (guchar *new_buf, guchar *orig_buf, gint new_width, gint orig_width, gint height)
+-{
+- int row;
+-
+- GST_DEBUG ("new_buf=%p, orig_buf=%p, new_width=%d, orig_width=%d, height=%d",
+- new_buf, orig_buf, new_width, orig_width, height);
+- /* if increasing the stride, work from bottom-up to avoid overwriting data
+- * that has not been moved yet.. otherwise, work in the opposite order,
+- * for the same reason.
+- */
+- if (new_width > orig_width) {
+- for (row=height-1; row>=0; row--) {
+- memmove (new_buf+(new_width*row), orig_buf+(orig_width*row), orig_width);
+- }
+- } else {
+- for (row=0; row<height; row++) {
+- memmove (new_buf+(new_width*row), orig_buf+(orig_width*row), new_width);
+- }
+- }
+-}
++ self->conversion = NULL;
+
+-
+-/**
+- * Convert from a non-strided buffer to strided. The two buffer pointers could
+- * be pointing to the same memory block for in-place transform.. assuming that
+- * the buffer is large enough
+- *
+- * @strided: the pointer to the resulting strided buffer
+- * @unstrided: the pointer to the initial unstrided buffer
+- * @fourcc: the color format
+- * @stride: the stride, in bytes
+- * @width: the width in pixels
+- * @height: the height in pixels
+- */
+-static GstFlowReturn
+-stridify (GstStrideTransform *self, guchar *strided, guchar *unstrided)
+-{
+- gint width = self->width;
+- gint height = self->height;
+- gint stride = self->out_rowstride;
+-
+- if (self->out_format != self->in_format) {
+-
+- if ((self->in_format == GST_VIDEO_FORMAT_I420) &&
+- (self->out_format == GST_VIDEO_FORMAT_NV12)) {
+- /* note: if not an in-place conversion, then doing the U&V in one pass
+- * would be more efficient... but if it is an in-place conversion, I'd
+- * need to think about whether it is potential for the new UV plane to
+- * corrupt the V plane before it is done copying..
+- */
+- stridemove_demux (
+- strided + (height*stride) + 1,
+- unstrided + (int)(height*width*1.25),
+- stride, width/2, height/2, 2); /* move V */
+- stridemove_demux (
+- strided + (height*stride),
+- unstrided + (height*width),
+- stride, width/2, height/2, 2); /* move U */
+- stridemove (strided, unstrided, stride, width, height); /* move Y */
+- return GST_FLOW_OK;
++ for (i=0; stride_conversions[i].format[0]!=GST_VIDEO_FORMAT_UNKNOWN; i++) {
++ if ((stride_conversions[i].format[0] == in_format) &&
++ (stride_conversions[i].format[1] == out_format)) {
++ GST_DEBUG_OBJECT (self, "found stride_conversion: %d", i);
++ self->conversion = &stride_conversions[i];
++ break;
+ }
+ }
+
+- switch (self->out_format) {
+- case GST_VIDEO_FORMAT_NV12:
+- g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
+- stridemove (strided, unstrided, stride, width, (GST_ROUND_UP_2 (height) * 3) / 2);
+- return GST_FLOW_OK;
+- case GST_VIDEO_FORMAT_I420:
+- case GST_VIDEO_FORMAT_YV12:
+- g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
+- stridemove (
+- strided + (int)(height*stride*1.5),
+- unstrided + (int)(height*width*1.5),
+- stride, width/2, height); /* move U/V */
+- stridemove (
+- strided + (height*stride),
+- unstrided + (height*width),
+- stride, width/2, height); /* move V/U */
+- stridemove (strided, unstrided, stride, width, height); /* move Y */
+- return GST_FLOW_OK;
+- case GST_VIDEO_FORMAT_YUY2:
+- case GST_VIDEO_FORMAT_UYVY:
+- g_return_val_if_fail (stride >= (width*2), GST_FLOW_ERROR);
+- stridemove (strided, unstrided, stride, width*2, height);
+- return GST_FLOW_OK;
+- default:
+- GST_WARNING ("unknown color format!\n");
+- return GST_FLOW_ERROR;
+- }
+-}
+-
++ g_return_val_if_fail (self->conversion, FALSE);
++ g_return_val_if_fail (self->conversion->unstridify || !self->in_rowstride, FALSE);
++ g_return_val_if_fail (self->conversion->stridify || !self->out_rowstride, FALSE);
++ g_return_val_if_fail (self->width == width, FALSE);
++ g_return_val_if_fail (self->height == height, FALSE);
+
+-/**
+- * Convert from a strided buffer to non-strided. The two buffer pointers could
+- * be pointing to the same memory block for in-place transform..
+- *
+- * @unstrided: the pointer to the resulting unstrided buffer
+- * @strided: the pointer to the initial strided buffer
+- */
+-static GstFlowReturn
+-unstridify (GstStrideTransform *self, guchar *unstrided, guchar *strided)
+-{
+- gint width = self->width;
+- gint height = self->height;
+- gint stride = self->in_rowstride;
+-
+- switch (self->out_format) {
+- case GST_VIDEO_FORMAT_NV12:
+- g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
+- stridemove (unstrided, strided, width, stride, (GST_ROUND_UP_2 (height) * 3) / 2);
+- return GST_FLOW_OK;
+- case GST_VIDEO_FORMAT_I420:
+- case GST_VIDEO_FORMAT_YV12:
+- g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
+- stridemove (unstrided, strided, width, stride, height); /* move Y */
+- stridemove (
+- unstrided + (height*width),
+- strided + (height*stride),
+- width/2, stride, height); /* move V/U */
+- stridemove (
+- unstrided + (int)(height*width*1.5),
+- strided + (int)(height*stride*1.5),
+- width/2, stride, height); /* move U/V */
+- return GST_FLOW_OK;
+- case GST_VIDEO_FORMAT_YUY2:
+- case GST_VIDEO_FORMAT_UYVY:
+- g_return_val_if_fail (stride >= (width*2), GST_FLOW_ERROR);
+- stridemove (unstrided, strided, width*2, stride, height);
+- return GST_FLOW_OK;
+- default:
+- GST_WARNING ("unknown color format!\n");
+- return GST_FLOW_ERROR;
+- }
++ return TRUE;
+ }
+
+-
+ static GstFlowReturn
+ gst_stride_transform_transform (GstBaseTransform *base,
+ GstBuffer *inbuf, GstBuffer *outbuf)
+@@ -543,10 +371,10 @@ gst_stride_transform_transform (GstBaseTransform *base,
+ GST_DEBUG_OBJECT (self, "not implemented"); // TODO
+ return GST_FLOW_ERROR;
+ } else if (self->in_rowstride) {
+- return unstridify (self,
++ return self->conversion->unstridify (self,
+ GST_BUFFER_DATA (outbuf), GST_BUFFER_DATA (inbuf));
+ } else if (self->out_rowstride) {
+- return stridify (self,
++ return self->conversion->stridify (self,
+ GST_BUFFER_DATA (outbuf), GST_BUFFER_DATA (inbuf));
+ }
+
+@@ -555,12 +383,3 @@ gst_stride_transform_transform (GstBaseTransform *base,
+
+ return GST_FLOW_ERROR;
+ }
+-
+-static GstFlowReturn
+-gst_stride_transform_transform_ip (GstBaseTransform *base,
+- GstBuffer *buf)
+-{
+- /* transform function is safe to call with same buffer ptr:
+- */
+- return gst_stride_transform_transform (base, buf, buf);
+-}
+diff --git a/gst/stride/gststridetransform.h b/gst/stride/gststridetransform.h
+index 0141571..bce2526 100644
+--- a/gst/stride/gststridetransform.h
++++ b/gst/stride/gststridetransform.h
+@@ -2,7 +2,7 @@
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc - http://www.ti.com/
+ *
+- * Description: V4L2 sink element
++ * Description: stride transform element
+ * Created on: Jul 2, 2009
+ * Author: Rob Clark <rob@ti.com>
+ *
+@@ -29,7 +29,6 @@
+ #include <gst/video/gstvideofilter.h>
+ #include <gst/video/video.h>
+
+-
+ G_BEGIN_DECLS
+
+ #define GST_TYPE_STRIDE_TRANSFORM \
+@@ -47,6 +46,19 @@ typedef struct _GstStrideTransform GstStrideTransform;
+ typedef struct _GstStrideTransformClass GstStrideTransformClass;
+
+ /**
++ * stride/colorspace conversion table (used internally)
++ */
++typedef struct {
++
++ GstVideoFormat format[2]; /* in_format, out_format */
++
++ GstFlowReturn (*stridify) (GstStrideTransform *self, guchar *strided, guchar *unstrided);
++ GstFlowReturn (*unstridify) (GstStrideTransform *self, guchar *unstrided, guchar *strided);
++
++} Conversion;
++
++
++/**
+ * GstStrideTransform:
+ *
+ * Opaque datastructure.
+@@ -55,10 +67,10 @@ struct _GstStrideTransform {
+ GstVideoFilter videofilter;
+
+ /*< private >*/
+- GstVideoFormat in_format, out_format;
+ gint width, height;
+ gint in_rowstride;
+ gint out_rowstride;
++ const Conversion *conversion;
+
+ /* for caching the tranform_size() results.. */
+ GstCaps *cached_caps[2];
+--
+1.7.1
+
diff --git a/media-libs/gst-plugins-base/files/gst-0.10.32-0011-add-some-neon.patch b/media-libs/gst-plugins-base/files/gst-0.10.32-0011-add-some-neon.patch
new file mode 100644
index 0000000..6737811
--- /dev/null
+++ b/media-libs/gst-plugins-base/files/gst-0.10.32-0011-add-some-neon.patch
@@ -0,0 +1,293 @@
+From 537d185b9e9b25f7dacb5e5c4dab47bb8524da34 Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Thu, 8 Apr 2010 00:30:25 -0500
+Subject: [PATCH 11/24] add some neon
+
+---
+ configure.ac | 1 +
+ gst/stride/Makefile.am | 1 +
+ gst/stride/armv7.s | 119 ++++++++++++++++++++++++++++++++++++++++++++++++
+ gst/stride/convert.c | 76 ++++++++++++++++--------------
+ 4 files changed, 162 insertions(+), 35 deletions(-)
+ create mode 100644 gst/stride/armv7.s
+
+diff --git a/configure.ac b/configure.ac
+index af6cd52..8e7ba18 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -58,6 +58,7 @@ dnl AS_LIBTOOL_TAGS
+
+ AC_LIBTOOL_WIN32_DLL
+ AM_PROG_LIBTOOL
++AM_PROG_AS
+
+ dnl *** required versions of GStreamer stuff ***
+ GST_REQ=0.10.32
+diff --git a/gst/stride/Makefile.am b/gst/stride/Makefile.am
+index 0b61d55..3b466de 100644
+--- a/gst/stride/Makefile.am
++++ b/gst/stride/Makefile.am
+@@ -3,6 +3,7 @@ plugin_LTLIBRARIES = libgststridetransform.la
+ libgststridetransform_la_SOURCES = \
+ gststridetransform.c \
+ convert.c \
++ armv7.s \
+ plugin.c
+
+ libgststridetransform_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS)
+diff --git a/gst/stride/armv7.s b/gst/stride/armv7.s
+new file mode 100644
+index 0000000..ed636f7
+--- /dev/null
++++ b/gst/stride/armv7.s
+@@ -0,0 +1,119 @@
++@ GStreamer
++@
++@ Copyright (C) 2009 Texas Instruments, Inc - http://www.ti.com/
++@
++@ Description: NEON/VFP accelerated functions for armv7 architecture
++@ Created on: Nov 27, 2009
++@ Author: Rob Clark <rob@ti.com>
++@
++@ 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.
++
++ .fpu neon
++ .text
++
++ .align
++ .global stride_copy_zip2
++ .type stride_copy_zip2, %function
++@void
++@stride_copy_zip2 (guchar *new_buf, guchar *orig_buf1, guchar *orig_buf2, gint sz)
++@{
++@@@@ note: r0-r3, q0-3, and q8-q15 do not need to be preserved
++stride_copy_zip2:
++@ interleave remaining >= 16 bytes:
++ pld [r1, #64]
++ pld [r2, #64]
++ cmp r3, #16
++ blt stride_copy_zip2_2
++stride_copy_zip2_1:
++ vld1.8 {q8}, [r1]!
++ vld1.8 {q9}, [r2]!
++
++ vzip.8 q8, q9
++
++ pld [r1, #64]
++ vst1.8 {q8,q9}, [r0]!
++ pld [r2, #64]
++ sub r3, r3, #16
++
++ cmp r3, #16
++ bge stride_copy_zip2_1
++@ interleave remaining >= 8 bytes:
++stride_copy_zip2_2:
++ cmp r3, #8
++ blt stride_copy_zip2_3
++
++ vld1.8 {d16}, [r1]!
++ vld1.8 {d17}, [r2]!
++
++ vzip.8 d16, d17
++
++ vst1.8 {d16,d17}, [r0]!
++ sub r3, r3, #8
++
++@ interleave remaining < 8 bytes:
++stride_copy_zip2_3:
++@XXX
++ bx lr
++@}
++
++ .align
++ .global stride_copy
++ .type stride_copy, %function
++@void
++@stride_copy (guchar *new_buf, guchar *orig_buf, gint sz)
++@{
++@@@@ note: r0-r3, q0-3, and q8-q15 do not need to be preserved
++stride_copy:
++@ copy remaining >= 64 bytes:
++ pld [r1, #64]
++ cmp r2, #64
++ blt stride_copy_2
++stride_copy_1:
++ vld1.8 {q8-q9}, [r1]!
++ sub r2, r2, #64
++ vld1.8 {q10-q11},[r1]!
++ vst1.8 {q8-q9}, [r0]!
++ pld [r1, #64]
++ cmp r2, #64
++ vst1.8 {q10-q11},[r0]!
++ bge stride_copy_1
++@ copy remaining >= 32 bytes:
++stride_copy_2:
++ cmp r2, #32
++ blt stride_copy_3
++ vld1.8 {q8-q9}, [r1]!
++ sub r2, r2, #32
++ vst1.8 {q8-q9}, [r0]!
++@ copy remaining >= 16 bytes:
++stride_copy_3:
++ cmp r2, #16
++ blt stride_copy_4
++ vld1.8 {q8}, [r1]!
++ sub r2, r2, #16
++ vst1.8 {q8}, [r0]!
++@ copy remaining >= 8 bytes:
++stride_copy_4:
++ cmp r2, #8
++ blt stride_copy_5
++ vld1.8 {d16}, [r1]!
++ sub r2, r2, #8
++ vst1.8 {d16}, [r0]!
++@ copy remaining < 8 bytes:
++stride_copy_5:
++@XXX
++ bx lr
++@}
++
+diff --git a/gst/stride/convert.c b/gst/stride/convert.c
+index 860f16c..a15063b 100644
+--- a/gst/stride/convert.c
++++ b/gst/stride/convert.c
+@@ -37,38 +37,43 @@ GST_DEBUG_CATEGORY_EXTERN (stridetransform_debug);
+ #define GST_CAT_DEFAULT stridetransform_debug
+
+
++/* note: some parts of code support in-place transform.. some do not.. I'm
++ * not sure if zip/interleave functions could really support in-place copy..
++ * I need to think about this after having some sleep ;-)
++ */
++
++#define WEAK __attribute__((weak))
++
+ /*
+ * Conversion utilities:
+ */
+
+-static void
+-memmove_demux (guchar *new_buf, guchar *orig_buf, gint sz, gint pxstride)
++WEAK void
++stride_copy_zip2 (guchar *new_buf, guchar *orig_buf1, guchar *orig_buf2, gint sz)
+ {
+- if (new_buf > orig_buf) {
+- /* copy backwards */
+- new_buf += ((sz - 1) * pxstride);
+- orig_buf += sz - 1;
+- while(sz--) {
+- *new_buf = *orig_buf;
+- new_buf -= pxstride;
+- orig_buf--;
+- }
+- } else {
+- while(sz--) {
+- *new_buf = *orig_buf;
+- new_buf += pxstride;
+- orig_buf++;
+- }
++ while (sz--) {
++ *new_buf++ = *orig_buf1++;
++ *new_buf++ = *orig_buf2++;
+ }
+ }
+
++WEAK void
++stride_copy (guchar *new_buf, guchar *orig_buf, gint sz)
++{
++ memcpy (new_buf, orig_buf, sz);
++}
++
++
++/**
++ * move to strided buffer, interleaving two planes of identical dimensions
++ */
+ static void
+-stridemove_demux (guchar *new_buf, guchar *orig_buf, gint new_width, gint orig_width, gint height, gint pxstride)
++stridemove_zip2 (guchar *new_buf, guchar *orig_buf1, guchar *orig_buf2, gint new_width, gint orig_width, gint height)
+ {
+ int row;
+
+- GST_DEBUG ("new_buf=%p, orig_buf=%p, new_width=%d, orig_width=%d, height=%d",
+- new_buf, orig_buf, new_width, orig_width, height);
++ GST_DEBUG ("new_buf=%p, orig_buf1=%p, orig_buf2=%p, new_width=%d, orig_width=%d, height=%d",
++ new_buf, orig_buf1, orig_buf2, new_width, orig_width, height);
+
+ /* if increasing the stride, work from bottom-up to avoid overwriting data
+ * that has not been moved yet.. otherwise, work in the opposite order,
+@@ -76,11 +81,19 @@ stridemove_demux (guchar *new_buf, guchar *orig_buf, gint new_width, gint orig_w
+ */
+ if (new_width > orig_width) {
+ for (row=height-1; row>=0; row--) {
+- memmove_demux (new_buf+(new_width*row), orig_buf+(orig_width*row), orig_width, pxstride);
++ stride_copy_zip2 (
++ new_buf+(new_width*row),
++ orig_buf1+(orig_width*row),
++ orig_buf2+(orig_width*row),
++ orig_width);
+ }
+ } else {
+ for (row=0; row<height; row++) {
+- memmove_demux (new_buf+(new_width*row), orig_buf+(orig_width*row), new_width, pxstride);
++ stride_copy_zip2 (
++ new_buf+(new_width*row),
++ orig_buf1+(orig_width*row),
++ orig_buf2+(orig_width*row),
++ new_width);
+ }
+ }
+ }
+@@ -106,11 +119,11 @@ stridemove (guchar *new_buf, guchar *orig_buf, gint new_width, gint orig_width,
+ */
+ if (new_width > orig_width) {
+ for (row=height-1; row>=0; row--) {
+- memmove (new_buf+(new_width*row), orig_buf+(orig_width*row), orig_width);
++ stride_copy (new_buf+(new_width*row), orig_buf+(orig_width*row), orig_width);
+ }
+ } else {
+ for (row=0; row<height; row++) {
+- memmove (new_buf+(new_width*row), orig_buf+(orig_width*row), new_width);
++ stride_copy (new_buf+(new_width*row), orig_buf+(orig_width*row), new_width);
+ }
+ }
+ }
+@@ -234,19 +247,12 @@ stridify_i420_nv12 (GstStrideTransform *self, guchar *strided, guchar *unstrided
+
+ g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
+
+- /* note: if not an in-place conversion, then doing the U&V in one pass
+- * would be more efficient... but if it is an in-place conversion, I'd
+- * need to think about whether it is potential for the new UV plane to
+- * corrupt the V plane before it is done copying..
+- */
+- stridemove_demux (
+- strided + (height*stride) + 1,
+- unstrided + (int)(height*width*1.25),
+- stride, width/2, height/2, 2); /* move V */
+- stridemove_demux (
++ /* XXX widths/heights/strides that are not multiple of four??: */
++ stridemove_zip2 (
+ strided + (height*stride),
+ unstrided + (height*width),
+- stride, width/2, height/2, 2); /* move U */
++ unstrided + (int)(height*width*1.25),
++ stride, width/2, height/2); /* interleave U&V */
+ stridemove (strided, unstrided, stride, width, height); /* move Y */
+
+ return GST_FLOW_OK;
+--
+1.7.1
+
diff --git a/media-libs/gst-plugins-base/files/gst-0.10.32-0012-add-support-to-convert-to-YUY2-YUYV-color-format.patch b/media-libs/gst-plugins-base/files/gst-0.10.32-0012-add-support-to-convert-to-YUY2-YUYV-color-format.patch
new file mode 100644
index 0000000..1156754
--- /dev/null
+++ b/media-libs/gst-plugins-base/files/gst-0.10.32-0012-add-support-to-convert-to-YUY2-YUYV-color-format.patch
@@ -0,0 +1,197 @@
+From 2f3ab39353cb9dde02ba64ab89b7c7725b25ae3b Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Tue, 1 Dec 2009 22:42:43 -0600
+Subject: [PATCH 12/24] add support to convert to YUY2/YUYV color format
+
+---
+ gst/stride/armv7.s | 63 ++++++++++++++++++++++++++++++++++++++++++
+ gst/stride/convert.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++---
+ 2 files changed, 133 insertions(+), 4 deletions(-)
+
+diff --git a/gst/stride/armv7.s b/gst/stride/armv7.s
+index ed636f7..2697a14 100644
+--- a/gst/stride/armv7.s
++++ b/gst/stride/armv7.s
+@@ -69,6 +69,69 @@ stride_copy_zip2_3:
+ bx lr
+ @}
+
++
++ .align
++ .global stride_copy_zip3a
++ .type stride_copy_zip3a, %function
++@void
++@stride_copy_zip3a (guchar *new_buf,
++@ guchar *orig_buf1, guchar *orig_buf2, guchar *orig_buf3, gint sz)
++@{
++@@@@ note: r0-r3, q0-3, and q8-q15 do not need to be preserved
++stride_copy_zip3a:
++ pld [r1, #64]
++ pld [r2, #64]
++ pld [r3, #64]
++ ldr ip, [sp] @ the sz arg
++@ interleave remaining >= 32 bytes:
++ cmp ip, #32
++ blt stride_copy_zip3a_2
++stride_copy_zip3a_1:
++ vld1.8 {q8}, [r1]! @ Y
++ vld1.8 {q10}, [r1]! @ Y
++ vld1.8 {q9}, [r2]! @ U
++ vld1.8 {q11}, [r3]! @ V
++
++ pld [r1, #64]
++ pld [r2, #64]
++ pld [r3, #64]
++
++ vzip.8 q9, q11 @ interleave U&V
++ vzip.8 q8, q9 @ interleave Y1UV1
++ vzip.8 q10, q11 @ interleave Y2UV2
++
++ vst1.8 {q8,q9}, [r0]!
++ vst1.8 {q10,q11}, [r0]!
++
++ sub ip, ip, #32
++
++ cmp ip, #32
++ bge stride_copy_zip3a_1
++@ interleave remaining >= 16 bytes:
++stride_copy_zip3a_2:
++ cmp ip, #16
++ blt stride_copy_zip3a_3
++
++ vld1.8 {d16}, [r1]! @ Y
++ vld1.8 {d18}, [r1]! @ Y
++ vld1.8 {d17}, [r2]! @ U
++ vld1.8 {d19}, [r3]! @ V
++
++ vzip.8 d17, d19 @ interleave U&V
++ vzip.8 d16, d17 @ interleave Y1UV1
++ vzip.8 d18, d19 @ interleave Y2UV2
++
++ vst1.8 {d16,d17}, [r0]!
++ vst1.8 {d18,d19}, [r0]!
++
++ sub ip, ip, #16
++@ copy remaining >= 8 bytes:
++stride_copy_zip3a_3:
++@XXX
++ bx lr
++@}
++
++
+ .align
+ .global stride_copy
+ .type stride_copy, %function
+diff --git a/gst/stride/convert.c b/gst/stride/convert.c
+index a15063b..0f59e78 100644
+--- a/gst/stride/convert.c
++++ b/gst/stride/convert.c
+@@ -58,6 +58,19 @@ stride_copy_zip2 (guchar *new_buf, guchar *orig_buf1, guchar *orig_buf2, gint sz
+ }
+
+ WEAK void
++stride_copy_zip3a (guchar *new_buf,
++ guchar *orig_buf1, guchar *orig_buf2, guchar *orig_buf3, gint sz)
++{
++ while (sz > 1) {
++ *new_buf++ = *orig_buf1++;
++ *new_buf++ = *orig_buf2++;
++ *new_buf++ = *orig_buf1++;
++ *new_buf++ = *orig_buf3++;
++ sz -= 2;
++ }
++}
++
++WEAK void
+ stride_copy (guchar *new_buf, guchar *orig_buf, gint sz)
+ {
+ memcpy (new_buf, orig_buf, sz);
+@@ -99,6 +112,36 @@ stridemove_zip2 (guchar *new_buf, guchar *orig_buf1, guchar *orig_buf2, gint new
+ }
+
+ /**
++ * move to strided buffer, interleaving three planes, where the first plane
++ * (orig_buf1) has 2x as many samples.. Ie. ABACABAC..
++ */
++static void
++stridemove_zip3a (guchar *new_buf,
++ guchar *orig_buf1, guchar *orig_buf2, guchar *orig_buf3,
++ guint new_width, gint orig_width, gint height)
++{
++ gint copy_width = (new_width < orig_width) ? new_width : orig_width;
++
++ while (height > 0) {
++
++ /* even row */
++ stride_copy_zip3a (new_buf, orig_buf1, orig_buf2, orig_buf3, copy_width);
++ new_buf += new_width;
++ orig_buf1 += orig_width;
++
++ /* odd row, recycles same U & V */
++ stride_copy_zip3a (new_buf, orig_buf1, orig_buf2, orig_buf3, copy_width);
++ new_buf += new_width;
++ orig_buf1 += orig_width;
++
++ orig_buf2 += orig_width/2;
++ orig_buf3 += orig_width/2;
++
++ height -= 2;
++ }
++}
++
++/**
+ * Convert from one stride to another... like memmove, but can convert stride in
+ * the process. This function is not aware of pixels, only of bytes. So widths
+ * are given in bytes, not pixels. The new_buf and orig_buf can point to the
+@@ -250,14 +293,36 @@ stridify_i420_nv12 (GstStrideTransform *self, guchar *strided, guchar *unstrided
+ /* XXX widths/heights/strides that are not multiple of four??: */
+ stridemove_zip2 (
+ strided + (height*stride),
+- unstrided + (height*width),
+- unstrided + (int)(height*width*1.25),
+- stride, width/2, height/2); /* interleave U&V */
+- stridemove (strided, unstrided, stride, width, height); /* move Y */
++ unstrided + (height*width), /* U */
++ unstrided + (int)(height*width*1.25), /* V */
++ stride, width/2, height/2);
++ stridemove (strided, unstrided, stride, width, height); /* Y */
++
++ return GST_FLOW_OK;
++}
++
++/** convert I420 unstrided to YUY2 strided */
++static GstFlowReturn
++stridify_i420_yuy2 (GstStrideTransform *self, guchar *strided, guchar *unstrided)
++{
++ gint width = self->width;
++ gint height = self->height;
++ gint stride = self->out_rowstride;
++
++ g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
++
++ /* XXX widths/heights/strides that are not multiple of four??: */
++ stridemove_zip3a (
++ strided,
++ unstrided, /* Y */
++ unstrided + (height*width), /* U */
++ unstrided + (int)(height*width*1.25), /* V */
++ stride, width, height);
+
+ return GST_FLOW_OK;
+ }
+
++
+ /* last entry has GST_VIDEO_FORMAT_UNKNOWN for in/out formats */
+ Conversion stride_conversions[] = {
+ { { GST_VIDEO_FORMAT_NV12, GST_VIDEO_FORMAT_NV12 }, stridify_420sp_420sp, unstridify_420sp_420sp },
+@@ -266,6 +331,7 @@ Conversion stride_conversions[] = {
+ { { GST_VIDEO_FORMAT_YUY2, GST_VIDEO_FORMAT_YUY2 }, stridify_422i_422i, unstridify_422i_422i },
+ { { GST_VIDEO_FORMAT_UYVY, GST_VIDEO_FORMAT_UYVY }, stridify_422i_422i, unstridify_422i_422i },
+ { { GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_NV12 }, stridify_i420_nv12, NULL },
++ { { GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_YUY2 }, stridify_i420_yuy2, NULL },
+ /* add new entries before here */
+ { { GST_VIDEO_FORMAT_UNKNOWN } }
+ };
+--
+1.7.1
+
diff --git a/media-libs/gst-plugins-base/files/gst-0.10.32-0013-Add-support-for-RGB565-to-stridetransform.patch b/media-libs/gst-plugins-base/files/gst-0.10.32-0013-Add-support-for-RGB565-to-stridetransform.patch
new file mode 100644
index 0000000..d07c1b9
--- /dev/null
+++ b/media-libs/gst-plugins-base/files/gst-0.10.32-0013-Add-support-for-RGB565-to-stridetransform.patch
@@ -0,0 +1,336 @@
+From 28a5ad7c5ccfa98ffa7bb1425dc38ab16535fc26 Mon Sep 17 00:00:00 2001
+From: Castaneda Sheissa, Roberto <rsheissa@ti.com>
+Date: Sun, 3 Jan 2010 13:40:30 -0600
+Subject: [PATCH 13/24] Add support for RGB565 to stridetransform
+
+---
+ gst/stride/convert.c | 30 ++++++++++
+ gst/stride/gststridetransform.c | 120 ++++++++++++++++++++------------------
+ 2 files changed, 93 insertions(+), 57 deletions(-)
+
+diff --git a/gst/stride/convert.c b/gst/stride/convert.c
+index 0f59e78..fdb02ae 100644
+--- a/gst/stride/convert.c
++++ b/gst/stride/convert.c
+@@ -322,6 +322,35 @@ stridify_i420_yuy2 (GstStrideTransform *self, guchar *strided, guchar *unstrided
+ return GST_FLOW_OK;
+ }
+
++/** convert RGB565 to RGB565 strided **/
++static GstFlowReturn
++stridify_rgb565_rgb565 (GstStrideTransform *self, guchar *strided, guchar *unstrided)
++{
++ gint width = self->width;
++ gint height = self->height;
++ gint stride = self->out_rowstride;
++
++ g_return_val_if_fail (stride >= (width*2), GST_FLOW_ERROR);
++
++ stridemove (strided, unstrided, stride, width*2, height);
++
++ return GST_FLOW_OK;
++}
++
++/** convert RGB565 strided to RGB565 **/
++static GstFlowReturn
++unstridify_rgb565_rgb565 (GstStrideTransform *self, guchar *strided, guchar *unstrided)
++{
++ gint width = self->width;
++ gint height = self->height;
++ gint stride = self->in_rowstride;
++
++ g_return_val_if_fail (stride >= (width*2), GST_FLOW_ERROR);
++
++ stridemove (unstrided, strided, width*2, stride, height);
++ return GST_FLOW_OK;
++}
++
+
+ /* last entry has GST_VIDEO_FORMAT_UNKNOWN for in/out formats */
+ Conversion stride_conversions[] = {
+@@ -332,6 +361,7 @@ Conversion stride_conversions[] = {
+ { { GST_VIDEO_FORMAT_UYVY, GST_VIDEO_FORMAT_UYVY }, stridify_422i_422i, unstridify_422i_422i },
+ { { GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_NV12 }, stridify_i420_nv12, NULL },
+ { { GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_YUY2 }, stridify_i420_yuy2, NULL },
++ { { GST_VIDEO_FORMAT_RGB16, GST_VIDEO_FORMAT_RGB16 }, stridify_rgb565_rgb565, unstridify_rgb565_rgb565 },
+ /* add new entries before here */
+ { { GST_VIDEO_FORMAT_UNKNOWN } }
+ };
+diff --git a/gst/stride/gststridetransform.c b/gst/stride/gststridetransform.c
+index 6ab0479..c35be73 100644
+--- a/gst/stride/gststridetransform.c
++++ b/gst/stride/gststridetransform.c
+@@ -66,46 +66,47 @@ GST_ELEMENT_DETAILS ("Stride transform",
+
+
+ /* TODO: add rgb formats too! */
+-#define SUPPORTED_CAPS \
+- GST_VIDEO_CAPS_YUV_STRIDED ("{ I420, YV12, YUY2, UYVY, NV12 }", "[ 0, max ]")
++#define YUV_SUPPORTED_CAPS \
++ GST_VIDEO_CAPS_YUV_STRIDED ("{I420, YV12, YUY2, UYVY, NV12 }", "[ 0, max ]")
+
++#define RGB_SUPPORTED_CAPS \
++ GST_VIDEO_CAPS_RGB_16_STRIDED ("[ 0, max ]")
+
+-static GstStaticPadTemplate src_template =
+-GST_STATIC_PAD_TEMPLATE ("src",
++
++static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+- GST_STATIC_CAPS (SUPPORTED_CAPS)
+-);
++ GST_STATIC_CAPS (YUV_SUPPORTED_CAPS ";" RGB_SUPPORTED_CAPS)
++ );
+
+-static GstStaticPadTemplate sink_template =
+-GST_STATIC_PAD_TEMPLATE ("sink",
++static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+- GST_STATIC_CAPS (SUPPORTED_CAPS)
+-);
++ GST_STATIC_CAPS (YUV_SUPPORTED_CAPS ";" RGB_SUPPORTED_CAPS)
++ );
+
+
+ GST_DEBUG_CATEGORY (stridetransform_debug);
+ #define GST_CAT_DEFAULT stridetransform_debug
+
+ /* type functions */
+-static void gst_stride_transform_dispose (GObject *obj);
++static void gst_stride_transform_dispose (GObject * obj);
+
+ /* GstBaseTransform functions */
+-static gboolean gst_stride_transform_get_unit_size (GstBaseTransform *base,
+- GstCaps *caps, guint *size);
+-static gboolean gst_stride_transform_transform_size (GstBaseTransform *base,
++static gboolean gst_stride_transform_get_unit_size (GstBaseTransform * base,
++ GstCaps * caps, guint * size);
++static gboolean gst_stride_transform_transform_size (GstBaseTransform * base,
+ GstPadDirection direction,
+- GstCaps *caps, guint size,
+- GstCaps *othercaps, guint *othersize);
+-static GstCaps *gst_stride_transform_transform_caps (GstBaseTransform *base,
+- GstPadDirection direction, GstCaps *caps);
+-static gboolean gst_stride_transform_set_caps (GstBaseTransform *base,
+- GstCaps *incaps, GstCaps *outcaps);
+-static GstFlowReturn gst_stride_transform_transform (GstBaseTransform *base,
+- GstBuffer *inbuf, GstBuffer *outbuf);
++ GstCaps * caps, guint size, GstCaps * othercaps, guint * othersize);
++static GstCaps *gst_stride_transform_transform_caps (GstBaseTransform * base,
++ GstPadDirection direction, GstCaps * caps);
++static gboolean gst_stride_transform_set_caps (GstBaseTransform * base,
++ GstCaps * incaps, GstCaps * outcaps);
++static GstFlowReturn gst_stride_transform_transform (GstBaseTransform * base,
++ GstBuffer * inbuf, GstBuffer * outbuf);
+
+-GST_BOILERPLATE (GstStrideTransform, gst_stride_transform, GstVideoFilter, GST_TYPE_VIDEO_FILTER);
++GST_BOILERPLATE (GstStrideTransform, gst_stride_transform, GstVideoFilter,
++ GST_TYPE_VIDEO_FILTER);
+
+
+ static void
+@@ -113,7 +114,8 @@ gst_stride_transform_base_init (gpointer g_class)
+ {
+ GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
+
+- GST_DEBUG_CATEGORY_INIT (stridetransform_debug, "stride", 0, "stride transform element");
++ GST_DEBUG_CATEGORY_INIT (stridetransform_debug, "stride", 0,
++ "stride transform element");
+
+ gst_element_class_set_details (gstelement_class, &stridetransform_details);
+
+@@ -124,7 +126,7 @@ gst_stride_transform_base_init (gpointer g_class)
+ }
+
+ static void
+-gst_stride_transform_class_init (GstStrideTransformClass *klass)
++gst_stride_transform_class_init (GstStrideTransformClass * klass)
+ {
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GstBaseTransformClass *basetransform_class = GST_BASE_TRANSFORM_CLASS (klass);
+@@ -146,14 +148,15 @@ gst_stride_transform_class_init (GstStrideTransformClass *klass)
+ }
+
+ static void
+-gst_stride_transform_init (GstStrideTransform *self, GstStrideTransformClass *klass)
++gst_stride_transform_init (GstStrideTransform * self,
++ GstStrideTransformClass * klass)
+ {
+ GST_DEBUG_OBJECT (self, "not implemented");
+ }
+
+
+ static void
+-gst_stride_transform_dispose (GObject *object)
++gst_stride_transform_dispose (GObject * object)
+ {
+ GstStrideTransform *self = GST_STRIDE_TRANSFORM (object);
+ GST_DEBUG_OBJECT (self, "not implemented");
+@@ -164,15 +167,15 @@ gst_stride_transform_dispose (GObject *object)
+ * figure out the required buffer size based on @caps
+ */
+ static gboolean
+-gst_stride_transform_get_unit_size (GstBaseTransform *base,
+- GstCaps *caps, guint *size)
++gst_stride_transform_get_unit_size (GstBaseTransform * base,
++ GstCaps * caps, guint * size)
+ {
+ GstStrideTransform *self = GST_STRIDE_TRANSFORM (base);
+ GstVideoFormat format;
+ gint width, height, rowstride;
+
+- g_return_val_if_fail (gst_video_format_parse_caps_strided (
+- caps, &format, &width, &height, &rowstride), FALSE);
++ g_return_val_if_fail (gst_video_format_parse_caps_strided (caps, &format,
++ &width, &height, &rowstride), FALSE);
+
+ *size = gst_video_format_get_size_strided (format, width, height, rowstride);
+
+@@ -188,16 +191,14 @@ gst_stride_transform_get_unit_size (GstBaseTransform *base,
+ * buffer size is a multiple of the unit size.. which doesn't hold true.
+ */
+ static gboolean
+-gst_stride_transform_transform_size (GstBaseTransform *base,
++gst_stride_transform_transform_size (GstBaseTransform * base,
+ GstPadDirection direction,
+- GstCaps *caps, guint size,
+- GstCaps *othercaps, guint *othersize)
++ GstCaps * caps, guint size, GstCaps * othercaps, guint * othersize)
+ {
+ GstStrideTransform *self = GST_STRIDE_TRANSFORM (base);
+ guint idx = (direction == GST_PAD_SINK) ? 0 : 1;
+
+- if (self->cached_caps[idx] != othercaps)
+- {
++ if (self->cached_caps[idx] != othercaps) {
+ guint sz;
+ if (!gst_stride_transform_get_unit_size (base, othercaps, &sz)) {
+ return FALSE;
+@@ -220,13 +221,15 @@ gst_stride_transform_transform_size (GstBaseTransform *base,
+ * helper to add all fields, other than rowstride to @caps, copied from @s.
+ */
+ static void
+-add_all_fields (GstCaps *caps, const gchar *name, GstStructure *s, gboolean rowstride, GstPadDirection direction)
++add_all_fields (GstCaps * caps, const gchar * name, GstStructure * s,
++ gboolean rowstride, GstPadDirection direction)
+ {
+ gint idx;
+ GstStructure *new_s = gst_structure_new (name, NULL);
+
+ if (rowstride) {
+- gst_structure_set (new_s, "rowstride", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
++ gst_structure_set (new_s, "rowstride", GST_TYPE_INT_RANGE, 1, G_MAXINT,
++ NULL);
+ }
+
+ idx = gst_structure_n_fields (s) - 1;
+@@ -245,15 +248,16 @@ add_all_fields (GstCaps *caps, const gchar *name, GstStructure *s, gboolean rows
+ gint from_format = (direction == GST_PAD_SRC) ? 1 : 0;
+
+ if (gst_structure_get_fourcc (s, "format", &fourcc)) {
+- GValue formats = {0};
+- GValue fourccval = {0};
++ GValue formats = { 0 };
++ GValue fourccval = { 0 };
+ gint i;
+ GstVideoFormat format = gst_video_format_from_fourcc (fourcc);
+
+ g_value_init (&formats, GST_TYPE_LIST);
+ g_value_init (&fourccval, GST_TYPE_FOURCC);
+
+- for (i=0; stride_conversions[i].format[0]!=GST_VIDEO_FORMAT_UNKNOWN; i++) {
++ for (i = 0; stride_conversions[i].format[0] != GST_VIDEO_FORMAT_UNKNOWN;
++ i++) {
+ if (stride_conversions[i].format[from_format] == format) {
+ gst_value_set_fourcc (&fourccval, gst_video_format_to_fourcc
+ (stride_conversions[i].format[to_format]));
+@@ -281,8 +285,8 @@ add_all_fields (GstCaps *caps, const gchar *name, GstStructure *s, gboolean rows
+ * identical parameters
+ */
+ static GstCaps *
+-gst_stride_transform_transform_caps (GstBaseTransform *base,
+- GstPadDirection direction, GstCaps *caps)
++gst_stride_transform_transform_caps (GstBaseTransform * base,
++ GstPadDirection direction, GstCaps * caps)
+ {
+ GstStrideTransform *self = GST_STRIDE_TRANSFORM (base);
+ GstCaps *ret;
+@@ -321,8 +325,8 @@ gst_stride_transform_transform_caps (GstBaseTransform *base,
+ * plus the requested rowstride of the @incaps and @outcaps
+ */
+ static gboolean
+-gst_stride_transform_set_caps (GstBaseTransform *base,
+- GstCaps *incaps, GstCaps *outcaps)
++gst_stride_transform_set_caps (GstBaseTransform * base,
++ GstCaps * incaps, GstCaps * outcaps)
+ {
+ GstStrideTransform *self = GST_STRIDE_TRANSFORM (base);
+ gint width, height;
+@@ -333,13 +337,13 @@ gst_stride_transform_set_caps (GstBaseTransform *base,
+ LOG_CAPS (self, outcaps);
+
+ g_return_val_if_fail (gst_video_format_parse_caps_strided (incaps,
+- &in_format, &self->width, &self->height, &self->in_rowstride), FALSE);
++ &in_format, &self->width, &self->height, &self->in_rowstride), FALSE);
+ g_return_val_if_fail (gst_video_format_parse_caps_strided (outcaps,
+- &out_format, &width, &height, &self->out_rowstride), FALSE);
++ &out_format, &width, &height, &self->out_rowstride), FALSE);
+
+ self->conversion = NULL;
+
+- for (i=0; stride_conversions[i].format[0]!=GST_VIDEO_FORMAT_UNKNOWN; i++) {
++ for (i = 0; stride_conversions[i].format[0] != GST_VIDEO_FORMAT_UNKNOWN; i++) {
+ if ((stride_conversions[i].format[0] == in_format) &&
+ (stride_conversions[i].format[1] == out_format)) {
+ GST_DEBUG_OBJECT (self, "found stride_conversion: %d", i);
+@@ -349,26 +353,27 @@ gst_stride_transform_set_caps (GstBaseTransform *base,
+ }
+
+ g_return_val_if_fail (self->conversion, FALSE);
+- g_return_val_if_fail (self->conversion->unstridify || !self->in_rowstride, FALSE);
+- g_return_val_if_fail (self->conversion->stridify || !self->out_rowstride, FALSE);
+- g_return_val_if_fail (self->width == width, FALSE);
++ g_return_val_if_fail (self->conversion->unstridify
++ || !self->in_rowstride, FALSE);
++ g_return_val_if_fail (self->conversion->stridify
++ || !self->out_rowstride, FALSE);
++ g_return_val_if_fail (self->width == width, FALSE);
+ g_return_val_if_fail (self->height == height, FALSE);
+
+ return TRUE;
+ }
+
+ static GstFlowReturn
+-gst_stride_transform_transform (GstBaseTransform *base,
+- GstBuffer *inbuf, GstBuffer *outbuf)
++gst_stride_transform_transform (GstBaseTransform * base,
++ GstBuffer * inbuf, GstBuffer * outbuf)
+ {
+ GstStrideTransform *self = GST_STRIDE_TRANSFORM (base);
+
+ GST_DEBUG_OBJECT (self, "inbuf=%p (size=%d), outbuf=%p (size=%d)",
+- inbuf, GST_BUFFER_SIZE (inbuf),
+- outbuf, GST_BUFFER_SIZE (outbuf));
++ inbuf, GST_BUFFER_SIZE (inbuf), outbuf, GST_BUFFER_SIZE (outbuf));
+
+ if (self->in_rowstride && self->out_rowstride) {
+- GST_DEBUG_OBJECT (self, "not implemented"); // TODO
++ GST_DEBUG_OBJECT (self, "not implemented"); // TODO
+ return GST_FLOW_ERROR;
+ } else if (self->in_rowstride) {
+ return self->conversion->unstridify (self,
+@@ -378,7 +383,8 @@ gst_stride_transform_transform (GstBaseTransform *base,
+ GST_BUFFER_DATA (outbuf), GST_BUFFER_DATA (inbuf));
+ }
+
+- GST_DEBUG_OBJECT (self, "this shouldn't happen! in_rowstride=%d, out_rowstride=%d",
++ GST_DEBUG_OBJECT (self,
++ "this shouldn't happen! in_rowstride=%d, out_rowstride=%d",
+ self->in_rowstride, self->out_rowstride);
+
+ return GST_FLOW_ERROR;
+--
+1.7.1
+
diff --git a/media-libs/gst-plugins-base/files/gst-0.10.32-0014-stridetransform-updates-for-new-extra-anal-compiler-.patch b/media-libs/gst-plugins-base/files/gst-0.10.32-0014-stridetransform-updates-for-new-extra-anal-compiler-.patch
new file mode 100644
index 0000000..4e60f32
--- /dev/null
+++ b/media-libs/gst-plugins-base/files/gst-0.10.32-0014-stridetransform-updates-for-new-extra-anal-compiler-.patch
@@ -0,0 +1,61 @@
+From e97373aac252f312c5ac69305228db50886a7c5c Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Thu, 8 Apr 2010 03:30:35 -0500
+Subject: [PATCH 14/24] stridetransform: updates for new extra-anal compiler warning flags
+
+---
+ gst/stride/convert.c | 6 ++++++
+ gst/stride/gststridetransform.c | 13 ++++---------
+ 2 files changed, 10 insertions(+), 9 deletions(-)
+
+diff --git a/gst/stride/convert.c b/gst/stride/convert.c
+index fdb02ae..ad9c0aa 100644
+--- a/gst/stride/convert.c
++++ b/gst/stride/convert.c
+@@ -48,6 +48,12 @@ GST_DEBUG_CATEGORY_EXTERN (stridetransform_debug);
+ * Conversion utilities:
+ */
+
++void stride_copy_zip2 (guchar * new_buf, guchar * orig_buf1,
++ guchar * orig_buf2, gint sz);
++void stride_copy_zip3a (guchar * new_buf, guchar * orig_buf1,
++ guchar * orig_buf2, guchar * orig_buf3, gint sz);
++void stride_copy (guchar * new_buf, guchar * orig_buf, gint sz);
++
+ WEAK void
+ stride_copy_zip2 (guchar *new_buf, guchar *orig_buf1, guchar *orig_buf2, gint sz)
+ {
+diff --git a/gst/stride/gststridetransform.c b/gst/stride/gststridetransform.c
+index c35be73..de07c11 100644
+--- a/gst/stride/gststridetransform.c
++++ b/gst/stride/gststridetransform.c
+@@ -57,14 +57,6 @@
+ /* last entry has GST_VIDEO_FORMAT_UNKNOWN for in/out formats */
+ extern const Conversion stride_conversions[];
+
+-
+-static const GstElementDetails stridetransform_details =
+-GST_ELEMENT_DETAILS ("Stride transform",
+- "Filter/Converter/Video",
+- "Convert between video buffers with and without stride, or with differing stride",
+- "Rob Clark <rob@ti.com>,");
+-
+-
+ /* TODO: add rgb formats too! */
+ #define YUV_SUPPORTED_CAPS \
+ GST_VIDEO_CAPS_YUV_STRIDED ("{I420, YV12, YUY2, UYVY, NV12 }", "[ 0, max ]")
+@@ -117,7 +109,10 @@ gst_stride_transform_base_init (gpointer g_class)
+ GST_DEBUG_CATEGORY_INIT (stridetransform_debug, "stride", 0,
+ "stride transform element");
+
+- gst_element_class_set_details (gstelement_class, &stridetransform_details);
++ gst_element_class_set_details_simple (gstelement_class,
++ "Stride transform", "Filter/Converter/Video",
++ "Convert between video buffers with and without stride, or with differing stride",
++ "Rob Clark <rob@ti.com>,");
+
+ gst_element_class_add_pad_template (gstelement_class,
+ gst_static_pad_template_get (&sink_template));
+--
+1.7.1
+
diff --git a/media-libs/gst-plugins-base/files/gst-0.10.32-0015-stridetransform-fix-problem-transforming-caps-with-l.patch b/media-libs/gst-plugins-base/files/gst-0.10.32-0015-stridetransform-fix-problem-transforming-caps-with-l.patch
new file mode 100644
index 0000000..0d757d9
--- /dev/null
+++ b/media-libs/gst-plugins-base/files/gst-0.10.32-0015-stridetransform-fix-problem-transforming-caps-with-l.patch
@@ -0,0 +1,544 @@
+From c8db3522e32ca6afbbd117b816068516eed8c594 Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Sat, 30 Jan 2010 14:32:42 -0600
+Subject: [PATCH 15/24] stridetransform: fix problem transforming caps with list of fourcc's
+
+previous logic assumed that the format field would contain just a single fourcc
+---
+ gst/stride/convert.c | 206 ++++++++++++++++++++-------------------
+ gst/stride/gststridetransform.c | 78 +++++++++++-----
+ 2 files changed, 159 insertions(+), 125 deletions(-)
+
+diff --git a/gst/stride/convert.c b/gst/stride/convert.c
+index ad9c0aa..17f9e2a 100644
+--- a/gst/stride/convert.c
++++ b/gst/stride/convert.c
+@@ -55,7 +55,8 @@ void stride_copy_zip3a (guchar * new_buf, guchar * orig_buf1,
+ void stride_copy (guchar * new_buf, guchar * orig_buf, gint sz);
+
+ WEAK void
+-stride_copy_zip2 (guchar *new_buf, guchar *orig_buf1, guchar *orig_buf2, gint sz)
++stride_copy_zip2 (guchar * new_buf, guchar * orig_buf1, guchar * orig_buf2,
++ gint sz)
+ {
+ while (sz--) {
+ *new_buf++ = *orig_buf1++;
+@@ -64,8 +65,8 @@ stride_copy_zip2 (guchar *new_buf, guchar *orig_buf1, guchar *orig_buf2, gint sz
+ }
+
+ WEAK void
+-stride_copy_zip3a (guchar *new_buf,
+- guchar *orig_buf1, guchar *orig_buf2, guchar *orig_buf3, gint sz)
++stride_copy_zip3a (guchar * new_buf,
++ guchar * orig_buf1, guchar * orig_buf2, guchar * orig_buf3, gint sz)
+ {
+ while (sz > 1) {
+ *new_buf++ = *orig_buf1++;
+@@ -77,7 +78,7 @@ stride_copy_zip3a (guchar *new_buf,
+ }
+
+ WEAK void
+-stride_copy (guchar *new_buf, guchar *orig_buf, gint sz)
++stride_copy (guchar * new_buf, guchar * orig_buf, gint sz)
+ {
+ memcpy (new_buf, orig_buf, sz);
+ }
+@@ -87,11 +88,13 @@ stride_copy (guchar *new_buf, guchar *orig_buf, gint sz)
+ * move to strided buffer, interleaving two planes of identical dimensions
+ */
+ static void
+-stridemove_zip2 (guchar *new_buf, guchar *orig_buf1, guchar *orig_buf2, gint new_width, gint orig_width, gint height)
++stridemove_zip2 (guchar * new_buf, guchar * orig_buf1, guchar * orig_buf2,
++ gint new_width, gint orig_width, gint height)
+ {
+ int row;
+
+- GST_DEBUG ("new_buf=%p, orig_buf1=%p, orig_buf2=%p, new_width=%d, orig_width=%d, height=%d",
++ GST_DEBUG
++ ("new_buf=%p, orig_buf1=%p, orig_buf2=%p, new_width=%d, orig_width=%d, height=%d",
+ new_buf, orig_buf1, orig_buf2, new_width, orig_width, height);
+
+ /* if increasing the stride, work from bottom-up to avoid overwriting data
+@@ -99,20 +102,16 @@ stridemove_zip2 (guchar *new_buf, guchar *orig_buf1, guchar *orig_buf2, gint new
+ * for the same reason.
+ */
+ if (new_width > orig_width) {
+- for (row=height-1; row>=0; row--) {
+- stride_copy_zip2 (
+- new_buf+(new_width*row),
+- orig_buf1+(orig_width*row),
+- orig_buf2+(orig_width*row),
+- orig_width);
++ for (row = height - 1; row >= 0; row--) {
++ stride_copy_zip2 (new_buf + (new_width * row),
++ orig_buf1 + (orig_width * row),
++ orig_buf2 + (orig_width * row), orig_width);
+ }
+ } else {
+- for (row=0; row<height; row++) {
+- stride_copy_zip2 (
+- new_buf+(new_width*row),
+- orig_buf1+(orig_width*row),
+- orig_buf2+(orig_width*row),
+- new_width);
++ for (row = 0; row < height; row++) {
++ stride_copy_zip2 (new_buf + (new_width * row),
++ orig_buf1 + (orig_width * row),
++ orig_buf2 + (orig_width * row), new_width);
+ }
+ }
+ }
+@@ -122,8 +121,8 @@ stridemove_zip2 (guchar *new_buf, guchar *orig_buf1, guchar *orig_buf2, gint new
+ * (orig_buf1) has 2x as many samples.. Ie. ABACABAC..
+ */
+ static void
+-stridemove_zip3a (guchar *new_buf,
+- guchar *orig_buf1, guchar *orig_buf2, guchar *orig_buf3,
++stridemove_zip3a (guchar * new_buf,
++ guchar * orig_buf1, guchar * orig_buf2, guchar * orig_buf3,
+ guint new_width, gint orig_width, gint height)
+ {
+ gint copy_width = (new_width < orig_width) ? new_width : orig_width;
+@@ -140,8 +139,8 @@ stridemove_zip3a (guchar *new_buf,
+ new_buf += new_width;
+ orig_buf1 += orig_width;
+
+- orig_buf2 += orig_width/2;
+- orig_buf3 += orig_width/2;
++ orig_buf2 += orig_width / 2;
++ orig_buf3 += orig_width / 2;
+
+ height -= 2;
+ }
+@@ -155,7 +154,8 @@ stridemove_zip3a (guchar *new_buf,
+ * enough.
+ */
+ static void
+-stridemove (guchar *new_buf, guchar *orig_buf, gint new_width, gint orig_width, gint height)
++stridemove (guchar * new_buf, guchar * orig_buf, gint new_width,
++ gint orig_width, gint height)
+ {
+ int row;
+
+@@ -167,12 +167,14 @@ stridemove (guchar *new_buf, guchar *orig_buf, gint new_width, gint orig_width,
+ * for the same reason.
+ */
+ if (new_width > orig_width) {
+- for (row=height-1; row>=0; row--) {
+- stride_copy (new_buf+(new_width*row), orig_buf+(orig_width*row), orig_width);
++ for (row = height - 1; row >= 0; row--) {
++ stride_copy (new_buf + (new_width * row), orig_buf + (orig_width * row),
++ orig_width);
+ }
+ } else {
+- for (row=0; row<height; row++) {
+- stride_copy (new_buf+(new_width*row), orig_buf+(orig_width*row), new_width);
++ for (row = 0; row < height; row++) {
++ stride_copy (new_buf + (new_width * row), orig_buf + (orig_width * row),
++ new_width);
+ }
+ }
+ }
+@@ -183,9 +185,10 @@ stridemove (guchar *new_buf, guchar *orig_buf, gint new_width, gint orig_width,
+
+ /** convert 4:2:0 semiplanar to same 4:2:0 semiplanar */
+ static GstFlowReturn
+-unstridify_420sp_420sp (GstStrideTransform *self, guchar *unstrided, guchar *strided)
++unstridify_420sp_420sp (GstStrideTransform * self, guchar * unstrided,
++ guchar * strided)
+ {
+- gint width = self->width;
++ gint width = self->width;
+ gint height = self->height;
+ gint stride = self->in_rowstride;
+
+@@ -196,10 +199,12 @@ unstridify_420sp_420sp (GstStrideTransform *self, guchar *unstrided, guchar *str
+
+ return GST_FLOW_OK;
+ }
++
+ static GstFlowReturn
+-stridify_420sp_420sp (GstStrideTransform *self, guchar *strided, guchar *unstrided)
++stridify_420sp_420sp (GstStrideTransform * self, guchar * strided,
++ guchar * unstrided)
+ {
+- gint width = self->width;
++ gint width = self->width;
+ gint height = self->height;
+ gint stride = self->out_rowstride;
+
+@@ -214,115 +219,107 @@ stridify_420sp_420sp (GstStrideTransform *self, guchar *strided, guchar *unstrid
+
+ /** convert 4:2:0 planar to same 4:2:0 planar */
+ static GstFlowReturn
+-unstridify_420p_420p (GstStrideTransform *self, guchar *unstrided, guchar *strided)
++unstridify_420p_420p (GstStrideTransform * self, guchar * unstrided,
++ guchar * strided)
+ {
+- gint width = self->width;
++ gint width = self->width;
+ gint height = self->height;
+ gint stride = self->in_rowstride;
+
+ g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
+
+- stridemove (unstrided, strided, width, stride, height); /* move Y */
+- stridemove (
+- unstrided + (height*width),
+- strided + (height*stride),
+- width/2, stride, height); /* move V/U */
++ stridemove (unstrided, strided, width, stride, height); /* move Y */
++ stridemove (unstrided + (height * width), strided + (height * stride), width / 2, stride, height); /* move V/U */
+ /* XXX odd widths/heights/strides: */
+- stridemove (
+- unstrided + (int)(height*width*1.5),
+- strided + (int)(height*stride*1.5),
+- width/2, stride, height); /* move U/V */
++ stridemove (unstrided + (int) (height * width * 1.5), strided + (int) (height * stride * 1.5), width / 2, stride, height); /* move U/V */
+
+ return GST_FLOW_OK;
+ }
++
+ static GstFlowReturn
+-stridify_420p_420p (GstStrideTransform *self, guchar *strided, guchar *unstrided)
++stridify_420p_420p (GstStrideTransform * self, guchar * strided,
++ guchar * unstrided)
+ {
+- gint width = self->width;
++ gint width = self->width;
+ gint height = self->height;
+ gint stride = self->out_rowstride;
+
+ g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
+
+ /* XXX odd widths/heights/strides: */
+- stridemove (
+- strided + (int)(height*stride*1.5),
+- unstrided + (int)(height*width*1.5),
+- stride, width/2, height); /* move U/V */
+- stridemove (
+- strided + (height*stride),
+- unstrided + (height*width),
+- stride, width/2, height); /* move V/U */
+- stridemove (strided, unstrided, stride, width, height); /* move Y */
++ stridemove (strided + (int) (height * stride * 1.5), unstrided + (int) (height * width * 1.5), stride, width / 2, height); /* move U/V */
++ stridemove (strided + (height * stride), unstrided + (height * width), stride, width / 2, height); /* move V/U */
++ stridemove (strided, unstrided, stride, width, height); /* move Y */
+
+ return GST_FLOW_OK;
+ }
+
+ /** convert 4:2:2 packed to same 4:2:2 packed */
+ static GstFlowReturn
+-unstridify_422i_422i (GstStrideTransform *self, guchar *unstrided, guchar *strided)
++unstridify_422i_422i (GstStrideTransform * self, guchar * unstrided,
++ guchar * strided)
+ {
+- gint width = self->width;
++ gint width = self->width;
+ gint height = self->height;
+ gint stride = self->in_rowstride;
+
+- g_return_val_if_fail (stride >= (width*2), GST_FLOW_ERROR);
++ g_return_val_if_fail (stride >= (width * 2), GST_FLOW_ERROR);
+
+- stridemove (unstrided, strided, width*2, stride, height);
++ stridemove (unstrided, strided, width * 2, stride, height);
+
+ return GST_FLOW_OK;
+ }
++
+ static GstFlowReturn
+-stridify_422i_422i (GstStrideTransform *self, guchar *strided, guchar *unstrided)
++stridify_422i_422i (GstStrideTransform * self, guchar * strided,
++ guchar * unstrided)
+ {
+- gint width = self->width;
++ gint width = self->width;
+ gint height = self->height;
+ gint stride = self->out_rowstride;
+
+- g_return_val_if_fail (stride >= (width*2), GST_FLOW_ERROR);
++ g_return_val_if_fail (stride >= (width * 2), GST_FLOW_ERROR);
+
+- stridemove (strided, unstrided, stride, width*2, height);
++ stridemove (strided, unstrided, stride, width * 2, height);
+
+ return GST_FLOW_OK;
+ }
+
+ /** convert I420 unstrided to NV12 strided */
+ static GstFlowReturn
+-stridify_i420_nv12 (GstStrideTransform *self, guchar *strided, guchar *unstrided)
++stridify_i420_nv12 (GstStrideTransform * self, guchar * strided,
++ guchar * unstrided)
+ {
+- gint width = self->width;
++ gint width = self->width;
+ gint height = self->height;
+ gint stride = self->out_rowstride;
+
+ g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
+
+ /* XXX widths/heights/strides that are not multiple of four??: */
+- stridemove_zip2 (
+- strided + (height*stride),
+- unstrided + (height*width), /* U */
+- unstrided + (int)(height*width*1.25), /* V */
+- stride, width/2, height/2);
+- stridemove (strided, unstrided, stride, width, height); /* Y */
++ stridemove_zip2 (strided + (height * stride), unstrided + (height * width), /* U */
++ unstrided + (int) (height * width * 1.25), /* V */
++ stride, width / 2, height / 2);
++ stridemove (strided, unstrided, stride, width, height); /* Y */
+
+ return GST_FLOW_OK;
+ }
+
+ /** convert I420 unstrided to YUY2 strided */
+ static GstFlowReturn
+-stridify_i420_yuy2 (GstStrideTransform *self, guchar *strided, guchar *unstrided)
++stridify_i420_yuy2 (GstStrideTransform * self, guchar * strided,
++ guchar * unstrided)
+ {
+- gint width = self->width;
++ gint width = self->width;
+ gint height = self->height;
+ gint stride = self->out_rowstride;
+
+ g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
+
+ /* XXX widths/heights/strides that are not multiple of four??: */
+- stridemove_zip3a (
+- strided,
+- unstrided, /* Y */
+- unstrided + (height*width), /* U */
+- unstrided + (int)(height*width*1.25), /* V */
++ stridemove_zip3a (strided, unstrided, /* Y */
++ unstrided + (height * width), /* U */
++ unstrided + (int) (height * width * 1.25), /* V */
+ stride, width, height);
+
+ return GST_FLOW_OK;
+@@ -330,46 +327,51 @@ stridify_i420_yuy2 (GstStrideTransform *self, guchar *strided, guchar *unstrided
+
+ /** convert RGB565 to RGB565 strided **/
+ static GstFlowReturn
+-stridify_rgb565_rgb565 (GstStrideTransform *self, guchar *strided, guchar *unstrided)
++stridify_rgb565_rgb565 (GstStrideTransform * self, guchar * strided,
++ guchar * unstrided)
+ {
+- gint width = self->width;
+- gint height = self->height;
+- gint stride = self->out_rowstride;
++ gint width = self->width;
++ gint height = self->height;
++ gint stride = self->out_rowstride;
+
+- g_return_val_if_fail (stride >= (width*2), GST_FLOW_ERROR);
++ g_return_val_if_fail (stride >= (width * 2), GST_FLOW_ERROR);
+
+- stridemove (strided, unstrided, stride, width*2, height);
++ stridemove (strided, unstrided, stride, width * 2, height);
+
+- return GST_FLOW_OK;
++ return GST_FLOW_OK;
+ }
+
+ /** convert RGB565 strided to RGB565 **/
+ static GstFlowReturn
+-unstridify_rgb565_rgb565 (GstStrideTransform *self, guchar *strided, guchar *unstrided)
++unstridify_rgb565_rgb565 (GstStrideTransform * self, guchar * strided,
++ guchar * unstrided)
+ {
+- gint width = self->width;
+- gint height = self->height;
+- gint stride = self->in_rowstride;
++ gint width = self->width;
++ gint height = self->height;
++ gint stride = self->in_rowstride;
+
+- g_return_val_if_fail (stride >= (width*2), GST_FLOW_ERROR);
++ g_return_val_if_fail (stride >= (width * 2), GST_FLOW_ERROR);
+
+- stridemove (unstrided, strided, width*2, stride, height);
+- return GST_FLOW_OK;
++ stridemove (unstrided, strided, width * 2, stride, height);
++ return GST_FLOW_OK;
+ }
+
++#define CONVERT(tofmt, fromfmt, stridify, unstridify) \
++ { \
++ { GST_VIDEO_FORMAT_##tofmt, GST_VIDEO_FORMAT_##fromfmt }, \
++ stridify, unstridify \
++ }
+
+ /* last entry has GST_VIDEO_FORMAT_UNKNOWN for in/out formats */
+-Conversion stride_conversions[] = {
+- { { GST_VIDEO_FORMAT_NV12, GST_VIDEO_FORMAT_NV12 }, stridify_420sp_420sp, unstridify_420sp_420sp },
+- { { GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_I420 }, stridify_420p_420p, unstridify_420p_420p },
+- { { GST_VIDEO_FORMAT_YV12, GST_VIDEO_FORMAT_YV12 }, stridify_420p_420p, unstridify_420p_420p },
+- { { GST_VIDEO_FORMAT_YUY2, GST_VIDEO_FORMAT_YUY2 }, stridify_422i_422i, unstridify_422i_422i },
+- { { GST_VIDEO_FORMAT_UYVY, GST_VIDEO_FORMAT_UYVY }, stridify_422i_422i, unstridify_422i_422i },
+- { { GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_NV12 }, stridify_i420_nv12, NULL },
+- { { GST_VIDEO_FORMAT_I420, GST_VIDEO_FORMAT_YUY2 }, stridify_i420_yuy2, NULL },
+- { { GST_VIDEO_FORMAT_RGB16, GST_VIDEO_FORMAT_RGB16 }, stridify_rgb565_rgb565, unstridify_rgb565_rgb565 },
++const Conversion stride_conversions[] = {
++ CONVERT (NV12, NV12, stridify_420sp_420sp, unstridify_420sp_420sp),
++ CONVERT (I420, I420, stridify_420p_420p, unstridify_420p_420p),
++ CONVERT (YV12, YV12, stridify_420p_420p, unstridify_420p_420p),
++ CONVERT (YUY2, YUY2, stridify_422i_422i, unstridify_422i_422i),
++ CONVERT (UYVY, UYVY, stridify_422i_422i, unstridify_422i_422i),
++ CONVERT (I420, NV12, stridify_i420_nv12, NULL),
++ CONVERT (I420, YUY2, stridify_i420_yuy2, NULL),
++ CONVERT (RGB16, RGB16, stridify_rgb565_rgb565, unstridify_rgb565_rgb565),
+ /* add new entries before here */
+- { { GST_VIDEO_FORMAT_UNKNOWN } }
++ {{GST_VIDEO_FORMAT_UNKNOWN}}
+ };
+-
+-
+diff --git a/gst/stride/gststridetransform.c b/gst/stride/gststridetransform.c
+index de07c11..4469e7f 100644
+--- a/gst/stride/gststridetransform.c
++++ b/gst/stride/gststridetransform.c
+@@ -146,7 +146,9 @@ static void
+ gst_stride_transform_init (GstStrideTransform * self,
+ GstStrideTransformClass * klass)
+ {
+- GST_DEBUG_OBJECT (self, "not implemented");
++ GST_DEBUG_OBJECT (self, "ENTER");
++ self->cached_caps[0] = NULL;
++ self->cached_caps[1] = NULL;
+ }
+
+
+@@ -154,7 +156,7 @@ static void
+ gst_stride_transform_dispose (GObject * object)
+ {
+ GstStrideTransform *self = GST_STRIDE_TRANSFORM (object);
+- GST_DEBUG_OBJECT (self, "not implemented");
++ GST_DEBUG_OBJECT (self, "ENTER");
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+ }
+
+@@ -210,7 +212,30 @@ gst_stride_transform_transform_size (GstBaseTransform * base,
+ return TRUE;
+ }
+
++/**
++ * helper to check possible @fourcc conversions to the list @formats
++ */
++static void
++add_all_fourcc_conversions (GValue * formats, guint32 fourcc,
++ GstPadDirection direction)
++{
++ gint to_format = (direction == GST_PAD_SINK) ? 1 : 0;
++ gint from_format = (direction == GST_PAD_SRC) ? 1 : 0;
++ GValue fourccval = { 0 };
++ gint i;
++ GstVideoFormat format = gst_video_format_from_fourcc (fourcc);
+
++ g_value_init (&fourccval, GST_TYPE_FOURCC);
++
++ for (i = 0; stride_conversions[i].format[0] != GST_VIDEO_FORMAT_UNKNOWN; i++) {
++ if (stride_conversions[i].format[from_format] == format) {
++ guint result_fourcc =
++ gst_video_format_to_fourcc (stride_conversions[i].format[to_format]);
++ gst_value_set_fourcc (&fourccval, result_fourcc);
++ gst_value_list_append_value (formats, &fourccval);
++ }
++ }
++}
+
+ /**
+ * helper to add all fields, other than rowstride to @caps, copied from @s.
+@@ -230,43 +255,44 @@ add_all_fields (GstCaps * caps, const gchar * name, GstStructure * s,
+ idx = gst_structure_n_fields (s) - 1;
+ while (idx >= 0) {
+ const gchar *name = gst_structure_nth_field_name (s, idx);
++ const GValue *val = gst_structure_get_value (s, name);
++
+ idx--;
+
+ /* for format field, check the stride_conversions table to see what
+ * we can support:
+ */
+ if (!strcmp ("format", name)) {
+- guint fourcc;
++ GValue formats = { 0 };
+
+- /* XXX double check this: */
+- gint to_format = (direction == GST_PAD_SINK) ? 1 : 0;
+- gint from_format = (direction == GST_PAD_SRC) ? 1 : 0;
++ g_value_init (&formats, GST_TYPE_LIST);
+
+- if (gst_structure_get_fourcc (s, "format", &fourcc)) {
+- GValue formats = { 0 };
+- GValue fourccval = { 0 };
++ if (GST_VALUE_HOLDS_FOURCC (val)) {
++ add_all_fourcc_conversions (&formats,
++ gst_value_get_fourcc (val), direction);
++ } else if (GST_VALUE_HOLDS_LIST (val)) {
+ gint i;
+- GstVideoFormat format = gst_video_format_from_fourcc (fourcc);
+-
+- g_value_init (&formats, GST_TYPE_LIST);
+- g_value_init (&fourccval, GST_TYPE_FOURCC);
+-
+- for (i = 0; stride_conversions[i].format[0] != GST_VIDEO_FORMAT_UNKNOWN;
+- i++) {
+- if (stride_conversions[i].format[from_format] == format) {
+- gst_value_set_fourcc (&fourccval, gst_video_format_to_fourcc
+- (stride_conversions[i].format[to_format]));
+- gst_value_list_append_value (&formats, &fourccval);
++ for (i = 0; i < gst_value_list_get_size (val); i++) {
++ const GValue *list_val = gst_value_list_get_value (val, i);
++ if (GST_VALUE_HOLDS_FOURCC (list_val)) {
++ add_all_fourcc_conversions (&formats,
++ gst_value_get_fourcc (list_val), direction);
++ } else {
++ GST_WARNING ("malformed caps!!");
++ break;
+ }
+ }
+-
+- continue;
++ } else {
++ GST_WARNING ("malformed caps!!");
+ }
++
++ gst_structure_set_value (new_s, "format", &formats);
++
++ continue;
+ }
+
+ /* copy over all other non-rowstride fields: */
+ if (strcmp ("rowstride", name)) {
+- const GValue *val = gst_structure_get_value (s, name);
+ gst_structure_set_value (new_s, name, val);
+ }
+ }
+@@ -347,6 +373,10 @@ gst_stride_transform_set_caps (GstBaseTransform * base,
+ }
+ }
+
++ GST_DEBUG_OBJECT (self,
++ "conversion[%d]=%p, in_rowstride=%d, out_rowstride=%d",
++ i, self->conversion, self->in_rowstride, self->out_rowstride);
++
+ g_return_val_if_fail (self->conversion, FALSE);
+ g_return_val_if_fail (self->conversion->unstridify
+ || !self->in_rowstride, FALSE);
+@@ -355,6 +385,8 @@ gst_stride_transform_set_caps (GstBaseTransform * base,
+ g_return_val_if_fail (self->width == width, FALSE);
+ g_return_val_if_fail (self->height == height, FALSE);
+
++ GST_DEBUG_OBJECT (self, "caps are ok");
++
+ return TRUE;
+ }
+
+--
+1.7.1
+
diff --git a/media-libs/gst-plugins-base/files/gst-0.10.32-0016-modify-playbin-to-use-stridetransform.patch b/media-libs/gst-plugins-base/files/gst-0.10.32-0016-modify-playbin-to-use-stridetransform.patch
new file mode 100644
index 0000000..82c9b25
--- /dev/null
+++ b/media-libs/gst-plugins-base/files/gst-0.10.32-0016-modify-playbin-to-use-stridetransform.patch
@@ -0,0 +1,62 @@
+From eb2753337944d24419dc13968137bf06a5e8f77c Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Sat, 6 Feb 2010 22:10:16 -0600
+Subject: [PATCH 16/24] modify playbin to use stridetransform
+
+---
+ gst/playback/gstplaysink.c | 29 ++++-------------------------
+ 1 files changed, 4 insertions(+), 25 deletions(-)
+
+diff --git a/gst/playback/gstplaysink.c b/gst/playback/gstplaysink.c
+index bb41a03..dedd3be 100644
+--- a/gst/playback/gstplaysink.c
++++ b/gst/playback/gstplaysink.c
+@@ -1267,13 +1267,13 @@ gen_video_chain (GstPlaySink * playsink, gboolean raw, gboolean async)
+ }
+
+ if (raw && !(playsink->flags & GST_PLAY_FLAG_NATIVE_VIDEO)) {
+- GST_DEBUG_OBJECT (playsink, "creating ffmpegcolorspace");
+- chain->conv = gst_element_factory_make ("ffmpegcolorspace", "vconv");
++ GST_DEBUG_OBJECT (playsink, "creating stridetransform");
++ chain->conv = gst_element_factory_make ("stridetransform", "vconv");
+ if (chain->conv == NULL) {
+- post_missing_element_message (playsink, "ffmpegcolorspace");
++ post_missing_element_message (playsink, "stridetransform");
+ GST_ELEMENT_WARNING (playsink, CORE, MISSING_PLUGIN,
+ (_("Missing element '%s' - check your GStreamer installation."),
+- "ffmpegcolorspace"), ("video rendering might fail"));
++ "stridetransform"), ("video rendering might fail"));
+ } else {
+ gst_bin_add (bin, chain->conv);
+ if (prev) {
+@@ -1285,27 +1285,6 @@ gen_video_chain (GstPlaySink * playsink, gboolean raw, gboolean async)
+ }
+ prev = chain->conv;
+ }
+-
+- GST_DEBUG_OBJECT (playsink, "creating videoscale");
+- chain->scale = gst_element_factory_make ("videoscale", "vscale");
+- if (chain->scale == NULL) {
+- post_missing_element_message (playsink, "videoscale");
+- GST_ELEMENT_WARNING (playsink, CORE, MISSING_PLUGIN,
+- (_("Missing element '%s' - check your GStreamer installation."),
+- "videoscale"), ("possibly a liboil version mismatch?"));
+- } else {
+- /* Add black borders if necessary to keep the DAR */
+- g_object_set (chain->scale, "add-borders", TRUE, NULL);
+- gst_bin_add (bin, chain->scale);
+- if (prev) {
+- if (!gst_element_link_pads_full (prev, "src", chain->scale, "sink",
+- GST_PAD_LINK_CHECK_TEMPLATE_CAPS))
+- goto link_failed;
+- } else {
+- head = chain->scale;
+- }
+- prev = chain->scale;
+- }
+ }
+
+ if (prev) {
+--
+1.7.1
+
diff --git a/media-libs/gst-plugins-base/files/gst-0.10.32-0017-playbin-disable-interlaced-support.patch b/media-libs/gst-plugins-base/files/gst-0.10.32-0017-playbin-disable-interlaced-support.patch
new file mode 100644
index 0000000..44bb868
--- /dev/null
+++ b/media-libs/gst-plugins-base/files/gst-0.10.32-0017-playbin-disable-interlaced-support.patch
@@ -0,0 +1,33 @@
+From 82d8f741f626ed449c84e0ae4c8e27219557149e Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Thu, 19 Aug 2010 10:32:52 -0500
+Subject: [PATCH 17/24] playbin: disable interlaced support
+
+Latest totem is enabling interlaced support, which causes similar issues
+to when native-video is not used.. for now, since none of the codecs
+support it, disable interlaced support.
+---
+ gst/playback/gstplaysink.c | 2 ++
+ 1 files changed, 2 insertions(+), 0 deletions(-)
+
+diff --git a/gst/playback/gstplaysink.c b/gst/playback/gstplaysink.c
+index dedd3be..957f288 100644
+--- a/gst/playback/gstplaysink.c
++++ b/gst/playback/gstplaysink.c
+@@ -2118,11 +2118,13 @@ gst_play_sink_reconfigure (GstPlaySink * playsink)
+ /* we have video and we are requested to show it */
+ need_video = TRUE;
+
++#if 0
+ /* we only deinterlace if native video is not requested and
+ * we have raw video */
+ if ((flags & GST_PLAY_FLAG_DEINTERLACE)
+ && !(flags & GST_PLAY_FLAG_NATIVE_VIDEO) && playsink->video_pad_raw)
+ need_deinterlace = TRUE;
++#endif
+ }
+
+ if (playsink->audio_pad) {
+--
+1.7.1
+
diff --git a/media-libs/gst-plugins-base/files/gst-0.10.32-0018-textoverlay-add-stride-support.patch b/media-libs/gst-plugins-base/files/gst-0.10.32-0018-textoverlay-add-stride-support.patch
new file mode 100644
index 0000000..8c0c423
--- /dev/null
+++ b/media-libs/gst-plugins-base/files/gst-0.10.32-0018-textoverlay-add-stride-support.patch
@@ -0,0 +1,132 @@
+From 8cd575c6c2f46464d7704e07102a648bba08a6c6 Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Mon, 23 Aug 2010 14:01:14 -0500
+Subject: [PATCH 18/24] textoverlay: add stride support
+
+---
+ ext/pango/gsttextoverlay.c | 37 +++++++++++++++++++++++++------------
+ ext/pango/gsttextoverlay.h | 1 +
+ 2 files changed, 26 insertions(+), 12 deletions(-)
+
+diff --git a/ext/pango/gsttextoverlay.c b/ext/pango/gsttextoverlay.c
+index 915a59c..1bf3638 100644
+--- a/ext/pango/gsttextoverlay.c
++++ b/ext/pango/gsttextoverlay.c
+@@ -187,7 +187,7 @@ static GstStaticPadTemplate src_template_factory =
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_BGRx ";"
+ GST_VIDEO_CAPS_xRGB ";"
+- GST_VIDEO_CAPS_YUV ("{AYUV, I420, UYVY, NV12, NV21}"))
++ GST_VIDEO_CAPS_YUV_STRIDED ("{AYUV, I420, UYVY, NV12, NV21}", "[0, max]"))
+ );
+
+ static GstStaticPadTemplate video_sink_template_factory =
+@@ -196,7 +196,7 @@ static GstStaticPadTemplate video_sink_template_factory =
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_BGRx ";"
+ GST_VIDEO_CAPS_xRGB ";"
+- GST_VIDEO_CAPS_YUV ("{AYUV, I420, UYVY, NV12, NV21}"))
++ GST_VIDEO_CAPS_YUV_STRIDED ("{AYUV, I420, UYVY, NV12, NV21}", "[0, max]"))
+ );
+
+ static GstStaticPadTemplate text_sink_template_factory =
+@@ -724,12 +724,13 @@ gst_text_overlay_setcaps (GstPad * pad, GstCaps * caps)
+
+ overlay->width = 0;
+ overlay->height = 0;
++ overlay->rowstride = 0;
+ structure = gst_caps_get_structure (caps, 0);
+ fps = gst_structure_get_value (structure, "framerate");
+
+ if (fps
+- && gst_video_format_parse_caps (caps, &overlay->format, &overlay->width,
+- &overlay->height)) {
++ && gst_video_format_parse_caps_strided (caps, &overlay->format, &overlay->width,
++ &overlay->height, &overlay->rowstride)) {
+ ret = gst_pad_set_caps (overlay->srcpad, caps);
+ }
+
+@@ -1364,14 +1365,21 @@ gst_text_overlay_render_pangocairo (GstTextOverlay * overlay,
+ #define BOX_XPAD 6
+ #define BOX_YPAD 6
+
++static gint
++gst_text_overlay_get_stride (GstTextOverlay * overlay, gint component)
++{
++ if (overlay->rowstride)
++ return overlay->rowstride;
++ return gst_video_format_get_row_stride (overlay->format, 0, overlay->width);
++}
++
+ static inline void
+ gst_text_overlay_shade_planar_Y (GstTextOverlay * overlay, guchar * dest,
+ gint x0, gint x1, gint y0, gint y1)
+ {
+ gint i, j, dest_stride;
+
+- dest_stride = gst_video_format_get_row_stride (overlay->format, 0,
+- overlay->width);
++ dest_stride = gst_text_overlay_get_stride (overlay, 0);
+
+ x0 = CLAMP (x0 - BOX_XPAD, 0, overlay->width);
+ x1 = CLAMP (x1 + BOX_XPAD, 0, overlay->width);
+@@ -1436,7 +1444,9 @@ static inline void
+ gst_text_overlay_shade_xRGB (GstTextOverlay * overlay, guchar * dest,
+ gint x0, gint x1, gint y0, gint y1)
+ {
+- gint i, j;
++ gint i, j, dest_stride;
++
++ dest_stride = gst_text_overlay_get_stride (overlay, 0);
+
+ x0 = CLAMP (x0 - BOX_XPAD, 0, overlay->width);
+ x1 = CLAMP (x1 + BOX_XPAD, 0, overlay->width);
+@@ -1448,7 +1458,7 @@ gst_text_overlay_shade_xRGB (GstTextOverlay * overlay, guchar * dest,
+ for (j = x0; j < x1; j++) {
+ gint y, y_pos, k;
+
+- y_pos = (i * 4 * overlay->width) + j * 4;
++ y_pos = (i * dest_stride) + j * 4;
+ for (k = 0; k < 4; k++) {
+ y = dest[y_pos + k] + overlay->shading_value;
+ dest[y_pos + k] = CLAMP (y, 0, 255);
+@@ -1480,10 +1490,10 @@ gst_text_overlay_blit_NV12_NV21 (GstTextOverlay * overlay,
+ w = overlay->width;
+ h = overlay->height;
+
+- y_stride = gst_video_format_get_row_stride (overlay->format, 0, w);
+- uv_stride = gst_video_format_get_row_stride (overlay->format, 1, w);
+- u_offset = gst_video_format_get_component_offset (overlay->format, 1, w, h);
+- v_offset = gst_video_format_get_component_offset (overlay->format, 2, w, h);
++ y_stride = gst_text_overlay_get_stride (overlay, 0);
++ uv_stride = gst_text_overlay_get_stride (overlay, 1);
++ u_offset = gst_video_format_get_component_offset (overlay->format, 1, y_stride, h);
++ v_offset = gst_video_format_get_component_offset (overlay->format, 2, y_stride, h);
+
+ gst_text_overlay_blit_1 (overlay, yuv_pixels, xpos, ypos, overlay->text_image,
+ y_stride);
+@@ -1509,6 +1519,9 @@ gst_text_overlay_blit_I420 (GstTextOverlay * overlay,
+ w = overlay->width;
+ h = overlay->height;
+
++ /* XXX this is not updated for rowstride.. but rowstride could be
++ * ambiguous for I420.. is the U and V plane rowstride or rowstride/2?
++ */
+ y_stride = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, 0, w);
+ u_stride = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, 1, w);
+ v_stride = gst_video_format_get_row_stride (GST_VIDEO_FORMAT_I420, 2, w);
+diff --git a/ext/pango/gsttextoverlay.h b/ext/pango/gsttextoverlay.h
+index 5fddf3a..bc2940b 100644
+--- a/ext/pango/gsttextoverlay.h
++++ b/ext/pango/gsttextoverlay.h
+@@ -112,6 +112,7 @@ struct _GstTextOverlay {
+
+ gint width;
+ gint height;
++ gint rowstride;
+ gint fps_n;
+ gint fps_d;
+ GstVideoFormat format;
+--
+1.7.1
+
diff --git a/media-libs/gst-plugins-base/files/gst-0.10.32-0019-video-more-flexible-video-caps-utility.patch b/media-libs/gst-plugins-base/files/gst-0.10.32-0019-video-more-flexible-video-caps-utility.patch
new file mode 100644
index 0000000..fcf4fd6
--- /dev/null
+++ b/media-libs/gst-plugins-base/files/gst-0.10.32-0019-video-more-flexible-video-caps-utility.patch
@@ -0,0 +1,228 @@
+From ecac5f6e2cab295e742784f6d4d11800b1f37c6d Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Mon, 13 Sep 2010 19:04:47 -0500
+Subject: [PATCH 19/24] video: more flexible video caps utility
+
+Add gst_video_format_new_caps_simple() to allow for more flexible video
+caps builder, which could be used for template caps and non-fixed caps.
+---
+ gst-libs/gst/video/video.c | 129 ++++++++++++++++++++++++++------------------
+ gst-libs/gst/video/video.h | 2 +
+ 2 files changed, 78 insertions(+), 53 deletions(-)
+
+diff --git a/gst-libs/gst/video/video.c b/gst-libs/gst/video/video.c
+index ff9c4fb..ef8edcc 100644
+--- a/gst-libs/gst/video/video.c
++++ b/gst-libs/gst/video/video.c
+@@ -590,15 +590,12 @@ gst_video_format_new_caps_interlaced (GstVideoFormat format,
+ }
+
+ /**
+- * gst_video_format_new_caps_strided:
++ * gst_video_format_new_caps_simple:
+ * @format: the #GstVideoFormat describing the raw video format
+- * @width: width of video
+- * @height: height of video
+- * @rowstride: the rowstride (in bytes), or 0 if no rowstride
+- * @framerate_n: numerator of frame rate
+- * @framerate_d: denominator of frame rate
+- * @par_n: numerator of pixel aspect ratio
+- * @par_d: denominator of pixel aspect ratio
++ * @rowstride: 0 for unstrided, -1 for any stride (unfixed), or other
++ * for fixed stride
++ * @fieldname: first field to set
++ * @...: additional arguments
+ *
+ * Creates a new #GstCaps object based on the parameters provided.
+ *
+@@ -607,25 +604,20 @@ gst_video_format_new_caps_interlaced (GstVideoFormat format,
+ * Returns: a new #GstCaps object, or NULL if there was an error
+ */
+ GstCaps *
+-gst_video_format_new_caps_strided (GstVideoFormat format,
+- int width, int height, int rowstride,
+- int framerate_n, int framerate_d, int par_n, int par_d)
++gst_video_format_new_caps_simple (GstVideoFormat format, int rowstride,
++ const char *fieldname, ...)
+ {
+- GstCaps *caps = NULL;
++ va_list varargs;
++ GstStructure *s;
+
+ g_return_val_if_fail (format != GST_VIDEO_FORMAT_UNKNOWN, NULL);
+- g_return_val_if_fail (width > 0 && height > 0, NULL);
+
+ if (gst_video_format_is_yuv (format)) {
+- caps = gst_caps_new_simple (
+- rowstride ? "video/x-raw-yuv-strided" : "video/x-raw-yuv",
++ s = gst_structure_new (rowstride ?
++ "video/x-raw-yuv-strided" : "video/x-raw-yuv",
+ "format", GST_TYPE_FOURCC, gst_video_format_to_fourcc (format),
+- "width", G_TYPE_INT, width,
+- "height", G_TYPE_INT, height,
+- "framerate", GST_TYPE_FRACTION, framerate_n, framerate_d,
+- "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d, NULL);
++ NULL);
+ } else if (gst_video_format_is_rgb (format)) {
+- GstCaps *caps;
+ int red_mask = 0;
+ int blue_mask = 0;
+ int green_mask = 0;
+@@ -684,15 +676,12 @@ gst_video_format_new_caps_strided (GstVideoFormat format,
+ } else {
+ mask = 0xff0000;
+ }
+- red_mask =
+- mask >> (8 * gst_video_format_get_component_offset (format, 0,
+- width, height));
+- green_mask =
+- mask >> (8 * gst_video_format_get_component_offset (format, 1,
+- width, height));
+- blue_mask =
+- mask >> (8 * gst_video_format_get_component_offset (format, 2,
+- width, height));
++ red_mask = mask >>
++ (8 * gst_video_format_get_component_offset (format, 0, 1, 1));
++ green_mask = mask >>
++ (8 * gst_video_format_get_component_offset (format, 1, 1, 1));
++ blue_mask = mask >>
++ (8 * gst_video_format_get_component_offset (format, 2, 1, 1));
+ } else if (bpp == 16) {
+ switch (format) {
+ case GST_VIDEO_FORMAT_RGB16:
+@@ -723,17 +712,13 @@ gst_video_format_new_caps_strided (GstVideoFormat format,
+ return NULL;
+ }
+
+- caps = gst_caps_new_simple (
++ s = gst_structure_new (
+ rowstride ? "video/x-raw-rgb-strided" : "video/x-raw-rgb",
+ "bpp", G_TYPE_INT, bpp,
+- "depth", G_TYPE_INT, depth,
+- "width", G_TYPE_INT, width,
+- "height", G_TYPE_INT, height,
+- "framerate", GST_TYPE_FRACTION, framerate_n, framerate_d,
+- "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d, NULL);
++ "depth", G_TYPE_INT, depth, NULL);
+
+ if (bpp != 8) {
+- gst_caps_set_simple (caps,
++ gst_structure_set (s,
+ "endianness", G_TYPE_INT, G_BIG_ENDIAN,
+ "red_mask", G_TYPE_INT, red_mask,
+ "green_mask", G_TYPE_INT, green_mask,
+@@ -741,10 +726,12 @@ gst_video_format_new_caps_strided (GstVideoFormat format,
+ }
+
+ if (have_alpha) {
+- alpha_mask =
+- mask >> (8 * gst_video_format_get_component_offset (format, 3,
+- width, height));
+- gst_caps_set_simple (caps, "alpha_mask", G_TYPE_INT, alpha_mask, NULL);
++ /* note: we are passing a bogus width/height to get_component_offset(),
++ * but those parameters are ignored for the packed formats so it is ok
++ */
++ alpha_mask = mask >>
++ (8 * gst_video_format_get_component_offset (format, 3, 1, 1));
++ gst_structure_set (s, "alpha_mask", G_TYPE_INT, alpha_mask, NULL);
+ }
+ } else if (gst_video_format_is_gray (format)) {
+ int bpp;
+@@ -770,32 +757,68 @@ gst_video_format_new_caps_strided (GstVideoFormat format,
+ }
+
+ if (bpp > 8) {
+- caps = gst_caps_new_simple ("video/x-raw-gray",
++ s = gst_structure_new (rowstride ?
++ "video/x-raw-gray-strided" : "video/x-raw-gray",
+ "bpp", G_TYPE_INT, bpp,
+ "depth", G_TYPE_INT, depth,
+- "width", G_TYPE_INT, width,
+- "height", G_TYPE_INT, height,
+- "framerate", GST_TYPE_FRACTION, framerate_n, framerate_d,
+- "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d, NULL);
++ NULL);
+ } else {
+- caps = gst_caps_new_simple ("video/x-raw-gray",
++ s = gst_structure_new (rowstride ?
++ "video/x-raw-gray-strided" : "video/x-raw-gray",
+ "bpp", G_TYPE_INT, bpp,
+ "depth", G_TYPE_INT, depth,
+ "endianness", G_TYPE_INT, G_BIG_ENDIAN,
+- "width", G_TYPE_INT, width,
+- "height", G_TYPE_INT, height,
+- "framerate", GST_TYPE_FRACTION, framerate_n, framerate_d,
+- "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d, NULL);
++ NULL);
+ }
+ } else {
+ return NULL;
+ }
+
+- if (rowstride) {
+- gst_caps_set_simple (caps, "rowstride", G_TYPE_INT, rowstride, NULL);
++ if (rowstride > 0) {
++ gst_structure_set (s, "rowstride",
++ G_TYPE_INT, rowstride, NULL);
++ } else if (rowstride < 0) {
++ gst_structure_set (s, "rowstride",
++ GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
+ }
+
+- return caps;
++ va_start (varargs, fieldname);
++ gst_structure_set_valist (s, fieldname, varargs);
++ va_end (varargs);
++
++ return gst_caps_new_full (s, NULL);
++}
++
++/**
++ * gst_video_format_new_caps_strided:
++ * @format: the #GstVideoFormat describing the raw video format
++ * @width: width of video
++ * @height: height of video
++ * @rowstride: the rowstride (in bytes), or 0 if no rowstride
++ * @framerate_n: numerator of frame rate
++ * @framerate_d: denominator of frame rate
++ * @par_n: numerator of pixel aspect ratio
++ * @par_d: denominator of pixel aspect ratio
++ *
++ * Creates a new #GstCaps object based on the parameters provided.
++ *
++ * Since: ???
++ *
++ * Returns: a new #GstCaps object, or NULL if there was an error
++ */
++GstCaps *
++gst_video_format_new_caps_strided (GstVideoFormat format,
++ int width, int height, int rowstride,
++ int framerate_n, int framerate_d, int par_n, int par_d)
++{
++ g_return_val_if_fail (width > 0 && height > 0, NULL);
++
++ return gst_video_format_new_caps_simple (format, rowstride,
++ "width", G_TYPE_INT, width,
++ "height", G_TYPE_INT, height,
++ "framerate", GST_TYPE_FRACTION, framerate_n, framerate_d,
++ "pixel-aspect-ratio", GST_TYPE_FRACTION, par_n, par_d,
++ NULL);
+ }
+
+ /**
+diff --git a/gst-libs/gst/video/video.h b/gst-libs/gst/video/video.h
+index 5bac21f..bbd33f7 100644
+--- a/gst-libs/gst/video/video.h
++++ b/gst-libs/gst/video/video.h
+@@ -430,6 +430,8 @@ GstCaps * gst_video_format_new_caps_interlaced (GstVideoFormat format,
+ GstCaps * gst_video_format_new_caps_strided (GstVideoFormat format,
+ int width, int height, int rowstride,
+ int framerate_n, int framerate_d, int par_n, int par_d);
++GstCaps * gst_video_format_new_caps_simple (GstVideoFormat format,
++ int rowstride, const char *fieldname, ...);
+ GstVideoFormat gst_video_format_from_fourcc (guint32 fourcc);
+ guint32 gst_video_format_to_fourcc (GstVideoFormat format);
+ gboolean gst_video_format_is_rgb (GstVideoFormat format);
+--
+1.7.1
+
diff --git a/media-libs/gst-plugins-base/files/gst-0.10.32-0020-video-fix-endianess-issue-for-16bit-RGB-formats.patch b/media-libs/gst-plugins-base/files/gst-0.10.32-0020-video-fix-endianess-issue-for-16bit-RGB-formats.patch
new file mode 100644
index 0000000..bf07cea
--- /dev/null
+++ b/media-libs/gst-plugins-base/files/gst-0.10.32-0020-video-fix-endianess-issue-for-16bit-RGB-formats.patch
@@ -0,0 +1,41 @@
+From 569f9ca7a8ce923d43956771e8a142a9b31114f1 Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Mon, 13 Sep 2010 19:05:56 -0500
+Subject: [PATCH 20/24] video: fix endianess issue for 16bit RGB formats
+
+---
+ gst-libs/gst/video/video.c | 4 +++-
+ 1 files changed, 3 insertions(+), 1 deletions(-)
+
+diff --git a/gst-libs/gst/video/video.c b/gst-libs/gst/video/video.c
+index ef8edcc..a5ec6b7 100644
+--- a/gst-libs/gst/video/video.c
++++ b/gst-libs/gst/video/video.c
+@@ -625,6 +625,7 @@ gst_video_format_new_caps_simple (GstVideoFormat format, int rowstride,
+ int depth;
+ int bpp;
+ gboolean have_alpha;
++ int endianness = G_BIG_ENDIAN;
+ unsigned int mask = 0;
+
+ switch (format) {
+@@ -708,6 +709,7 @@ gst_video_format_new_caps_simple (GstVideoFormat format, int rowstride,
+ default:
+ return NULL;
+ }
++ endianness = G_BYTE_ORDER;
+ } else if (bpp != 8) {
+ return NULL;
+ }
+@@ -719,7 +721,7 @@ gst_video_format_new_caps_simple (GstVideoFormat format, int rowstride,
+
+ if (bpp != 8) {
+ gst_structure_set (s,
+- "endianness", G_TYPE_INT, G_BIG_ENDIAN,
++ "endianness", G_TYPE_INT, endianness,
+ "red_mask", G_TYPE_INT, red_mask,
+ "green_mask", G_TYPE_INT, green_mask,
+ "blue_mask", G_TYPE_INT, blue_mask, NULL);
+--
+1.7.1
+
diff --git a/media-libs/gst-plugins-base/files/gst-0.10.32-0021-stride-more-flexible-stride-color-conversion.patch b/media-libs/gst-plugins-base/files/gst-0.10.32-0021-stride-more-flexible-stride-color-conversion.patch
new file mode 100644
index 0000000..b897c5e
--- /dev/null
+++ b/media-libs/gst-plugins-base/files/gst-0.10.32-0021-stride-more-flexible-stride-color-conversion.patch
@@ -0,0 +1,1131 @@
+From e8e3c9ae037daa4abd60f08bc49f370dd5f7b3c6 Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Mon, 13 Sep 2010 19:10:36 -0500
+Subject: [PATCH 21/24] stride: more flexible stride/color conversion
+
+Refactor stride transform element to address a number of limitations:
+1) support converting buffers from one rowstride to another, in addition to
+just handling conversion from strided <-> unstrided.
+2) refactor convert code to make it easier to add new formats
+3) refactor caps handling code to build template caps based upon color
+formats listed in convert (stride_conversions table).
+4) refactor caps parsing/building to correctly handle RGB formats
+5) add support for crop.. currently we optimize by just only copying the
+uncropped part of the frame, but this is the first step to true handling of
+cropping, so that we can crop out padding for the benefit of sink elements
+that don't understand crop or stride. (The convert code handles it fine..
+the caps parsing/building in gststridetransform.c would need to handle caps
+re-negotiation when the crop changes for this to be complete.)
+---
+ gst/stride/armv7.s | 8 +-
+ gst/stride/convert.c | 400 ++++++++++++++++++++-------------------
+ gst/stride/gststridetransform.c | 375 +++++++++++++++++++++++++------------
+ gst/stride/gststridetransform.h | 25 +++-
+ 4 files changed, 490 insertions(+), 318 deletions(-)
+
+diff --git a/gst/stride/armv7.s b/gst/stride/armv7.s
+index 2697a14..5f4200d 100644
+--- a/gst/stride/armv7.s
++++ b/gst/stride/armv7.s
+@@ -28,7 +28,7 @@
+ .global stride_copy_zip2
+ .type stride_copy_zip2, %function
+ @void
+-@stride_copy_zip2 (guchar *new_buf, guchar *orig_buf1, guchar *orig_buf2, gint sz)
++@stride_copy_zip2 (guchar * out, guchar * in1, guchar * in2, gint sz)
+ @{
+ @@@@ note: r0-r3, q0-3, and q8-q15 do not need to be preserved
+ stride_copy_zip2:
+@@ -74,8 +74,8 @@ stride_copy_zip2_3:
+ .global stride_copy_zip3a
+ .type stride_copy_zip3a, %function
+ @void
+-@stride_copy_zip3a (guchar *new_buf,
+-@ guchar *orig_buf1, guchar *orig_buf2, guchar *orig_buf3, gint sz)
++@stride_copy_zip3a (guchar * out,
++@ guchar * in1, guchar * in2, guchar * in3, gint sz)
+ @{
+ @@@@ note: r0-r3, q0-3, and q8-q15 do not need to be preserved
+ stride_copy_zip3a:
+@@ -136,7 +136,7 @@ stride_copy_zip3a_3:
+ .global stride_copy
+ .type stride_copy, %function
+ @void
+-@stride_copy (guchar *new_buf, guchar *orig_buf, gint sz)
++@stride_copy (guchar *out, guchar *in, gint sz)
+ @{
+ @@@@ note: r0-r3, q0-3, and q8-q15 do not need to be preserved
+ stride_copy:
+diff --git a/gst/stride/convert.c b/gst/stride/convert.c
+index 17f9e2a..5d392ac 100644
+--- a/gst/stride/convert.c
++++ b/gst/stride/convert.c
+@@ -55,32 +55,31 @@ void stride_copy_zip3a (guchar * new_buf, guchar * orig_buf1,
+ void stride_copy (guchar * new_buf, guchar * orig_buf, gint sz);
+
+ WEAK void
+-stride_copy_zip2 (guchar * new_buf, guchar * orig_buf1, guchar * orig_buf2,
+- gint sz)
++stride_copy_zip2 (guchar * out, guchar * in1, guchar * in2, gint sz)
+ {
+ while (sz--) {
+- *new_buf++ = *orig_buf1++;
+- *new_buf++ = *orig_buf2++;
++ *out++ = *in1++;
++ *out++ = *in2++;
+ }
+ }
+
+ WEAK void
+-stride_copy_zip3a (guchar * new_buf,
+- guchar * orig_buf1, guchar * orig_buf2, guchar * orig_buf3, gint sz)
++stride_copy_zip3a (guchar * out,
++ guchar * in1, guchar * in2, guchar * in3, gint sz)
+ {
+ while (sz > 1) {
+- *new_buf++ = *orig_buf1++;
+- *new_buf++ = *orig_buf2++;
+- *new_buf++ = *orig_buf1++;
+- *new_buf++ = *orig_buf3++;
++ *out++ = *in1++;
++ *out++ = *in2++;
++ *out++ = *in1++;
++ *out++ = *in3++;
+ sz -= 2;
+ }
+ }
+
+ WEAK void
+-stride_copy (guchar * new_buf, guchar * orig_buf, gint sz)
++stride_copy (guchar * out, guchar * in, gint sz)
+ {
+- memcpy (new_buf, orig_buf, sz);
++ memcpy (out, in, sz);
+ }
+
+
+@@ -88,31 +87,19 @@ stride_copy (guchar * new_buf, guchar * orig_buf, gint sz)
+ * move to strided buffer, interleaving two planes of identical dimensions
+ */
+ static void
+-stridemove_zip2 (guchar * new_buf, guchar * orig_buf1, guchar * orig_buf2,
+- gint new_width, gint orig_width, gint height)
++stridemove_zip2 (guchar * out, guchar * in1, guchar * in2,
++ gint out_bpl, gint in_bpl, gint width, gint height)
+ {
+ int row;
+
+ GST_DEBUG
+- ("new_buf=%p, orig_buf1=%p, orig_buf2=%p, new_width=%d, orig_width=%d, height=%d",
+- new_buf, orig_buf1, orig_buf2, new_width, orig_width, height);
+-
+- /* if increasing the stride, work from bottom-up to avoid overwriting data
+- * that has not been moved yet.. otherwise, work in the opposite order,
+- * for the same reason.
+- */
+- if (new_width > orig_width) {
+- for (row = height - 1; row >= 0; row--) {
+- stride_copy_zip2 (new_buf + (new_width * row),
+- orig_buf1 + (orig_width * row),
+- orig_buf2 + (orig_width * row), orig_width);
+- }
+- } else {
+- for (row = 0; row < height; row++) {
+- stride_copy_zip2 (new_buf + (new_width * row),
+- orig_buf1 + (orig_width * row),
+- orig_buf2 + (orig_width * row), new_width);
+- }
++ ("out=%p, in1=%p, in2=%p, out_bpl=%d, in_bpl=%d, width=%d, height=%d",
++ out, in1, in2, out_bpl, in_bpl, width, height);
++
++ for (row = 0; row < height; row++) {
++ stride_copy_zip2 (out + (out_bpl * row),
++ in1 + (in_bpl * row),
++ in2 + (in_bpl * row), width);
+ }
+ }
+
+@@ -121,26 +108,28 @@ stridemove_zip2 (guchar * new_buf, guchar * orig_buf1, guchar * orig_buf2,
+ * (orig_buf1) has 2x as many samples.. Ie. ABACABAC..
+ */
+ static void
+-stridemove_zip3a (guchar * new_buf,
+- guchar * orig_buf1, guchar * orig_buf2, guchar * orig_buf3,
+- guint new_width, gint orig_width, gint height)
++stridemove_zip3a (guchar * out,
++ guchar * in1, guchar * in2, guchar * in3,
++ guint out_bpl, gint in_bpl, gint width, gint height)
+ {
+- gint copy_width = (new_width < orig_width) ? new_width : orig_width;
++ GST_DEBUG
++ ("out=%p, in1=%p, in2=%p, in3=%p, out_bpl=%d, in_bpl=%d, width=%d, height=%d",
++ out, in1, in2, in3, out_bpl, in_bpl, width, height);
+
+ while (height > 0) {
+
+ /* even row */
+- stride_copy_zip3a (new_buf, orig_buf1, orig_buf2, orig_buf3, copy_width);
+- new_buf += new_width;
+- orig_buf1 += orig_width;
++ stride_copy_zip3a (out, in1, in2, in3, width);
++ out += out_bpl;
++ in1 += in_bpl;
+
+ /* odd row, recycles same U & V */
+- stride_copy_zip3a (new_buf, orig_buf1, orig_buf2, orig_buf3, copy_width);
+- new_buf += new_width;
+- orig_buf1 += orig_width;
++ stride_copy_zip3a (out, in1, in2, in3, width);
++ out += out_bpl;
++ in1 += in_bpl;
+
+- orig_buf2 += orig_width / 2;
+- orig_buf3 += orig_width / 2;
++ in2 += in_bpl / 2;
++ in3 += in_bpl / 2;
+
+ height -= 2;
+ }
+@@ -154,28 +143,18 @@ stridemove_zip3a (guchar * new_buf,
+ * enough.
+ */
+ static void
+-stridemove (guchar * new_buf, guchar * orig_buf, gint new_width,
+- gint orig_width, gint height)
++stridemove (guchar * out, guchar * in, gint out_bpl, gint in_bpl,
++ gint width, gint height)
+ {
+ int row;
+
+- GST_DEBUG ("new_buf=%p, orig_buf=%p, new_width=%d, orig_width=%d, height=%d",
+- new_buf, orig_buf, new_width, orig_width, height);
+-
+- /* if increasing the stride, work from bottom-up to avoid overwriting data
+- * that has not been moved yet.. otherwise, work in the opposite order,
+- * for the same reason.
+- */
+- if (new_width > orig_width) {
+- for (row = height - 1; row >= 0; row--) {
+- stride_copy (new_buf + (new_width * row), orig_buf + (orig_width * row),
+- orig_width);
+- }
+- } else {
+- for (row = 0; row < height; row++) {
+- stride_copy (new_buf + (new_width * row), orig_buf + (orig_width * row),
+- new_width);
+- }
++ GST_DEBUG ("out=%p, in=%p, out_bpl=%d, in_bpl=%d, width=%d, height=%d",
++ out, in, out_bpl, in_bpl, width, height);
++
++ for (row = 0; row < height; row++) {
++ stride_copy (out, in, width);
++ out += out_bpl;
++ in += in_bpl;
+ }
+ }
+
+@@ -183,195 +162,232 @@ stridemove (guchar * new_buf, guchar * orig_buf, gint new_width,
+ * Conversion Functions:
+ */
+
+-/** convert 4:2:0 semiplanar to same 4:2:0 semiplanar */
+-static GstFlowReturn
+-unstridify_420sp_420sp (GstStrideTransform * self, guchar * unstrided,
+- guchar * strided)
++/**
++ * helper to calculate offsets/sizes that are re-used for each frame (until
++ * caps or crop changes)
++ * @isx: input sub-sampling in x direction
++ * @osx: output sub-sampling in x direction
++ * @isy: input sub-sampling in y direction
++ * @isx: input sub-sampling in y direction
++ */
++static inline gboolean refresh_cache(GstStrideTransform * self,
++ gint nplanes, gint bpp, gint * isx, gint * osx, gint * isy, gint * osy)
+ {
+- gint width = self->width;
+- gint height = self->height;
+- gint stride = self->in_rowstride;
++ gint in_off, out_off;
++ int i;
+
+- g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
++ if (((self->crop_top + self->crop_height) > self->height) ||
++ ((self->crop_left + self->crop_width) > self->width)) {
++ GST_ERROR_OBJECT (self, "invalid crop parameter");
++ return GST_FLOW_ERROR;
++ }
+
+- stridemove (unstrided, strided, width, stride,
+- (GST_ROUND_UP_2 (height) * 3) / 2);
++ in_off = out_off = 0;
+
+- return GST_FLOW_OK;
+-}
++ for (i = 0; i < nplanes; i++) {
++ Cache * cache = &self->cache[i];
+
+-static GstFlowReturn
+-stridify_420sp_420sp (GstStrideTransform * self, guchar * strided,
+- guchar * unstrided)
+-{
+- gint width = self->width;
+- gint height = self->height;
+- gint stride = self->out_rowstride;
++ cache->in_bpl = self->in_rowstride ?
++ self->in_rowstride : bpp * self->width;
+
+- g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
++ cache->out_bpl = self->out_rowstride ?
++ self->out_rowstride : bpp * self->width;
+
+- g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
+- stridemove (strided, unstrided, stride, width,
+- (GST_ROUND_UP_2 (height) * 3) / 2);
++ if ((cache->in_bpl < (self->width * bpp)) ||
++ (cache->out_bpl < (self->width * bpp))) {
++ GST_ERROR_OBJECT (self, "invalid stride parameter");
++ return GST_FLOW_ERROR;
++ }
+
+- return GST_FLOW_OK;
+-}
++ cache->width = self->crop_width ?
++ self->crop_width : self->width;
+
+-/** convert 4:2:0 planar to same 4:2:0 planar */
+-static GstFlowReturn
+-unstridify_420p_420p (GstStrideTransform * self, guchar * unstrided,
+- guchar * strided)
+-{
+- gint width = self->width;
+- gint height = self->height;
+- gint stride = self->in_rowstride;
++ cache->height = self->crop_height ?
++ self->crop_height : self->height;
+
+- g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
++ if ((cache->width > self->width) ||
++ (cache->height > self->height)) {
++ GST_ERROR_OBJECT (self, "invalid crop width/height parameter");
++ return GST_FLOW_ERROR;
++ }
+
+- stridemove (unstrided, strided, width, stride, height); /* move Y */
+- stridemove (unstrided + (height * width), strided + (height * stride), width / 2, stride, height); /* move V/U */
+- /* XXX odd widths/heights/strides: */
+- stridemove (unstrided + (int) (height * width * 1.5), strided + (int) (height * stride * 1.5), width / 2, stride, height); /* move U/V */
++ /* note: everything above here is same for each plane, so in theory we
++ * could only calculate on first plane, and copy on subsequent planes
++ */
++
++ /* adjust for sub-sampling and bytes per pixel (bpp): */
++ cache->in_bpl /= *isx;
++ cache->out_bpl /= *osx;
++ cache->width *= bpp;
++ cache->width /= *isx;
++ cache->height /= *isy;
++
++ /* calculate offset to beginning of data to copy/transform: */
++ cache->in_off = in_off;
++ cache->in_off += (bpp * self->crop_left / *isx) +
++ (cache->in_bpl * self->crop_top / *isy);
++
++ cache->out_off = out_off;
++ cache->out_off += (bpp * self->crop_left / *osx) +
++ (cache->out_bpl * self->crop_top / *osy);
++
++ in_off += (self->height / *isy) * cache->in_bpl;
++ out_off += (self->height / *osy) * cache->out_bpl;
++
++ osx++;
++ isx++;
++ osy++;
++ isy++;
++ }
+
+ return GST_FLOW_OK;
+ }
+
+-static GstFlowReturn
+-stridify_420p_420p (GstStrideTransform * self, guchar * strided,
+- guchar * unstrided)
++/** perform simple convert between buffers of same format */
++static inline GstFlowReturn convert_n_n (GstStrideTransform *self,
++ guchar * out, guchar * in, gint nplanes)
+ {
+- gint width = self->width;
+- gint height = self->height;
+- gint stride = self->out_rowstride;
+-
+- g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
++ int i;
+
+- /* XXX odd widths/heights/strides: */
+- stridemove (strided + (int) (height * stride * 1.5), unstrided + (int) (height * width * 1.5), stride, width / 2, height); /* move U/V */
+- stridemove (strided + (height * stride), unstrided + (height * width), stride, width / 2, height); /* move V/U */
+- stridemove (strided, unstrided, stride, width, height); /* move Y */
++ for (i = 0; i < nplanes; i++) {
++ stridemove (out + self->cache[i].out_off, in + self->cache[i].in_off,
++ self->cache[i].out_bpl, self->cache[i].in_bpl,
++ self->cache[i].width, self->cache[i].height);
++ }
+
+ return GST_FLOW_OK;
+ }
+
+-/** convert 4:2:2 packed to same 4:2:2 packed */
++/** convert 4:2:0 semiplanar to same 4:2:0 semiplanar */
+ static GstFlowReturn
+-unstridify_422i_422i (GstStrideTransform * self, guchar * unstrided,
+- guchar * strided)
++convert_420sp_420sp (GstStrideTransform * self,
++ guchar * out, guchar * in)
+ {
+- gint width = self->width;
+- gint height = self->height;
+- gint stride = self->in_rowstride;
+-
+- g_return_val_if_fail (stride >= (width * 2), GST_FLOW_ERROR);
+-
+- stridemove (unstrided, strided, width * 2, stride, height);
++ if (G_UNLIKELY (self->needs_refresh)) {
++ gint sx[] = {1, 1};
++ gint sy[] = {1, 2};
++ if (refresh_cache (self, 2, 1, sx, sx, sy, sy))
++ return GST_FLOW_ERROR;
++ self->needs_refresh = FALSE;
++ }
+
+- return GST_FLOW_OK;
++ return convert_n_n (self, out, in, 2);
+ }
+
++/** convert 4:2:0 planar to same 4:2:0 planar */
+ static GstFlowReturn
+-stridify_422i_422i (GstStrideTransform * self, guchar * strided,
+- guchar * unstrided)
++convert_420p_420p (GstStrideTransform * self,
++ guchar * out, guchar * in)
+ {
+- gint width = self->width;
+- gint height = self->height;
+- gint stride = self->out_rowstride;
+-
+- g_return_val_if_fail (stride >= (width * 2), GST_FLOW_ERROR);
+-
+- stridemove (strided, unstrided, stride, width * 2, height);
++ if (G_UNLIKELY (self->needs_refresh)) {
++ gint sx[] = {1, 2, 2};
++ gint sy[] = {1, 2, 2};
++ if (refresh_cache (self, 3, 1, sx, sx, sy, sy))
++ return GST_FLOW_ERROR;
++ self->needs_refresh = FALSE;
++ }
+
+- return GST_FLOW_OK;
++ return convert_n_n (self, out, in, 3);
+ }
+
+-/** convert I420 unstrided to NV12 strided */
++/** convert 4:2:2 packed to same 4:2:2 packed */
++
+ static GstFlowReturn
+-stridify_i420_nv12 (GstStrideTransform * self, guchar * strided,
+- guchar * unstrided)
++convert_422i_422i (GstStrideTransform * self,
++ guchar * out, guchar * in)
+ {
+- gint width = self->width;
+- gint height = self->height;
+- gint stride = self->out_rowstride;
+-
+- g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
+-
+- /* XXX widths/heights/strides that are not multiple of four??: */
+- stridemove_zip2 (strided + (height * stride), unstrided + (height * width), /* U */
+- unstrided + (int) (height * width * 1.25), /* V */
+- stride, width / 2, height / 2);
+- stridemove (strided, unstrided, stride, width, height); /* Y */
++ if (G_UNLIKELY (self->needs_refresh)) {
++ gint sx[] = {1};
++ gint sy[] = {1};
++ if (refresh_cache (self, 1, 2, sx, sx, sy, sy))
++ return GST_FLOW_ERROR;
++ self->needs_refresh = FALSE;
++ }
+
+- return GST_FLOW_OK;
++ return convert_n_n (self, out, in, 1);
+ }
+
+-/** convert I420 unstrided to YUY2 strided */
++/** convert I420 unstrided to NV12 strided */
+ static GstFlowReturn
+-stridify_i420_yuy2 (GstStrideTransform * self, guchar * strided,
+- guchar * unstrided)
++convert_i420_nv12 (GstStrideTransform * self,
++ guchar * out, guchar * in)
+ {
+- gint width = self->width;
+- gint height = self->height;
+- gint stride = self->out_rowstride;
++ GstFlowReturn ret;
++
++ if (G_UNLIKELY (self->needs_refresh)) {
++ gint isx[] = {1, 2, 2};
++ gint osx[] = {1, 1, 1};
++ gint sy[] = {1, 2, 2};
++ if (refresh_cache (self, 3, 1, isx, osx, sy, sy))
++ return GST_FLOW_ERROR;
++ self->needs_refresh = FALSE;
++ }
+
+- g_return_val_if_fail (stride >= width, GST_FLOW_ERROR);
++ ret = convert_n_n (self, out, in, 1);
++ if (ret != GST_FLOW_OK)
++ return ret;
+
+- /* XXX widths/heights/strides that are not multiple of four??: */
+- stridemove_zip3a (strided, unstrided, /* Y */
+- unstrided + (height * width), /* U */
+- unstrided + (int) (height * width * 1.25), /* V */
+- stride, width, height);
++ stridemove_zip2 (out + self->cache[1].out_off,
++ in + self->cache[1].in_off, /* U */
++ in + self->cache[2].in_off, /* V */
++ self->cache[2].out_bpl,
++ self->cache[1].in_bpl,
++ self->cache[1].width,
++ self->cache[1].height);
+
+ return GST_FLOW_OK;
+ }
+
+-/** convert RGB565 to RGB565 strided **/
++/** convert I420 unstrided to YUY2 strided */
+ static GstFlowReturn
+-stridify_rgb565_rgb565 (GstStrideTransform * self, guchar * strided,
+- guchar * unstrided)
++convert_i420_yuy2 (GstStrideTransform * self,
++ guchar * out, guchar * in)
+ {
+- gint width = self->width;
+- gint height = self->height;
+- gint stride = self->out_rowstride;
+-
+- g_return_val_if_fail (stride >= (width * 2), GST_FLOW_ERROR);
++ if (G_UNLIKELY (self->needs_refresh)) {
++ gint sx[] = {1, 2, 2};
++ gint sy[] = {1, 2, 2};
++ if (refresh_cache (self, 3, 1, sx, sx, sy, sy))
++ return GST_FLOW_ERROR;
++ self->needs_refresh = FALSE;
++ }
+
+- stridemove (strided, unstrided, stride, width * 2, height);
++ stridemove_zip3a (out,
++ in + self->cache[0].in_off, /* Y */
++ in + self->cache[1].in_off, /* U */
++ in + self->cache[2].in_off, /* V */
++ self->cache[0].out_bpl,
++ self->cache[0].in_bpl,
++ self->cache[0].width,
++ self->cache[0].height);
+
+ return GST_FLOW_OK;
+ }
+
+-/** convert RGB565 strided to RGB565 **/
++/** convert 16bpp rgb formats */
+ static GstFlowReturn
+-unstridify_rgb565_rgb565 (GstStrideTransform * self, guchar * strided,
+- guchar * unstrided)
++convert_rgb16_rgb16 (GstStrideTransform * self,
++ guchar * out, guchar * in)
+ {
+- gint width = self->width;
+- gint height = self->height;
+- gint stride = self->in_rowstride;
+-
+- g_return_val_if_fail (stride >= (width * 2), GST_FLOW_ERROR);
+-
+- stridemove (unstrided, strided, width * 2, stride, height);
+- return GST_FLOW_OK;
++ /* format is same 2-bytes per pixel */
++ return convert_422i_422i (self, out, in);
+ }
+
+-#define CONVERT(tofmt, fromfmt, stridify, unstridify) \
++#define CONVERT(tofmt, fromfmt, convert) \
+ { \
+ { GST_VIDEO_FORMAT_##tofmt, GST_VIDEO_FORMAT_##fromfmt }, \
+- stridify, unstridify \
++ convert \
+ }
+
+ /* last entry has GST_VIDEO_FORMAT_UNKNOWN for in/out formats */
+ const Conversion stride_conversions[] = {
+- CONVERT (NV12, NV12, stridify_420sp_420sp, unstridify_420sp_420sp),
+- CONVERT (I420, I420, stridify_420p_420p, unstridify_420p_420p),
+- CONVERT (YV12, YV12, stridify_420p_420p, unstridify_420p_420p),
+- CONVERT (YUY2, YUY2, stridify_422i_422i, unstridify_422i_422i),
+- CONVERT (UYVY, UYVY, stridify_422i_422i, unstridify_422i_422i),
+- CONVERT (I420, NV12, stridify_i420_nv12, NULL),
+- CONVERT (I420, YUY2, stridify_i420_yuy2, NULL),
+- CONVERT (RGB16, RGB16, stridify_rgb565_rgb565, unstridify_rgb565_rgb565),
++ CONVERT (NV12, NV12, convert_420sp_420sp),
++ CONVERT (I420, I420, convert_420p_420p),
++ CONVERT (YV12, YV12, convert_420p_420p),
++ CONVERT (YUY2, YUY2, convert_422i_422i),
++ CONVERT (UYVY, UYVY, convert_422i_422i),
++ CONVERT (I420, NV12, convert_i420_nv12),
++ CONVERT (I420, YUY2, convert_i420_yuy2),
++ CONVERT (RGB16, RGB16, convert_rgb16_rgb16),
+ /* add new entries before here */
+ {{GST_VIDEO_FORMAT_UNKNOWN}}
+ };
+diff --git a/gst/stride/gststridetransform.c b/gst/stride/gststridetransform.c
+index 4469e7f..7874ed4 100644
+--- a/gst/stride/gststridetransform.c
++++ b/gst/stride/gststridetransform.c
+@@ -57,27 +57,6 @@
+ /* last entry has GST_VIDEO_FORMAT_UNKNOWN for in/out formats */
+ extern const Conversion stride_conversions[];
+
+-/* TODO: add rgb formats too! */
+-#define YUV_SUPPORTED_CAPS \
+- GST_VIDEO_CAPS_YUV_STRIDED ("{I420, YV12, YUY2, UYVY, NV12 }", "[ 0, max ]")
+-
+-#define RGB_SUPPORTED_CAPS \
+- GST_VIDEO_CAPS_RGB_16_STRIDED ("[ 0, max ]")
+-
+-
+-static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
+- GST_PAD_SRC,
+- GST_PAD_ALWAYS,
+- GST_STATIC_CAPS (YUV_SUPPORTED_CAPS ";" RGB_SUPPORTED_CAPS)
+- );
+-
+-static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
+- GST_PAD_SINK,
+- GST_PAD_ALWAYS,
+- GST_STATIC_CAPS (YUV_SUPPORTED_CAPS ";" RGB_SUPPORTED_CAPS)
+- );
+-
+-
+ GST_DEBUG_CATEGORY (stridetransform_debug);
+ #define GST_CAT_DEFAULT stridetransform_debug
+
+@@ -85,6 +64,8 @@ GST_DEBUG_CATEGORY (stridetransform_debug);
+ static void gst_stride_transform_dispose (GObject * obj);
+
+ /* GstBaseTransform functions */
++static gboolean gst_stride_transform_event (GstBaseTransform * trans,
++ GstEvent * event);
+ static gboolean gst_stride_transform_get_unit_size (GstBaseTransform * base,
+ GstCaps * caps, guint * size);
+ static gboolean gst_stride_transform_transform_size (GstBaseTransform * base,
+@@ -96,6 +77,7 @@ static gboolean gst_stride_transform_set_caps (GstBaseTransform * base,
+ GstCaps * incaps, GstCaps * outcaps);
+ static GstFlowReturn gst_stride_transform_transform (GstBaseTransform * base,
+ GstBuffer * inbuf, GstBuffer * outbuf);
++static GstCaps * get_all_templ_caps (GstPadDirection direction);
+
+ GST_BOILERPLATE (GstStrideTransform, gst_stride_transform, GstVideoFilter,
+ GST_TYPE_VIDEO_FILTER);
+@@ -115,9 +97,11 @@ gst_stride_transform_base_init (gpointer g_class)
+ "Rob Clark <rob@ti.com>,");
+
+ gst_element_class_add_pad_template (gstelement_class,
+- gst_static_pad_template_get (&sink_template));
++ gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
++ get_all_templ_caps (GST_PAD_SINK)));
+ gst_element_class_add_pad_template (gstelement_class,
+- gst_static_pad_template_get (&src_template));
++ gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
++ get_all_templ_caps (GST_PAD_SRC)));
+ }
+
+ static void
+@@ -128,6 +112,8 @@ gst_stride_transform_class_init (GstStrideTransformClass * klass)
+
+ gobject_class->dispose = gst_stride_transform_dispose;
+
++ basetransform_class->event =
++ GST_DEBUG_FUNCPTR (gst_stride_transform_event);
+ basetransform_class->get_unit_size =
+ GST_DEBUG_FUNCPTR (gst_stride_transform_get_unit_size);
+ basetransform_class->transform_size =
+@@ -160,6 +146,35 @@ gst_stride_transform_dispose (GObject * object)
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+ }
+
++static gboolean
++gst_stride_transform_event (GstBaseTransform * trans, GstEvent * event)
++{
++ GstStrideTransform *self = GST_STRIDE_TRANSFORM (trans);
++
++ GST_DEBUG_OBJECT (self, "event %" GST_PTR_FORMAT, event);
++
++ switch (GST_EVENT_TYPE (event)) {
++ /* if we get a crop, we don't change output size (yet, although it
++ * would be nice to be able to figure out if the sink supported
++ * cropping and if it does not perform the crop ourselves.. which
++ * would involve adjusting output caps appropriately). For now
++ * we just treat it as an optimization and avoid copying the data
++ * that will be later cropped out by the sink.
++ */
++ case GST_EVENT_CROP:
++ gst_event_parse_crop (event, &self->crop_top, &self->crop_left,
++ &self->crop_width, &self->crop_height);
++ self->needs_refresh = TRUE;
++ GST_DEBUG_OBJECT (self, "cropping at %d,%d %dx%d", self->crop_top,
++ self->crop_left, self->crop_width, self->crop_height);
++ default:
++ break;
++ }
++
++ /* forward all events */
++ return TRUE;
++}
++
+ /**
+ * figure out the required buffer size based on @caps
+ */
+@@ -212,95 +227,205 @@ gst_stride_transform_transform_size (GstBaseTransform * base,
+ return TRUE;
+ }
+
++static inline GstCaps *
++get_templ_caps (GstVideoFormat fmt, gboolean strided)
++{
++ return gst_video_format_new_caps_simple (fmt,
++ strided ? -1 : 0,
++ "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
++ "height", GST_TYPE_INT_RANGE, 1, G_MAXINT,
++ "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1,
++ NULL);
++}
++
+ /**
+- * helper to check possible @fourcc conversions to the list @formats
++ * Utility to get all possible template caps for given direction
+ */
+-static void
+-add_all_fourcc_conversions (GValue * formats, guint32 fourcc,
+- GstPadDirection direction)
++static GstCaps *
++get_all_templ_caps (GstPadDirection direction)
+ {
++ int i;
+ gint to_format = (direction == GST_PAD_SINK) ? 1 : 0;
+- gint from_format = (direction == GST_PAD_SRC) ? 1 : 0;
+- GValue fourccval = { 0 };
+- gint i;
+- GstVideoFormat format = gst_video_format_from_fourcc (fourcc);
+-
+- g_value_init (&fourccval, GST_TYPE_FOURCC);
++ GstCaps *templ = gst_caps_new_empty ();
+
+- for (i = 0; stride_conversions[i].format[0] != GST_VIDEO_FORMAT_UNKNOWN; i++) {
+- if (stride_conversions[i].format[from_format] == format) {
+- guint result_fourcc =
+- gst_video_format_to_fourcc (stride_conversions[i].format[to_format]);
+- gst_value_set_fourcc (&fourccval, result_fourcc);
+- gst_value_list_append_value (formats, &fourccval);
+- }
++ for (i = 0; stride_conversions[i].format[0]; i++) {
++ const Conversion *c = &stride_conversions[i];
++ gst_caps_append (templ, get_templ_caps (c->format[to_format], TRUE));
++ gst_caps_append (templ, get_templ_caps (c->format[to_format], FALSE));
+ }
++
++ gst_caps_do_simplify (templ);
++
++ GST_DEBUG ("template %s caps: %"GST_PTR_FORMAT,
++ (direction == GST_PAD_SINK) ? "sink" : "src", templ);
++
++ return templ;
+ }
+
+-/**
+- * helper to add all fields, other than rowstride to @caps, copied from @s.
+- */
+-static void
+-add_all_fields (GstCaps * caps, const gchar * name, GstStructure * s,
+- gboolean rowstride, GstPadDirection direction)
++static inline gboolean
++is_filtered_field (const gchar *name)
+ {
+- gint idx;
+- GstStructure *new_s = gst_structure_new (name, NULL);
++ static const gchar * filtered_fields[] = {
++ "rowstride", "format", "bpp", "depth", "endianness",
++ "red_mask", "green_mask", "blue_mask"
++ };
++ gint i;
++ for (i = 0; i < G_N_ELEMENTS (filtered_fields); i++)
++ if (!strcmp (filtered_fields[i], name))
++ return TRUE;
++ return FALSE;
++}
+
+- if (rowstride) {
+- gst_structure_set (new_s, "rowstride", GST_TYPE_INT_RANGE, 1, G_MAXINT,
+- NULL);
+- }
++static inline GstCaps *
++get_caps (GstVideoFormat fmt, gboolean strided, GstStructure *s)
++{
++ gint idx;
++ GstCaps *ret =
++ gst_video_format_new_caps_simple (fmt, strided ? -1 : 0, NULL);
+
+ idx = gst_structure_n_fields (s) - 1;
+ while (idx >= 0) {
+ const gchar *name = gst_structure_nth_field_name (s, idx);
+- const GValue *val = gst_structure_get_value (s, name);
+
+ idx--;
+
+- /* for format field, check the stride_conversions table to see what
+- * we can support:
++ /* filter out certain format specific fields.. copy everything else
++ * from the original struct
+ */
+- if (!strcmp ("format", name)) {
+- GValue formats = { 0 };
+-
+- g_value_init (&formats, GST_TYPE_LIST);
++ if (!is_filtered_field (name)) {
++ const GValue *val = gst_structure_get_value (s, name);
++ gst_caps_set_value (ret, name, val);
++ }
++ }
+
+- if (GST_VALUE_HOLDS_FOURCC (val)) {
+- add_all_fourcc_conversions (&formats,
+- gst_value_get_fourcc (val), direction);
+- } else if (GST_VALUE_HOLDS_LIST (val)) {
+- gint i;
+- for (i = 0; i < gst_value_list_get_size (val); i++) {
+- const GValue *list_val = gst_value_list_get_value (val, i);
+- if (GST_VALUE_HOLDS_FOURCC (list_val)) {
+- add_all_fourcc_conversions (&formats,
+- gst_value_get_fourcc (list_val), direction);
+- } else {
+- GST_WARNING ("malformed caps!!");
+- break;
+- }
+- }
+- } else {
+- GST_WARNING ("malformed caps!!");
+- }
++ return ret;
++}
+
+- gst_structure_set_value (new_s, "format", &formats);
++/**
++ * Utility to get all possible caps that can be converted to/from (depending
++ * on 'direction') the specified 'fmt'. The rest of the fields are populated
++ * from 's'
++ */
++static GstCaps *
++get_all_caps (GstPadDirection direction, GstVideoFormat fmt, GstStructure *s)
++{
++ GstCaps *ret = gst_caps_new_empty ();
++ gint to_format = (direction == GST_PAD_SINK) ? 1 : 0;
++ gint from_format = (direction == GST_PAD_SRC) ? 1 : 0;
++ gint i;
+
+- continue;
++ for (i = 0; stride_conversions[i].format[0]; i++) {
++ const Conversion *c = &stride_conversions[i];
++ if (c->format[from_format] == fmt) {
++ gst_caps_append (ret, get_caps (c->format[to_format], TRUE, s));
++ gst_caps_append (ret, get_caps (c->format[to_format], FALSE, s));
+ }
++ }
++
++ return ret;
++}
+
+- /* copy over all other non-rowstride fields: */
+- if (strcmp ("rowstride", name)) {
+- gst_structure_set_value (new_s, name, val);
++/** convert GValue holding fourcc to GstVideoFormat (for YUV) */
++static inline GstVideoFormat
++fmt_from_val (const GValue *val)
++{
++ return gst_video_format_from_fourcc (gst_value_get_fourcc (val));
++}
++
++/** convert structure to GstVideoFormat (for RGB) */
++static inline GstVideoFormat
++fmt_from_struct (const GstStructure *s)
++{
++ /* hmm.. this is not supporting any case where ranges/lists are used
++ * for any of the rgb related fields in the caps. But I'm not quite
++ * sure a sane way to handle that.. rgb caps suck
++ */
++ gint depth, bpp, endianness;
++ gint red_mask, green_mask, blue_mask, alpha_mask;
++ gboolean have_alpha, ok = TRUE;
++
++ ok &= gst_structure_get_int (s, "depth", &depth);
++ ok &= gst_structure_get_int (s, "bpp", &bpp);
++ ok &= gst_structure_get_int (s, "endianness", &endianness);
++ ok &= gst_structure_get_int (s, "red_mask", &red_mask);
++ ok &= gst_structure_get_int (s, "green_mask", &green_mask);
++ ok &= gst_structure_get_int (s, "blue_mask", &blue_mask);
++ have_alpha = gst_structure_get_int (s, "alpha_mask", &alpha_mask);
++
++ if (!ok)
++ return GST_VIDEO_FORMAT_UNKNOWN;
++
++ if (depth == 24 && bpp == 32 && endianness == G_BIG_ENDIAN) {
++ if (red_mask == 0xff000000 && green_mask == 0x00ff0000 &&
++ blue_mask == 0x0000ff00) {
++ return GST_VIDEO_FORMAT_RGBx;
++ }
++ if (red_mask == 0x0000ff00 && green_mask == 0x00ff0000 &&
++ blue_mask == 0xff000000) {
++ return GST_VIDEO_FORMAT_BGRx;
++ }
++ if (red_mask == 0x00ff0000 && green_mask == 0x0000ff00 &&
++ blue_mask == 0x000000ff) {
++ return GST_VIDEO_FORMAT_xRGB;
++ }
++ if (red_mask == 0x000000ff && green_mask == 0x0000ff00 &&
++ blue_mask == 0x00ff0000) {
++ return GST_VIDEO_FORMAT_xBGR;
++ }
++ } else if (depth == 32 && bpp == 32 && endianness == G_BIG_ENDIAN &&
++ have_alpha) {
++ if (red_mask == 0xff000000 && green_mask == 0x00ff0000 &&
++ blue_mask == 0x0000ff00 && alpha_mask == 0x000000ff) {
++ return GST_VIDEO_FORMAT_RGBA;
++ }
++ if (red_mask == 0x0000ff00 && green_mask == 0x00ff0000 &&
++ blue_mask == 0xff000000 && alpha_mask == 0x000000ff) {
++ return GST_VIDEO_FORMAT_BGRA;
++ }
++ if (red_mask == 0x00ff0000 && green_mask == 0x0000ff00 &&
++ blue_mask == 0x000000ff && alpha_mask == 0xff000000) {
++ return GST_VIDEO_FORMAT_ARGB;
++ }
++ if (red_mask == 0x000000ff && green_mask == 0x0000ff00 &&
++ blue_mask == 0x00ff0000 && alpha_mask == 0xff000000) {
++ return GST_VIDEO_FORMAT_ABGR;
++ }
++ } else if (depth == 24 && bpp == 24 && endianness == G_BIG_ENDIAN) {
++ if (red_mask == 0xff0000 && green_mask == 0x00ff00 &&
++ blue_mask == 0x0000ff) {
++ return GST_VIDEO_FORMAT_RGB;
++ }
++ if (red_mask == 0x0000ff && green_mask == 0x00ff00 &&
++ blue_mask == 0xff0000) {
++ return GST_VIDEO_FORMAT_BGR;
++ }
++ } else if ((depth == 15 || depth == 16) && bpp == 16 &&
++ endianness == G_BYTE_ORDER) {
++ if (red_mask == GST_VIDEO_COMP1_MASK_16_INT
++ && green_mask == GST_VIDEO_COMP2_MASK_16_INT
++ && blue_mask == GST_VIDEO_COMP3_MASK_16_INT) {
++ return GST_VIDEO_FORMAT_RGB16;
++ }
++ if (red_mask == GST_VIDEO_COMP3_MASK_16_INT
++ && green_mask == GST_VIDEO_COMP2_MASK_16_INT
++ && blue_mask == GST_VIDEO_COMP1_MASK_16_INT) {
++ return GST_VIDEO_FORMAT_BGR16;
++ }
++ if (red_mask == GST_VIDEO_COMP1_MASK_15_INT
++ && green_mask == GST_VIDEO_COMP2_MASK_15_INT
++ && blue_mask == GST_VIDEO_COMP3_MASK_15_INT) {
++ return GST_VIDEO_FORMAT_RGB15;
++ }
++ if (red_mask == GST_VIDEO_COMP3_MASK_15_INT
++ && green_mask == GST_VIDEO_COMP2_MASK_15_INT
++ && blue_mask == GST_VIDEO_COMP1_MASK_15_INT) {
++ return GST_VIDEO_FORMAT_BGR15;
+ }
+ }
+
+- gst_caps_merge_structure (caps, new_s);
++ return GST_VIDEO_FORMAT_UNKNOWN;
+ }
+
+-
+ /**
+ * we can transform @caps to strided or non-strided caps with otherwise
+ * identical parameters
+@@ -310,31 +435,50 @@ gst_stride_transform_transform_caps (GstBaseTransform * base,
+ GstPadDirection direction, GstCaps * caps)
+ {
+ GstStrideTransform *self = GST_STRIDE_TRANSFORM (base);
+- GstCaps *ret;
+- GstStructure *s;
+-
+- g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), NULL);
+-
+- GST_DEBUG_OBJECT (self, "direction=%d, caps=%p", direction, caps);
+- LOG_CAPS (self, caps);
+-
+- ret = gst_caps_new_empty ();
+- s = gst_caps_get_structure (caps, 0);
+-
+- if (gst_structure_has_name (s, "video/x-raw-yuv") ||
+- gst_structure_has_name (s, "video/x-raw-yuv-strided")) {
+-
+- add_all_fields (ret, "video/x-raw-yuv", s, FALSE, direction);
+- add_all_fields (ret, "video/x-raw-yuv-strided", s, TRUE, direction);
+-
+- } else if (gst_structure_has_name (s, "video/x-raw-rgb") ||
+- gst_structure_has_name (s, "video/x-raw-rgb-strided")) {
+-
+- add_all_fields (ret, "video/x-raw-rgb", s, FALSE, direction);
+- add_all_fields (ret, "video/x-raw-rgb-strided", s, TRUE, direction);
++ GstCaps *ret = gst_caps_new_empty ();
++ int i;
++
++ for (i = 0; i < gst_caps_get_size (caps); i++) {
++ GstStructure *s = gst_caps_get_structure (caps, i);
++ const char *name = gst_structure_get_name (s);
++
++ /* this is a bit ugly.. ideally it would be easier to parse caps
++ * a bit more generically without having to care so much about
++ * difference between RGB and YUV.. but YUV can be specified as
++ * a list of format params, whereas RGB is a combination of many
++ * fields..
++ */
++ if (g_str_has_prefix (name, "video/x-raw-yuv")) {
++ const GValue *val = gst_structure_get_value (s, "format");
+
++ if (GST_VALUE_HOLDS_FOURCC (val)) {
++ gst_caps_append (ret,
++ get_all_caps (direction, fmt_from_val (val), s));
++ } else if (GST_VALUE_HOLDS_LIST (val)) {
++ gint j;
++ for (j = 0; j < gst_value_list_get_size (val); j++) {
++ const GValue *list_val = gst_value_list_get_value (val, j);
++ if (GST_VALUE_HOLDS_FOURCC (list_val)) {
++ gst_caps_append (ret,
++ get_all_caps (direction, fmt_from_val (list_val), s));
++ } else {
++ GST_WARNING_OBJECT (self,
++ "malformed format in caps: %"GST_PTR_FORMAT, s);
++ break;
++ }
++ }
++ } else {
++ GST_WARNING_OBJECT (self, "malformed yuv caps: %"GST_PTR_FORMAT, s);
++ }
++ } else if (g_str_has_prefix (name, "video/x-raw-rgb")) {
++ gst_caps_append (ret, get_all_caps (direction, fmt_from_struct (s), s));
++ } else {
++ GST_WARNING_OBJECT (self, "ignoring: %"GST_PTR_FORMAT, s);
++ }
+ }
+
++ gst_caps_do_simplify (ret);
++
+ LOG_CAPS (self, ret);
+
+ return ret;
+@@ -369,6 +513,7 @@ gst_stride_transform_set_caps (GstBaseTransform * base,
+ (stride_conversions[i].format[1] == out_format)) {
+ GST_DEBUG_OBJECT (self, "found stride_conversion: %d", i);
+ self->conversion = &stride_conversions[i];
++ self->needs_refresh = TRUE;
+ break;
+ }
+ }
+@@ -378,10 +523,6 @@ gst_stride_transform_set_caps (GstBaseTransform * base,
+ i, self->conversion, self->in_rowstride, self->out_rowstride);
+
+ g_return_val_if_fail (self->conversion, FALSE);
+- g_return_val_if_fail (self->conversion->unstridify
+- || !self->in_rowstride, FALSE);
+- g_return_val_if_fail (self->conversion->stridify
+- || !self->out_rowstride, FALSE);
+ g_return_val_if_fail (self->width == width, FALSE);
+ g_return_val_if_fail (self->height == height, FALSE);
+
+@@ -399,20 +540,14 @@ gst_stride_transform_transform (GstBaseTransform * base,
+ GST_DEBUG_OBJECT (self, "inbuf=%p (size=%d), outbuf=%p (size=%d)",
+ inbuf, GST_BUFFER_SIZE (inbuf), outbuf, GST_BUFFER_SIZE (outbuf));
+
+- if (self->in_rowstride && self->out_rowstride) {
+- GST_DEBUG_OBJECT (self, "not implemented"); // TODO
+- return GST_FLOW_ERROR;
+- } else if (self->in_rowstride) {
+- return self->conversion->unstridify (self,
+- GST_BUFFER_DATA (outbuf), GST_BUFFER_DATA (inbuf));
+- } else if (self->out_rowstride) {
+- return self->conversion->stridify (self,
++ if (self->conversion) {
++ return self->conversion->convert (self,
+ GST_BUFFER_DATA (outbuf), GST_BUFFER_DATA (inbuf));
+ }
+
+ GST_DEBUG_OBJECT (self,
+- "this shouldn't happen! in_rowstride=%d, out_rowstride=%d",
+- self->in_rowstride, self->out_rowstride);
++ "this shouldn't happen! in_rowstride=%d, out_rowstride=%d, conversion=%p",
++ self->in_rowstride, self->out_rowstride, self->conversion);
+
+ return GST_FLOW_ERROR;
+ }
+diff --git a/gst/stride/gststridetransform.h b/gst/stride/gststridetransform.h
+index bce2526..34733cd 100644
+--- a/gst/stride/gststridetransform.h
++++ b/gst/stride/gststridetransform.h
+@@ -52,11 +52,18 @@ typedef struct {
+
+ GstVideoFormat format[2]; /* in_format, out_format */
+
+- GstFlowReturn (*stridify) (GstStrideTransform *self, guchar *strided, guchar *unstrided);
+- GstFlowReturn (*unstridify) (GstStrideTransform *self, guchar *unstrided, guchar *strided);
++ GstFlowReturn (*convert) (GstStrideTransform *self, guchar *out, guchar *in);
+
+ } Conversion;
+
++typedef struct {
++ gint in_bpl; /* bytes per line in input */
++ gint out_bpl; /* bytes per line in output */
++ gint in_off;
++ gint out_off;
++ gint width;
++ gint height;
++} Cache;
+
+ /**
+ * GstStrideTransform:
+@@ -67,9 +74,23 @@ struct _GstStrideTransform {
+ GstVideoFilter videofilter;
+
+ /*< private >*/
++
++ /* values set from caps: */
+ gint width, height;
+ gint in_rowstride;
+ gint out_rowstride;
++
++ /* values set from set from crop event: */
++ gint crop_width, crop_height, crop_top, crop_left;
++
++ /* cached values used for each conversion, indexed by plane in case of
++ * multi-planar formats. These won't have zero values meaning not-used
++ * (as long as !needs_refresh), but will be set to whatever byte width/
++ * offset is appropriate for the format.
++ */
++ Cache cache[3];
++ gboolean needs_refresh;
++
+ const Conversion *conversion;
+
+ /* for caching the tranform_size() results.. */
+--
+1.7.1
+
diff --git a/media-libs/gst-plugins-base/files/gst-0.10.32-0022-stride-support-for-32bit-RGB-formats.patch b/media-libs/gst-plugins-base/files/gst-0.10.32-0022-stride-support-for-32bit-RGB-formats.patch
new file mode 100644
index 0000000..ac56a08
--- /dev/null
+++ b/media-libs/gst-plugins-base/files/gst-0.10.32-0022-stride-support-for-32bit-RGB-formats.patch
@@ -0,0 +1,54 @@
+From 30b32e864e9a77b66a36d27d3b071f59633d08b7 Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Mon, 13 Sep 2010 19:16:02 -0500
+Subject: [PATCH 22/24] stride: support for 32bit RGB formats
+
+---
+ gst/stride/convert.c | 24 ++++++++++++++++++++++++
+ 1 files changed, 24 insertions(+), 0 deletions(-)
+
+diff --git a/gst/stride/convert.c b/gst/stride/convert.c
+index 5d392ac..7f976a5 100644
+--- a/gst/stride/convert.c
++++ b/gst/stride/convert.c
+@@ -372,6 +372,22 @@ convert_rgb16_rgb16 (GstStrideTransform * self,
+ return convert_422i_422i (self, out, in);
+ }
+
++/** convert 32bbp rgb formats */
++static GstFlowReturn
++convert_rgb32_rgb32 (GstStrideTransform * self,
++ guchar * out, guchar * in)
++{
++ if (G_UNLIKELY (self->needs_refresh)) {
++ gint sx[] = {1};
++ gint sy[] = {1};
++ if (refresh_cache (self, 1, 4, sx, sx, sy, sy))
++ return GST_FLOW_ERROR;
++ self->needs_refresh = FALSE;
++ }
++
++ return convert_n_n (self, out, in, 1);
++}
++
+ #define CONVERT(tofmt, fromfmt, convert) \
+ { \
+ { GST_VIDEO_FORMAT_##tofmt, GST_VIDEO_FORMAT_##fromfmt }, \
+@@ -388,6 +404,14 @@ const Conversion stride_conversions[] = {
+ CONVERT (I420, NV12, convert_i420_nv12),
+ CONVERT (I420, YUY2, convert_i420_yuy2),
+ CONVERT (RGB16, RGB16, convert_rgb16_rgb16),
++ CONVERT (RGBx, RGBx, convert_rgb32_rgb32),
++ CONVERT (BGRx, BGRx, convert_rgb32_rgb32),
++ CONVERT (xRGB, xRGB, convert_rgb32_rgb32),
++ CONVERT (xBGR, xBGR, convert_rgb32_rgb32),
++ CONVERT (RGBA, RGBA, convert_rgb32_rgb32),
++ CONVERT (BGRA, BGRA, convert_rgb32_rgb32),
++ CONVERT (ARGB, ARGB, convert_rgb32_rgb32),
++ CONVERT (ABGR, ABGR, convert_rgb32_rgb32),
+ /* add new entries before here */
+ {{GST_VIDEO_FORMAT_UNKNOWN}}
+ };
+--
+1.7.1
+
diff --git a/media-libs/gst-plugins-base/files/gst-0.10.32-0023-ffmpegcolorspace-support-for-rowstride.patch b/media-libs/gst-plugins-base/files/gst-0.10.32-0023-ffmpegcolorspace-support-for-rowstride.patch
new file mode 100644
index 0000000..d81de9c
--- /dev/null
+++ b/media-libs/gst-plugins-base/files/gst-0.10.32-0023-ffmpegcolorspace-support-for-rowstride.patch
@@ -0,0 +1,410 @@
+From 379447918aafc7f38a79219511764f6c04a2cbf9 Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Fri, 24 Dec 2010 20:55:43 -0600
+Subject: [PATCH 23/24] ffmpegcolorspace: support for rowstride
+
+---
+ gst/ffmpegcolorspace/avcodec.h | 2 +-
+ gst/ffmpegcolorspace/gstffmpegcodecmap.c | 85 +++++++++++++++++++--------
+ gst/ffmpegcolorspace/gstffmpegcodecmap.h | 1 +
+ gst/ffmpegcolorspace/gstffmpegcolorspace.c | 30 ++++++++--
+ gst/ffmpegcolorspace/gstffmpegcolorspace.h | 1 +
+ gst/ffmpegcolorspace/imgconvert.c | 12 ++--
+ 6 files changed, 93 insertions(+), 38 deletions(-)
+
+diff --git a/gst/ffmpegcolorspace/avcodec.h b/gst/ffmpegcolorspace/avcodec.h
+index 57f551c..a4928ee 100644
+--- a/gst/ffmpegcolorspace/avcodec.h
++++ b/gst/ffmpegcolorspace/avcodec.h
+@@ -217,7 +217,7 @@ typedef struct AVPaletteControl {
+
+ } AVPaletteControl;
+
+-int avpicture_get_size(int pix_fmt, int width, int height);
++int avpicture_get_size(int pix_fmt, int width, int height, int stride);
+
+ void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift);
+ const char *avcodec_get_pix_fmt_name(int pix_fmt);
+diff --git a/gst/ffmpegcolorspace/gstffmpegcodecmap.c b/gst/ffmpegcolorspace/gstffmpegcodecmap.c
+index 318a90e..9c6a123 100644
+--- a/gst/ffmpegcolorspace/gstffmpegcodecmap.c
++++ b/gst/ffmpegcolorspace/gstffmpegcodecmap.c
+@@ -619,7 +619,8 @@ gst_ffmpeg_caps_to_pixfmt (const GstCaps * caps,
+ if (!raw)
+ return;
+
+- if (gst_structure_has_name (structure, "video/x-raw-yuv")) {
++ if (gst_structure_has_name (structure, "video/x-raw-yuv") ||
++ gst_structure_has_name (structure, "video/x-raw-yuv-strided")) {
+ guint32 fourcc;
+
+ if (gst_structure_get_fourcc (structure, "format", &fourcc)) {
+@@ -828,10 +829,10 @@ gst_ffmpegcsp_caps_with_codectype (enum CodecType type,
+ int
+ gst_ffmpegcsp_avpicture_fill (AVPicture * picture,
+ uint8_t * ptr, enum PixelFormat pix_fmt, int width, int height,
+- int interlaced)
++ int stride, int interlaced)
+ {
+ int size, w2, h2, size2;
+- int stride, stride2;
++ int stride2;
+ PixFmtInfo *pinfo;
+
+ pinfo = get_pix_fmt_info (pix_fmt);
+@@ -847,11 +848,15 @@ gst_ffmpegcsp_avpicture_fill (AVPicture * picture,
+ case PIX_FMT_YUVJ420P:
+ case PIX_FMT_YUVJ422P:
+ case PIX_FMT_YUVJ444P:
+- stride = GST_ROUND_UP_4 (width);
+ h2 = ROUND_UP_X (height, pinfo->y_chroma_shift);
+- size = stride * h2;
+ w2 = DIV_ROUND_UP_X (width, pinfo->x_chroma_shift);
+- stride2 = GST_ROUND_UP_4 (w2);
++ if (stride) {
++ stride2 = stride;
++ } else {
++ stride = GST_ROUND_UP_4 (width);
++ stride2 = GST_ROUND_UP_4 (w2);
++ }
++ size = stride * h2;
+ h2 = DIV_ROUND_UP_X (height, pinfo->y_chroma_shift);
+ size2 = stride2 * h2;
+ picture->data[0] = ptr;
+@@ -864,11 +869,15 @@ gst_ffmpegcsp_avpicture_fill (AVPicture * picture,
+ /* PIX_FMT_YVU420P = YV12: same as PIX_FMT_YUV420P, but
+ * with U and V plane swapped. Strides as in videotestsrc */
+ case PIX_FMT_YUVA420P:
+- stride = GST_ROUND_UP_4 (width);
+ h2 = ROUND_UP_X (height, pinfo->y_chroma_shift);
+- size = stride * h2;
+ w2 = DIV_ROUND_UP_X (width, pinfo->x_chroma_shift);
+- stride2 = GST_ROUND_UP_4 (w2);
++ if (stride) {
++ stride2 = stride;
++ } else {
++ stride = GST_ROUND_UP_4 (width);
++ stride2 = GST_ROUND_UP_4 (w2);
++ }
++ size = stride * h2;
+ h2 = DIV_ROUND_UP_X (height, pinfo->y_chroma_shift);
+ size2 = stride2 * h2;
+ picture->data[0] = ptr;
+@@ -882,11 +891,15 @@ gst_ffmpegcsp_avpicture_fill (AVPicture * picture,
+ return 2 * size + 2 * size2;
+ case PIX_FMT_YVU410P:
+ case PIX_FMT_YVU420P:
+- stride = GST_ROUND_UP_4 (width);
+ h2 = ROUND_UP_X (height, pinfo->y_chroma_shift);
+- size = stride * h2;
+ w2 = DIV_ROUND_UP_X (width, pinfo->x_chroma_shift);
+- stride2 = GST_ROUND_UP_4 (w2);
++ if (stride) {
++ stride2 = stride;
++ } else {
++ stride = GST_ROUND_UP_4 (width);
++ stride2 = GST_ROUND_UP_4 (w2);
++ }
++ size = stride * h2;
+ h2 = DIV_ROUND_UP_X (height, pinfo->y_chroma_shift);
+ size2 = stride2 * h2;
+ picture->data[0] = ptr;
+@@ -898,11 +911,15 @@ gst_ffmpegcsp_avpicture_fill (AVPicture * picture,
+ return size + 2 * size2;
+ case PIX_FMT_NV12:
+ case PIX_FMT_NV21:
+- stride = GST_ROUND_UP_4 (width);
+ h2 = ROUND_UP_X (height, pinfo->y_chroma_shift);
+- size = stride * h2;
+ w2 = 2 * DIV_ROUND_UP_X (width, pinfo->x_chroma_shift);
+- stride2 = GST_ROUND_UP_4 (w2);
++ if (stride) {
++ stride2 = stride;
++ } else {
++ stride = GST_ROUND_UP_4 (width);
++ stride2 = GST_ROUND_UP_4 (w2);
++ }
++ size = stride * h2;
+ h2 = DIV_ROUND_UP_X (height, pinfo->y_chroma_shift);
+ size2 = stride2 * h2;
+ picture->data[0] = ptr;
+@@ -914,7 +931,9 @@ gst_ffmpegcsp_avpicture_fill (AVPicture * picture,
+ return size + size2;
+ case PIX_FMT_RGB24:
+ case PIX_FMT_BGR24:
+- stride = GST_ROUND_UP_4 (width * 3);
++ if (!stride) {
++ stride = GST_ROUND_UP_4 (width * 3);
++ }
+ size = stride * height;
+ picture->data[0] = ptr;
+ picture->data[1] = NULL;
+@@ -930,7 +949,9 @@ gst_ffmpegcsp_avpicture_fill (AVPicture * picture,
+ case PIX_FMT_ABGR32:
+ case PIX_FMT_xRGB32:
+ case PIX_FMT_BGRx32:
+- stride = width * 4;
++ if (!stride) {
++ stride = width * 4;
++ }
+ size = stride * height;
+ picture->data[0] = ptr;
+ picture->data[1] = NULL;
+@@ -942,7 +963,9 @@ gst_ffmpegcsp_avpicture_fill (AVPicture * picture,
+ case PIX_FMT_YUV422:
+ case PIX_FMT_UYVY422:
+ case PIX_FMT_YVYU422:
+- stride = GST_ROUND_UP_4 (width * 2);
++ if (!stride) {
++ stride = GST_ROUND_UP_4 (width * 2);
++ }
+ size = stride * height;
+ picture->data[0] = ptr;
+ picture->data[1] = NULL;
+@@ -950,7 +973,9 @@ gst_ffmpegcsp_avpicture_fill (AVPicture * picture,
+ picture->linesize[0] = stride;
+ return size;
+ case PIX_FMT_V308:
+- stride = GST_ROUND_UP_4 (width * 3);
++ if (!stride) {
++ stride = GST_ROUND_UP_4 (width * 3);
++ }
+ size = stride * height;
+ picture->data[0] = ptr;
+ picture->data[1] = NULL;
+@@ -958,8 +983,10 @@ gst_ffmpegcsp_avpicture_fill (AVPicture * picture,
+ picture->linesize[0] = stride;
+ return size;
+ case PIX_FMT_UYVY411:
+- stride =
+- GST_ROUND_UP_4 (GST_ROUND_UP_4 (width) + GST_ROUND_UP_4 (width) / 2);
++ if (!stride) {
++ stride = GST_ROUND_UP_4 (GST_ROUND_UP_4 (width) +
++ GST_ROUND_UP_4 (width) / 2);
++ }
+ size = stride * height;
+ picture->data[0] = ptr;
+ picture->data[1] = NULL;
+@@ -968,7 +995,9 @@ gst_ffmpegcsp_avpicture_fill (AVPicture * picture,
+ return size;
+ case PIX_FMT_Y800:
+ case PIX_FMT_GRAY8:
+- stride = GST_ROUND_UP_4 (width);
++ if (!stride) {
++ stride = GST_ROUND_UP_4 (width);
++ }
+ size = stride * height;
+ picture->data[0] = ptr;
+ picture->data[1] = NULL;
+@@ -978,7 +1007,9 @@ gst_ffmpegcsp_avpicture_fill (AVPicture * picture,
+ case PIX_FMT_Y16:
+ case PIX_FMT_GRAY16_L:
+ case PIX_FMT_GRAY16_B:
+- stride = GST_ROUND_UP_4 (width * 2);
++ if (!stride) {
++ stride = GST_ROUND_UP_4 (width * 2);
++ }
+ size = stride * height;
+ picture->data[0] = ptr;
+ picture->data[1] = NULL;
+@@ -987,7 +1018,9 @@ gst_ffmpegcsp_avpicture_fill (AVPicture * picture,
+ return size;
+ case PIX_FMT_MONOWHITE:
+ case PIX_FMT_MONOBLACK:
+- stride = GST_ROUND_UP_4 ((width + 7) >> 3);
++ if (!stride) {
++ stride = GST_ROUND_UP_4 ((width + 7) >> 3);
++ }
+ size = stride * height;
+ picture->data[0] = ptr;
+ picture->data[1] = NULL;
+@@ -996,7 +1029,9 @@ gst_ffmpegcsp_avpicture_fill (AVPicture * picture,
+ return size;
+ case PIX_FMT_PAL8:
+ /* already forced to be with stride, so same result as other function */
+- stride = GST_ROUND_UP_4 (width);
++ if (!stride) {
++ stride = GST_ROUND_UP_4 (width);
++ }
+ size = stride * height;
+ picture->data[0] = ptr;
+ picture->data[1] = ptr + size; /* palette is stored here as 256 32 bit words */
+diff --git a/gst/ffmpegcolorspace/gstffmpegcodecmap.h b/gst/ffmpegcolorspace/gstffmpegcodecmap.h
+index 515f530..bcd212a 100644
+--- a/gst/ffmpegcolorspace/gstffmpegcodecmap.h
++++ b/gst/ffmpegcolorspace/gstffmpegcodecmap.h
+@@ -52,6 +52,7 @@ gst_ffmpegcsp_avpicture_fill (AVPicture * picture,
+ enum PixelFormat pix_fmt,
+ int width,
+ int height,
++ int stride,
+ int interlaced);
+
+ #endif /* __GST_FFMPEG_CODECMAP_H__ */
+diff --git a/gst/ffmpegcolorspace/gstffmpegcolorspace.c b/gst/ffmpegcolorspace/gstffmpegcolorspace.c
+index 4ba0204..63430a0 100644
+--- a/gst/ffmpegcolorspace/gstffmpegcolorspace.c
++++ b/gst/ffmpegcolorspace/gstffmpegcolorspace.c
+@@ -48,6 +48,10 @@ GST_DEBUG_CATEGORY (ffmpegcolorspace_performance);
+ "video/x-raw-yuv, width = "GST_VIDEO_SIZE_RANGE" , " \
+ "height="GST_VIDEO_SIZE_RANGE",framerate="GST_VIDEO_FPS_RANGE"," \
+ "format= (fourcc) { I420 , NV12 , NV21 , YV12 , YUY2 , Y42B , Y444 , YUV9 , YVU9 , Y41B , Y800 , Y8 , GREY , Y16 , UYVY , YVYU , IYU1 , v308 , AYUV, A420} ;" \
++ "video/x-raw-yuv-strided, width = "GST_VIDEO_SIZE_RANGE" , " \
++ "height="GST_VIDEO_SIZE_RANGE",framerate="GST_VIDEO_FPS_RANGE"," \
++ "rowstride="GST_VIDEO_SIZE_RANGE"," \
++ "format= (fourcc) { I420 , NV12 , NV21 , YV12 , YUY2 , Y42B , Y444 , YUV9 , YVU9 , Y41B , Y800 , Y8 , GREY , Y16 , UYVY , YVYU , IYU1 , v308 , AYUV, A420} ;" \
+ GST_VIDEO_CAPS_RGB";" \
+ GST_VIDEO_CAPS_BGR";" \
+ GST_VIDEO_CAPS_RGBx";" \
+@@ -205,8 +209,8 @@ gst_ffmpegcsp_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
+ {
+ GstFFMpegCsp *space;
+ GstStructure *structure;
+- gint in_height, in_width;
+- gint out_height, out_width;
++ gint in_height, in_width, in_stride = 0;
++ gint out_height, out_width, out_stride = 0;
+ const GValue *in_framerate = NULL;
+ const GValue *out_framerate = NULL;
+ const GValue *in_par = NULL;
+@@ -225,6 +229,10 @@ gst_ffmpegcsp_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
+ if (!res)
+ goto no_width_height;
+
++ /* stride is optional: */
++ if (gst_structure_has_name (structure, "video/x-raw-yuv-strided"))
++ gst_structure_get_int (structure, "rowstride", &in_stride);
++
+ /* and framerate */
+ in_framerate = gst_structure_get_value (structure, "framerate");
+ if (in_framerate == NULL || !GST_VALUE_HOLDS_FRACTION (in_framerate))
+@@ -241,6 +249,10 @@ gst_ffmpegcsp_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
+ if (!res)
+ goto no_width_height;
+
++ /* stride is optional: */
++ if (gst_structure_has_name (structure, "video/x-raw-yuv-strided"))
++ gst_structure_get_int (structure, "rowstride", &out_stride);
++
+ /* and framerate */
+ out_framerate = gst_structure_get_value (structure, "framerate");
+ if (out_framerate == NULL || !GST_VALUE_HOLDS_FRACTION (out_framerate))
+@@ -263,6 +275,8 @@ gst_ffmpegcsp_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
+
+ space->width = ctx->width = in_width;
+ space->height = ctx->height = in_height;
++ space->in_stride = in_stride;
++ space->out_stride = out_stride;
+
+ space->interlaced = FALSE;
+ gst_structure_get_boolean (structure, "interlaced", &space->interlaced);
+@@ -401,7 +415,7 @@ gst_ffmpegcsp_get_unit_size (GstBaseTransform * btrans, GstCaps * caps,
+ GstStructure *structure = NULL;
+ AVCodecContext *ctx = NULL;
+ gboolean ret = TRUE;
+- gint width, height;
++ gint width, height, stride = 0;
+
+ g_assert (size);
+
+@@ -409,6 +423,10 @@ gst_ffmpegcsp_get_unit_size (GstBaseTransform * btrans, GstCaps * caps,
+ gst_structure_get_int (structure, "width", &width);
+ gst_structure_get_int (structure, "height", &height);
+
++ /* stride is optional: */
++ if (gst_structure_has_name (structure, "video/x-raw-yuv-strided"))
++ gst_structure_get_int (structure, "rowstride", &stride);
++
+ ctx = avcodec_alloc_context ();
+
+ g_assert (ctx != NULL);
+@@ -422,7 +440,7 @@ gst_ffmpegcsp_get_unit_size (GstBaseTransform * btrans, GstCaps * caps,
+ goto beach;
+ }
+
+- *size = avpicture_get_size (ctx->pix_fmt, width, height);
++ *size = avpicture_get_size (ctx->pix_fmt, width, height, stride);
+
+ /* ffmpeg frames have the palette after the frame data, whereas
+ * GStreamer currently puts it into the caps as 'palette_data' field,
+@@ -460,7 +478,7 @@ gst_ffmpegcsp_transform (GstBaseTransform * btrans, GstBuffer * inbuf,
+ /* fill from with source data */
+ gst_ffmpegcsp_avpicture_fill (&space->from_frame,
+ GST_BUFFER_DATA (inbuf), space->from_pixfmt, space->width, space->height,
+- space->interlaced);
++ space->in_stride, space->interlaced);
+
+ /* fill optional palette */
+ if (space->palette)
+@@ -469,7 +487,7 @@ gst_ffmpegcsp_transform (GstBaseTransform * btrans, GstBuffer * inbuf,
+ /* fill target frame */
+ gst_ffmpegcsp_avpicture_fill (&space->to_frame,
+ GST_BUFFER_DATA (outbuf), space->to_pixfmt, space->width, space->height,
+- space->interlaced);
++ space->out_stride, space->interlaced);
+
+ /* and convert */
+ result = img_convert (&space->to_frame, space->to_pixfmt,
+diff --git a/gst/ffmpegcolorspace/gstffmpegcolorspace.h b/gst/ffmpegcolorspace/gstffmpegcolorspace.h
+index 198ab8a..bd5e01c 100644
+--- a/gst/ffmpegcolorspace/gstffmpegcolorspace.h
++++ b/gst/ffmpegcolorspace/gstffmpegcolorspace.h
+@@ -46,6 +46,7 @@ struct _GstFFMpegCsp {
+ GstVideoFilter element;
+
+ gint width, height;
++ gint in_stride, out_stride;
+ gboolean interlaced;
+ gfloat fps;
+ enum PixelFormat from_pixfmt, to_pixfmt;
+diff --git a/gst/ffmpegcolorspace/imgconvert.c b/gst/ffmpegcolorspace/imgconvert.c
+index cb145bb..414c4a0 100644
+--- a/gst/ffmpegcolorspace/imgconvert.c
++++ b/gst/ffmpegcolorspace/imgconvert.c
+@@ -594,12 +594,12 @@ avpicture_layout (const AVPicture * src, int pix_fmt, int width, int height,
+ #endif
+
+ int
+-avpicture_get_size (int pix_fmt, int width, int height)
++avpicture_get_size (int pix_fmt, int width, int height, int stride)
+ {
+ AVPicture dummy_pict;
+
+ return gst_ffmpegcsp_avpicture_fill (&dummy_pict, NULL, pix_fmt, width,
+- height, FALSE);
++ height, stride, FALSE);
+ }
+
+ /**
+@@ -3518,16 +3518,16 @@ get_convert_table_entry (int src_pix_fmt, int dst_pix_fmt)
+
+ static int
+ avpicture_alloc (AVPicture * picture, int pix_fmt, int width, int height,
+- int interlaced)
++ int stride, int interlaced)
+ {
+ unsigned int size;
+ void *ptr;
+
+- size = avpicture_get_size (pix_fmt, width, height);
++ size = avpicture_get_size (pix_fmt, width, height, stride);
+ ptr = av_malloc (size);
+ if (!ptr)
+ goto fail;
+- gst_ffmpegcsp_avpicture_fill (picture, ptr, pix_fmt, width, height,
++ gst_ffmpegcsp_avpicture_fill (picture, ptr, pix_fmt, width, height, stride,
+ interlaced);
+ return 0;
+ fail:
+@@ -3775,7 +3775,7 @@ no_chroma_filter:
+ else
+ int_pix_fmt = PIX_FMT_RGB24;
+ }
+- if (avpicture_alloc (tmp, int_pix_fmt, dst_width, dst_height,
++ if (avpicture_alloc (tmp, int_pix_fmt, dst_width, dst_height, 0,
+ dst->interlaced) < 0)
+ return -1;
+ ret = -1;
+--
+1.7.1
+
diff --git a/media-libs/gst-plugins-base/files/gst-0.10.32-0024-discoverer-rowstride-support.patch b/media-libs/gst-plugins-base/files/gst-0.10.32-0024-discoverer-rowstride-support.patch
new file mode 100644
index 0000000..ebe1b6f
--- /dev/null
+++ b/media-libs/gst-plugins-base/files/gst-0.10.32-0024-discoverer-rowstride-support.patch
@@ -0,0 +1,45 @@
+From 3bb025f5ba20aeb5d2fa575e4a78ea61e3bf5c1b Mon Sep 17 00:00:00 2001
+From: Rob Clark <rob@ti.com>
+Date: Wed, 5 Jan 2011 11:40:03 -0600
+Subject: [PATCH 24/24] discoverer: rowstride support
+
+---
+ gst-libs/gst/pbutils/gstdiscoverer.c | 8 ++++----
+ 1 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/gst-libs/gst/pbutils/gstdiscoverer.c b/gst-libs/gst/pbutils/gstdiscoverer.c
+index 8422d8f..2176196 100644
+--- a/gst-libs/gst/pbutils/gstdiscoverer.c
++++ b/gst-libs/gst/pbutils/gstdiscoverer.c
+@@ -558,7 +558,7 @@ collect_information (GstDiscoverer * dc, const GstStructure * st,
+ GstCaps *caps;
+ GstStructure *caps_st, *tags_st;
+ const gchar *name;
+- int tmp, tmp2;
++ int tmp, tmp2, tmp3;
+ guint utmp;
+ gboolean btmp;
+
+@@ -626,7 +626,7 @@ collect_information (GstDiscoverer * dc, const GstStructure * st,
+ info->parent.caps = caps;
+ }
+
+- if (gst_video_format_parse_caps (caps, &format, &tmp, &tmp2)) {
++ if (gst_video_format_parse_caps_strided (caps, &format, &tmp, &tmp2, &tmp3)) {
+ info->width = (guint) tmp;
+ info->height = (guint) tmp2;
+ }
+@@ -930,8 +930,8 @@ discoverer_collect (GstDiscoverer * dc)
+ gst_caps_get_structure (dc->priv->current_info->stream_info->caps, 0);
+
+ if (g_str_has_prefix (gst_structure_get_name (st), "image/"))
+- ((GstDiscovererVideoInfo *) dc->priv->current_info->
+- stream_info)->is_image = TRUE;
++ ((GstDiscovererVideoInfo *) dc->priv->current_info->stream_info)->
++ is_image = TRUE;
+ }
+ }
+
+--
+1.7.1
+
diff --git a/media-libs/gst-plugins-base/gst-plugins-base-0.10.32_p20110127.ebuild b/media-libs/gst-plugins-base/gst-plugins-base-0.10.32_p20110127.ebuild
new file mode 100644
index 0000000..93160d5
--- /dev/null
+++ b/media-libs/gst-plugins-base/gst-plugins-base-0.10.32_p20110127.ebuild
@@ -0,0 +1,78 @@
+# Copyright 1999-2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: $
+
+EAPI=1
+
+# order is important, gnome2 after gst-plugins
+inherit gst-plugins-base gst-plugins10 gnome2 flag-o-matic autotools eutils
+# libtool
+
+DESCRIPTION="Basepack of plugins for gstreamer"
+HOMEPAGE="http://gstreamer.sourceforge.net"
+MY_P=${P%%_*}
+SRC_URI="http://gstreamer.freedesktop.org/src/${PN}/${MY_P}.tar.bz2"
+S="${WORKDIR}/${MY_P}"
+
+LICENSE="GPL-2"
+KEYWORDS="~alpha ~amd64 arm ~hppa ~ia64 ~ppc ~ppc64 ~sh ~sparc ~x86 ~x86-fbsd ~x86-freebsd ~x86-interix ~amd64-linux ~x86-linux ~ppc-macos ~x64-macos ~x86-macos ~sparc-solaris ~x64-solaris ~x86-solaris"
+IUSE="+introspection +orc"
+
+RDEPEND=">=dev-libs/glib-2.20
+ =media-libs/gstreamer-0.10.32_p20110127
+ dev-libs/libxml2
+ app-text/iso-codes
+ orc? ( >=dev-lang/orc-0.4.5 )
+ !<media-libs/gst-plugins-bad-0.10.10"
+DEPEND="${RDEPEND}
+ dev-util/pkgconfig
+ dev-util/gtk-doc-am"
+
+GST_PLUGINS_BUILD=""
+
+DOCS="AUTHORS NEWS README RELEASE"
+
+src_unpack() {
+ unpack ${A}
+ cd "${S}"
+ epatch "${FILESDIR}"/gst-0.10.32-0001-add-rowstride-support-to-video-utility-functions.patch
+ epatch "${FILESDIR}"/gst-0.10.32-0002-stridetransform-skeletal-implementation-of-stridetra.patch
+ epatch "${FILESDIR}"/gst-0.10.32-0003-stridetransform-implement-caps-negotiation-and-relat.patch
+ epatch "${FILESDIR}"/gst-0.10.32-0004-stridetransform-implement-transform-function.patch
+ epatch "${FILESDIR}"/gst-0.10.32-0005-add-gst_stride_transform_transform_size.patch
+ epatch "${FILESDIR}"/gst-0.10.32-0006-fix-a-small-typo.-need-to-use-the-smaller-of-new_wid.patch
+ epatch "${FILESDIR}"/gst-0.10.32-0007-Add-NV12-support-in-stridetransform.patch
+ epatch "${FILESDIR}"/gst-0.10.32-0008-add-basic-support-for-I420-NV12-colorspace-conversio.patch
+ epatch "${FILESDIR}"/gst-0.10.32-0009-fix-to-avoid-parsing-caps-on-every-frame.patch
+ epatch "${FILESDIR}"/gst-0.10.32-0010-refactor-stridetransform-to-make-it-easier-to-add-ne.patch
+ epatch "${FILESDIR}"/gst-0.10.32-0011-add-some-neon.patch
+ epatch "${FILESDIR}"/gst-0.10.32-0012-add-support-to-convert-to-YUY2-YUYV-color-format.patch
+ epatch "${FILESDIR}"/gst-0.10.32-0013-Add-support-for-RGB565-to-stridetransform.patch
+ epatch "${FILESDIR}"/gst-0.10.32-0014-stridetransform-updates-for-new-extra-anal-compiler-.patch
+ epatch "${FILESDIR}"/gst-0.10.32-0015-stridetransform-fix-problem-transforming-caps-with-l.patch
+ epatch "${FILESDIR}"/gst-0.10.32-0016-modify-playbin-to-use-stridetransform.patch
+ epatch "${FILESDIR}"/gst-0.10.32-0017-playbin-disable-interlaced-support.patch
+ epatch "${FILESDIR}"/gst-0.10.32-0018-textoverlay-add-stride-support.patch
+ epatch "${FILESDIR}"/gst-0.10.32-0019-video-more-flexible-video-caps-utility.patch
+ epatch "${FILESDIR}"/gst-0.10.32-0020-video-fix-endianess-issue-for-16bit-RGB-formats.patch
+ epatch "${FILESDIR}"/gst-0.10.32-0021-stride-more-flexible-stride-color-conversion.patch
+ epatch "${FILESDIR}"/gst-0.10.32-0022-stride-support-for-32bit-RGB-formats.patch
+ epatch "${FILESDIR}"/gst-0.10.32-0023-ffmpegcolorspace-support-for-rowstride.patch
+ eautoreconf
+}
+
+src_compile() {
+ # gst doesnt handle opts well, last tested with 0.10.15
+ strip-flags
+ replace-flags "-O3" "-O2"
+
+ gst-plugins-base_src_configure \
+ --disable-nls \
+ $(use_enable introspection) \
+ $(use_enable orc)
+ emake || die "emake failed."
+}
+
+src_install() {
+ gnome2_src_install
+}