author | jiyu.yang <jiyu.yang@amlogic.com> | 2012-09-07 10:08:22 (GMT) |
---|---|---|
committer | jiyu.yang <jiyu.yang@amlogic.com> | 2012-09-07 10:08:22 (GMT) |
commit | 127fc4ace3c51be4e883de135c1387072aff3f9c (patch) | |
tree | beffcf697732021c28a55304ad89ca4f473117a2 | |
parent | 7ee125825baae49ecbca06e08d50d09938a59623 (diff) | |
download | camera-127fc4ace3c51be4e883de135c1387072aff3f9c.zip camera-127fc4ace3c51be4e883de135c1387072aff3f9c.tar.gz camera-127fc4ace3c51be4e883de135c1387072aff3f9c.tar.bz2 |
add yuv420p(YV12) support for cts
-rwxr-xr-x | ANativeWindowDisplayAdapter.cpp | 20 | ||||
-rwxr-xr-x | Android.mk | 7 | ||||
-rwxr-xr-x | AppCallbackNotifier.cpp | 44 | ||||
-rwxr-xr-x | V4LCameraAdapter/V4LCameraAdapter.cpp | 33 | ||||
-rwxr-xr-x | inc/CameraHal.h | 15 | ||||
-rwxr-xr-x | inc/V4LCameraAdapter/V4LCameraAdapter.h | 1 | ||||
-rwxr-xr-x | utils/util.cpp | 23 | ||||
-rwxr-xr-x | utils/util.h | 1 |
8 files changed, 111 insertions, 33 deletions
diff --git a/ANativeWindowDisplayAdapter.cpp b/ANativeWindowDisplayAdapter.cpp index 94282ab..3227efa 100755 --- a/ANativeWindowDisplayAdapter.cpp +++ b/ANativeWindowDisplayAdapter.cpp @@ -50,14 +50,15 @@ const char* getPixFormatConstant(const char* parameters_format) CAMHAL_LOGVA("CbYCrY format selected"); pixFormat = (const char *) CameraParameters::PIXEL_FORMAT_YUV422I; } - else if(strcmp(parameters_format, (const char *) CameraParameters::PIXEL_FORMAT_YUV420SP) == 0 || - strcmp(parameters_format, (const char *) CameraParameters::PIXEL_FORMAT_YUV420P) == 0) + else if(strcmp(parameters_format, (const char *) CameraParameters::PIXEL_FORMAT_YUV420SP) == 0 ) { - // TODO(XXX): We are treating YV12 the same as YUV420SP CAMHAL_LOGVA("YUV420SP format selected"); pixFormat = (const char *) CameraParameters::PIXEL_FORMAT_YUV420SP; } - else if(strcmp(parameters_format, (const char *) CameraParameters::PIXEL_FORMAT_RGB565) == 0) + else if( strcmp(parameters_format, (const char *) CameraParameters::PIXEL_FORMAT_YUV420P) == 0){ + CAMHAL_LOGVA("YUV420P(YV12) format selected"); + pixFormat = (const char *) CameraParameters::PIXEL_FORMAT_YUV420P; + }else if(strcmp(parameters_format, (const char *) CameraParameters::PIXEL_FORMAT_RGB565) == 0) { CAMHAL_LOGVA("RGB565 format selected"); pixFormat = (const char *) CameraParameters::PIXEL_FORMAT_RGB565; @@ -86,10 +87,12 @@ static size_t getBufSize(const char* parameters_format, int width, int height) (const char *) CameraParameters::PIXEL_FORMAT_YUV422I) == 0) { buf_size = width * height * 2; } - else if((strcmp(parameters_format, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) || - (strcmp(parameters_format, CameraParameters::PIXEL_FORMAT_YUV420P) == 0)) { + else if(strcmp(parameters_format, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0){ buf_size = width * height * 3 / 2; } + else if (strcmp(parameters_format, CameraParameters::PIXEL_FORMAT_YUV420P) == 0){ + buf_size = width * height * 3 / 2; + } else if(strcmp(parameters_format, (const char *) CameraParameters::PIXEL_FORMAT_RGB565) == 0) { buf_size = width * height * 2; @@ -534,9 +537,10 @@ void* ANativeWindowDisplayAdapter::allocateBuffer(int width, int height, const c if ( format != NULL ) { if (strcmp(format, (const char *) CameraParameters::PIXEL_FORMAT_YUV422I) == 0) { win_format = HAL_PIXEL_FORMAT_YCbCr_422_I; - }else if((strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) || - (strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) == 0)) { + }else if(strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) { win_format = HAL_PIXEL_FORMAT_YCrCb_420_SP; + }else if (strcmp(format, CameraParameters::PIXEL_FORMAT_YUV420P) == 0) { + win_format = HAL_PIXEL_FORMAT_YV12; }else if(strcmp(format, (const char *) CameraParameters::PIXEL_FORMAT_RGB565) == 0) { win_format = HAL_PIXEL_FORMAT_RGB_565; } else { @@ -26,11 +26,8 @@ CAMERA_V4L_SRC:= \ CAMERA_UTILS_SRC:= \ utils/ErrorUtils.cpp \ utils/MessageQueue.cpp \ - utils/Semaphore.cpp - -ifeq ($(BOARD_USE_USB_CAMERA),true) - CAMERA_UTILS_SRC += utils/util.cpp -endif + utils/Semaphore.cpp \ + utils/util.cpp include $(CLEAR_VARS) diff --git a/AppCallbackNotifier.cpp b/AppCallbackNotifier.cpp index 7f6f949..7842e79 100755 --- a/AppCallbackNotifier.cpp +++ b/AppCallbackNotifier.cpp @@ -29,6 +29,9 @@ #include "NV12_resize.h" #include <gralloc_priv.h> +#ifndef ALIGN +#define ALIGN(b,w) (((b)+((w)-1))/(w)*(w)) +#endif namespace android { @@ -440,6 +443,7 @@ static void copy2Dto1D(void *dst, void *src, int width, int height, + unsigned int srcpixelfmtflag, size_t stride, uint32_t offset, unsigned int bytesPerPixel, @@ -454,13 +458,14 @@ static void copy2Dto1D(void *dst, unsigned int *y_uv = (unsigned int *)src; CAMHAL_LOGDB("copy2Dto1D() y= 0x%x ; uv=0x%x.",y_uv[0], y_uv[1]); - CAMHAL_LOGDB("pixelFormat,= %d; offset=%d; length=%d;width=%d,%d;stride=%d;",*pixelFormat,offset,length,width,height,stride); + CAMHAL_LOGDB("pixelFormat= %s; offset=%d; length=%d;width=%d,%d;stride=%d;", + pixelFormat,offset,length,width,height,stride); if (pixelFormat!=NULL) { if (strcmp(pixelFormat, CameraParameters::PIXEL_FORMAT_YUV422I) == 0) { bytesPerPixel = 2; } else if (strcmp(pixelFormat, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0 || - strcmp(pixelFormat, CameraParameters::PIXEL_FORMAT_YUV420P) == 0) { + strcmp(pixelFormat, CameraParameters::PIXEL_FORMAT_YUV420P) == 0) { bytesPerPixel = 1; bufferDst = ( unsigned char * ) dst; bufferDstEnd = ( unsigned char * ) dst + width*height*bytesPerPixel; @@ -485,7 +490,8 @@ static void copy2Dto1D(void *dst, //bufferSrc_UV = ( uint16_t * ) ((uint8_t*)y_uv[1] + (stride/2)*yOff + xOff); bufferSrc_UV =( uint16_t * ) ( y_uv[0]+stride*height+ (stride/2)*yOff + xOff) ; - if (strcmp(pixelFormat, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) { + if ((strcmp(pixelFormat, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) + && (CameraFrame::PIXEL_FMT_NV21 == srcpixelfmtflag) ){ uint16_t *bufferDst_UV; bufferDst_UV = (uint16_t *) (((uint8_t*)dst)+row*height); memcpy(bufferDst_UV, bufferSrc_UV, stride*height/2); @@ -534,7 +540,15 @@ static void copy2Dto1D(void *dst, ); } #endif - } else if (strcmp(pixelFormat, CameraParameters::PIXEL_FORMAT_YUV420P) == 0) { + } else if( (strcmp(pixelFormat, CameraParameters::PIXEL_FORMAT_YUV420P) == 0) + && (CameraFrame::PIXEL_FMT_YV12 == srcpixelfmtflag) ){ + bufferSrc =(unsigned char *) bufferSrc_UV; + bufferDst = (unsigned char *)(((unsigned char*)dst)+row*height); + row = ALIGN(stride/2, 16); + + memcpy(bufferDst, bufferSrc, row*height); + } else if ( (strcmp(pixelFormat, CameraParameters::PIXEL_FORMAT_YUV420P) == 0) + && ( CameraFrame::PIXEL_FMT_NV21 == srcpixelfmtflag) ){ uint16_t *bufferDst_U; uint16_t *bufferDst_V; @@ -543,8 +557,8 @@ static void copy2Dto1D(void *dst, // camera adapter to support YV12. Need to address for // USBCamera - bufferDst_V = (uint16_t *) (((uint8_t*)dst)+row*height); - bufferDst_U = (uint16_t *) (((uint8_t*)dst)+row*height+row*height/4); + bufferDst_U = (uint16_t *) (((uint8_t*)dst)+row*height); + bufferDst_V = (uint16_t *) (((uint8_t*)dst)+row*height+row*height/4); for (int i = 0 ; i < height/2 ; i++, bufferSrc_UV += alignedRow/2) { int n = width; @@ -677,12 +691,13 @@ void AppCallbackNotifier::copyAndSendPreviewFrame(CameraFrame* frame, int32_t ms dest = (void*) mPreviewBufs[mPreviewBufCount]; - CAMHAL_LOGVB("%d:copy2Dto1D(%p, %p, %d, %d, %d, %d, %d,%s)", + CAMHAL_LOGVB("%d:copy2Dto1D(%p, %p, %d, %d, %d, %d, %d, %d,%s)", __LINE__, NULL, //buf, frame->mBuffer, frame->mWidth, frame->mHeight, + frame->mPixelFmt, frame->mAlignment, 2, frame->mLength, @@ -706,6 +721,7 @@ void AppCallbackNotifier::copyAndSendPreviewFrame(CameraFrame* frame, int32_t ms frame->mYuv, frame->mWidth, frame->mHeight, + frame->mPixelFmt, frame->mAlignment, frame->mOffset, 2, @@ -1477,12 +1493,22 @@ status_t AppCallbackNotifier::startPreviewCallbacks(CameraParameters ¶ms, vo size = w*h*2; mPreviewPixelFormat = CameraParameters::PIXEL_FORMAT_YUV422I; } - else if(strcmp(mPreviewPixelFormat, (const char *) CameraParameters::PIXEL_FORMAT_YUV420SP) == 0 || - strcmp(mPreviewPixelFormat, (const char *) CameraParameters::PIXEL_FORMAT_YUV420P) == 0) + else if(strcmp(mPreviewPixelFormat, (const char *) CameraParameters::PIXEL_FORMAT_YUV420SP) == 0 ) { size = (w*h*3)/2; mPreviewPixelFormat = CameraParameters::PIXEL_FORMAT_YUV420SP; } + else if( strcmp(mPreviewPixelFormat, (const char *) CameraParameters::PIXEL_FORMAT_YUV420P) == 0) + { + int y_size,c_size,c_stride; + w = ALIGN(w,2); + y_size = w*h; + c_stride = ALIGN(w/2, 16); + c_size = c_stride * h/2; + size = y_size + c_size*2; + + mPreviewPixelFormat = CameraParameters::PIXEL_FORMAT_YUV420P; + } else if(strcmp(mPreviewPixelFormat, (const char *) CameraParameters::PIXEL_FORMAT_RGB565) == 0) { size = w*h*2; diff --git a/V4LCameraAdapter/V4LCameraAdapter.cpp b/V4LCameraAdapter/V4LCameraAdapter.cpp index b0edc3d..bb35111 100755 --- a/V4LCameraAdapter/V4LCameraAdapter.cpp +++ b/V4LCameraAdapter/V4LCameraAdapter.cpp @@ -238,6 +238,7 @@ status_t V4LCameraAdapter::initialize(CameraProperties::Properties* caps) mEnableContiFocus = false; cur_focus_mode_for_conti = CAM_FOCUS_MODE_RELEASE; mFlashMode = FLASHLIGHT_OFF; + mPixelFormat = 0; #ifdef AMLOGIC_USB_CAMERA_SUPPORT mIsDequeuedEIOError = false; @@ -644,14 +645,30 @@ status_t V4LCameraAdapter::UseBuffersPreview(void* bufArr, int num) int width, height; mParams.getPreviewSize(&width, &height); + #ifdef AMLOGIC_USB_CAMERA_SUPPORT - ret = setBuffersFormat(width, height, V4L2_PIX_FMT_YUYV); + ret = setBuffersFormat(width, height, V4L2_PIX_FMT_YUYV);// if( 0 > ret ){ CAMHAL_LOGEB("VIDIOC_S_FMT failed: %s", strerror(errno)); return BAD_VALUE; } #else - setBuffersFormat(width, height, DEFAULT_PREVIEW_PIXEL_FORMAT); + const char *pixfmtchar; + int pixfmt = V4L2_PIX_FMT_NV21; + + pixfmtchar = mParams.getPreviewFormat(); + if(strcasecmp( pixfmtchar, "yuv420p")==0){ + pixfmt = V4L2_PIX_FMT_YVU420; + mPixelFormat =CameraFrame::PIXEL_FMT_YV12; + }else if(strcasecmp( pixfmtchar, "yuv420sp")==0){ + pixfmt = V4L2_PIX_FMT_NV21; + mPixelFormat = CameraFrame::PIXEL_FMT_NV21; + }else if(strcasecmp( pixfmtchar, "yuv422")==0){ + pixfmt = V4L2_PIX_FMT_YUYV; + mPixelFormat = CameraFrame::PIXEL_FMT_YUYV; +} + + setBuffersFormat(width, height, pixfmt); #endif //First allocate adapter internal buffers at V4L level for USB Cam //These are the buffers from which we will copy the data into overlay buffers @@ -1330,7 +1347,11 @@ int V4LCameraAdapter::previewThread() //convert yuyv to nv21 yuyv422_to_nv21(src,dest,width,height); #else - memcpy(dest,src,frame.mLength); + if ( CameraFrame::PIXEL_FMT_NV21 == mPixelFormat){ + memcpy(dest,src,frame.mLength); + }else{ + yv12_adjust_memcpy(dest,src,width,height); + } #endif }else{ //default case frame.mLength = width*height*3/2; @@ -1350,6 +1371,7 @@ int V4LCameraAdapter::previewThread() frame.mWidth = width; frame.mHeight = height; frame.mTimestamp = systemTime(SYSTEM_TIME_MONOTONIC); + frame.mPixelFmt = mPixelFormat; ret = setInitFrameRefCount(frame.mBuffer, frame.mFrameMask); if (ret) LOGE("setInitFrameRefCount err=%d", ret); @@ -2038,11 +2060,6 @@ static bool getCameraBanding(int camera_fd, char* banding_modes, char*def_bandin item_count ++; strcat( tmpbuf, "60hz,"); } - tmp = strstr( banding_modes, "Disabled"); - if(tmp){ - item_count ++; - strcat( tmpbuf, "off"); - } strcpy( banding_modes, tmpbuf); memset(tmpbuf, 0, 256); diff --git a/inc/CameraHal.h b/inc/CameraHal.h index 81b2f5a..3ce77d7 100755 --- a/inc/CameraHal.h +++ b/inc/CameraHal.h @@ -263,6 +263,14 @@ class CameraFrame ENCODE_RAW_YUV420SP_TO_JPEG = 0x1 << 2, HAS_EXIF_DATA = 0x1 << 3, }; + enum PixelFormat + { + PIXEL_FMT_NV21 = 1, + PIXEL_FMT_YV12, + PIXEL_FMT_YU12, + PIXEL_FMT_YUYV, + PIXEL_FMT_RGB24, + }; //default contrustor CameraFrame(): @@ -278,7 +286,8 @@ class CameraFrame mFd(0), mLength(0), mFrameMask(0), - mQuirks(0) { + mQuirks(0), + mPixelFmt(0) { mYuv[0] = NULL; mYuv[1] = NULL; @@ -298,7 +307,8 @@ class CameraFrame mFd(frame.mFd), mLength(frame.mLength), mFrameMask(frame.mFrameMask), - mQuirks(frame.mQuirks) { + mQuirks(frame.mQuirks), + mPixelFmt(frame.mPixelFmt) { mYuv[0] = frame.mYuv[0]; mYuv[1] = frame.mYuv[1]; @@ -316,6 +326,7 @@ class CameraFrame size_t mLength; unsigned mFrameMask; unsigned int mQuirks; + unsigned int mPixelFmt; unsigned int mYuv[2]; ///@todo add other member vars like stride etc }; diff --git a/inc/V4LCameraAdapter/V4LCameraAdapter.h b/inc/V4LCameraAdapter/V4LCameraAdapter.h index 56f942d..2f14eec 100755 --- a/inc/V4LCameraAdapter/V4LCameraAdapter.h +++ b/inc/V4LCameraAdapter/V4LCameraAdapter.h @@ -346,6 +346,7 @@ private: int nDequeued; int mZoomlevel; + unsigned int mPixelFormat; #ifdef AMLOGIC_USB_CAMERA_SUPPORT int mUsbCameraStatus; diff --git a/utils/util.cpp b/utils/util.cpp index 2dfbd50..969e40f 100755 --- a/utils/util.cpp +++ b/utils/util.cpp @@ -5,6 +5,7 @@ #include <sys/types.h> #include <sys/stat.h> +#ifdef AMLOGIC_USB_CAMERA_SUPPORT #define swap_cbcr static void convert_rgb16_to_nv21(uint8_t *rgb, uint8_t *yuv, int width, int height) { @@ -282,4 +283,24 @@ void convert_rgb24_to_rgb16(uint8_t *src, uint8_t *dst, int width, int height) j += 2; } } - +#else +#ifndef ALIGN +#define ALIGN(b,w) (((b)+((w)-1))/(w)*(w)) +#endif +void yv12_adjust_memcpy(unsigned char *dst, unsigned char *src, int width, int height) +{ + //width should be an even number. + int i,stride; + memcpy( dst, src, width*height); + src += width*height; + dst += width*height; + + stride = ALIGN(width/2, 16); + for(i =0; i< height; i++) + { + memcpy(dst,src, stride); + src+=width/2; + dst+=stride; + } +} +#endif diff --git a/utils/util.h b/utils/util.h index b60aeee..6434dcb 100755 --- a/utils/util.h +++ b/utils/util.h @@ -7,4 +7,5 @@ void yuyv422_to_rgb16(unsigned char *from, unsigned char *to, int width,int heig void yuyv422_to_rgb16(unsigned char *from, unsigned char *to, int size); void yuyv422_to_rgb24(unsigned char *buf, unsigned char *rgb, int width, int height); void yuyv422_to_nv21(unsigned char *bufsrc, unsigned char *bufdest, int width, int height); +void yv12_adjust_memcpy(unsigned char *dst, unsigned char *src, int width, int height); #endif /* AML_CAMERA_HARDWARE_INCLUDE_*/ |