int CameraHal::CapturePicture() { int image_width, image_height, preview_width, preview_height; unsigned long base, offset; struct v4l2_buffer buffer; // for VIDIOC_QUERYBUF and VIDIOC_QBUF struct v4l2_format format; struct v4l2_buffer cfilledbuffer; // for VIDIOC_DQBUF struct v4l2_requestbuffers creqbuf; // for VIDIOC_REQBUFS and VIDIOC_STREAMON and VIDIOC_STREAMOFF sp<MemoryBase> mPictureBuffer; sp<MemoryBase> mFinalPictureBuffer; sp<MemoryHeapBase> mJPEGPictureHeap; sp<MemoryBase> mJPEGPictureMemBase; #if OMAP_SCALE sp<MemoryHeapBase> TempHeapBase; sp<MemoryBase> TempBase; sp<IMemoryHeap> TempHeap; #endif ssize_t newoffset; size_t newsize; mCaptureFlag = true; int jpegSize; void* outBuffer; int err, i; int err_cnt = 0; int EXIF_Data_Size = 0; int ThumbNail_Data_Size = 0; unsigned char* pExifBuf = new unsigned char[65536]; //64*1024 int twoSecondReviewMode = getTwoSecondReviewMode(); int orientation = getOrientation(); LOG_FUNCTION_NAME if (CameraSetFrameRate()) { LOGE("Error in setting Camera frame rate\n"); return -1; } HAL_PRINT("\n\n\n PICTURE NUMBER =%d\n\n\n",++pictureNumber); mParameters.getPictureSize(&image_width, &image_height); mParameters.getPreviewSize(&preview_width, &preview_height); HAL_PRINT("Picture Size: Width = %d \t Height = %d\n", image_width, image_height); HAL_PRINT("Preview Size: Width = %d \t Height = %d\n", preview_width, preview_height); #if OPEN_CLOSE_WORKAROUND close(camera_device); camera_device = open(VIDEO_DEVICE, O_RDWR); if (camera_device < 0) { LOGE ("!!!!!!!!!FATAL Error: Could not open the camera device: %s!!!!!!!!!\n", strerror(errno) ); } #endif if(mCamera_Mode == CAMERA_MODE_JPEG) { int jpeg_width = GetJPEG_Capture_Width(); int jpeg_height = GetJPEG_Capture_Height(); capture_len = jpeg_width * jpeg_height * 2; } else { capture_len = image_width * image_height * 2; } if (capture_len & 0xfff) { capture_len = (capture_len & 0xfffff000) + 0x1000; } HAL_PRINT("pictureFrameSize = 0x%x = %d\n", capture_len, capture_len); mPictureHeap = new MemoryHeapBase(capture_len); base = (unsigned long)mPictureHeap->getBase(); base = (base + 0xfff) & 0xfffff000; offset = base - (unsigned long)mPictureHeap->getBase(); /* set size & format of the video image */ format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; format.fmt.pix.width = image_width; format.fmt.pix.height = image_height; if(mCamera_Mode == CAMERA_MODE_JPEG) format.fmt.pix.pixelformat = PIXEL_FORMAT_JPEG; else format.fmt.pix.pixelformat = PIXEL_FORMAT; if (ioctl(camera_device, VIDIOC_S_FMT, &format) < 0) { LOGE ("Failed to set VIDIOC_S_FMT.\n"); return -1; } #if OMAP_SCALE if(mCameraIndex == VGA_CAMERA && mCamMode != VT_MODE) { if(orientation == 0 || orientation == 180) { struct v4l2_control vc; CLEAR(vc); vc.id = V4L2_CID_FLIP; vc.value = CAMERA_FLIP_MIRROR; if (ioctl (camera_device, VIDIOC_S_CTRL, &vc) < 0) { LOGE("V4L2_CID_FLIP fail!\n"); return UNKNOWN_ERROR; } } } #endif /* Shutter CallBack */ if(mMsgEnabled & CAMERA_MSG_SHUTTER) { mNotifyCb(CAMERA_MSG_SHUTTER,0,0,mCallbackCookie); } /* Check if the camera driver can accept 1 buffer */ creqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; creqbuf.memory = V4L2_MEMORY_USERPTR; creqbuf.count = 1; if (ioctl(camera_device, VIDIOC_REQBUFS, &creqbuf) < 0) { LOGE ("VIDIOC_REQBUFS Failed. errno = %d\n", errno); return -1; } buffer.type = creqbuf.type; buffer.memory = creqbuf.memory; buffer.index = 0; if (ioctl(camera_device, VIDIOC_QUERYBUF, &buffer) < 0) { LOGE("VIDIOC_QUERYBUF Failed"); return -1; } buffer.m.userptr = base; mPictureBuffer = new MemoryBase(mPictureHeap, offset, buffer.length); LOGD("Picture Buffer: Base = %p Offset = 0x%x\n", (void *)base, (unsigned int)offset); if (ioctl(camera_device, VIDIOC_QBUF, &buffer) < 0) { LOGE("CAMERA VIDIOC_QBUF Failed"); return -1; } /* turn on streaming */ creqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (ioctl(camera_device, VIDIOC_STREAMON, &creqbuf.type) < 0) { LOGE("VIDIOC_STREAMON Failed\n"); return -1; } HAL_PRINT("De-queue the next avaliable buffer\n"); /* De-queue the next avaliable buffer */ cfilledbuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; cfilledbuffer.memory = creqbuf.memory; while (ioctl(camera_device, VIDIOC_DQBUF, &cfilledbuffer) < 0) { LOGE("VIDIOC_DQBUF Failed cnt = %d\n", err_cnt); if(err_cnt++ > 10) { mNotifyCb(CAMERA_MSG_ERROR,CAMERA_DEVICE_ERROR_FOR_RESTART,0,mCallbackCookie); mPictureBuffer.clear(); mPictureHeap.clear(); return NO_ERROR; } } #if TIMECHECK PPM("AFTER CAPTURE YUV IMAGE\n"); #endif /* turn off streaming */ creqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (ioctl(camera_device, VIDIOC_STREAMOFF, &creqbuf.type) < 0) { LOGE("VIDIOC_STREAMON Failed\n"); return -1; } #if OMAP_SCALE if(mCameraIndex == VGA_CAMERA && mCamMode != VT_MODE) { if(orientation == 0 || orientation == 180) { struct v4l2_control vc; CLEAR(vc); vc.id = V4L2_CID_FLIP; vc.value = CAMERA_FLIP_NONE; if (ioctl (camera_device, VIDIOC_S_CTRL, &vc) < 0) { LOGE("V4L2_CID_FLIP fail!\n"); return UNKNOWN_ERROR; } } } #endif if(mCamera_Mode == CAMERA_MODE_JPEG) { int JPEG_Image_Size = GetJpegImageSize(); int thumbNailOffset = GetThumbNailOffset(); int yuvOffset = GetYUVOffset(); ThumbNail_Data_Size = GetThumbNailDataSize(); sp<IMemoryHeap> heap = mPictureBuffer->getMemory(&newoffset, &newsize); uint8_t* pInJPEGDataBUuf = (uint8_t *)heap->base() + newoffset ; uint8_t* pInThumbNailDataBuf = (uint8_t *)heap->base() + thumbNailOffset; uint8_t* pYUVDataBuf = (uint8_t *)heap->base() + yuvOffset; CreateExif(pInThumbNailDataBuf,ThumbNail_Data_Size,pExifBuf,EXIF_Data_Size,1); //create a new binder object mFinalPictureHeap = new MemoryHeapBase(EXIF_Data_Size+JPEG_Image_Size); mFinalPictureBuffer = new MemoryBase(mFinalPictureHeap,0,EXIF_Data_Size+JPEG_Image_Size); heap = mFinalPictureBuffer->getMemory(&newoffset, &newsize); uint8_t* pOutFinalJpegDataBuf = (uint8_t *)heap->base(); //create a new binder obj to send yuv data if(yuvOffset) { int mFrameSizeConvert = (preview_width*preview_height*3/2) ; mYUVPictureHeap = new MemoryHeapBase(mFrameSizeConvert); mYUVPictureBuffer = new MemoryBase(mYUVPictureHeap,0,mFrameSizeConvert); sp<IMemoryHeap> newheap = mYUVPictureBuffer->getMemory(&newoffset, &newsize); #if TIMECHECK PPM("YUV COLOR CONVERSION STARTED\n"); #endif Neon_Convert_yuv422_to_NV21((uint8_t *)pYUVDataBuf, (uint8_t *)newheap->base(), mPreviewWidth, mPreviewHeight); #if TIMECHECK PPM("YUV COLOR CONVERSION ENDED\n"); #endif } //create final JPEG with EXIF into that int OutJpegSize = 0; err = CreateJpegWithExif(pInJPEGDataBUuf,JPEG_Image_Size,pExifBuf,EXIF_Data_Size,pOutFinalJpegDataBuf,OutJpegSize); if(err==false) return -1; if(yuvOffset) { #ifdef HARDWARE_OMX if(twoSecondReviewMode == 1) { DrawOverlay(pYUVDataBuf, true); } #endif //HARDWARE_OMX if(mMsgEnabled & CAMERA_MSG_RAW_IMAGE) { mDataCb(CAMERA_MSG_RAW_IMAGE, mYUVPictureBuffer, mCallbackCookie); } } if (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE) { mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, mFinalPictureBuffer, mCallbackCookie); } #if OPEN_CLOSE_WORKAROUND close(camera_device); camera_device = open(VIDEO_DEVICE, O_RDWR); if (camera_device < 0) { LOGE ("!!!!!!!!!FATAL Error: Could not open the camera device: %s!!!!!!!!!\n", strerror(errno) ); } #endif } if(mCamera_Mode == CAMERA_MODE_YUV) { #ifdef HARDWARE_OMX int mFrameSizeConvert = (image_width*image_height*2) ; mVGAYUVPictureHeap = new MemoryHeapBase(mFrameSizeConvert); mVGAYUVPictureBuffer = new MemoryBase(mVGAYUVPictureHeap,0,mFrameSizeConvert); mVGANewheap = mVGAYUVPictureBuffer->getMemory(&newoffset, &newsize); sp<IMemoryHeap> heap = mPictureBuffer->getMemory(&newoffset, &newsize); uint8_t* pYUVDataBuf = (uint8_t *)heap->base() + newoffset ; LOGD("PictureThread: generated a picture, yuv_buffer=%p yuv_len=%d\n",pYUVDataBuf,capture_len); #if OMAP_SCALE TempHeapBase = new MemoryHeapBase(mFrameSizeConvert); TempBase = new MemoryBase(TempHeapBase,0,mFrameSizeConvert); TempHeap = TempBase->getMemory(&newoffset, &newsize); if(scale_process((void*)pYUVDataBuf, mPreviewWidth, mPreviewHeight,(void*)TempHeap->base(), mPreviewHeight, mPreviewWidth, 0, PIX_YUV422I, 1)) { LOGE("scale_process() failed\n"); } #endif #if TIMECHECK PPM("YUV COLOR ROTATION STARTED\n"); #endif #if 0 //YUV dump code for testing FILE* fIn = NULL; fIn = fopen("/data/output.yuv", "w"); if ( fIn == NULL ) { LOGE("Error: failed to open the file for writing\n"); } fwrite((uint8_t*)mVGANewheap->base(), 1, mPreviewWidth*mPreviewHeight*2, fIn); fclose(fIn); #endif /* for VGA capture case pYUVDataBuf : Input buffer from Camera Driver YUV422. mVGANewheap->base() : 90 or 270 degree rotated YUV422 format. */ { int error = 0; #if OMAP_SCALE neon_args->pIn = (uint8_t*)TempHeap->base(); #else neon_args->pIn = (uint8_t*)pYUVDataBuf; #endif neon_args->pOut = (uint8_t*)mVGANewheap->base(); neon_args->height = mPreviewWidth; neon_args->width = mPreviewHeight; #if OMAP_SCALE neon_args->rotate = NEON_ROT90; #else neon_args->rotate = NEON_ROT270; #endif if (Neon_Rotate != NULL) error = (*Neon_Rotate)(neon_args); else LOGE("Rotate Fucntion pointer Null"); if (error < 0) { LOGE("Error in Rotation 90"); } } #if OMAP_SCALE TempHeapBase.clear(); TempBase.clear(); TempHeap.clear(); #endif #if TIMECHECK PPM("YUV COLOR ROTATION Done\n"); #endif #endif //HARDWARE_OMX if (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE) { #ifdef HARDWARE_OMX int jpegSize = image_width * image_height*2; capture_len = (image_width*image_height*2) ; CreateExif(NULL, 0, pExifBuf, EXIF_Data_Size, 0); HAL_PRINT("VGA EXIF size : %d\n", EXIF_Data_Size); mJPEGPictureHeap = new MemoryHeapBase(jpegSize + 256); outBuffer = (void *)((unsigned long)(mJPEGPictureHeap->getBase()) + 128); #if TIMECHECK PPM("BEFORE JPEG Encode Image\n"); #endif HAL_PRINT("VGA capture : outbuffer = 0x%x, jpegSize = %d, yuv_buffer = 0x%x, yuv_len = %d, image_width = %d, image_height = %d, quality = %d, mippMode =%d\n", outBuffer, jpegSize, yuv_buffer, capture_len, image_width, image_height, mYcbcrQuality, mippMode); if(isStart_JPEG) { int jpegFormat = PIX_YUV422I; #ifdef OMAP_ENHANCEMENT #if OMAP_SCALE err = jpegEncoder->encodeImage(outBuffer, jpegSize, (uint8_t*)mVGANewheap->base(), capture_len, pExifBuf, EXIF_Data_Size, image_width, // image_height, // mThumbnailWidth, mThumbnailHeight, mYcbcrQuality, jpegFormat); #else err = jpegEncoder->encodeImage(outBuffer, jpegSize, (uint8_t*)mVGANewheap->base(), capture_len, pExifBuf, EXIF_Data_Size, image_height, // image_width, // mThumbnailWidth, mThumbnailHeight, mYcbcrQuality, jpegFormat); #endif LOGD("JPEG ENCODE END\n"); if(err != true) { LOGE("Jpeg encode failed!!\n"); return -1; } else { LOGD("Jpeg encode success!!\n"); } #endif } #if TIMECHECK PPM("AFTER JPEG Encode Image\n"); #endif #ifdef OMAP_ENHANCEMENT mJPEGPictureMemBase = new MemoryBase(mJPEGPictureHeap, 128, jpegEncoder->jpegSize); #endif if (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE) { mDataCb(CAMERA_MSG_COMPRESSED_IMAGE,mJPEGPictureMemBase,mCallbackCookie); } mJPEGPictureMemBase.clear(); mJPEGPictureHeap.clear(); #endif //HARDWARE_OMX }//END of CAMERA_MSG_COMPRESSED_IMAGE yuv_buffer = (uint8_t*)cfilledbuffer.m.userptr; if(twoSecondReviewMode == 1) { DrawOverlay(yuv_buffer, true); } //yuv_buffer: [Reused]Output buffer with YUV 420P 270 degree rotated. if(mMsgEnabled & CAMERA_MSG_RAW_IMAGE) { Neon_Convert_yuv422_to_YUV420P((uint8_t *)mVGANewheap->base(), (uint8_t *)yuv_buffer, mPreviewHeight, mPreviewWidth); mDataCb(CAMERA_MSG_RAW_IMAGE, mPictureBuffer, mCallbackCookie); } } //END of CAMERA_MODE_YUV mPictureBuffer.clear(); mPictureHeap.clear(); if(mCamera_Mode == CAMERA_MODE_JPEG) { mFinalPictureBuffer.clear(); mFinalPictureHeap.clear(); mYUVPictureBuffer.clear(); mYUVPictureHeap.clear(); } if(mCamera_Mode == CAMERA_MODE_YUV) { if(mCameraIndex == VGA_CAMERA) { mVGAYUVPictureBuffer.clear(); mVGAYUVPictureHeap.clear(); } } delete []pExifBuf; mCaptureFlag = false; LOG_FUNCTION_NAME_EXIT return NO_ERROR; }
int CameraHal::CapturePicture() { int image_width, image_height, preview_width, preview_height; int capture_len; unsigned long base, offset; #ifdef R3D4_CONVERT CColorConvert* pConvert; //class for image processing #endif struct v4l2_buffer buffer; // for VIDIOC_QUERYBUF and VIDIOC_QBUF struct v4l2_format format; //struct v4l2_buffer cfilledbuffer; // for VIDIOC_DQBUF struct v4l2_requestbuffers creqbuf; // for VIDIOC_REQBUFS and VIDIOC_STREAMON and VIDIOC_STREAMOFF sp<MemoryBase> mPictureBuffer; sp<MemoryBase> mFinalPictureBuffer; sp<MemoryHeapBase> mJPEGPictureHeap; sp<MemoryBase> mJPEGPictureMemBase; ssize_t newoffset; size_t newsize; mCaptureFlag = true; int jpegSize; void* outBuffer; int err, i; int err_cnt = 0; int exifDataSize = 0; int thumbnaiDataSize = 0; unsigned char* pExifBuf = new unsigned char[64*1024]; int twoSecondReviewMode = getTwoSecondReviewMode(); int orientation = getOrientation(); LOG_FUNCTION_NAME if (CameraSetFrameRate()) { LOGE("Error in setting Camera frame rate\n"); return -1; } LOGD("\n\n\n PICTURE NUMBER =%d\n\n\n",++pictureNumber); mParameters.getPictureSize(&image_width, &image_height); mParameters.getPreviewSize(&preview_width, &preview_height); LOGV("mCameraIndex = %d\n", mCameraIndex); LOGD("Picture Size: Width = %d \t Height = %d\n", image_width, image_height); /* set size & format of the video image */ format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; format.fmt.pix.width = image_width; format.fmt.pix.height = image_height; if(mCamera_Mode == CAMERA_MODE_JPEG) { format.fmt.pix.pixelformat = PIXEL_FORMAT_JPEG; capture_len = GetJPEG_Capture_Width() * GetJPEG_Capture_Height() * JPG_BYTES_PER_PIXEL; } else { format.fmt.pix.pixelformat = PIXEL_FORMAT; capture_len = image_width * image_height * UYV_BYTES_PER_PIXEL; } // round up to 4096 bytes if (capture_len & 0xfff) capture_len = (capture_len & 0xfffff000) + 0x1000; LOGV("capture: %s mode, pictureFrameSize = 0x%x = %d\n", (mCamera_Mode == CAMERA_MODE_JPEG)?"jpeg":"yuv", capture_len, capture_len); mPictureHeap = new MemoryHeapBase(capture_len); base = (unsigned long)mPictureHeap->getBase(); base = (base + 0xfff) & 0xfffff000; offset = base - (unsigned long)mPictureHeap->getBase(); // set capture format if (ioctl(camera_device, VIDIOC_S_FMT, &format) < 0) { LOGE ("Failed to set VIDIOC_S_FMT.\n"); return -1; } #if OMAP_SCALE if(mCameraIndex == VGA_CAMERA && mCamMode != VT_MODE) if(orientation == 0 || orientation == 180) setFlip(CAMERA_FLIP_MIRROR); #endif /* Shutter CallBack */ if(mMsgEnabled & CAMERA_MSG_SHUTTER) { mNotifyCb(CAMERA_MSG_SHUTTER, 0, 0, mCallbackCookie); } /* Check if the camera driver can accept 1 buffer */ creqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; creqbuf.memory = V4L2_MEMORY_USERPTR; creqbuf.count = 1; if (ioctl(camera_device, VIDIOC_REQBUFS, &creqbuf) < 0) { LOGE ("VIDIOC_REQBUFS Failed. errno = %d\n", errno); return -1; } buffer.type = creqbuf.type; buffer.memory = creqbuf.memory; buffer.index = 0; if (ioctl(camera_device, VIDIOC_QUERYBUF, &buffer) < 0) { LOGE("VIDIOC_QUERYBUF Failed"); return -1; } buffer.m.userptr = base; mPictureBuffer = new MemoryBase(mPictureHeap, offset, buffer.length); LOGD("Picture Buffer: Base = %p Offset = 0x%x\n", (void *)base, (unsigned int)offset); if (ioctl(camera_device, VIDIOC_QBUF, &buffer) < 0) { LOGE("CAMERA VIDIOC_QBUF Failed"); return -1; } /* turn on streaming */ if (ioctl(camera_device, VIDIOC_STREAMON, &creqbuf.type) < 0) { LOGE("VIDIOC_STREAMON Failed\n"); return -1; } LOGD("De-queue the next avaliable buffer\n"); /* De-queue the next avaliable buffer */ //try to get buffer from camearo for 10 times while (ioctl(camera_device, VIDIOC_DQBUF, &buffer) < 0) { LOGE("VIDIOC_DQBUF Failed cnt = %d\n", err_cnt); if(err_cnt++ > 10) { mNotifyCb(CAMERA_MSG_ERROR, CAMERA_DEVICE_ERROR_FOR_RESTART, 0, mCallbackCookie); mPictureBuffer.clear(); mPictureHeap.clear(); return NO_ERROR; } } PPM("AFTER CAPTURE YUV IMAGE\n"); /* turn off streaming */ if (ioctl(camera_device, VIDIOC_STREAMOFF, &creqbuf.type) < 0) { LOGE("VIDIOC_STREAMON Failed\n"); return -1; } #if OMAP_SCALE if(mCameraIndex == VGA_CAMERA && mCamMode != VT_MODE) if(orientation == 0 || orientation == 180) setFlip(CAMERA_FLIP_NONE); #endif // camera returns processed jpeg image if(mCamera_Mode == CAMERA_MODE_JPEG) { int JPEG_Image_Size = GetJpegImageSize(); int thumbNailOffset = 0; //m4mo doesnt store offset ? int yuvOffset =0; //m4mo doesnt store yuv image ? // int thumbNailOffset = GetThumbNailOffset(); // int yuvOffset = GetYUVOffset(); thumbnaiDataSize = GetThumbNailDataSize(); sp<IMemoryHeap> heap = mPictureBuffer->getMemory(&newoffset, &newsize); uint8_t* pInJPEGDataBUuf = (uint8_t *)heap->base() + newoffset ; //ptr to jpeg data uint8_t* pInThumbNailDataBuf = (uint8_t *)heap->base() + thumbNailOffset; //ptr to thmubnail uint8_t* pYUVDataBuf = (uint8_t *)heap->base() + yuvOffset; // FILE* fOut = NULL; // fOut = fopen("/dump/dump.jpg", "w"); // fwrite(pInJPEGDataBUuf, 1, JPEG_Image_Size, fOut); // fclose(fOut); CreateExif(pInThumbNailDataBuf, thumbnaiDataSize, pExifBuf, exifDataSize, EXIF_SET_JPEG_LENGTH); //create a new binder object mFinalPictureHeap = new MemoryHeapBase(exifDataSize+JPEG_Image_Size); mFinalPictureBuffer = new MemoryBase(mFinalPictureHeap,0,exifDataSize+JPEG_Image_Size); heap = mFinalPictureBuffer->getMemory(&newoffset, &newsize); uint8_t* pOutFinalJpegDataBuf = (uint8_t *)heap->base(); //create a new binder obj to send yuv data if(yuvOffset) { int mFrameSizeConvert = (preview_width*preview_height*3/2) ; mYUVPictureHeap = new MemoryHeapBase(mFrameSizeConvert); mYUVPictureBuffer = new MemoryBase(mYUVPictureHeap,0,mFrameSizeConvert); mYUVNewheap = mYUVPictureBuffer->getMemory(&newoffset, &newsize); PPM("YUV COLOR CONVERSION STARTED\n"); #ifdef NEON Neon_Convert_yuv422_to_NV21((uint8_t *)pYUVDataBuf, (uint8_t *)mYUVNewheap->base(), mPreviewWidth, mPreviewHeight); PPM("YUV COLOR CONVERSION ENDED\n"); if(mMsgEnabled & CAMERA_MSG_RAW_IMAGE) { mDataCb(CAMERA_MSG_RAW_IMAGE, mYUVPictureBuffer, mCallbackCookie); } #else if(mMsgEnabled & CAMERA_MSG_RAW_IMAGE) mDataCb(CAMERA_MSG_RAW_IMAGE, pYUVDataBuf, mCallbackCookie); #endif } //create final JPEG with EXIF into that int OutJpegSize = 0; if(!CreateJpegWithExif( pInJPEGDataBUuf, JPEG_Image_Size, pExifBuf, exifDataSize, pOutFinalJpegDataBuf, OutJpegSize)) { LOGE("createJpegWithExif fail!!\n"); return -1; } if (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE) { mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, mFinalPictureBuffer, mCallbackCookie); } } //CAMERA_MODE_JPEG // camera returns 16 bit uyv image // -> needs to process (rotate/flip) // -> and compess to jpeg (with dsp) if(mCamera_Mode == CAMERA_MODE_YUV) { #ifdef HARDWARE_OMX // create new buffer for image processing int mFrameSizeConvert = (image_width*image_height*2) ; mYUVPictureHeap = new MemoryHeapBase(mFrameSizeConvert); mYUVPictureBuffer = new MemoryBase(mYUVPictureHeap,0,mFrameSizeConvert); mYUVNewheap = mYUVPictureBuffer->getMemory(&newoffset, &newsize); // buffer from v4l holding the actual image uint8_t *pYuvBuffer = (uint8_t*)buffer.m.userptr; LOGD("PictureThread: generated a picture, pYuvBuffer=%p yuv_len=%d\n", pYuvBuffer, capture_len); PPM("YUV COLOR ROTATION STARTED\n"); #ifdef R3D4_CONVERT if(mCameraIndex == VGA_CAMERA) { LOGV("use rotation"); // color converter and image processing (flip/rotate) // neon lib doesnt seem to work, jpeg was corrupted? // so use own stuff pConvert = new CColorConvert(pYuvBuffer, image_width, image_height, UYV2); //pConvert->writeFile(DUMP_PATH "before_rotate.uyv", SOURCE); //pConvert->writeFile(DUMP_PATH "before_rotate.bmp", BMP); if(mCameraIndex == VGA_CAMERA ) pConvert->rotateImage(ROTATE_270); // else // pConvert->flipImage(FLIP_VERTICAL); // write rotatet image back to input buffer //pConvert->writeFile(DUMP_PATH "after_rotate.bmp", BMP); pConvert->makeUYV2(NULL, INPLACE); //INPLACE: no new buffer, write to input buffer image_width = pConvert->getWidth(); image_height = pConvert->geHeight(); } #else #endif PPM("YUV COLOR ROTATION Done\n"); //pYuvBuffer: [Reused]Output buffer with YUV 420P 270 degree rotated. if(mMsgEnabled & CAMERA_MSG_RAW_IMAGE) { // convert pYuvBuffer(YUV422I) to mYUVPictureBuffer(YUV420P) Neon_Convert_yuv422_to_YUV420P(pYuvBuffer, (uint8_t *)mYUVNewheap->base(), image_width, image_height); mDataCb(CAMERA_MSG_RAW_IMAGE, mYUVPictureBuffer, mCallbackCookie); } #endif //HARDWARE_OMX if (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE) { #ifdef HARDWARE_OMX // int inputFormat = PIX_YUV420P; // int imputSize = image_width * image_height * PIX_YUV420P_BYTES_PER_PIXEL; int inputFormat = PIX_YUV422I; int inputSize = image_width * image_height * PIX_YUV422I_BYTES_PER_PIXEL; int jpegSize = image_width * image_height * JPG_BYTES_PER_PIXEL; CreateExif(NULL, 0, pExifBuf, exifDataSize, EXIF_NOTSET_JPEG_LENGTH); HAL_PRINT("VGA EXIF size : %d\n", exifDataSize); mJPEGPictureHeap = new MemoryHeapBase(jpegSize + 256); outBuffer = (void *)((unsigned long)(mJPEGPictureHeap->getBase()) + 128); HAL_PRINT("YUV capture : outbuffer = 0x%x, jpegSize = %d, pYuvBuffer = 0x%x, yuv_len = %d, image_width = %d, image_height = %d, quality = %d, mippMode =%d\n", outBuffer, jpegSize, pYuvBuffer, capture_len, image_width, image_height, mYcbcrQuality, mippMode); if(jpegEncoder) { PPM("BEFORE JPEG Encode Image\n"); err = jpegEncoder->encodeImage( outBuffer, // void* outputBuffer, jpegSize, // int outBuffSize, pYuvBuffer, // void *inputBuffer, inputSize, // int inBuffSize, pExifBuf, // unsigned char* pExifBuf, exifDataSize, // int ExifSize, image_width, // int width, image_height, // int height, mThumbnailWidth, // int ThumbWidth, mThumbnailHeight, // int ThumbHeight, mYcbcrQuality, // int quality, inputFormat); // int isPixelFmt420p) PPM("AFTER JPEG Encode Image\n"); LOGD("JPEG ENCODE END\n"); if(err != true) { LOGE("Jpeg encode failed!!\n"); return -1; } else LOGD("Jpeg encode success!!\n"); } mJPEGPictureMemBase = new MemoryBase(mJPEGPictureHeap, 128, jpegEncoder->jpegSize); if (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE) { mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, mJPEGPictureMemBase, mCallbackCookie); } mJPEGPictureMemBase.clear(); mJPEGPictureHeap.clear(); #endif //HARDWARE_OMX }//END of CAMERA_MSG_COMPRESSED_IMAGE #ifdef R3D4_CONVERT delete pConvert; #endif }//END of CAMERA_MODE_YUV mPictureBuffer.clear(); mPictureHeap.clear(); if(mCamera_Mode == CAMERA_MODE_JPEG) { mFinalPictureBuffer.clear(); mFinalPictureHeap.clear(); } mYUVPictureBuffer.clear(); mYUVPictureHeap.clear(); delete []pExifBuf; mCaptureFlag = false; LOG_FUNCTION_NAME_EXIT return NO_ERROR; }