diff options
author | Saravanan Solaiyappan <saravanan.s@ti.com> | 2012-04-23 18:22:05 -0500 |
---|---|---|
committer | Daniel Levin <dendy@ti.com> | 2012-07-25 08:56:43 -0500 |
commit | 8714ecc4563e563a7c13d5fddcdff514319786cd (patch) | |
tree | 86e40c2701e1b8030d8ca88dd894e3981d5502df /camera/Encoder_libjpeg.cpp | |
parent | 7c2946c85eb5ff2a56d107645a9e61aa4b1862e1 (diff) | |
download | hardware_ti_omap4-8714ecc4563e563a7c13d5fddcdff514319786cd.zip hardware_ti_omap4-8714ecc4563e563a7c13d5fddcdff514319786cd.tar.gz hardware_ti_omap4-8714ecc4563e563a7c13d5fddcdff514319786cd.tar.bz2 |
CameraHAL: Extends pixel format YUV422i-uyvy for video snapshot.
[Comment]
Ducati camera always gives CbYCrY(uyvy) pixel format for YUV422I.
But CameraParameters class only supports YUV422-yuyv (YCbYCr).
This patch adds the YUV422-uyvy pixel format and updates the
jpeg encoder for video snapshot capture.
This also adds the support for jpeg encoding from YUV422i-yuyv
pixel format. This will be used in V4L/USB camera capture.
Change-Id: I564bd00d1a12efba1490190926efa30441298181
Signed-off-by: Solaiyappan Saravanan <saravanan.s@ti.com>
Diffstat (limited to 'camera/Encoder_libjpeg.cpp')
-rw-r--r-- | camera/Encoder_libjpeg.cpp | 76 |
1 files changed, 68 insertions, 8 deletions
diff --git a/camera/Encoder_libjpeg.cpp b/camera/Encoder_libjpeg.cpp index 3388048..e64af8e 100644 --- a/camera/Encoder_libjpeg.cpp +++ b/camera/Encoder_libjpeg.cpp @@ -26,6 +26,7 @@ #include "CameraHal.h" #include "Encoder_libjpeg.h" #include "NV12_resize.h" +#include "TICameraParameters.h" #include <stdlib.h> #include <unistd.h> @@ -149,7 +150,7 @@ static void uyvy_to_yuv(uint8_t* dst, uint32_t* src, int width) { " blt 5f \n\t" "0: @ 16 pixel swap \n\t" " vld2.8 {q0, q1} , [%[src]]! @ q0 = uv q1 = y \n\t" - " vuzp.8 q0, q2 @ d1 = u d5 = v \n\t" + " vuzp.8 q0, q2 @ d0 = u d4 = v \n\t" " vmov d1, d0 @ q0 = u0u1u2..u0u1u2... \n\t" " vmov d5, d4 @ q2 = v0v1v2..v0v1v2... \n\t" " vzip.8 d0, d1 @ q0 = u0u0u1u1u2u2... \n\t" @@ -171,6 +172,61 @@ static void uyvy_to_yuv(uint8_t* dst, uint32_t* src, int width) { } } +static void yuyv_to_yuv(uint8_t* dst, uint32_t* src, int width) { + if (!dst || !src) { + return; + } + + if (width % 2) { + return; // not supporting odd widths + } + + // currently, neon routine only supports multiple of 16 width + if (width % 16) { + while ((width-=2) >= 0) { + uint8_t y0 = (src[0] >> 0) & 0xFF; + uint8_t u0 = (src[0] >> 8) & 0xFF; + uint8_t y1 = (src[0] >> 16) & 0xFF; + uint8_t v0 = (src[0] >> 24) & 0xFF; + dst[0] = y0; + dst[1] = u0; + dst[2] = v0; + dst[3] = y1; + dst[4] = u0; + dst[5] = v0; + dst += 6; + src++; + } + } else { + int n = width; + asm volatile ( + " pld [%[src], %[src_stride], lsl #2] \n\t" + " cmp %[n], #16 \n\t" + " blt 5f \n\t" + "0: @ 16 pixel swap \n\t" + " vld2.8 {q0, q1} , [%[src]]! @ q0 = yyyy.. q1 = uvuv.. \n\t" + " vuzp.8 q1, q2 @ d2 = u d4 = v \n\t" + " vmov d3, d2 @ q1 = u0u1u2..u0u1u2... \n\t" + " vmov d5, d4 @ q2 = v0v1v2..v0v1v2... \n\t" + " vzip.8 d2, d3 @ q1 = u0u0u1u1u2u2... \n\t" + " vzip.8 d4, d5 @ q2 = v0v0v1v1v2v2... \n\t" + " @ now q0 = y q1 = u q2 = v \n\t" + " vst3.8 {d0,d2,d4},[%[dst]]! \n\t" + " vst3.8 {d1,d3,d5},[%[dst]]! \n\t" + " sub %[n], %[n], #16 \n\t" + " cmp %[n], #16 \n\t" + " bge 0b \n\t" + "5: @ end \n\t" +#ifdef NEEDS_ARM_ERRATA_754319_754320 + " vmov s0,s0 @ add noop for errata item \n\t" +#endif + : [dst] "+r" (dst), [src] "+r" (src), [n] "+r" (n) + : [src_stride] "r" (width) + : "cc", "memory", "q0", "q1", "q2" + ); + } +} + static void resize_nv12(Encoder_libjpeg::params* params, uint8_t* dst_buffer) { structConvImage o_img_ptr, i_img_ptr; @@ -396,13 +452,14 @@ size_t Encoder_libjpeg::encode(params* input) { resize_nv12(input, resize_src); if (resize_src) src = resize_src; } - } else if ((in_width != out_width) || (in_height != out_height)) { - CAMHAL_LOGEB("Encoder: resizing is not supported for this format: %s", input->format); - goto exit; - } else if (strcmp(input->format, CameraParameters::PIXEL_FORMAT_YUV422I)) { + } else if (strcmp(input->format, CameraParameters::PIXEL_FORMAT_YUV422I) && + strcmp(input->format, TICameraParameters::PIXEL_FORMAT_YUV422I_UYVY)) { // we currently only support yuv422i and yuv420sp CAMHAL_LOGEB("Encoder: format not supported: %s", input->format); goto exit; + } else if ((in_width != out_width) || (in_height != out_height)) { + CAMHAL_LOGEB("Encoder: resizing is not supported for this format: %s", input->format); + goto exit; } cinfo.err = jpeg_std_error(&jerr); @@ -414,9 +471,10 @@ size_t Encoder_libjpeg::encode(params* input) { "height:%d \n\t" "dest %p \n\t" "dest size:%d \n\t" - "mSrc %p", + "mSrc %p \n\t" + "format: %s", out_width, out_height, input->dst, - input->dst_size, src); + input->dst_size, src, input->format); cinfo.dest = &dest_mgr; cinfo.image_width = out_width - right_crop; @@ -441,8 +499,10 @@ size_t Encoder_libjpeg::encode(params* input) { // convert input yuv format to yuv444 if (strcmp(input->format, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) { nv21_to_yuv(row_tmp, row_src, row_uv, out_width - right_crop); - } else { + } else if (strcmp(input->format, TICameraParameters::PIXEL_FORMAT_YUV422I_UYVY) == 0) { uyvy_to_yuv(row_tmp, (uint32_t*)row_src, out_width - right_crop); + } else if (strcmp(input->format, CameraParameters::PIXEL_FORMAT_YUV422I) == 0) { + yuyv_to_yuv(row_tmp, (uint32_t*)row_src, out_width - right_crop); } row[0] = row_tmp; |