summaryrefslogtreecommitdiffstats
path: root/camera/Encoder_libjpeg.cpp
diff options
context:
space:
mode:
authorSaravanan Solaiyappan <saravanan.s@ti.com>2012-04-23 18:22:05 -0500
committerDaniel Levin <dendy@ti.com>2012-07-25 08:56:43 -0500
commit8714ecc4563e563a7c13d5fddcdff514319786cd (patch)
tree86e40c2701e1b8030d8ca88dd894e3981d5502df /camera/Encoder_libjpeg.cpp
parent7c2946c85eb5ff2a56d107645a9e61aa4b1862e1 (diff)
downloadhardware_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.cpp76
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;