diff options
author | Tyler Luu <tluu@ti.com> | 2012-03-26 19:09:14 -0500 |
---|---|---|
committer | Daniel Levin <dendy@ti.com> | 2012-07-25 08:55:45 -0500 |
commit | f1582e6e9dc33bf5cd13c24e0e755edbaaec9868 (patch) | |
tree | a79a61495588d03156f697b9160c21206ad4d3b8 | |
parent | 69a4da08343fcf51fb3181422c84f9bb2af8dfe6 (diff) | |
download | hardware_ti_omap4-f1582e6e9dc33bf5cd13c24e0e755edbaaec9868.tar.gz hardware_ti_omap4-f1582e6e9dc33bf5cd13c24e0e755edbaaec9868.tar.bz2 hardware_ti_omap4-f1582e6e9dc33bf5cd13c24e0e755edbaaec9868.zip |
camera: add reprocess() functionality
implementation for reprocess
state change sequence should look like this:
preview->loaded_reprocess->loaded_reprocess_capture->
reprocess
Reprocess uses takePicture call to send output buffers
to camera adapter and to signal start reprocess.
Change-Id: I98a7ccd32778760603e9c367ab3cd4ef30fab8dc
Signed-off-by: Tyler Luu <tluu@ti.com>
-rw-r--r-- | camera/Android.mk | 1 | ||||
-rw-r--r-- | camera/AppCallbackNotifier.cpp | 2 | ||||
-rw-r--r-- | camera/BaseCameraAdapter.cpp | 149 | ||||
-rw-r--r-- | camera/BufferSourceAdapter.cpp | 4 | ||||
-rw-r--r-- | camera/CameraHal.cpp | 92 | ||||
-rw-r--r-- | camera/CameraHal_Module.cpp | 36 | ||||
-rw-r--r-- | camera/OMXCameraAdapter/OMXCameraAdapter.cpp | 67 | ||||
-rw-r--r-- | camera/OMXCameraAdapter/OMXCapture.cpp | 86 | ||||
-rw-r--r-- | camera/OMXCameraAdapter/OMXReprocess.cpp | 325 | ||||
-rw-r--r-- | camera/inc/BaseCameraAdapter.h | 6 | ||||
-rw-r--r-- | camera/inc/CameraHal.h | 71 | ||||
-rw-r--r-- | camera/inc/OMXCameraAdapter/OMXCameraAdapter.h | 20 |
12 files changed, 802 insertions, 57 deletions
diff --git a/camera/Android.mk b/camera/Android.mk index 68e30f0..48bdf48 100644 --- a/camera/Android.mk +++ b/camera/Android.mk @@ -59,6 +59,7 @@ OMAP4_CAMERA_OMX_SRC:= \ OMXCameraAdapter/OMXCameraAdapter.cpp \ OMXCameraAdapter/OMXCapabilities.cpp \ OMXCameraAdapter/OMXCapture.cpp \ + OMXCameraAdapter/OMXReprocess.cpp \ OMXCameraAdapter/OMXDefaults.cpp \ OMXCameraAdapter/OMXExif.cpp \ OMXCameraAdapter/OMXFD.cpp \ diff --git a/camera/AppCallbackNotifier.cpp b/camera/AppCallbackNotifier.cpp index 3b9c63f..28cac05 100644 --- a/camera/AppCallbackNotifier.cpp +++ b/camera/AppCallbackNotifier.cpp @@ -619,7 +619,7 @@ void AppCallbackNotifier::copyAndSendPictureFrame(CameraFrame* frame, int32_t ms void *dest = NULL, *src = NULL; // scope for lock - { + if (mCameraHal->msgTypeEnabled(msgType)) { Mutex::Autolock lock(mLock); if(mNotifierState != AppCallbackNotifier::NOTIFIER_STARTED) { diff --git a/camera/BaseCameraAdapter.cpp b/camera/BaseCameraAdapter.cpp index fe4e9b2..05a32c4 100644 --- a/camera/BaseCameraAdapter.cpp +++ b/camera/BaseCameraAdapter.cpp @@ -46,7 +46,9 @@ const LUT cameraCommandsUserToHAL[] = { { "CAMERA_START_FD", CameraAdapter::CAMERA_START_FD }, { "CAMERA_STOP_FD", CameraAdapter::CAMERA_STOP_FD }, { "CAMERA_SWITCH_TO_EXECUTING", CameraAdapter::CAMERA_SWITCH_TO_EXECUTING }, - { "CAMERA_USE_BUFFERS_VIDEO_CAPTURE", CameraAdapter::CAMERA_USE_BUFFERS_VIDEO_CAPTURE } + { "CAMERA_USE_BUFFERS_VIDEO_CAPTURE", CameraAdapter::CAMERA_USE_BUFFERS_VIDEO_CAPTURE }, + { "CAMERA_USE_BUFFERS_REPROCESS", CameraAdapter::CAMERA_USE_BUFFERS_REPROCESS }, + { "CAMERA_START_REPROCESS", CameraAdapter::CAMERA_START_REPROCESS } }; const LUTtypeHAL CamCommandsLUT = @@ -103,6 +105,7 @@ BaseCameraAdapter::~BaseCameraAdapter() mImageSubscribers.clear(); mRawSubscribers.clear(); mVideoSubscribers.clear(); + mVideoInSubscribers.clear(); mFocusSubscribers.clear(); mShutterSubscribers.clear(); mZoomSubscribers.clear(); @@ -190,6 +193,9 @@ void BaseCameraAdapter::enableMsgType(int32_t msgs, frame_callback callback, eve case CameraFrame::VIDEO_FRAME_SYNC: mVideoSubscribers.add((int) cookie, callback); break; + case CameraFrame::REPROCESS_INPUT_FRAME: + mVideoInSubscribers.add((int) cookie, callback); + break; default: CAMHAL_LOGEA("Frame message type id=0x%x subscription no supported yet!", frameMsg); break; @@ -244,12 +250,16 @@ void BaseCameraAdapter::disableMsgType(int32_t msgs, void* cookie) case CameraFrame::VIDEO_FRAME_SYNC: mVideoSubscribers.removeItem((int) cookie); break; + case CameraFrame::REPROCESS_INPUT_FRAME: + mVideoInSubscribers.removeItem((int) cookie); + break; case CameraFrame::ALL_FRAMES: mFrameSubscribers.removeItem((int) cookie); mFrameDataSubscribers.removeItem((int) cookie); mImageSubscribers.removeItem((int) cookie); mRawSubscribers.removeItem((int) cookie); mVideoSubscribers.removeItem((int) cookie); + mVideoInSubscribers.removeItem((int) cookie); break; default: CAMHAL_LOGEA("Frame message type id=0x%x subscription remove not supported yet!", frameMsg); @@ -551,6 +561,46 @@ status_t BaseCameraAdapter::sendCommand(CameraCommands operation, int value1, in break; + case CameraAdapter::CAMERA_USE_BUFFERS_REPROCESS: + CAMHAL_LOGDA("Use buffers for reprocessing"); + desc = (BuffersDescriptor *) value1; + + if (NULL == desc) { + CAMHAL_LOGEA("Invalid capture buffers!"); + return -EINVAL; + } + + if (ret == NO_ERROR) { + ret = setState(operation); + } + + if (ret == NO_ERROR) { + Mutex::Autolock lock(mVideoInBufferLock); + mVideoInBuffers = desc->mBuffers; + mVideoInBuffersAvailable.clear(); + for (uint32_t i = 0 ; i < desc->mMaxQueueable ; i++) { + mVideoInBuffersAvailable.add(&mVideoInBuffers[i], 0); + } + // initial ref count for undeqeueued buffers is 1 since buffer provider + // is still holding on to it + for ( uint32_t i = desc->mMaxQueueable ; i < desc->mCount ; i++ ) { + mVideoInBuffersAvailable.add(&mVideoInBuffers[i], 1); + } + ret = useBuffers(CameraAdapter::CAMERA_REPROCESS, + desc->mBuffers, + desc->mCount, + desc->mLength, + desc->mMaxQueueable); + } + + if ( ret == NO_ERROR ) { + ret = commitState(); + } else { + ret |= rollbackState(); + } + + break; + case CameraAdapter::CAMERA_START_SMOOTH_ZOOM: { @@ -1262,6 +1312,11 @@ status_t BaseCameraAdapter::sendFrameToSubscribers(CameraFrame *frame) ret = __sendFrameToSubscribers(frame, &mFrameDataSubscribers, CameraFrame::FRAME_DATA_SYNC); } break; + case CameraFrame::REPROCESS_INPUT_FRAME: + { + ret = __sendFrameToSubscribers(frame, &mVideoInSubscribers, CameraFrame::REPROCESS_INPUT_FRAME); + } + break; default: CAMHAL_LOGEB("FRAMETYPE NOT SUPPORTED 0x%x", mask); break; @@ -1385,6 +1440,11 @@ int BaseCameraAdapter::setInitFrameRefCount(CameraBuffer * buf, unsigned int mas setFrameRefCount(buf, CameraFrame::FRAME_DATA_SYNC, mFrameDataSubscribers.size()); } break; + case CameraFrame::REPROCESS_INPUT_FRAME: + { + setFrameRefCount(buf,CameraFrame::REPROCESS_INPUT_FRAME, mVideoInSubscribers.size()); + } + break; default: CAMHAL_LOGEB("FRAMETYPE NOT SUPPORTED 0x%x", lmask); break; @@ -1430,6 +1490,11 @@ int BaseCameraAdapter::getFrameRefCount(CameraBuffer * frameBuf, CameraFrame::Fr res = mVideoBuffersAvailable.valueFor(frameBuf ); } break; + case CameraFrame::REPROCESS_INPUT_FRAME: { + Mutex::Autolock lock(mVideoInBufferLock); + res = mVideoInBuffersAvailable.valueFor(frameBuf ); + } + break; default: break; }; @@ -1472,6 +1537,11 @@ void BaseCameraAdapter::setFrameRefCount(CameraBuffer * frameBuf, CameraFrame::F mVideoBuffersAvailable.replaceValueFor(frameBuf, refCount); } break; + case CameraFrame::REPROCESS_INPUT_FRAME: { + Mutex::Autolock lock(mVideoInBufferLock); + mVideoInBuffersAvailable.replaceValueFor(frameBuf, refCount); + } + break; default: break; }; @@ -1860,6 +1930,12 @@ status_t BaseCameraAdapter::setState(CameraCommands operation) mNextState = LOADED_CAPTURE_STATE; break; + case CAMERA_USE_BUFFERS_REPROCESS: + CAMHAL_LOGDB("Adapter state switch PREVIEW_STATE->LOADED_REPROCESS_STATE event = %s", + printState); + mNextState = LOADED_REPROCESS_STATE; + break; + case CAMERA_START_VIDEO: CAMHAL_LOGDB("Adapter state switch PREVIEW_STATE->VIDEO_STATE event = %s", printState); @@ -1884,6 +1960,42 @@ status_t BaseCameraAdapter::setState(CameraCommands operation) break; + case LOADED_REPROCESS_STATE: + switch (operation) { + case CAMERA_USE_BUFFERS_IMAGE_CAPTURE: + CAMHAL_LOGDB("Adapter state switch LOADED_REPROCESS_STATE->LOADED_REPROCESS_CAPTURE_STATE event = %s", + printState); + mNextState = LOADED_REPROCESS_CAPTURE_STATE; + break; + case CAMERA_QUERY_BUFFER_SIZE_IMAGE_CAPTURE: + CAMHAL_LOGDB("Adapter state switch LOADED_REPROCESS_STATE->LOADED_REPROCESS_STATE event = %s", + printState); + mNextState = LOADED_REPROCESS_STATE; + break; + default: + CAMHAL_LOGEB("Adapter state switch LOADED_REPROCESS_STATE Invalid Op! event = %s", + printState); + ret = INVALID_OPERATION; + break; + } + + break; + + case LOADED_REPROCESS_CAPTURE_STATE: + switch (operation) { + case CAMERA_START_IMAGE_CAPTURE: + CAMHAL_LOGDB("Adapter state switch LOADED_REPROCESS_CAPTURE_STATE->REPROCESS_STATE event = %s", + printState); + mNextState = REPROCESS_STATE; + break; + default: + CAMHAL_LOGEB("Adapter state switch LOADED_REPROCESS_CAPTURE_STATE Invalid Op! event = %s", + printState); + ret = INVALID_OPERATION; + break; + } + break; + case LOADED_CAPTURE_STATE: switch ( operation ) @@ -1923,11 +2035,17 @@ status_t BaseCameraAdapter::setState(CameraCommands operation) break; case CAMERA_START_IMAGE_CAPTURE: - CAMHAL_LOGDB("Adapter state switch CAPTURE_STATE->CAPTURE_STATE event = 0x%x", - operation); + CAMHAL_LOGDB("Adapter state switch CAPTURE_STATE->CAPTURE_STATE event = %s", + printState); mNextState = CAPTURE_STATE; break; + case CAMERA_USE_BUFFERS_REPROCESS: + CAMHAL_LOGDB("Adapter state switch CAPTURE_STATE->->LOADED_REPROCESS_STATE event = %s", + printState); + mNextState = LOADED_REPROCESS_STATE; + break; + default: CAMHAL_LOGEB("Adapter state switch CAPTURE_STATE Invalid Op! event = %s", printState); @@ -2214,6 +2332,31 @@ status_t BaseCameraAdapter::setState(CameraCommands operation) break; + case REPROCESS_STATE: + switch (operation) { + case CAMERA_STOP_IMAGE_CAPTURE: + CAMHAL_LOGDB("Adapter state switch REPROCESS_STATE->PREVIEW_STATE event = %s", + printState); + mNextState = PREVIEW_STATE; + break; + case CAMERA_START_IMAGE_CAPTURE: + case CAMERA_USE_BUFFERS_REPROCESS: + CAMHAL_LOGDB("Adapter state switch REPROCESS_STATE->REPROCESS_STATE event = %s", + printState); + mNextState = REPROCESS_STATE; + break; + + default: + CAMHAL_LOGEB("Adapter state switch REPROCESS_STATE Invalid Op! event = %s", + printState); + ret = INVALID_OPERATION; + break; + + } + + break; + + default: CAMHAL_LOGEA("Invalid Adapter state!"); ret = INVALID_OPERATION; diff --git a/camera/BufferSourceAdapter.cpp b/camera/BufferSourceAdapter.cpp index edf78fb..b11304d 100644 --- a/camera/BufferSourceAdapter.cpp +++ b/camera/BufferSourceAdapter.cpp @@ -429,7 +429,7 @@ CameraBuffer* BufferSourceAdapter::getBufferList(int *num) { LOG_FUNCTION_NAME; status_t err; const int lnumBufs = 1; - int format, stride; + int format; GraphicBufferMapper &mapper = GraphicBufferMapper::get(); buffer_handle_t *handle; @@ -442,7 +442,7 @@ CameraBuffer* BufferSourceAdapter::getBufferList(int *num) { return NULL; } - err = mBufferSource->update_and_get_buffer(mBufferSource, &handle, &stride); + err = mBufferSource->update_and_get_buffer(mBufferSource, &handle, &mBuffers[0].stride); if (err != 0) { CAMHAL_LOGEB("update and get buffer failed: %s (%d)", strerror(-err), -err); if ( ENODEV == err ) { diff --git a/camera/CameraHal.cpp b/camera/CameraHal.cpp index 840dc04..f3751b8 100644 --- a/camera/CameraHal.cpp +++ b/camera/CameraHal.cpp @@ -43,7 +43,7 @@ extern "C" CameraAdapter* V4LCameraAdapter_Factory(size_t); //// Currently, they are hard-coded const int CameraHal::NO_BUFFERS_PREVIEW = MAX_CAMERA_BUFFERS; -const int CameraHal::NO_BUFFERS_IMAGE_CAPTURE = 9; +const int CameraHal::NO_BUFFERS_IMAGE_CAPTURE = 5; const int CameraHal::SW_SCALING_FPS_LIMIT = 15; const uint32_t MessageNotifier::EVENT_BIT_FIELD_POSITION = 16; @@ -2692,6 +2692,20 @@ status_t CameraHal::stopImageBracketing() */ status_t CameraHal::takePicture(const char *params) { + Mutex::Autolock lock(mLock); + return __takePicture(params); +} + +/** + @brief Internal function for getting a captured image. + shared by takePicture and reprocess. + @param none + @return NO_ERROR If able to switch to image capture + @todo Define error codes if unable to switch to image capture + + */ +status_t CameraHal::__takePicture(const char *params) +{ status_t ret = NO_ERROR; CameraFrame frame; CameraAdapter::BuffersDescriptor desc; @@ -2702,8 +2716,6 @@ status_t CameraHal::takePicture(const char *params) unsigned int rawBufferCount = 1; bool isCPCamMode = false; - Mutex::Autolock lock(mLock); - #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS gettimeofday(&mStartCapture, NULL); @@ -2775,8 +2787,9 @@ status_t CameraHal::takePicture(const char *params) // if we are already in the middle of a capture...then we just need // setParameters and start image capture to queue more shots - if ((mCameraAdapter->getState() == CameraAdapter::CAPTURE_STATE && - mCameraAdapter->getNextState() != CameraAdapter::PREVIEW_STATE)) { + if (((mCameraAdapter->getState() & CameraAdapter::CAPTURE_STATE) == + CameraAdapter::CAPTURE_STATE) && + (mCameraAdapter->getNextState() != CameraAdapter::PREVIEW_STATE)) { #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS //pass capture timestamp along with the camera adapter command ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_START_IMAGE_CAPTURE, @@ -3032,6 +3045,73 @@ char* CameraHal::getParameters() return params_string; } +/** + @brief Starts reprocessing operation. + */ +status_t CameraHal::reprocess(const char *params) +{ + status_t ret = NO_ERROR; + int bufferCount = 0; + CameraAdapter::BuffersDescriptor desc; + CameraBuffer *reprocBuffers = NULL; + ShotParameters shotParams; + + Mutex::Autolock lock(mLock); + + LOG_FUNCTION_NAME; + + // 1. Get buffers + if (mBufferSourceAdapter_In.get()) reprocBuffers = mBufferSourceAdapter_In->getBufferList(&bufferCount); + if (!reprocBuffers) { + CAMHAL_LOGE("Error: couldn't get input buffers for reprocess()"); + goto exit; + } + + // 2. Get buffer information and parse parameters + { + shotParams.setBurst(bufferCount); + } + + // 3. Give buffer to camera adapter + desc.mBuffers = reprocBuffers; + desc.mOffsets = 0; + desc.mFd = 0; + desc.mLength = 0; + desc.mCount = (size_t) bufferCount; + desc.mMaxQueueable = (size_t) bufferCount; + ret = mCameraAdapter->sendCommand(CameraAdapter::CAMERA_USE_BUFFERS_REPROCESS, (int) &desc); + if (ret != NO_ERROR) { + CAMHAL_LOGE("Error calling camera use buffers"); + goto exit; + } + + // 4. Start reprocessing + ret = mBufferSourceAdapter_In->enableDisplay(0, 0, NULL); + if (ret != NO_ERROR) { + CAMHAL_LOGE("Error enabling tap in point"); + goto exit; + } + + // 5. Start capturing + ret = __takePicture(shotParams.flatten().string()); + + exit: + return ret; +} + +/** + @brief Cancels current reprocessing operation + + */ +status_t CameraHal::cancel_reprocess( ) +{ + LOG_FUNCTION_NAME; + status_t ret = NO_ERROR; + + ret = signalEndImageCapture(); + return NO_ERROR; +} + void CameraHal::putParameters(char *parms) { free(parms); @@ -3962,7 +4042,7 @@ void CameraHal::resetPreviewRes(CameraParameters *mParams, int width, int height void * camera_buffer_get_omx_ptr (CameraBuffer *buffer) { - CAMHAL_LOGD("buffer_type %d opaque %p", buffer->type, buffer->opaque); + CAMHAL_LOGV("buffer_type %d opaque %p", buffer->type, buffer->opaque); if (buffer->type == CAMERA_BUFFER_ANW) { buffer_handle_t *handle = (buffer_handle_t *)buffer->opaque; diff --git a/camera/CameraHal_Module.cpp b/camera/CameraHal_Module.cpp index 2181cc2..91baca6 100644 --- a/camera/CameraHal_Module.cpp +++ b/camera/CameraHal_Module.cpp @@ -365,6 +365,38 @@ int camera_cancel_picture(struct camera_device * device) return rv; } +int camera_reprocess(struct camera_device * device, const char *params) +{ + int rv = -EINVAL; + ti_camera_device_t* ti_dev = NULL; + + LOGV("%s", __FUNCTION__); + + if(!device) + return rv; + + ti_dev = (ti_camera_device_t*) device; + + rv = gCameraHals[ti_dev->cameraid]->reprocess(params); + return rv; +} + +int camera_cancel_reprocess(struct camera_device * device) +{ + int rv = -EINVAL; + ti_camera_device_t* ti_dev = NULL; + + LOGV("%s", __FUNCTION__); + + if(!device) + return rv; + + ti_dev = (ti_camera_device_t*) device; + + rv = gCameraHals[ti_dev->cameraid]->cancel_reprocess(); + return rv; +} + int camera_set_parameters(struct camera_device * device, const char *params) { int rv = -EINVAL; @@ -588,6 +620,10 @@ int camera_device_open(const hw_module_t* module, const char* name, camera_ops->send_command = camera_send_command; camera_ops->release = camera_release; camera_ops->dump = camera_dump; +#ifdef OMAP_ENHANCEMENT + camera_ops->reprocess = camera_reprocess; + camera_ops->cancel_reprocess = camera_cancel_reprocess; +#endif *device = &camera_device->base.common; diff --git a/camera/OMXCameraAdapter/OMXCameraAdapter.cpp b/camera/OMXCameraAdapter/OMXCameraAdapter.cpp index 09d9b04..5f08a27 100644 --- a/camera/OMXCameraAdapter/OMXCameraAdapter.cpp +++ b/camera/OMXCameraAdapter/OMXCameraAdapter.cpp @@ -80,6 +80,7 @@ status_t OMXCameraAdapter::initialize(CameraProperties::Properties* caps) mCameraAdapterParameters.mMeasurementPortIndex = OMX_CAMERA_PORT_VIDEO_OUT_MEASUREMENT; //currently not supported use preview port instead mCameraAdapterParameters.mVideoPortIndex = OMX_CAMERA_PORT_VIDEO_OUT_VIDEO; + mCameraAdapterParameters.mVideoInPortIndex = OMX_CAMERA_PORT_VIDEO_IN_VIDEO; eError = OMX_Init(); if (eError != OMX_ErrorNone) { @@ -180,6 +181,7 @@ status_t OMXCameraAdapter::initialize(CameraProperties::Properties* caps) mCaptureSignalled = false; mCaptureConfigured = false; + mReprocConfigured = false; mRecording = false; mWaitingForSnapshot = false; mSnapshotCount = 0; @@ -294,6 +296,7 @@ status_t OMXCameraAdapter::initialize(CameraProperties::Properties* caps) memset(&mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mImagePortIndex], 0, sizeof(OMXCameraPortParameters)); memset(&mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mPrevPortIndex], 0, sizeof(OMXCameraPortParameters)); memset(&mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoPortIndex], 0, sizeof(OMXCameraPortParameters)); + memset(&mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoInPortIndex], 0, sizeof(OMXCameraPortParameters)); // initialize 3A defaults mParameters3A.Effect = getLUTvalue_HALtoOMX(OMXCameraAdapter::DEFAULT_EFFECT, EffLUT); @@ -983,6 +986,13 @@ status_t OMXCameraAdapter::setFormat(OMX_U32 port, OMXCameraPortParameters &port portCheck.format.image.nStride = 0; portCheck.nBufferSize = portParams.mStride * portParams.mWidth * portParams.mHeight; portCheck.nBufferCountActual = portParams.mNumBufs; + } else if (OMX_CAMERA_PORT_VIDEO_IN_VIDEO == port) { + portCheck.format.video.nFrameWidth = portParams.mWidth; + portCheck.format.video.nStride = portParams.mStride; + portCheck.format.video.nFrameHeight = portParams.mHeight; + portCheck.format.video.eColorFormat = portParams.mColorFormat; + portCheck.format.video.xFramerate = 30 << 16; + portCheck.nBufferCountActual = portParams.mNumBufs; } else { CAMHAL_LOGEB("Unsupported port index (%lu)", port); } @@ -1182,6 +1192,11 @@ status_t OMXCameraAdapter::useBuffers(CameraMode mode, CameraBuffer * bufArr, in ret = UseBuffersPreviewData(bufArr, num); break; + case CAMERA_REPROCESS: + mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoInPortIndex].mNumBufs = num; + mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoInPortIndex].mMaxQueueable = queueable; + ret = UseBuffersReprocess(bufArr, num); + break; } LOG_FUNCTION_NAME_EXIT; @@ -2464,7 +2479,14 @@ status_t OMXCameraAdapter::takePicture() } } - msg.command = CommandHandler::CAMERA_START_IMAGE_CAPTURE; + // TODO(XXX): re-using take picture to kick off reprocessing pipe + // Need to rethink this approach during reimplementation + if (mNextState == REPROCESS_STATE) { + msg.command = CommandHandler::CAMERA_START_REPROCESS; + } else { + msg.command = CommandHandler::CAMERA_START_IMAGE_CAPTURE; + } + msg.arg1 = mErrorNotifier; ret = mCommandHandler->put(&msg); @@ -2998,11 +3020,36 @@ OMX_ERRORTYPE OMXCameraAdapter::OMXCameraAdapterEmptyBufferDone(OMX_IN OMX_HANDL OMX_IN OMX_BUFFERHEADERTYPE* pBuffHeader) { - LOG_FUNCTION_NAME; + LOG_FUNCTION_NAME; + status_t stat = NO_ERROR; + status_t res1, res2; + OMXCameraPortParameters *pPortParam; + CameraFrame::FrameType typeOfFrame = CameraFrame::ALL_FRAMES; + unsigned int refCount = 0; + unsigned int mask = 0xFFFF; + CameraFrame cameraFrame; + OMX_TI_PLATFORMPRIVATE *platformPrivate; - LOG_FUNCTION_NAME_EXIT; + res1 = res2 = NO_ERROR; + + if (!pBuffHeader || !pBuffHeader->pBuffer) { + CAMHAL_LOGE("NULL Buffer from OMX"); + return OMX_ErrorNone; + } + + pPortParam = &(mCameraAdapterParameters.mCameraPortParams[pBuffHeader->nInputPortIndex]); + platformPrivate = (OMX_TI_PLATFORMPRIVATE*) pBuffHeader->pPlatformPrivate; + + if (pBuffHeader->nInputPortIndex == OMX_CAMERA_PORT_VIDEO_IN_VIDEO) { + typeOfFrame = CameraFrame::REPROCESS_INPUT_FRAME; + mask = (unsigned int)CameraFrame::REPROCESS_INPUT_FRAME; + + stat = sendCallBacks(cameraFrame, pBuffHeader, mask, pPortParam); + } + + LOG_FUNCTION_NAME_EXIT; - return OMX_ErrorNone; + return OMX_ErrorNone; } static void debugShowFPS() @@ -3518,8 +3565,14 @@ bool OMXCameraAdapter::CommandHandler::Handler() } case CommandHandler::CAMERA_SWITCH_TO_EXECUTING: { - stat = mCameraAdapter->doSwitchToExecuting(); - break; + stat = mCameraAdapter->doSwitchToExecuting(); + break; + } + case CommandHandler::CAMERA_START_REPROCESS: + { + stat = mCameraAdapter->startReprocess(); + stat = mCameraAdapter->startImageCapture(false); + break; } } @@ -3670,10 +3723,12 @@ OMXCameraAdapter::OMXCameraAdapter(size_t sensor_index) mUsePreviewDataSem.Create(0); mUsePreviewSem.Create(0); mUseCaptureSem.Create(0); + mUseReprocessSem.Create(0); mStartPreviewSem.Create(0); mStopPreviewSem.Create(0); mStartCaptureSem.Create(0); mStopCaptureSem.Create(0); + mStopReprocSem.Create(0); mSwitchToLoadedSem.Create(0); mCaptureSem.Create(0); diff --git a/camera/OMXCameraAdapter/OMXCapture.cpp b/camera/OMXCameraAdapter/OMXCapture.cpp index fa8acd5..e5e5bf5 100644 --- a/camera/OMXCameraAdapter/OMXCapture.cpp +++ b/camera/OMXCameraAdapter/OMXCapture.cpp @@ -304,6 +304,7 @@ status_t OMXCameraAdapter::setParametersCapture(const CameraParameters ¶ms, // shots inCaptureState = (CAPTURE_ACTIVE & mAdapterState) && (CAPTURE_ACTIVE & mNextState); if ((mPendingCaptureSettings & ~SetExpBracket) && !inCaptureState) { + disableReprocess(); disableImagePort(); if ( NULL != mReleaseImageBuffersCallback ) { mReleaseImageBuffersCallback(mReleaseData); @@ -480,8 +481,6 @@ status_t OMXCameraAdapter::doExposureBracketing(int *evValues, } } - if (0) initInternalBuffers(); - LOG_FUNCTION_NAME_EXIT; return ret; @@ -1052,6 +1051,29 @@ status_t OMXCameraAdapter::startImageCapture(bool bracketing) } } + // Choose proper single preview mode for cpcapture capture (reproc or hs) + if (( NO_ERROR == ret) && (OMXCameraAdapter::CP_CAM == mCapMode)) { + OMX_TI_CONFIG_SINGLEPREVIEWMODETYPE singlePrevMode; + OMX_INIT_STRUCT_PTR (&singlePrevMode, OMX_TI_CONFIG_SINGLEPREVIEWMODETYPE); + if (mAdapterState == CAPTURE_STATE) { + singlePrevMode.eMode = OMX_TI_SinglePreviewMode_ImageCaptureHighSpeed; + } else if (mAdapterState == REPROCESS_STATE) { + singlePrevMode.eMode = OMX_TI_SinglePreviewMode_Reprocess; + } else { + CAMHAL_LOGE("Wrong state trying to start a capture in CPCAM mode?"); + singlePrevMode.eMode = OMX_TI_SinglePreviewMode_ImageCaptureHighSpeed; + } + eError = OMX_SetConfig(mCameraAdapterParameters.mHandleComp, + (OMX_INDEXTYPE) OMX_TI_IndexConfigSinglePreviewMode, + &singlePrevMode); + if ( OMX_ErrorNone != eError ) { + CAMHAL_LOGEB("Error while configuring single preview mode 0x%x", eError); + ret = ErrorUtils::omxToAndroidError(eError); + } else { + CAMHAL_LOGDA("single preview mode configured successfully"); + } + } + if ( NO_ERROR == ret ) { if (mPendingCaptureSettings & SetRotation) { mPendingCaptureSettings &= ~SetRotation; @@ -1124,6 +1146,8 @@ status_t OMXCameraAdapter::startImageCapture(bool bracketing) while ((mBurstFramesQueued < mBurstFramesAccum) && (index < capData->mNumBufs)) { if (capData->mStatus[index] == OMXCameraPortParameters::IDLE) { + CAMHAL_LOGDB("Queuing buffer on Capture port - %p", + capData->mBufferHeader[index]->pBuffer); capData->mStatus[index] = OMXCameraPortParameters::FILL; eError = OMX_FillThisBuffer(mCameraAdapterParameters.mHandleComp, (OMX_BUFFERHEADERTYPE*)capData->mBufferHeader[index]); @@ -1135,9 +1159,9 @@ status_t OMXCameraAdapter::startImageCapture(bool bracketing) } else if ( NO_ERROR == ret ) { ///Queue all the buffers on capture port for ( int index = 0 ; index < capData->mMaxQueueable ; index++ ) { - CAMHAL_LOGDB("Queuing buffer on Capture port - 0x%x", - ( unsigned int ) capData->mBufferHeader[index]->pBuffer); if (mBurstFramesQueued < mBurstFramesAccum) { + CAMHAL_LOGDB("Queuing buffer on Capture port - %p", + capData->mBufferHeader[index]->pBuffer); capData->mStatus[index] = OMXCameraPortParameters::FILL; eError = OMX_FillThisBuffer(mCameraAdapterParameters.mHandleComp, (OMX_BUFFERHEADERTYPE*)capData->mBufferHeader[index]); @@ -1249,6 +1273,11 @@ status_t OMXCameraAdapter::stopImageCapture() goto EXIT; } + // TODO(XXX): Reprocessing is currently piggy-backing capture commands + if (mAdapterState == REPROCESS_STATE) { + ret = stopReprocess(); + } + //Disable the callback first mWaitingForSnapshot = false; mSnapshotCount = 0; @@ -1319,6 +1348,16 @@ status_t OMXCameraAdapter::stopImageCapture() mFirstFrameCondition.broadcast(); } + // Stop is always signalled externally in CPCAM mode + // We need to make sure we really stop + if ((mCapMode == CP_CAM)) { + disableReprocess(); + disableImagePort(); + if ( NULL != mReleaseImageBuffersCallback ) { + mReleaseImageBuffersCallback(mReleaseData); + } + } + return (ret | ErrorUtils::omxToAndroidError(eError)); EXIT: @@ -1401,6 +1440,8 @@ status_t OMXCameraAdapter::disableImagePort(){ goto EXIT; } + deinitInternalBuffers(mCameraAdapterParameters.mImagePortIndex); + if (mRawCapture) { ///Register for Video port Disable event @@ -1439,16 +1480,15 @@ EXIT: return (ret | ErrorUtils::omxToAndroidError(eError)); } -status_t OMXCameraAdapter::initInternalBuffers(void) +status_t OMXCameraAdapter::initInternalBuffers(OMX_U32 portIndex) { OMX_ERRORTYPE eError = OMX_ErrorNone; - int ion_fd; int index = 0; OMX_TI_PARAM_USEBUFFERDESCRIPTOR bufferdesc; /* Indicate to Ducati that we're planning to use dynamically-mapped buffers */ OMX_INIT_STRUCT_PTR (&bufferdesc, OMX_TI_PARAM_USEBUFFERDESCRIPTOR); - bufferdesc.nPortIndex = mCameraAdapterParameters.mImagePortIndex; + bufferdesc.nPortIndex = portIndex; bufferdesc.bEnabled = OMX_FALSE; bufferdesc.eBufferType = OMX_TI_BufferTypePhysicalPageList; @@ -1460,14 +1500,12 @@ status_t OMXCameraAdapter::initInternalBuffers(void) return -EINVAL; } - ion_fd = ion_open (); - CAMHAL_LOGDA("Initializing internal buffers"); do { OMX_TI_PARAM_COMPONENTBUFALLOCTYPE bufferalloc; OMX_TI_PARAM_COMPONENTBUFALLOCTYPE bufferallocset; OMX_INIT_STRUCT_PTR (&bufferalloc, OMX_TI_PARAM_COMPONENTBUFALLOCTYPE); - bufferalloc.nPortIndex = mCameraAdapterParameters.mImagePortIndex; + bufferalloc.nPortIndex = portIndex; bufferalloc.nIndex = index; eError = OMX_GetParameter (mCameraAdapterParameters.mHandleComp, @@ -1488,7 +1526,7 @@ status_t OMXCameraAdapter::initInternalBuffers(void) bufferalloc.eBufType = OMX_TI_BufferTypeHardwareReserved1D; OMX_INIT_STRUCT_PTR (&bufferallocset, OMX_TI_PARAM_COMPONENTBUFALLOCTYPE); - bufferallocset.nPortIndex = mCameraAdapterParameters.mImagePortIndex; + bufferallocset.nPortIndex = portIndex; bufferallocset.nIndex = index; bufferallocset.eBufType = OMX_TI_BufferTypeHardwareReserved1D; bufferallocset.nAllocWidth = bufferalloc.nAllocWidth; @@ -1499,6 +1537,7 @@ status_t OMXCameraAdapter::initInternalBuffers(void) &bufferallocset); if (eError != OMX_ErrorNone) { CAMHAL_LOGE("SetParameter failed, error=%08x", eError); + if (eError == OMX_ErrorNoMore) return NO_ERROR; break; } @@ -1512,6 +1551,27 @@ status_t OMXCameraAdapter::initInternalBuffers(void) return -EINVAL; } +status_t OMXCameraAdapter::deinitInternalBuffers(OMX_U32 portIndex) +{ + OMX_ERRORTYPE eError = OMX_ErrorNone; + OMX_TI_PARAM_USEBUFFERDESCRIPTOR bufferdesc; + + OMX_INIT_STRUCT_PTR (&bufferdesc, OMX_TI_PARAM_USEBUFFERDESCRIPTOR); + bufferdesc.nPortIndex = portIndex; + bufferdesc.bEnabled = OMX_FALSE; + bufferdesc.eBufferType = OMX_TI_BufferTypeDefault; + + eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp, + (OMX_INDEXTYPE) OMX_TI_IndexUseBufferDescriptor, + &bufferdesc); + if (eError!=OMX_ErrorNone) { + CAMHAL_LOGEB("OMX_SetParameter - %x", eError); + return -EINVAL; + } + + return ErrorUtils::omxToAndroidError(eError); +} + status_t OMXCameraAdapter::UseBuffersCapture(CameraBuffer * bufArr, int num) { LOG_FUNCTION_NAME; @@ -1581,6 +1641,8 @@ status_t OMXCameraAdapter::UseBuffersCapture(CameraBuffer * bufArr, int num) } } + initInternalBuffers(mCameraAdapterParameters.mImagePortIndex); + ///Register for Image port ENABLE event ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, OMX_EventCmdComplete, @@ -1604,8 +1666,10 @@ status_t OMXCameraAdapter::UseBuffersCapture(CameraBuffer * bufArr, int num) domxUseGrallocHandles.nPortIndex = mCameraAdapterParameters.mImagePortIndex; if (bufArr[0].type == CAMERA_BUFFER_ANW) { + CAMHAL_LOGD ("Using ANW Buffers"); domxUseGrallocHandles.bEnable = OMX_TRUE; } else { + CAMHAL_LOGD ("Using ION Buffers"); domxUseGrallocHandles.bEnable = OMX_FALSE; } diff --git a/camera/OMXCameraAdapter/OMXReprocess.cpp b/camera/OMXCameraAdapter/OMXReprocess.cpp new file mode 100644 index 0000000..586b1c7 --- /dev/null +++ b/camera/OMXCameraAdapter/OMXReprocess.cpp @@ -0,0 +1,325 @@ +/* + * 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 OMXReprocess.cpp +* +* This file contains functionality for handling reprocessing operations. +* +*/ + +#include "CameraHal.h" +#include "OMXCameraAdapter.h" +#include "ErrorUtils.h" + + +namespace android { + +status_t OMXCameraAdapter::setParametersReprocess(const CameraParameters ¶ms, + CameraBuffer* buffers, + BaseCameraAdapter::AdapterState state) +{ + status_t ret = NO_ERROR; + int w, h, s; + OMX_COLOR_FORMATTYPE pixFormat; + OMXCameraPortParameters *portData; + const char* valstr; + + LOG_FUNCTION_NAME; + + if (!buffers) { + CAMHAL_LOGE("invalid buffer array"); + return BAD_VALUE; + } + + portData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoInPortIndex]; + + w = buffers[0].width; + h = buffers[0].height; + s = buffers[0].stride; + + valstr = buffers[0].format; + if (valstr != NULL) { + if(strcmp(valstr, (const char *) CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) { + CAMHAL_LOGDA("YUV420SP format selected"); + pixFormat = OMX_COLOR_FormatYUV420SemiPlanar; + } else { + CAMHAL_LOGDA("Format not supported, selecting YUV420SP by default"); + pixFormat = OMX_COLOR_FormatYUV420SemiPlanar; + } + } else { + CAMHAL_LOGDA("Format not supported, selecting YUV420SP by default"); + pixFormat = OMX_COLOR_FormatYUV420SemiPlanar; + } + + if ( (w != (int)portData->mWidth) || (h != (int)portData->mHeight) || + (s != (int) portData->mStride) || (pixFormat != portData->mColorFormat)) { + portData->mWidth = w; + portData->mHeight = h; + portData->mStride = s; + portData->mColorFormat = pixFormat; + + ret = setFormat(OMX_CAMERA_PORT_VIDEO_IN_VIDEO, *portData); + if ( ret != NO_ERROR ) { + CAMHAL_LOGEB("setFormat() failed %d", ret); + LOG_FUNCTION_NAME_EXIT; + return ret; + } + } + + LOG_FUNCTION_NAME_EXIT; + + return ret; +} + +status_t OMXCameraAdapter::startReprocess() +{ + status_t ret = NO_ERROR; + OMX_ERRORTYPE eError = OMX_ErrorNone; + OMXCameraPortParameters * portData = NULL; + + LOG_FUNCTION_NAME; + CAMHAL_LOGD ("mReprocConfigured = %d", mReprocConfigured); + if (!mReprocConfigured) { + return NO_ERROR; + } + + portData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoInPortIndex]; + + CAMHAL_LOGD ("mReprocConfigured = %d", mBurstFramesQueued); + if (NO_ERROR == ret) { + Mutex::Autolock lock(mBurstLock); + + for ( int index = 0 ; index < portData->mMaxQueueable ; index++ ) { + CAMHAL_LOGDB("Queuing buffer on video input port - %p", + portData->mBufferHeader[index]->pBuffer); + portData->mStatus[index] = OMXCameraPortParameters::FILL; + eError = OMX_EmptyThisBuffer(mCameraAdapterParameters.mHandleComp, + (OMX_BUFFERHEADERTYPE*)portData->mBufferHeader[index]); + GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); + } + } + + return (ret | ErrorUtils::omxToAndroidError(eError)); + +EXIT: + CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError); + performCleanupAfterError(); + LOG_FUNCTION_NAME_EXIT; + return (ret | ErrorUtils::omxToAndroidError(eError)); +} + +status_t OMXCameraAdapter::stopReprocess() +{ + status_t ret = NO_ERROR; + OMX_ERRORTYPE eError = OMX_ErrorNone; + OMXCameraPortParameters *portData = NULL; + + if (!mReprocConfigured) { + return NO_ERROR; + } + + portData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoInPortIndex]; + + // Disable port - send command and then free all buffers + ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, + OMX_EventCmdComplete, + OMX_CommandPortDisable, + mCameraAdapterParameters.mVideoInPortIndex, + mStopReprocSem); + eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp, + OMX_CommandPortDisable, + mCameraAdapterParameters.mVideoInPortIndex, + NULL); + if (portData) { + CAMHAL_LOGDB("Freeing buffers on reproc port - num: %d", portData->mNumBufs); + for (int index = 0 ; index < portData->mNumBufs ; index++) { + CAMHAL_LOGDB("Freeing buffer on reproc port - 0x%x", + ( unsigned int ) portData->mBufferHeader[index]->pBuffer); + eError = OMX_FreeBuffer(mCameraAdapterParameters.mHandleComp, + mCameraAdapterParameters.mVideoInPortIndex, + (OMX_BUFFERHEADERTYPE*)portData->mBufferHeader[index]); + GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); + } + } + CAMHAL_LOGDA("Waiting for port disable"); + ret = mStopReprocSem.WaitTimeout(OMX_CMD_TIMEOUT); + if (mComponentState == OMX_StateInvalid) { + CAMHAL_LOGEA("Invalid State after Disable Image Port Exitting!!!"); + goto EXIT; + } + if (NO_ERROR == ret) { + CAMHAL_LOGDA("Port disabled"); + } else { + ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp, + OMX_EventCmdComplete, + OMX_CommandPortDisable, + mCameraAdapterParameters.mVideoInPortIndex, + NULL); + CAMHAL_LOGDA("Timeout expired on port disable"); + goto EXIT; + } + + deinitInternalBuffers(mCameraAdapterParameters.mVideoInPortIndex); + + mReprocConfigured = false; + +EXIT: + CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError); + LOG_FUNCTION_NAME_EXIT; + return (ret | ErrorUtils::omxToAndroidError(eError)); +} + +status_t OMXCameraAdapter::disableReprocess(){ + status_t ret = NO_ERROR; + OMX_ERRORTYPE eError = OMX_ErrorNone; + + // no-op..for now + +EXIT: + return (ret | ErrorUtils::omxToAndroidError(eError)); +} + +status_t OMXCameraAdapter::UseBuffersReprocess(CameraBuffer *bufArr, int num) +{ + LOG_FUNCTION_NAME; + + status_t ret = NO_ERROR; + OMX_ERRORTYPE eError = OMX_ErrorNone; + OMXCameraPortParameters *portData = NULL; + + portData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoInPortIndex]; + + if ( 0 != mUseReprocessSem.Count() ) { + CAMHAL_LOGEB("Error mUseReprocessSem semaphore count %d", mUseReprocessSem.Count()); + return BAD_VALUE; + } + + if (mAdapterState == REPROCESS_STATE) { + stopReprocess(); + } else if (mAdapterState == CAPTURE_STATE) { + stopImageCapture(); + disableImagePort(); + } + + if (mReprocConfigured) { + return NO_ERROR; + } + + portData->mNumBufs = num; + + // Configure + ret = setParametersReprocess(mParams, bufArr, mAdapterState); + + initInternalBuffers(mCameraAdapterParameters.mVideoInPortIndex); + + // Configure DOMX to use either gralloc handles or vptrs + OMX_TI_PARAMUSENATIVEBUFFER domxUseGrallocHandles; + OMX_INIT_STRUCT_PTR (&domxUseGrallocHandles, OMX_TI_PARAMUSENATIVEBUFFER); + + domxUseGrallocHandles.nPortIndex = mCameraAdapterParameters.mVideoInPortIndex; + if (bufArr[0].type == CAMERA_BUFFER_ANW) { + CAMHAL_LOGD("Using ANW"); + domxUseGrallocHandles.bEnable = OMX_TRUE; + } else { + CAMHAL_LOGD("Using ION"); + domxUseGrallocHandles.bEnable = OMX_FALSE; + } + eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp, + (OMX_INDEXTYPE)OMX_TI_IndexUseNativeBuffers, &domxUseGrallocHandles); + if (eError!=OMX_ErrorNone) { + CAMHAL_LOGEB("OMX_SetParameter - %x", eError); + } + GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError); + + // Enable Port + ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp, + OMX_EventCmdComplete, + OMX_CommandPortEnable, + mCameraAdapterParameters.mVideoInPortIndex, + mUseReprocessSem); + eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp, + OMX_CommandPortEnable, + mCameraAdapterParameters.mVideoInPortIndex, + NULL); + GOTO_EXIT_IF(( eError != OMX_ErrorNone ), eError); + + for (int index = 0 ; index < portData->mNumBufs ; index++) + { + OMX_BUFFERHEADERTYPE *pBufferHdr; + CAMHAL_LOGDB("OMX_UseBuffer Capture address: 0x%x, size = %d", + (unsigned int)bufArr[index].opaque, + (int)portData->mBufSize); + + eError = OMX_UseBuffer(mCameraAdapterParameters.mHandleComp, + &pBufferHdr, + mCameraAdapterParameters.mVideoInPortIndex, + 0, + portData->mBufSize, + (OMX_U8*)camera_buffer_get_omx_ptr(&bufArr[index])); + + CAMHAL_LOGDB("OMX_UseBuffer = 0x%x", eError); + GOTO_EXIT_IF(( eError != OMX_ErrorNone ), eError); + + pBufferHdr->pAppPrivate = (OMX_PTR) &bufArr[index]; + bufArr[index].index = index; + pBufferHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); + pBufferHdr->nVersion.s.nVersionMajor = 1 ; + pBufferHdr->nVersion.s.nVersionMinor = 1 ; + pBufferHdr->nVersion.s.nRevision = 0; + pBufferHdr->nVersion.s.nStep = 0; + portData->mBufferHeader[index] = pBufferHdr; + } + + // Wait for port enable event + CAMHAL_LOGDA("Waiting for port enable"); + ret = mUseReprocessSem.WaitTimeout(OMX_CMD_TIMEOUT); + + // Error out if somethiing bad happened while we wait + if (mComponentState == OMX_StateInvalid) { + CAMHAL_LOGEA("Invalid State while trying to enable port for reprocessing"); + goto EXIT; + } + + if (ret == NO_ERROR) { + CAMHAL_LOGDA("Port enabled"); + } else { + ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp, + OMX_EventCmdComplete, + OMX_CommandPortEnable, + mCameraAdapterParameters.mVideoInPortIndex, + NULL); + CAMHAL_LOGDA("Timeout expired on port enable"); + goto EXIT; + } + + mReprocConfigured = true; + + return (ret | ErrorUtils::omxToAndroidError(eError)); + +EXIT: + CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError); + // Release image buffers + if ( NULL != mReleaseImageBuffersCallback ) { + mReleaseImageBuffersCallback(mReleaseData); + } + performCleanupAfterError(); + LOG_FUNCTION_NAME_EXIT; + return (ret | ErrorUtils::omxToAndroidError(eError)); + +} + +}; diff --git a/camera/inc/BaseCameraAdapter.h b/camera/inc/BaseCameraAdapter.h index 0467b7e..7a084d9 100644 --- a/camera/inc/BaseCameraAdapter.h +++ b/camera/inc/BaseCameraAdapter.h @@ -220,6 +220,7 @@ protected: KeyedVector<int, frame_callback> mFrameSubscribers; KeyedVector<int, frame_callback> mFrameDataSubscribers; KeyedVector<int, frame_callback> mVideoSubscribers; + KeyedVector<int, frame_callback> mVideoInSubscribers; KeyedVector<int, frame_callback> mImageSubscribers; KeyedVector<int, frame_callback> mRawSubscribers; KeyedVector<int, event_callback> mFocusSubscribers; @@ -255,6 +256,11 @@ protected: size_t mPreviewDataBuffersLength; mutable Mutex mPreviewDataBufferLock; + //Video input buffer management data (used for reproc pipe) + CameraBuffer *mVideoInBuffers; + KeyedVector<CameraBuffer *, int> mVideoInBuffersAvailable; + mutable Mutex mVideoInBufferLock; + TIUTILS::MessageQueue mFrameQ; TIUTILS::MessageQueue mAdapterQ; mutable Mutex mSubscriberLock; diff --git a/camera/inc/CameraHal.h b/camera/inc/CameraHal.h index 5d04881..c613749 100644 --- a/camera/inc/CameraHal.h +++ b/camera/inc/CameraHal.h @@ -354,6 +354,7 @@ typedef struct _CameraBuffer { /* These describe the camera buffer */ int width; + int stride; int height; const char *format; } CameraBuffer; @@ -878,15 +879,17 @@ class CameraAdapter: public FrameNotifier, public virtual RefBase { protected: enum AdapterActiveStates { - INTIALIZED_ACTIVE = 1 << 0, - LOADED_PREVIEW_ACTIVE = 1 << 1, - PREVIEW_ACTIVE = 1 << 2, - LOADED_CAPTURE_ACTIVE = 1 << 3, - CAPTURE_ACTIVE = 1 << 4, - BRACKETING_ACTIVE = 1 << 5, - AF_ACTIVE = 1 << 6, - ZOOM_ACTIVE = 1 << 7, - VIDEO_ACTIVE = 1 << 8, + INTIALIZED_ACTIVE = 1 << 0, + LOADED_PREVIEW_ACTIVE = 1 << 1, + PREVIEW_ACTIVE = 1 << 2, + LOADED_CAPTURE_ACTIVE = 1 << 3, + CAPTURE_ACTIVE = 1 << 4, + BRACKETING_ACTIVE = 1 << 5, + AF_ACTIVE = 1 << 6, + ZOOM_ACTIVE = 1 << 7, + VIDEO_ACTIVE = 1 << 8, + LOADED_REPROCESS_ACTIVE = 1 << 9, + REPROCESS_ACTIVE = 1 << 10, }; public: typedef struct @@ -927,6 +930,8 @@ public: CAMERA_STOP_FD = 23, CAMERA_SWITCH_TO_EXECUTING = 24, CAMERA_USE_BUFFERS_VIDEO_CAPTURE = 25, + CAMERA_USE_BUFFERS_REPROCESS = 26, + CAMERA_START_REPROCESS = 27, }; enum CameraMode @@ -934,25 +939,29 @@ public: CAMERA_PREVIEW, CAMERA_IMAGE_CAPTURE, CAMERA_VIDEO, - CAMERA_MEASUREMENT + CAMERA_MEASUREMENT, + CAMERA_REPROCESS, }; enum AdapterState { - INTIALIZED_STATE = INTIALIZED_ACTIVE, - LOADED_PREVIEW_STATE = LOADED_PREVIEW_ACTIVE | INTIALIZED_ACTIVE, - PREVIEW_STATE = PREVIEW_ACTIVE | INTIALIZED_ACTIVE, - LOADED_CAPTURE_STATE = LOADED_CAPTURE_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE, - CAPTURE_STATE = CAPTURE_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE, - BRACKETING_STATE = BRACKETING_ACTIVE | CAPTURE_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE , - AF_STATE = AF_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE, - ZOOM_STATE = ZOOM_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE, - VIDEO_STATE = VIDEO_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE, - VIDEO_AF_STATE = VIDEO_ACTIVE | AF_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, + INTIALIZED_STATE = INTIALIZED_ACTIVE, + LOADED_PREVIEW_STATE = LOADED_PREVIEW_ACTIVE | INTIALIZED_ACTIVE, + PREVIEW_STATE = PREVIEW_ACTIVE | INTIALIZED_ACTIVE, + LOADED_CAPTURE_STATE = LOADED_CAPTURE_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE, + CAPTURE_STATE = CAPTURE_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE, + BRACKETING_STATE = BRACKETING_ACTIVE | CAPTURE_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE , + AF_STATE = AF_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE, + ZOOM_STATE = ZOOM_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE, + VIDEO_STATE = VIDEO_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE, + VIDEO_AF_STATE = VIDEO_ACTIVE | AF_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, + LOADED_REPROCESS_STATE = LOADED_REPROCESS_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE, + LOADED_REPROCESS_CAPTURE_STATE = LOADED_REPROCESS_ACTIVE | LOADED_CAPTURE_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE, + REPROCESS_STATE = REPROCESS_ACTIVE | CAPTURE_ACTIVE | PREVIEW_ACTIVE | INTIALIZED_ACTIVE, }; @@ -1206,6 +1215,16 @@ public: */ int dump(int fd) const; + /** + * start a reprocessing operation. + */ + int reprocess(const char* params); + + /** + * cancels current reprocessing operation + */ + int cancel_reprocess(); + status_t storeMetaDataInBuffers(bool enable); @@ -1330,6 +1349,8 @@ private: bool setPreferredPreviewRes(const CameraParameters ¶ms, int width, int height); void resetPreviewRes(CameraParameters *mParams, int width, int height); + // Internal __takePicture function - used in public takePicture() and reprocess() + int __takePicture(const char* params); //@} diff --git a/camera/inc/OMXCameraAdapter/OMXCameraAdapter.h b/camera/inc/OMXCameraAdapter/OMXCameraAdapter.h index c820396..c41c652 100644 --- a/camera/inc/OMXCameraAdapter/OMXCameraAdapter.h +++ b/camera/inc/OMXCameraAdapter/OMXCameraAdapter.h @@ -366,6 +366,7 @@ public: OMX_U32 mPrevPortIndex; OMX_U32 mImagePortIndex; OMX_U32 mMeasurementPortIndex; + OMX_U32 mVideoInPortIndex; OMXCameraPortParameters mCameraPortParams[MAX_NO_PORTS]; }; @@ -739,7 +740,16 @@ private: FILE * parseDCCsubDir(DIR *pDir, char *path); // Internal buffers - status_t initInternalBuffers (void); + status_t initInternalBuffers (OMX_U32); + status_t deinitInternalBuffers (OMX_U32); + + // Reprocess Methods -- implementation in OMXReprocess.cpp + status_t setParametersReprocess(const CameraParameters ¶ms, CameraBuffer* bufs, + BaseCameraAdapter::AdapterState state); + status_t startReprocess(); + status_t disableReprocess(); + status_t stopReprocess(); + status_t UseBuffersReprocess(CameraBuffer *bufArr, int num); class CommandHandler : public Thread { public: @@ -766,8 +776,9 @@ private: enum { COMMAND_EXIT = -1, CAMERA_START_IMAGE_CAPTURE = 0, - CAMERA_PERFORM_AUTOFOCUS = 1, - CAMERA_SWITCH_TO_EXECUTING + CAMERA_PERFORM_AUTOFOCUS, + CAMERA_SWITCH_TO_EXECUTING, + CAMERA_START_REPROCESS }; private: @@ -1027,6 +1038,7 @@ private: unsigned int mPendingPreviewSettings; OMX_TI_ANCILLARYDATATYPE* mCaptureAncillaryData; OMX_TI_WHITEBALANCERESULTTYPE* mWhiteBalanceData; + bool mReprocConfigured; //Temporal bracketing management data bool mBracketingSet; @@ -1054,6 +1066,8 @@ private: Semaphore mStopCaptureSem; Semaphore mSwitchToLoadedSem; Semaphore mSwitchToExecSem; + Semaphore mStopReprocSem; + Semaphore mUseReprocessSem; mutable Mutex mStateSwitchLock; |