diff options
Diffstat (limited to 'media-libs/gst-plugins-base/files/gst-0.10.32-0015-stridetransform-fix-problem-transforming-caps-with-l.patch')
-rw-r--r-- | media-libs/gst-plugins-base/files/gst-0.10.32-0015-stridetransform-fix-problem-transforming-caps-with-l.patch | 544 |
1 files changed, 544 insertions, 0 deletions
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 + |