Search
SailfishOS Open Build Service
>
Projects
>
home:sledge
:
branches:nemo:devel:hw:ti:omap4:common
>
gst-plugins-base
> 0010-refactor-stridetransform-to-make-it-easier-to-add-ne.patch
Log In
Username
Password
Cancel
Overview
Repositories
Revisions
Requests
Users
Advanced
Attributes
Meta
File 0010-refactor-stridetransform-to-make-it-easier-to-add-ne.patch of Package gst-plugins-base
From 5765d5239be3b930e9599e31ba1a711eb0593462 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/38] 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.5.4