From 739ac1ba016ab739763917d6a2386ea294214ce8 Mon Sep 17 00:00:00 2001 From: Ramakant Singh Date: Thu, 16 Feb 2012 19:14:37 +0530 Subject: [PATCH] Display/copybit:Fix YV12 multiple conversion issue Use a temporary buffer to replace inplace conversion CRs-fixed: 333784 (cherry picked from commit 927542660e4c6106f8062c79bd6461c7fef55b4a) Change-Id: I044bdaa31faea98552e35267bb78318317d68866 --- libcopybit/Android.mk | 2 +- libcopybit/copybit.cpp | 30 +++++++---- libcopybit/software_converter.cpp | 82 ++++++++----------------------- libcopybit/software_converter.h | 7 +-- 4 files changed, 44 insertions(+), 77 deletions(-) diff --git a/libcopybit/Android.mk b/libcopybit/Android.mk index 4a05a79..4ebbb16 100644 --- a/libcopybit/Android.mk +++ b/libcopybit/Android.mk @@ -61,7 +61,7 @@ else LOCAL_PRELINK_MODULE := false LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw - LOCAL_SHARED_LIBRARIES := liblog + LOCAL_SHARED_LIBRARIES := liblog libmemalloc LOCAL_SRC_FILES := software_converter.cpp copybit.cpp LOCAL_MODULE := copybit.$(TARGET_BOARD_PLATFORM) LOCAL_MODULE_TAGS := optional diff --git a/libcopybit/copybit.cpp b/libcopybit/copybit.cpp index 0b52c23..4c02de8 100644 --- a/libcopybit/copybit.cpp +++ b/libcopybit/copybit.cpp @@ -360,6 +360,7 @@ static int stretch_copybit( { struct copybit_context_t* ctx = (struct copybit_context_t*)dev; int status = 0; + private_handle_t *yv12_handle = NULL; if (ctx) { struct { uint32_t count; @@ -390,16 +391,25 @@ static int stretch_copybit( return -EINVAL; if(src->format == HAL_PIXEL_FORMAT_YV12) { - if(0 == convertYV12toYCrCb420SP(src)){ - (const_cast(src))->format = - HAL_PIXEL_FORMAT_YCrCb_420_SP; - } - else{ - LOGE("Error copybit conversion from yv12 failed"); - return -EINVAL; - } + int usage = GRALLOC_USAGE_PRIVATE_ADSP_HEAP | GRALLOC_USAGE_PRIVATE_MM_HEAP; + if (0 == alloc_buffer(&yv12_handle,src->w,src->h,src->format, usage)){ + if(0 == convertYV12toYCrCb420SP(src,yv12_handle)){ + (const_cast(src))->format = HAL_PIXEL_FORMAT_YCrCb_420_SP; + (const_cast(src))->handle = yv12_handle; + (const_cast(src))->base = (void *)yv12_handle->base; + } + else{ + LOGE("Error copybit conversion from yv12 failed"); + if(yv12_handle) + free_buffer(yv12_handle); + return -EINVAL; + } + } + else{ + LOGE("Error:unable to allocate memeory for yv12 software conversion"); + return -EINVAL; + } } - const uint32_t maxCount = sizeof(list.req)/sizeof(list.req[0]); const struct copybit_rect_t bounds = { 0, 0, dst->w, dst->h }; struct copybit_rect_t clip; @@ -437,6 +447,8 @@ static int stretch_copybit( } else { status = -EINVAL; } + if(yv12_handle) + free_buffer(yv12_handle); return status; } diff --git a/libcopybit/software_converter.cpp b/libcopybit/software_converter.cpp index 10e9db2..bca8888 100644 --- a/libcopybit/software_converter.cpp +++ b/libcopybit/software_converter.cpp @@ -34,11 +34,11 @@ #include "software_converter.h" /** Convert YV12 to YCrCb_420_SP */ -int convertYV12toYCrCb420SP(const copybit_image_t *src) +int convertYV12toYCrCb420SP(const copybit_image_t *src, private_handle_t *yv12_handle) { private_handle_t* hnd = (private_handle_t*)src->handle; - if(hnd == NULL){ + if(hnd == NULL || yv12_handle == NULL){ LOGE("Invalid handle"); return -1; } @@ -56,57 +56,18 @@ int convertYV12toYCrCb420SP(const copybit_image_t *src) unsigned int y_size = stride * src->h; unsigned int c_width = ALIGN(stride/2, 16); unsigned int c_size = c_width * src->h/2; - unsigned char* chroma = (unsigned char *) (hnd->base + y_size); - unsigned int tempBufSize = c_size * 2; - unsigned char* tempBuf = (unsigned char*) malloc (tempBufSize); - - if(tempBuf == NULL) { - LOGE("Failed to allocate temporary buffer"); - return -errno; - } + unsigned int chromaSize = c_size * 2; + unsigned char* newChroma = (unsigned char *)(yv12_handle->base + y_size); + unsigned char* oldChroma = (unsigned char*)(hnd->base + y_size); + memcpy((char *)yv12_handle->base,(char *)hnd->base,y_size); #ifdef __ARM_HAVE_NEON - /* copy into temp buffer */ - - unsigned char * t1 = chroma; - unsigned char * t2 = tempBuf; - -#ifdef TARGET_7x27A - // Since the Sparrow core on 7x27A has a performance issue - // with reading from uncached memory using Neon instructions, - // use regular ARM instructions to copy the buffer on this - // target. There is no issue with storing, hence using - // Neon instructions for interleaving - for(unsigned int i=0; i < (tempBufSize>>5); i++) { - __asm__ __volatile__ ( - "LDMIA %0!, {r3 - r10} \n" - "STMIA %1!, {r3 - r10} \n" - :"+r"(t1), "+r"(t2) - : - :"memory","r3","r4","r5", - "r6","r7","r8","r9","r10" - ); - - } -#else - for(unsigned int i=0; i < (tempBufSize>>5); i++) { - __asm__ __volatile__ ( - "vld1.u8 {d0-d3}, [%0]! \n" - "vst1.u8 {d0-d3}, [%1]! \n" - :"+r"(t1), "+r"(t2) - : - :"memory","d0","d1","d2","d3" - ); - - } -#endif //TARGET_7x27A - - /* interleave */ + /* interleave */ if(!padding) { - t1 = chroma; - t2 = tempBuf; - unsigned char * t3 = t2 + tempBufSize/2; - for(unsigned int i=0; i < (tempBufSize/2)>>3; i++) { + unsigned char * t1 = newChroma; + unsigned char * t2 = oldChroma; + unsigned char * t3 = t2 + chromaSize/2; + for(unsigned int i=0; i < (chromaSize/2)>>3; i++) { __asm__ __volatile__ ( "vld1.u8 d0, [%0]! \n" "vld1.u8 d1, [%1]! \n" @@ -119,11 +80,10 @@ int convertYV12toYCrCb420SP(const copybit_image_t *src) } } #else //__ARM_HAVE_NEON - memcpy(tempBuf, chroma, tempBufSize); if(!padding) { - for(unsigned int i = 0; i< tempBufSize/2; i++) { - chroma[i*2] = tempBuf[i]; - chroma[i*2+1] = tempBuf[i+tempBufSize/2]; + for(unsigned int i = 0; i< chromaSize/2; i++) { + newChroma[i*2] = oldChroma[i]; + newChroma[i*2+1] = oldChroma[i+chromaSize/2]; } } @@ -144,13 +104,13 @@ int convertYV12toYCrCb420SP(const copybit_image_t *src) continue; } if (j+1 == width/2) { - chroma[r2*c_width + j] = tempBuf[r1*c_width+i]; + newChroma[r2*c_width + j] = oldChroma[r1*c_width+i]; r2++; - chroma[r2*c_width] = tempBuf[r1*c_width+i+c_size]; + newChroma[r2*c_width] = oldChroma[r1*c_width+i+c_size]; j = 1; } else { - chroma[r2*c_width + j] = tempBuf[r1*c_width+i]; - chroma[r2*c_width + j + 1] = tempBuf[r1*c_width+i+c_size]; + newChroma[r2*c_width + j] = oldChroma[r1*c_width+i]; + newChroma[r2*c_width + j + 1] = oldChroma[r1*c_width+i+c_size]; j+=2; } i++; @@ -161,9 +121,7 @@ int convertYV12toYCrCb420SP(const copybit_image_t *src) } } - if(tempBuf) - free(tempBuf); - return 0; + return 0; } struct copyInfo{ @@ -302,4 +260,4 @@ int convert_yuv_android_to_yuv_c2d(private_handle_t *hnd, ret = copy_source_to_destination(hnd->base, dst_hnd->base, info); return ret; -} \ No newline at end of file +} diff --git a/libcopybit/software_converter.h b/libcopybit/software_converter.h index 8f98a93..02c17be 100644 --- a/libcopybit/software_converter.h +++ b/libcopybit/software_converter.h @@ -31,15 +31,12 @@ #include #include "gralloc_priv.h" +#include "gr.h" #define COPYBIT_SUCCESS 0 #define COPYBIT_FAILURE -1 -inline unsigned int ALIGN(unsigned int x, unsigned int align) { - return (x + align-1) & ~(align-1); -} - -int convertYV12toYCrCb420SP(const copybit_image_t *src); +int convertYV12toYCrCb420SP(const copybit_image_t *src,private_handle_t *yv12_handle); /* * Function to convert the c2d format into an equivalent Android format