diff options
Diffstat (limited to 'media-libs/gst-plugins-base/files/gst-0.10.32-0004-stridetransform-implement-transform-function.patch')
-rw-r--r-- | media-libs/gst-plugins-base/files/gst-0.10.32-0004-stridetransform-implement-transform-function.patch | 215 |
1 files changed, 215 insertions, 0 deletions
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 + |