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
This commit is contained in:
parent
d19d1e2ff9
commit
739ac1ba01
@ -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
|
||||
|
@ -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<copybit_image_t *>(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<copybit_image_t *>(src))->format = HAL_PIXEL_FORMAT_YCrCb_420_SP;
|
||||
(const_cast<copybit_image_t *>(src))->handle = yv12_handle;
|
||||
(const_cast<copybit_image_t *>(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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -31,15 +31,12 @@
|
||||
|
||||
#include <copybit.h>
|
||||
#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
|
||||
|
Loading…
Reference in New Issue
Block a user