diff options
author | Tyler Luu <tluu@ti.com> | 2011-08-31 21:12:17 -0500 |
---|---|---|
committer | Iliyan Malchev <malchev@google.com> | 2011-09-02 14:49:15 -0700 |
commit | ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cf (patch) | |
tree | 415e047ef28613e12c264f48cbc1e76f2183b7fa /camera | |
parent | bc0e345c35480fb8036a766f47a7ed65e98947c5 (diff) | |
download | hardware_ti_omap4xxx-ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cf.zip hardware_ti_omap4xxx-ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cf.tar.gz hardware_ti_omap4xxx-ee6bb64f60c228d711dc1d6875d8f4b0ed88b6cf.tar.bz2 |
CameraHal: Initial support for video snapshot
Adds support for capturing an image while
recording in video mode. Sets up Ducati to
return a YUV422I buffer and encode is performed
in AppCallbackNotifier with Encoder_libjpeg class.
Change-Id: Ia351fc99dab63a12add8c6c960b186bbe5be275a
Signed-off-by: Tyler Luu <tluu@ti.com>
Diffstat (limited to 'camera')
-rw-r--r-- | camera/Android.mk | 5 | ||||
-rw-r--r-- | camera/AppCallbackNotifier.cpp | 125 | ||||
-rw-r--r-- | camera/BaseCameraAdapter.cpp | 53 | ||||
-rw-r--r-- | camera/CameraHal.cpp | 50 | ||||
-rw-r--r-- | camera/Encoder_libjpeg.cpp | 158 | ||||
-rw-r--r-- | camera/OMXCameraAdapter/OMXCameraAdapter.cpp | 24 | ||||
-rw-r--r-- | camera/OMXCameraAdapter/OMXCapture.cpp | 39 | ||||
-rw-r--r-- | camera/inc/CameraHal.h | 20 | ||||
-rw-r--r-- | camera/inc/Encoder_libjpeg.h | 90 |
9 files changed, 523 insertions, 41 deletions
diff --git a/camera/Android.mk b/camera/Android.mk index 948c33c..21209d1 100644 --- a/camera/Android.mk +++ b/camera/Android.mk @@ -13,6 +13,7 @@ OMAP4_CAMERA_HAL_SRC := \ ANativeWindowDisplayAdapter.cpp \ CameraProperties.cpp \ MemoryManager.cpp \ + Encoder_libjpeg.cpp \ SensorListener.cpp OMAP4_CAMERA_COMMON_SRC:= \ @@ -63,7 +64,8 @@ LOCAL_C_INCLUDES += \ hardware/ti/omap4xxx/domx/omx_core/inc \ hardware/ti/omap4xxx/domx/mm_osal/inc \ frameworks/base/include/media/stagefright \ - frameworks/base/include/media/stagefright/openmax + frameworks/base/include/media/stagefright/openmax \ + external/jpeg LOCAL_SHARED_LIBRARIES:= \ libui \ @@ -78,6 +80,7 @@ LOCAL_SHARED_LIBRARIES:= \ libgui \ libdomx \ libion \ + libjpeg LOCAL_CFLAGS := -fno-short-enums -DCOPY_IMAGE_BUFFER diff --git a/camera/AppCallbackNotifier.cpp b/camera/AppCallbackNotifier.cpp index c209612..e6b112a 100644 --- a/camera/AppCallbackNotifier.cpp +++ b/camera/AppCallbackNotifier.cpp @@ -22,6 +22,7 @@ #include "CameraHal.h" #include "VideoMetadata.h" +#include "Encoder_libjpeg.h" #include <MetadataBufferType.h> #include <ui/GraphicBuffer.h> #include <ui/GraphicBufferMapper.h> @@ -31,13 +32,72 @@ namespace android { const int AppCallbackNotifier::NOTIFIER_TIMEOUT = -1; +void AppCallbackNotifierEncoderCallback(size_t jpeg_size, + uint8_t* src, + CameraFrame::FrameType type, + void* cookie1, + void* cookie2, + void* cookie3) +{ + if (cookie1) { + AppCallbackNotifier* cb = (AppCallbackNotifier*) cookie1; + cb->EncoderDoneCb(jpeg_size, src, type, cookie2); + } +} + /*--------------------NotificationHandler Class STARTS here-----------------------------*/ +void AppCallbackNotifier::EncoderDoneCb(size_t jpeg_size, uint8_t* src, CameraFrame::FrameType type, void* cookie1) +{ + camera_memory_t* encoded_mem = NULL; + + LOG_FUNCTION_NAME; + + Mutex::Autolock lock(mLock); + + encoded_mem = (camera_memory_t*) cookie1; + + // 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? + + camera_memory_t* picture = mRequestMemory(-1, jpeg_size, 1, NULL); + + if(picture && picture->data && encoded_mem && encoded_mem->data) { + memcpy(picture->data, encoded_mem->data, jpeg_size); + } + + { + Mutex::Autolock lock(mBurstLock); +#if 0 //TODO: enable burst mode later + if ( mBurst ) + { + `(CAMERA_MSG_BURST_IMAGE, JPEGPictureMemBase, mCallbackCookie); + } + else +#endif + { + mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, picture, 0, NULL, mCallbackCookie); + } + } + + if (encoded_mem) { + encoded_mem->release(encoded_mem); + } + + if (picture) { + picture->release(picture); + } + + mFrameProvider->returnFrame(src, type); + + LOG_FUNCTION_NAME_EXIT; +} + /** * NotificationHandler class */ - ///Initialization function for AppCallbackNotifier status_t AppCallbackNotifier::initialize() { @@ -573,6 +633,59 @@ void AppCallbackNotifier::notifyFrame() } } + else if ( (CameraFrame::IMAGE_FRAME == frame->mFrameType) && + (NULL != mCameraHal) && + (NULL != mDataCb) && + (CameraFrame::ENCODE_RAW_YUV422I_TO_JPEG & frame->mQuirks) ) + { + Mutex::Autolock lock(mLock); + + int encode_quality = 100; + const char* valstr = NULL; + camera_memory_t* raw_picture = mRequestMemory(-1, frame->mLength, 1, NULL); + + if(raw_picture) { + 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; + } + } + + CAMHAL_LOGVB("encoder(%p, %d, %p, %d, %d, %d, %d,%p,%d,%p,%p, %d)", + (uint8_t*)frame->mBuffer, + frame->mLength, + (uint8_t*)buf, + frame->mLength, + encode_quality, + frame->mWidth, + frame->mHeight, + AppCallbackNotifierEncoderCallback, + frame->mFrameType, + this, + raw_picture, + NULL); + + 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, + NULL); + encoder->run(); + encoder.clear(); + + } else if ( ( CameraFrame::IMAGE_FRAME == frame->mFrameType ) && ( NULL != mCameraHal ) && ( NULL != mDataCb) ) @@ -1133,6 +1246,16 @@ void AppCallbackNotifier::setBurst(bool burst) LOG_FUNCTION_NAME_EXIT; } +int AppCallbackNotifier::setParameters(const CameraParameters& params) +{ + LOG_FUNCTION_NAME; + + mParameters = params + + LOG_FUNCTION_NAME_EXIT; + return NO_ERROR; +} + status_t AppCallbackNotifier::stopPreviewCallbacks() { sp<MemoryHeapBase> heap; diff --git a/camera/BaseCameraAdapter.cpp b/camera/BaseCameraAdapter.cpp index cd20346..ec149bf 100644 --- a/camera/BaseCameraAdapter.cpp +++ b/camera/BaseCameraAdapter.cpp @@ -1786,6 +1786,18 @@ status_t BaseCameraAdapter::setState(CameraCommands operation) mNextState = VIDEO_ZOOM_STATE; break; + case CAMERA_USE_BUFFERS_IMAGE_CAPTURE: + CAMHAL_LOGDB("Adapter state switch VIDEO_STATE->VIDEO_LOADED_CAPTURE_STATE event = 0x%x", + operation); + mNextState = VIDEO_LOADED_CAPTURE_STATE; + break; + + case CAMERA_QUERY_BUFFER_SIZE_IMAGE_CAPTURE: + CAMHAL_LOGDB("Adapter state switch VIDEO_STATE->VIDEO_STATE event = 0x%x", + operation); + mNextState = VIDEO_STATE; + break; + default: CAMHAL_LOGEB("Adapter state switch VIDEO_STATE Invalid Op! event = 0x%x", operation); @@ -1796,6 +1808,47 @@ status_t BaseCameraAdapter::setState(CameraCommands operation) break; + case VIDEO_LOADED_CAPTURE_STATE: + + switch ( operation ) + { + + case CAMERA_START_IMAGE_CAPTURE: + CAMHAL_LOGDB("Adapter state switch LOADED_CAPTURE_STATE->CAPTURE_STATE event = 0x%x", + operation); + mNextState = VIDEO_CAPTURE_STATE; + break; + + default: + CAMHAL_LOGEB("Adapter state switch LOADED_CAPTURE_STATE Invalid Op! event = 0x%x", + operation); + ret = INVALID_OPERATION; + break; + + } + + break; + + case VIDEO_CAPTURE_STATE: + + switch ( operation ) + { + case CAMERA_STOP_IMAGE_CAPTURE: + CAMHAL_LOGDB("Adapter state switch CAPTURE_STATE->PREVIEW_STATE event = 0x%x", + operation); + mNextState = VIDEO_STATE; + break; + + default: + CAMHAL_LOGEB("Adapter state switch CAPTURE_STATE Invalid Op! event = 0x%x", + operation); + ret = INVALID_OPERATION; + break; + + } + + break; + case AF_ZOOM_STATE: switch ( operation ) diff --git a/camera/CameraHal.cpp b/camera/CameraHal.cpp index 4830ebf..c770b7a 100644 --- a/camera/CameraHal.cpp +++ b/camera/CameraHal.cpp @@ -2224,6 +2224,7 @@ status_t CameraHal::takePicture( ) CameraFrame frame; CameraAdapter::BuffersDescriptor desc; int burst; + const char *valstr = NULL; unsigned int bufferCount = 1; Mutex::Autolock lock(mLock); @@ -2239,15 +2240,27 @@ status_t CameraHal::takePicture( ) if(!previewEnabled() && !mDisplayPaused) { LOG_FUNCTION_NAME_EXIT; + CAMHAL_LOGEA("Preview not started..."); return NO_INIT; } - //If capture has already started, then queue this call for later execution - if ( mCameraAdapter->getState() == CameraAdapter::CAPTURE_STATE && - mCameraAdapter->getNextState() != CameraAdapter::PREVIEW_STATE) { + // return error if we are already capturing + if ( (mCameraAdapter->getState() == CameraAdapter::CAPTURE_STATE && + mCameraAdapter->getNextState() != CameraAdapter::PREVIEW_STATE) || + (mCameraAdapter->getState() == CameraAdapter::VIDEO_CAPTURE_STATE && + mCameraAdapter->getNextState() != CameraAdapter::VIDEO_STATE) ) { + CAMHAL_LOGEA("Already capturing an image..."); return NO_INIT; } + // we only support video snapshot if we are in video mode (recording hint is set) + valstr = mParameters.get(TICameraParameters::KEY_CAP_MODE); + if ( (mCameraAdapter->getState() == CameraAdapter::VIDEO_STATE) && + (valstr && strcmp(valstr, TICameraParameters::VIDEO_MODE)) ) { + CAMHAL_LOGEA("Trying to capture while recording without recording hint set..."); + return INVALID_OPERATION; + } + if ( !mBracketingRunning ) { @@ -2273,26 +2286,27 @@ status_t CameraHal::takePicture( ) } } - //Pause Preview during capture - if ( (NO_ERROR == ret) && ( NULL != mDisplayAdapter.get() ) && ( burst < 1 ) ) - { - mDisplayPaused = true; - mPreviewEnabled = false; - ret = mDisplayAdapter->pauseDisplay(mDisplayPaused); + // pause preview during normal image capture + // do not pause preview if recording (video state) + if (NO_ERROR == ret && + NULL != mDisplayAdapter.get() && + burst < 1) { + if (mCameraAdapter->getState() != CameraAdapter::VIDEO_STATE) { + mDisplayPaused = true; + mPreviewEnabled = false; + ret = mDisplayAdapter->pauseDisplay(mDisplayPaused); + // since preview is paused we should stop sending preview frames too + if(mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) { + mAppCallbackNotifier->disableMsgType (CAMERA_MSG_PREVIEW_FRAME); + } + } #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS - mDisplayAdapter->setSnapshotTimeRef(&mStartCapture); - #endif - // since preview is paused we should stop sending preview frames too - if(mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) - { - mAppCallbackNotifier->disableMsgType (CAMERA_MSG_PREVIEW_FRAME); - } - } + } - if ( (NO_ERROR == ret) && ( NULL != mCameraAdapter ) ) + if ( (NO_ERROR == ret) && (NULL != mCameraAdapter) ) { if ( NO_ERROR == ret ) ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_QUERY_BUFFER_SIZE_IMAGE_CAPTURE, diff --git a/camera/Encoder_libjpeg.cpp b/camera/Encoder_libjpeg.cpp new file mode 100644 index 0000000..dfdd934 --- /dev/null +++ b/camera/Encoder_libjpeg.cpp @@ -0,0 +1,158 @@ +/* + * Copyright (C) Texas Instruments - http://www.ti.com/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file Encoder_libjpeg.cpp +* +* This file encodes a YUV422I buffer to a jpeg +* TODO(XXX): Need to support formats other than yuv422i +* Change interface to pre/post-proc algo framework +* +*/ + +#define LOG_TAG "CameraHAL" + +#include "CameraHal.h" +#include "Encoder_libjpeg.h" + +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdio.h> +#include <errno.h> + +extern "C" { + #include "jpeglib.h" + #include "jerror.h" +} + +namespace android { + +struct libjpeg_destination_mgr : jpeg_destination_mgr { + libjpeg_destination_mgr(uint8_t* input, int size); + + uint8_t* buf; + int bufsize; + size_t jpegsize; +}; + +static void libjpeg_init_destination (j_compress_ptr cinfo) { + libjpeg_destination_mgr* dest = (libjpeg_destination_mgr*)cinfo->dest; + + dest->next_output_byte = dest->buf; + dest->free_in_buffer = dest->bufsize; + dest->jpegsize = 0; +} + +static boolean libjpeg_empty_output_buffer(j_compress_ptr cinfo) { + libjpeg_destination_mgr* dest = (libjpeg_destination_mgr*)cinfo->dest; + + dest->next_output_byte = dest->buf; + dest->free_in_buffer = dest->bufsize; + return TRUE; // ? +} + +static void libjpeg_term_destination (j_compress_ptr cinfo) { + libjpeg_destination_mgr* dest = (libjpeg_destination_mgr*)cinfo->dest; + dest->jpegsize = dest->bufsize - dest->free_in_buffer; +} + +libjpeg_destination_mgr::libjpeg_destination_mgr(uint8_t* input, int size) { + this->init_destination = libjpeg_init_destination; + this->empty_output_buffer = libjpeg_empty_output_buffer; + this->term_destination = libjpeg_term_destination; + + this->buf = input; + this->bufsize = size; +} + +/* private static functions */ + +static void uyvy_to_yuv(uint8_t* dst, uint32_t* src, int width) { + // TODO(XXX): optimize later + while ((width-=2) >= 0) { + uint8_t u0 = (src[0] >> 0) & 0xFF; + uint8_t y0 = (src[0] >> 8) & 0xFF; + uint8_t v0 = (src[0] >> 16) & 0xFF; + uint8_t y1 = (src[0] >> 24) & 0xFF; + dst[0] = y0; + dst[1] = u0; + dst[2] = v0; + dst[3] = y1; + dst[4] = u0; + dst[5] = v0; + dst += 6; + src++; + } +} + +/* private member functions */ +size_t Encoder_libjpeg::encode() { + jpeg_compress_struct cinfo; + jpeg_error_mgr jerr; + jpeg_destination_mgr jdest; + uint8_t* row_tmp = NULL; + uint8_t* row_src = NULL; + int bpp = 2; // TODO(XXX): hardcoded for uyvy + + 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); + + cinfo.dest = &dest_mgr; + cinfo.image_width = mWidth; + cinfo.image_height = mHeight; + cinfo.input_components = 3; + cinfo.in_color_space = JCS_YCbCr; + cinfo.input_gamma = 1; + + jpeg_set_defaults(&cinfo); + jpeg_set_quality(&cinfo, mQuality, TRUE); + cinfo.dct_method = JDCT_IFAST; + + jpeg_start_compress(&cinfo, TRUE); + + row_tmp = (uint8_t*)malloc(mWidth * 3); + row_src = mSrc; + + 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); + row[0] = row_tmp; + jpeg_write_scanlines(&cinfo, row, 1); + row_src = row_src + mWidth*bpp; + } + + jpeg_finish_compress(&cinfo); + jpeg_destroy_compress(&cinfo); + + return dest_mgr.jpegsize; +} + +} // namespace android diff --git a/camera/OMXCameraAdapter/OMXCameraAdapter.cpp b/camera/OMXCameraAdapter/OMXCameraAdapter.cpp index 9bd3643..6211c51 100644 --- a/camera/OMXCameraAdapter/OMXCameraAdapter.cpp +++ b/camera/OMXCameraAdapter/OMXCameraAdapter.cpp @@ -2712,7 +2712,7 @@ OMX_ERRORTYPE OMXCameraAdapter::OMXCameraAdapterFillBufferDone(OMX_IN OMX_HANDLE pPortParam); } - if( mWaitingForSnapshot ) + if( mWaitingForSnapshot && (mCapturedFrames > 0) ) { typeOfFrame = CameraFrame::SNAPSHOT_FRAME; } @@ -2739,8 +2739,8 @@ OMX_ERRORTYPE OMXCameraAdapter::OMXCameraAdapterFillBufferDone(OMX_IN OMX_HANDLE { mSnapshotCount++; - if ( ( mSnapshotCount == 1 ) && - ( HIGH_SPEED == mCapMode ) ) + if ( (mSnapshotCount == 1) && + ((HIGH_SPEED == mCapMode) || (VIDEO_MODE == mCapMode)) ) { notifyShutterSubscribers(); } @@ -2763,11 +2763,26 @@ OMX_ERRORTYPE OMXCameraAdapter::OMXCameraAdapterFillBufferDone(OMX_IN OMX_HANDLE } else if( pBuffHeader->nOutputPortIndex == OMX_CAMERA_PORT_IMAGE_OUT_IMAGE ) { + CameraFrame cameraFrame; + OMX_COLOR_FORMATTYPE pixFormat; + const char *valstr = NULL; - if ( OMX_COLOR_FormatUnused == mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex].mColorFormat ) + pixFormat = mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex].mColorFormat; + valstr = mParams.getPictureFormat(); + + if ( OMX_COLOR_FormatUnused == pixFormat ) { typeOfFrame = CameraFrame::IMAGE_FRAME; } + else if ( pixFormat == OMX_COLOR_FormatCbYCrY && + ((valstr && !strcmp(valstr, CameraParameters::PIXEL_FORMAT_JPEG)) || + !valstr) ) + { + // signals to callbacks that this needs to be coverted to jpeg + // before returning to framework + typeOfFrame = CameraFrame::IMAGE_FRAME; + cameraFrame.mQuirks |= CameraFrame::ENCODE_RAW_YUV422I_TO_JPEG; + } else { typeOfFrame = CameraFrame::RAW_FRAME; @@ -2804,7 +2819,6 @@ OMX_ERRORTYPE OMXCameraAdapter::OMXCameraAdapterFillBufferDone(OMX_IN OMX_HANDLE mCapturedFrames--; - CameraFrame cameraFrame; stat |= initCameraFrame(cameraFrame, pBuffHeader, typeOfFrame, diff --git a/camera/OMXCameraAdapter/OMXCapture.cpp b/camera/OMXCameraAdapter/OMXCapture.cpp index f6e26c9..6bec221 100644 --- a/camera/OMXCameraAdapter/OMXCapture.cpp +++ b/camera/OMXCameraAdapter/OMXCapture.cpp @@ -125,6 +125,16 @@ status_t OMXCameraAdapter::setParametersCapture(const CameraParameters ¶ms, pixFormat = OMX_COLOR_FormatUnused; } + // JPEG capture is not supported in video mode by OMX Camera + // Set capture format to yuv422i...jpeg encode will + // be done on A9 + valstr = params.get(TICameraParameters::KEY_CAP_MODE); + if ( (valstr && !strcmp(valstr, (const char *) TICameraParameters::VIDEO_MODE)) && + (pixFormat == OMX_COLOR_FormatUnused) ) { + CAMHAL_LOGDA("Capturing in video mode...selecting yuv422i"); + pixFormat = OMX_COLOR_FormatCbYCrY; + } + if ( pixFormat != cap->mColorFormat ) { updateImagePortParams = true; @@ -746,37 +756,38 @@ status_t OMXCameraAdapter::startImageCapture() } - if ( NO_ERROR == ret ) - { + if ( NO_ERROR == ret ) { capData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex]; ///Queue all the buffers on capture port - for ( int index = 0 ; index < capData->mNumBufs ; index++ ) - { + for ( int index = 0 ; index < capData->mNumBufs ; index++ ) { CAMHAL_LOGDB("Queuing buffer on Capture port - 0x%x", ( unsigned int ) capData->mBufferHeader[index]->pBuffer); eError = OMX_FillThisBuffer(mCameraAdapterParameters.mHandleComp, (OMX_BUFFERHEADERTYPE*)capData->mBufferHeader[index]); GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); - } + } mWaitingForSnapshot = true; mCaptureSignalled = false; - OMX_INIT_STRUCT_PTR (&bOMX, OMX_CONFIG_BOOLEANTYPE); - bOMX.bEnabled = OMX_TRUE; - - /// sending Capturing Command to the component - eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, - OMX_IndexConfigCapturing, - &bOMX); + // Capturing command is not needed when capturing in video mode + // Only need to queue buffers on image ports + if (mCapMode != VIDEO_MODE) { + OMX_INIT_STRUCT_PTR (&bOMX, OMX_CONFIG_BOOLEANTYPE); + bOMX.bEnabled = OMX_TRUE; - CAMHAL_LOGDB("Capture set - 0x%x", eError); + /// sending Capturing Command to the component + eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, + OMX_IndexConfigCapturing, + &bOMX); - GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); + CAMHAL_LOGDB("Capture set - 0x%x", eError); + GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); } + } //OMX shutter callback events are only available in hq mode if ( (HIGH_QUALITY == mCapMode) || (HIGH_QUALITY_ZSL== mCapMode)) diff --git a/camera/inc/CameraHal.h b/camera/inc/CameraHal.h index 8c09701..475f7fa 100644 --- a/camera/inc/CameraHal.h +++ b/camera/inc/CameraHal.h @@ -229,6 +229,11 @@ class CameraFrame ALL_FRAMES = 0xFFFF ///Maximum of 16 frame types supported }; + enum FrameQuirks + { + ENCODE_RAW_YUV422I_TO_JPEG = 0x1 << 0, + }; + //default contrustor CameraFrame(): mCookie(NULL), @@ -240,7 +245,8 @@ class CameraFrame mOffset(0), mAlignment(0), mFd(0), - mLength(0) {} + mLength(0), + mQuirks(0) {} //copy constructor CameraFrame(const CameraFrame &frame) : @@ -253,7 +259,8 @@ class CameraFrame mOffset(frame.mOffset), mAlignment(frame.mAlignment), mFd(frame.mFd), - mLength(frame.mLength) {} + mLength(frame.mLength), + mQuirks(frame.mQuirks) {} void *mCookie; void *mBuffer; @@ -264,6 +271,7 @@ class CameraFrame unsigned int mAlignment; int mFd; size_t mLength; + unsigned int mQuirks; ///@todo add other member vars like stride etc }; @@ -516,6 +524,8 @@ public: //Set Burst mode void setBurst(bool burst); + int setParameters(const CameraParameters& params); + //Notifications from CameraHal for video recording case status_t startRecording(); status_t stopRecording(); @@ -524,6 +534,8 @@ public: status_t useMetaDataBufferMode(bool enable); + void EncoderDoneCb(size_t jpeg_size, uint8_t* src, CameraFrame::FrameType type, void* cookie1); + //Internal class definitions class NotificationThread : public Thread { AppCallbackNotifier* mAppCallbackNotifier; @@ -600,6 +612,8 @@ private: bool mUseMetaDataBufferMode; + CameraParameters mParameters; + }; @@ -709,6 +723,8 @@ public: ZOOM_STATE = ZOOM_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE, VIDEO_STATE = VIDEO_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE, VIDEO_ZOOM_STATE = VIDEO_ACTIVE | ZOOM_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE, + VIDEO_LOADED_CAPTURE_STATE = VIDEO_ACTIVE | LOADED_CAPTURE_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE, + VIDEO_CAPTURE_STATE = VIDEO_ACTIVE | CAPTURE_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE, AF_ZOOM_STATE = AF_ACTIVE | ZOOM_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE, BRACKETING_ZOOM_STATE = BRACKETING_ACTIVE | ZOOM_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE, }; diff --git a/camera/inc/Encoder_libjpeg.h b/camera/inc/Encoder_libjpeg.h new file mode 100644 index 0000000..24ce672 --- /dev/null +++ b/camera/inc/Encoder_libjpeg.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) Texas Instruments - http://www.ti.com/ + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file Encoder_libjpeg.h +* +* This defines API for camerahal to encode YUV using libjpeg +* +*/ + +#ifndef ANDROID_CAMERA_HARDWARE_ENCODER_LIBJPEG_H +#define ANDROID_CAMERA_HARDWARE_ENCODER_LIBJPEG_H + +#include <utils/threads.h> +#include <utils/RefBase.h> + +namespace android { + +/** + * libjpeg encoder class - uses libjpeg to encode yuv + */ + +typedef void (*encoder_libjpeg_callback_t) (size_t jpeg_size, + uint8_t* src, + CameraFrame::FrameType type, + void* cookie1, + void* cookie2, + void* cookie3); + +class Encoder_libjpeg : public Thread { + 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) { + this->incStrong(this); + } + + ~Encoder_libjpeg() { + } + + virtual bool threadLoop() { + size_t size = encode(); + mCb(size, mSrc, 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; + encoder_libjpeg_callback_t mCb; + void* mCookie1; + void* mCookie2; + void* mCookie3; + CameraFrame::FrameType mType; + + size_t encode(); +}; + +} + +#endif |