Search
SailfishOS Open Build Service
>
Projects
>
home:sledge
:
branches:nemo:devel:hw:ti:omap4:common
>
gst-plugins-base
> 0012-add-support-to-convert-to-YUY2-YUYV-color-format.patch
Log In
Username
Password
Cancel
Overview
Repositories
Revisions
Requests
Users
Advanced
Attributes
Meta
File 0012-add-support-to-convert-to-YUY2-YUYV-color-format.patch of Package gst-plugins-base
From 57cbb98e546309ce6b1a3e8c9cb2586cf731572d 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/38] 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.5.4