diff options
Diffstat (limited to 'camera')
-rw-r--r-- | camera/AppCallbackNotifier.cpp | 152 | ||||
-rw-r--r-- | camera/CameraHal.cpp | 13 | ||||
-rw-r--r-- | camera/Encoder_libjpeg.cpp | 139 | ||||
-rw-r--r-- | camera/NV12_resize.c | 22 | ||||
-rwxr-xr-x[-rw-r--r--] | camera/OMXCameraAdapter/OMXExif.cpp | 4 | ||||
-rw-r--r-- | camera/inc/CameraHal.h | 2 | ||||
-rwxr-xr-x[-rw-r--r--] | camera/inc/Encoder_libjpeg.h | 76 | ||||
-rw-r--r-- | camera/inc/NV12_resize.h | 1 |
8 files changed, 308 insertions, 101 deletions
diff --git a/camera/AppCallbackNotifier.cpp b/camera/AppCallbackNotifier.cpp index 3ff28a8..f88cc3f 100644 --- a/camera/AppCallbackNotifier.cpp +++ b/camera/AppCallbackNotifier.cpp @@ -26,15 +26,14 @@ #include <MetadataBufferType.h> #include <ui/GraphicBuffer.h> #include <ui/GraphicBufferMapper.h> - #include "NV12_resize.h" namespace android { const int AppCallbackNotifier::NOTIFIER_TIMEOUT = -1; -void AppCallbackNotifierEncoderCallback(size_t jpeg_size, - uint8_t* src, +void AppCallbackNotifierEncoderCallback(void* main_jpeg, + void* thumb_jpeg, CameraFrame::FrameType type, void* cookie1, void* cookie2, @@ -42,15 +41,18 @@ void AppCallbackNotifierEncoderCallback(size_t jpeg_size, { if (cookie1) { AppCallbackNotifier* cb = (AppCallbackNotifier*) cookie1; - cb->EncoderDoneCb(jpeg_size, src, type, cookie2, cookie3); + cb->EncoderDoneCb(main_jpeg, thumb_jpeg, type, cookie2, cookie3); } } /*--------------------NotificationHandler Class STARTS here-----------------------------*/ -void AppCallbackNotifier::EncoderDoneCb(size_t jpeg_size, uint8_t* src, CameraFrame::FrameType type, void* cookie1, void* cookie2) +void AppCallbackNotifier::EncoderDoneCb(void* main_jpeg, void* thumb_jpeg, CameraFrame::FrameType type, void* cookie1, void* cookie2) { camera_memory_t* encoded_mem = NULL; + Encoder_libjpeg::params *main_param = NULL, *thumb_param = NULL; + size_t jpeg_size; + uint8_t* src = NULL; LOG_FUNCTION_NAME; @@ -59,18 +61,28 @@ void AppCallbackNotifier::EncoderDoneCb(size_t jpeg_size, uint8_t* src, CameraFr { Mutex::Autolock lock(mLock); - encoded_mem = (camera_memory_t*) cookie1; + if (!main_jpeg) { + goto exit; + } - // TODO(XXX): Need to temporarily allocate another chunk of memory and then memcpy - // encoded buffer since MemoryHeapBase and MemoryBase are passed as - // one camera_memory_t structure. How fix this? + encoded_mem = (camera_memory_t*) cookie1; + main_param = (Encoder_libjpeg::params *) main_jpeg; + jpeg_size = main_param->jpeg_size; + src = main_param->src; - if(encoded_mem && encoded_mem->data) { + if(encoded_mem && encoded_mem->data && (jpeg_size > 0)) { if (cookie2) { ExifElementsTable* exif = (ExifElementsTable*) cookie2; Section_t* exif_section = NULL; exif->insertExifToJpeg((unsigned char*) encoded_mem->data, jpeg_size); + + if(thumb_jpeg) { + thumb_param = (Encoder_libjpeg::params *) thumb_jpeg; + exif->insertExifThumbnailImage((const char*)thumb_param->dst, + (int)thumb_param->jpeg_size); + } + exif_section = FindSection(M_EXIF); if (exif_section) { @@ -88,11 +100,11 @@ void AppCallbackNotifier::EncoderDoneCb(size_t jpeg_size, uint8_t* src, CameraFr } } } - } + } // scope for mutex lock // Send the callback to the application only if the notifier is started and the message is enabled - if((mNotifierState==AppCallbackNotifier::NOTIFIER_STARTED) - && (mCameraHal->msgTypeEnabled(CAMERA_MSG_COMPRESSED_IMAGE))) + if(picture && (mNotifierState==AppCallbackNotifier::NOTIFIER_STARTED) && + (mCameraHal->msgTypeEnabled(CAMERA_MSG_COMPRESSED_IMAGE))) { Mutex::Autolock lock(mBurstLock); #if 0 //TODO: enable burst mode later @@ -107,6 +119,19 @@ void AppCallbackNotifier::EncoderDoneCb(size_t jpeg_size, uint8_t* src, CameraFr } } + exit: + + if (main_jpeg) { + free(main_jpeg); + } + + if (thumb_jpeg) { + if (((Encoder_libjpeg::params *) thumb_jpeg)->dst) { + free(((Encoder_libjpeg::params *) thumb_jpeg)->dst); + } + free(thumb_jpeg); + } + if (encoded_mem) { encoded_mem->release(encoded_mem); } @@ -767,8 +792,10 @@ void AppCallbackNotifier::notifyFrame() (CameraFrame::ENCODE_RAW_YUV422I_TO_JPEG & frame->mQuirks) ) { - int encode_quality = 100; - const char* valstr = NULL; + int encode_quality = 100, tn_quality = 100; + int tn_width, tn_height; + unsigned int current_snapshot = 0; + Encoder_libjpeg::params *main_jpeg = NULL, *tn_jpeg = NULL; void* exif_data = NULL; camera_memory_t* raw_picture = mRequestMemory(-1, frame->mLength, 1, NULL); @@ -776,47 +803,72 @@ void AppCallbackNotifier::notifyFrame() buf = raw_picture->data; } - valstr = mParameters.get(CameraParameters::KEY_JPEG_QUALITY); - if (valstr) { - encode_quality = atoi(valstr); - if (encode_quality < 0 || encode_quality > 100) { - encode_quality = 100; - } + encode_quality = mParameters.getInt(CameraParameters::KEY_JPEG_QUALITY); + if (encode_quality < 0 || encode_quality > 100) { + encode_quality = 100; + } + + tn_quality = mParameters.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY); + if (tn_quality < 0 || tn_quality > 100) { + tn_quality = 100; } if (CameraFrame::HAS_EXIF_DATA & frame->mQuirks) { exif_data = frame->mCookie2; } - CAMHAL_LOGVB("encoder(%p, %d, %p, %d, %d, %d, %d,%p,%d,%p,%p,%p)", - (uint8_t*)frame->mBuffer, - frame->mLength, - (uint8_t*)buf, - frame->mLength, - encode_quality, - frame->mWidth, - frame->mHeight, - AppCallbackNotifierEncoderCallback, - frame->mFrameType, - this, - raw_picture, - exif_data); - - sp<Encoder_libjpeg> encoder = new Encoder_libjpeg((uint8_t*)frame->mBuffer, - frame->mLength, - (uint8_t*)buf, - frame->mLength, - encode_quality, - frame->mWidth, - frame->mHeight, - AppCallbackNotifierEncoderCallback, - (CameraFrame::FrameType)frame->mFrameType, - this, - raw_picture, - exif_data); + main_jpeg = (Encoder_libjpeg::params*) + malloc(sizeof(Encoder_libjpeg::params)); + if (main_jpeg) { + main_jpeg->src = (uint8_t*) frame->mBuffer; + main_jpeg->src_size = frame->mLength; + main_jpeg->dst = (uint8_t*) buf; + main_jpeg->dst_size = frame->mLength; + main_jpeg->quality = encode_quality; + main_jpeg->in_width = frame->mWidth; + main_jpeg->in_height = frame->mHeight; + main_jpeg->out_width = frame->mWidth; + main_jpeg->out_height = frame->mHeight; + main_jpeg->format = CameraParameters::PIXEL_FORMAT_YUV422I; + } + + tn_width = mParameters.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH); + tn_height = mParameters.getInt(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT); + + if ((tn_width > 0) && (tn_height > 0)) { + tn_jpeg = (Encoder_libjpeg::params*) + malloc(sizeof(Encoder_libjpeg::params)); + // if malloc fails just keep going and encode main jpeg + if (!tn_jpeg) { + tn_jpeg = NULL; + } + } + + if (tn_jpeg) { + int width, height; + mParameters.getPreviewSize(&width,&height); + current_snapshot = (mPreviewBufCount + MAX_BUFFERS - 1) % MAX_BUFFERS; + tn_jpeg->src = (uint8_t*) mPreviewBufs[current_snapshot]; + tn_jpeg->src_size = mPreviewMemory->size / MAX_BUFFERS; + tn_jpeg->dst = (uint8_t*) malloc(tn_jpeg->src_size); + tn_jpeg->dst_size = tn_jpeg->src_size; + tn_jpeg->quality = tn_quality; + tn_jpeg->in_width = width; + tn_jpeg->in_height = height; + tn_jpeg->out_width = tn_width; + tn_jpeg->out_height = tn_height; + tn_jpeg->format = CameraParameters::PIXEL_FORMAT_YUV420SP;; + } + + sp<Encoder_libjpeg> encoder = new Encoder_libjpeg(main_jpeg, + tn_jpeg, + AppCallbackNotifierEncoderCallback, + (CameraFrame::FrameType)frame->mFrameType, + this, + raw_picture, + exif_data); encoder->run(); encoder.clear(); - } else if ( ( CameraFrame::IMAGE_FRAME == frame->mFrameType ) && ( NULL != mCameraHal ) && @@ -886,6 +938,7 @@ void AppCallbackNotifier::notifyFrame() structConvImage input = {frame->mWidth, frame->mHeight, + 4096, IC_FORMAT_YCbCr420_lp, (mmByte *)frame->mYuv[0], (mmByte *)frame->mYuv[1], @@ -893,6 +946,7 @@ void AppCallbackNotifier::notifyFrame() structConvImage output = {mVideoWidth, mVideoHeight, + 4096, IC_FORMAT_YCbCr420_lp, (mmByte *)y_uv[0], (mmByte *)y_uv[1], @@ -1346,7 +1400,7 @@ int AppCallbackNotifier::setParameters(const CameraParameters& params) { LOG_FUNCTION_NAME; - mParameters = params + mParameters = params; LOG_FUNCTION_NAME_EXIT; return NO_ERROR; diff --git a/camera/CameraHal.cpp b/camera/CameraHal.cpp index 448ba80..257c2a8 100644 --- a/camera/CameraHal.cpp +++ b/camera/CameraHal.cpp @@ -982,6 +982,10 @@ int CameraHal::setParameters(const CameraParameters& params) mParameters.unflatten(oldParams.flatten()); } + if ( NULL != mAppCallbackNotifier.get() ) { + mAppCallbackNotifier->setParameters(mParameters); + } + // Restart Preview if needed by KEY_RECODING_HINT only if preview is already running. // If preview is not started yet, Video Mode parameters will take effect on next startPreview() if(restartPreviewRequired && previewEnabled()) @@ -2479,6 +2483,15 @@ status_t CameraHal::takePicture( ) #endif } + // if we taking video snapshot... + if ((NO_ERROR == ret) && (mCameraAdapter->getState() == CameraAdapter::VIDEO_STATE)) { + // enable post view frames if not already enabled so we can internally + // save snapshot frames for generating thumbnail + if((mMsgEnabled & CAMERA_MSG_POSTVIEW_FRAME) == 0) { + mAppCallbackNotifier->enableMsgType(CAMERA_MSG_POSTVIEW_FRAME); + } + } + if ( (NO_ERROR == ret) && (NULL != mCameraAdapter) ) { if ( NO_ERROR == ret ) diff --git a/camera/Encoder_libjpeg.cpp b/camera/Encoder_libjpeg.cpp index 5ae4fdf..23058d3 100644 --- a/camera/Encoder_libjpeg.cpp +++ b/camera/Encoder_libjpeg.cpp @@ -27,6 +27,7 @@ #include "CameraHal.h" #include "Encoder_libjpeg.h" +#include "NV12_resize.h" #include <stdlib.h> #include <unistd.h> @@ -92,9 +93,28 @@ libjpeg_destination_mgr::libjpeg_destination_mgr(uint8_t* input, int size) { this->buf = input; this->bufsize = size; + + jpegsize = 0; } /* private static functions */ +static void nv21_to_yuv(uint8_t* dst, uint8_t* y, uint8_t* uv, int width) { + if (!dst || !y || !uv) { + return; + } + + while ((width--) >= 0) { + uint8_t y0 = y[0]; + uint8_t v0 = uv[0]; + uint8_t u0 = *(uv+1); + dst[0] = y0; + dst[1] = u0; + dst[2] = v0; + dst += 3; + y++; + if(!(width % 2)) uv+=2; + } +} static void uyvy_to_yuv(uint8_t* dst, uint32_t* src, int width) { if (!dst || !src) { @@ -151,6 +171,32 @@ static void uyvy_to_yuv(uint8_t* dst, uint32_t* src, int width) { } } +static void resize_nv12(Encoder_libjpeg::params* params, uint8_t* dst_buffer) { + structConvImage o_img_ptr, i_img_ptr; + + if (!params || !dst_buffer) { + return; + } + + //input + i_img_ptr.uWidth = params->in_width; + i_img_ptr.uStride = i_img_ptr.uWidth; + i_img_ptr.uHeight = params->in_height; + i_img_ptr.eFormat = IC_FORMAT_YCbCr420_lp; + i_img_ptr.imgPtr = (uint8_t*) params->src; + i_img_ptr.clrPtr = i_img_ptr.imgPtr + (i_img_ptr.uWidth * i_img_ptr.uHeight); + + //ouput + o_img_ptr.uWidth = params->out_width; + o_img_ptr.uStride = o_img_ptr.uWidth; + o_img_ptr.uHeight = params->out_height; + o_img_ptr.eFormat = IC_FORMAT_YCbCr420_lp; + o_img_ptr.imgPtr = dst_buffer; + o_img_ptr.clrPtr = o_img_ptr.imgPtr + (o_img_ptr.uWidth * o_img_ptr.uHeight); + + VT_resizeFrame_Video_opt2_lp(&i_img_ptr, &o_img_ptr, NULL, 0); +} + /* public static functions */ const char* ExifElementsTable::degreesToExifOrientation(const char* degrees) { for (unsigned int i = 0; i < ARRAY_SIZE(degress_to_exif_lut); i++) { @@ -171,6 +217,17 @@ void ExifElementsTable::insertExifToJpeg(unsigned char* jpeg, size_t jpeg_size) } } +status_t ExifElementsTable::insertExifThumbnailImage(const char* thumb, int len) { + status_t ret = NO_ERROR; + + if ((len > 0) && jpeg_opened) { + ret = ReplaceThumbnailFromBuffer(thumb, len); + CAMHAL_LOGDB("insertExifThumbnailImage. ReplaceThumbnail(). ret=%d", ret); + } + + return ret; +} + void ExifElementsTable::saveJpeg(unsigned char* jpeg, size_t jpeg_size) { if (jpeg_opened) { WriteJpegToBuffer(jpeg, jpeg_size); @@ -223,7 +280,7 @@ status_t ExifElementsTable::insertElement(const char* tag, const char* value) { table[position].Value = (char*) malloc(sizeof(char) * (value_length + 1)); if (table[position].Value) { - strncpy(table[position].Value, value, value_length); + strcpy(table[position].Value, value); table[position].DataLength = value_length + 1; } @@ -232,56 +289,112 @@ status_t ExifElementsTable::insertElement(const char* tag, const char* value) { } /* private member functions */ -size_t Encoder_libjpeg::encode() { +size_t Encoder_libjpeg::encode(params* input) { jpeg_compress_struct cinfo; jpeg_error_mgr jerr; jpeg_destination_mgr jdest; + uint8_t* src = NULL, *resize_src = NULL; uint8_t* row_tmp = NULL; uint8_t* row_src = NULL; - int bpp = 2; // TODO(XXX): hardcoded for uyvy + uint8_t* row_uv = NULL; // used only for NV12 + int out_width = 0, in_width = 0; + int out_height = 0, in_height = 0; + int bpp = 2; // for uyvy + + if (!input) { + return 0; + } + + out_width = input->out_width; + in_width = input->in_width; + out_height = input->out_height; + in_height = input->in_height; + src = input->src; + input->jpeg_size = 0; + + libjpeg_destination_mgr dest_mgr(input->dst, input->dst_size); + + // param check... + if ((in_width < 2) || (out_width < 2) || (in_height < 2) || (out_height < 2) || + (src == NULL) || (input->dst == NULL) || (input->quality < 1) || (input->src_size < 1) || + (input->dst_size < 1) || (input->format == NULL)) { + goto exit; + } + + if (strcmp(input->format, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) { + bpp = 1; + if ((in_width != out_width) || (in_height != out_height)) { + resize_src = (uint8_t*) malloc(input->dst_size); + 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)) { + // we currently only support yuv422i and yuv420sp + CAMHAL_LOGEB("Encoder: format not supported: %s", input->format); + goto exit; + } cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); - libjpeg_destination_mgr dest_mgr(mDest, mDestSize); - CAMHAL_LOGDB("encoding... \n\t" "width: %d \n\t" "height:%d \n\t" "dest %p \n\t" "dest size:%d \n\t" "mSrc %p", - mWidth, mHeight, mDest, mDestSize, mSrc); + out_width, out_height, input->dst, + input->dst_size, src); cinfo.dest = &dest_mgr; - cinfo.image_width = mWidth; - cinfo.image_height = mHeight; + cinfo.image_width = out_width; + cinfo.image_height = out_height; cinfo.input_components = 3; cinfo.in_color_space = JCS_YCbCr; cinfo.input_gamma = 1; jpeg_set_defaults(&cinfo); - jpeg_set_quality(&cinfo, mQuality, TRUE); + jpeg_set_quality(&cinfo, input->quality, TRUE); cinfo.dct_method = JDCT_IFAST; jpeg_start_compress(&cinfo, TRUE); - row_tmp = (uint8_t*)malloc(mWidth * 3); - row_src = mSrc; + row_tmp = (uint8_t*)malloc(out_width * 3); + row_src = src; + row_uv = src + out_width * out_height * bpp; while (cinfo.next_scanline < cinfo.image_height) { JSAMPROW row[1]; /* pointer to JSAMPLE row[s] */ - uyvy_to_yuv(row_tmp, (uint32_t*)row_src, mWidth); + // 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); + } else { + uyvy_to_yuv(row_tmp, (uint32_t*)row_src, out_width); + } + row[0] = row_tmp; jpeg_write_scanlines(&cinfo, row, 1); - row_src = row_src + mWidth*bpp; + row_src = row_src + out_width*bpp; + + // move uv row if input format needs it + if (strcmp(input->format, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) { + if (!(cinfo.next_scanline % 2)) + row_uv = row_uv + out_width * bpp; + } } jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); + if (resize_src) free(resize_src); + + exit: + input->jpeg_size = dest_mgr.jpegsize; return dest_mgr.jpegsize; } diff --git a/camera/NV12_resize.c b/camera/NV12_resize.c index 0d9377e..03c049e 100644 --- a/camera/NV12_resize.c +++ b/camera/NV12_resize.c @@ -93,9 +93,9 @@ VT_resizeFrame_Video_opt2_lp idy = i_img_ptr->uHeight; /* make sure valid input size */ - if (idx < 1 || idy < 1) + if (idx < 1 || idy < 1 || i_img_ptr->uStride < 1) { - LOGE("idx or idy less then 1"); + LOGE("idx or idy less then 1 idx = %d idy = %d stride = %d", idx, idy, i_img_ptr->uStride); LOGV("VT_resizeFrame_Video_opt2_lp-"); return FALSE; } @@ -116,8 +116,8 @@ VT_resizeFrame_Video_opt2_lp mmUchar *pu8Yrow2 = NULL; y = (mmUint16) ((mmUint32) (row*resizeFactorY) >> 9); yf = (mmUchar) ((mmUint32)((row*resizeFactorY) >> 6) & 0x7); - pu8Yrow1 = inImgPtrY + (y)*STRIDE; - pu8Yrow2 = pu8Yrow1 + STRIDE; + pu8Yrow1 = inImgPtrY + (y) * i_img_ptr->uStride; + pu8Yrow2 = pu8Yrow1 + i_img_ptr->uStride; for (col=0; col < codx; col++) { @@ -178,7 +178,7 @@ VT_resizeFrame_Video_opt2_lp ptr8++; } - ptr8 = ptr8 + (STRIDE-codx); + ptr8 = ptr8 + (o_img_ptr->uStride - codx); } ////////////////////////////for Y////////////////////////// @@ -199,10 +199,10 @@ VT_resizeFrame_Video_opt2_lp y = (mmUint16) ((mmUint32) (row*resizeFactorY) >> 9); yf = (mmUchar) ((mmUint32)((row*resizeFactorY) >> 6) & 0x7); - pu8Cbr1 = inImgPtrU + (y)*STRIDE; - pu8Cbr2 = pu8Cbr1 + STRIDE; - pu8Crr1 = inImgPtrV + (y)*STRIDE; - pu8Crr2 = pu8Crr1 + STRIDE; + pu8Cbr1 = inImgPtrU + (y) * i_img_ptr->uStride; + pu8Cbr2 = pu8Cbr1 + i_img_ptr->uStride; + pu8Crr1 = inImgPtrV + (y) * i_img_ptr->uStride; + pu8Crr2 = pu8Crr1 + i_img_ptr->uStride; for (col=0; col < (((codx)>>1)); col++) { @@ -290,8 +290,8 @@ VT_resizeFrame_Video_opt2_lp ptr8Cb++; ptr8Cr++; } - ptr8Cb = ptr8Cb + (STRIDE-codx); - ptr8Cr = ptr8Cr + (STRIDE-codx); + ptr8Cb = ptr8Cb + (o_img_ptr->uStride-codx); + ptr8Cr = ptr8Cr + (o_img_ptr->uStride-codx); } ///////////////////For Cb- Cr//////////////////////////////////////// } diff --git a/camera/OMXCameraAdapter/OMXExif.cpp b/camera/OMXCameraAdapter/OMXExif.cpp index af50a39..e13d145 100644..100755 --- a/camera/OMXCameraAdapter/OMXExif.cpp +++ b/camera/OMXCameraAdapter/OMXExif.cpp @@ -580,13 +580,13 @@ status_t OMXCameraAdapter::setupEXIF_libjpeg(ExifElementsTable* exifTable) if ((NO_ERROR == ret)) { char temp_value[5]; - snprintf(temp_value, sizeof(temp_value)/sizeof(char) - 1, "%lu", capData->mWidth); + snprintf(temp_value, sizeof(temp_value)/sizeof(char), "%lu", capData->mWidth); ret = exifTable->insertElement(TAG_IMAGE_WIDTH, temp_value); } if ((NO_ERROR == ret)) { char temp_value[5]; - snprintf(temp_value, sizeof(temp_value)/sizeof(char) - 1, "%lu", capData->mHeight); + snprintf(temp_value, sizeof(temp_value)/sizeof(char), "%lu", capData->mHeight); ret = exifTable->insertElement(TAG_IMAGE_LENGTH, temp_value); } diff --git a/camera/inc/CameraHal.h b/camera/inc/CameraHal.h index 07f084f..3ca9ed7 100644 --- a/camera/inc/CameraHal.h +++ b/camera/inc/CameraHal.h @@ -574,7 +574,7 @@ public: status_t useMetaDataBufferMode(bool enable); - void EncoderDoneCb(size_t jpeg_size, uint8_t* src, CameraFrame::FrameType type, void* cookie1, void* cookie2); + void EncoderDoneCb(void*, void*, CameraFrame::FrameType type, void* cookie1, void* cookie2); void useVideoBuffers(bool useVideoBuffers); diff --git a/camera/inc/Encoder_libjpeg.h b/camera/inc/Encoder_libjpeg.h index 8aaae02..62c534a 100644..100755 --- a/camera/inc/Encoder_libjpeg.h +++ b/camera/inc/Encoder_libjpeg.h @@ -37,9 +37,8 @@ namespace android { */ #define MAX_EXIF_TAGS_SUPPORTED 30 - -typedef void (*encoder_libjpeg_callback_t) (size_t jpeg_size, - uint8_t* src, +typedef void (*encoder_libjpeg_callback_t) (void* main_jpeg, + void* thumb_jpeg, CameraFrame::FrameType type, void* cookie1, void* cookie2, @@ -73,6 +72,7 @@ class ExifElementsTable { status_t insertElement(const char* tag, const char* value); void insertExifToJpeg(unsigned char* jpeg, size_t jpeg_size); + status_t insertExifThumbnailImage(const char*, int); void saveJpeg(unsigned char* picture, size_t jpeg_size); static const char* degreesToExifOrientation(const char*); private: @@ -84,22 +84,32 @@ class ExifElementsTable { }; class Encoder_libjpeg : public Thread { + /* public member types and variables */ + public: + struct params { + uint8_t* src; + int src_size; + uint8_t* dst; + int dst_size; + int quality; + int in_width; + int in_height; + int out_width; + int out_height; + const char* format; + size_t jpeg_size; + }; + /* public member functions */ public: - Encoder_libjpeg(uint8_t* src, - int src_size, - uint8_t* dst, - int dst_size, - int quality, - int width, - int height, - encoder_libjpeg_callback_t cb, - CameraFrame::FrameType type, - void* cookie1, - void* cookie2, - void* cookie3) - : Thread(false), mSrc(src), mDest(dst), mSrcSize(src_size), mDestSize(dst_size), - mQuality(quality), mWidth(width), mHeight(height), mCb(cb), mCookie1(cookie1), - mCookie2(cookie2), mCookie3(cookie3), mType(type) { + Encoder_libjpeg(params* main_jpeg, + params* tn_jpeg, + encoder_libjpeg_callback_t cb, + CameraFrame::FrameType type, + void* cookie1, + void* cookie2, + void* cookie3) + : Thread(false), mMainInput(main_jpeg), mThumbnailInput(tn_jpeg), mCb(cb), + mCookie1(cookie1), mCookie2(cookie2), mCookie3(cookie3), mType(type) { this->incStrong(this); } @@ -107,25 +117,41 @@ class Encoder_libjpeg : public Thread { } virtual bool threadLoop() { - size_t size = encode(); - mCb(size, mSrc, mType, mCookie1, mCookie2, mCookie3); + size_t size = 0; + sp<Encoder_libjpeg> tn = NULL; + if (mThumbnailInput) { + // start thread to encode thumbnail + tn = new Encoder_libjpeg(mThumbnailInput, NULL, NULL, mType, NULL, NULL, NULL); + tn->run(); + } + + // encode our main image + size = encode(mMainInput); + + // check if it is main jpeg thread + if(tn.get()) { + // wait until tn jpeg thread exits. + tn->join(); + tn.clear(); + if(mCb) { + mCb(mMainInput, mThumbnailInput, mType, mCookie1, mCookie2, mCookie3); + } + } // encoder thread runs, self-destructs, and then exits this->decStrong(this); return false; } private: - uint8_t* mSrc; - uint8_t* mDest; - int mSrcSize, mDestSize; - int mQuality, mWidth, mHeight; + params* mMainInput; + params* mThumbnailInput; encoder_libjpeg_callback_t mCb; void* mCookie1; void* mCookie2; void* mCookie3; CameraFrame::FrameType mType; - size_t encode(); + size_t encode(params*); }; } diff --git a/camera/inc/NV12_resize.h b/camera/inc/NV12_resize.h index 64afcea..927faf8 100644 --- a/camera/inc/NV12_resize.h +++ b/camera/inc/NV12_resize.h @@ -103,6 +103,7 @@ typedef struct { mmInt32 uWidth; mmInt32 uHeight; + mmInt32 uStride; enumImageFormat eFormat; mmByte *imgPtr; mmByte *clrPtr; |