diff options
Diffstat (limited to 'camera/OMXCameraAdapter/OMXReprocess.cpp')
-rw-r--r-- | camera/OMXCameraAdapter/OMXReprocess.cpp | 340 |
1 files changed, 340 insertions, 0 deletions
diff --git a/camera/OMXCameraAdapter/OMXReprocess.cpp b/camera/OMXCameraAdapter/OMXReprocess.cpp new file mode 100644 index 0000000..28f1744 --- /dev/null +++ b/camera/OMXCameraAdapter/OMXReprocess.cpp @@ -0,0 +1,340 @@ +/* + * 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 Ti { +namespace Camera { + +status_t OMXCameraAdapter::setParametersReprocess(const android::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, android::CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) { + CAMHAL_LOGDA("YUV420SP format selected"); + pixFormat = OMX_COLOR_FormatYUV420SemiPlanar; + } else if (strcmp(valstr, android::CameraParameters::PIXEL_FORMAT_BAYER_RGGB) == 0) { + CAMHAL_LOGDA("RAW Picture format selected"); + pixFormat = OMX_COLOR_FormatRawBayer10bit; + } 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; + + if ( OMX_COLOR_FormatRawBayer10bit == pixFormat ) { + portData->mStride = w * 2; + } else { + 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) { + android::AutoMutex 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 | Utils::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 | Utils::ErrorUtils::omxToAndroidError(eError)); +} + +status_t OMXCameraAdapter::stopReprocess() +{ + LOG_FUNCTION_NAME; + + 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 | Utils::ErrorUtils::omxToAndroidError(eError)); +} + +status_t OMXCameraAdapter::disableReprocess(){ + status_t ret = NO_ERROR; + OMX_ERRORTYPE eError = OMX_ErrorNone; + + // no-op..for now + +EXIT: + return (ret | Utils::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); + + // 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; + + // Need to allocate tiler reservation and state we are going to be using + // pagelist buffers. Assuming this happens when buffers if from anw + initInternalBuffers(mCameraAdapterParameters.mVideoInPortIndex); + } 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 | Utils::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 | Utils::ErrorUtils::omxToAndroidError(eError)); + +} + +} // namespace Camera +} // namespace Ti |