diff options
Diffstat (limited to 'media-libs/gst-plugins-base')
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 +} |