Home | History | Annotate | Download | only in OMXCameraAdapter
      1 /*
      2  * Copyright (C) Texas Instruments - http://www.ti.com/
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 /**
     18 * @file OMXReprocess.cpp
     19 *
     20 * This file contains functionality for handling reprocessing operations.
     21 *
     22 */
     23 
     24 #include "CameraHal.h"
     25 #include "OMXCameraAdapter.h"
     26 #include "ErrorUtils.h"
     27 
     28 
     29 namespace Ti {
     30 namespace Camera {
     31 
     32 status_t OMXCameraAdapter::setParametersReprocess(const android::CameraParameters &params,
     33                                                 CameraBuffer* buffers,
     34                                                 BaseCameraAdapter::AdapterState state)
     35 {
     36     status_t ret = NO_ERROR;
     37     int w, h, s;
     38     OMX_COLOR_FORMATTYPE pixFormat;
     39     OMXCameraPortParameters *portData;
     40     const char* valstr;
     41 
     42     LOG_FUNCTION_NAME;
     43 
     44     if (!buffers) {
     45         CAMHAL_LOGE("invalid buffer array");
     46         return BAD_VALUE;
     47     }
     48 
     49     portData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoInPortIndex];
     50 
     51     w = buffers[0].width;
     52     h = buffers[0].height;
     53     s = buffers[0].stride;
     54 
     55     valstr = buffers[0].format;
     56     if (valstr != NULL) {
     57         if(strcmp(valstr, android::CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) {
     58             CAMHAL_LOGDA("YUV420SP format selected");
     59             pixFormat = OMX_COLOR_FormatYUV420SemiPlanar;
     60         } else if (strcmp(valstr, android::CameraParameters::PIXEL_FORMAT_BAYER_RGGB) == 0) {
     61             CAMHAL_LOGDA("RAW Picture format selected");
     62             pixFormat = OMX_COLOR_FormatRawBayer10bit;
     63         } else if (strcmp(valstr, android::CameraParameters::PIXEL_FORMAT_YUV422I) == 0) {
     64             CAMHAL_LOGDA("YUV422i Picture format selected");
     65             pixFormat = OMX_COLOR_FormatCbYCrY;
     66         } else {
     67             CAMHAL_LOGDA("Format not supported, selecting YUV420SP by default");
     68             pixFormat = OMX_COLOR_FormatYUV420SemiPlanar;
     69         }
     70     } else {
     71         CAMHAL_LOGDA("Format not supported, selecting YUV420SP by default");
     72         pixFormat = OMX_COLOR_FormatYUV420SemiPlanar;
     73     }
     74 
     75     if ( (w != (int)portData->mWidth) || (h != (int)portData->mHeight) ||
     76          (s != (int) portData->mStride) || (pixFormat != portData->mColorFormat)) {
     77         portData->mWidth = w;
     78         portData->mHeight = h;
     79 
     80         if ( ( OMX_COLOR_FormatRawBayer10bit == pixFormat ) ||
     81              ( OMX_COLOR_FormatCbYCrY == pixFormat ) ) {
     82             portData->mStride = w * 2;
     83         } else {
     84             portData->mStride = s;
     85         }
     86 
     87         portData->mColorFormat = pixFormat;
     88 
     89         mPendingReprocessSettings |= SetFormat;
     90     }
     91 
     92     LOG_FUNCTION_NAME_EXIT;
     93 
     94     return ret;
     95 }
     96 
     97 status_t OMXCameraAdapter::startReprocess()
     98 {
     99     status_t ret = NO_ERROR;
    100     OMX_ERRORTYPE eError = OMX_ErrorNone;
    101     OMXCameraPortParameters * portData = NULL;
    102 
    103     LOG_FUNCTION_NAME;
    104     CAMHAL_LOGD ("mReprocConfigured = %d", mReprocConfigured);
    105     if (!mReprocConfigured) {
    106         return NO_ERROR;
    107     }
    108 
    109     portData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoInPortIndex];
    110 
    111     CAMHAL_LOGD ("mReprocConfigured = %d", mBurstFramesQueued);
    112     if (NO_ERROR == ret) {
    113         android::AutoMutex lock(mBurstLock);
    114 
    115         for ( int index = 0 ; index < portData->mMaxQueueable ; index++ ) {
    116             CAMHAL_LOGDB("Queuing buffer on video input port - %p, offset: %d, length: %d",
    117                          portData->mBufferHeader[index]->pBuffer,
    118                          portData->mBufferHeader[index]->nOffset,
    119                          portData->mBufferHeader[index]->nFilledLen);
    120             portData->mStatus[index] = OMXCameraPortParameters::FILL;
    121             eError = OMX_EmptyThisBuffer(mCameraAdapterParameters.mHandleComp,
    122                     (OMX_BUFFERHEADERTYPE*)portData->mBufferHeader[index]);
    123             GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
    124         }
    125     }
    126 
    127 #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
    128             CameraHal::PPM("startReprocess buffers queued on video port: ", &mStartCapture);
    129 #endif
    130 
    131     return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
    132 
    133 EXIT:
    134     CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
    135     performCleanupAfterError();
    136     LOG_FUNCTION_NAME_EXIT;
    137     return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
    138 }
    139 
    140 status_t OMXCameraAdapter::stopReprocess()
    141 {
    142     LOG_FUNCTION_NAME;
    143 
    144     status_t ret = NO_ERROR;
    145     OMX_ERRORTYPE eError = OMX_ErrorNone;
    146     OMXCameraPortParameters *portData = NULL;
    147 
    148     if (!mReprocConfigured) {
    149         return NO_ERROR;
    150     }
    151 
    152     portData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoInPortIndex];
    153 
    154     // Disable port - send command and then free all buffers
    155     ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
    156                                 OMX_EventCmdComplete,
    157                                 OMX_CommandPortDisable,
    158                                 mCameraAdapterParameters.mVideoInPortIndex,
    159                                 mStopReprocSem);
    160     eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
    161                                 OMX_CommandPortDisable,
    162                                 mCameraAdapterParameters.mVideoInPortIndex,
    163                                 NULL);
    164     if (portData) {
    165         CAMHAL_LOGDB("Freeing buffers on reproc port - num: %d", portData->mNumBufs);
    166         for (int index = 0 ; index < portData->mNumBufs ; index++) {
    167             CAMHAL_LOGDB("Freeing buffer on reproc port - 0x%x",
    168                          ( unsigned int ) portData->mBufferHeader[index]->pBuffer);
    169             eError = OMX_FreeBuffer(mCameraAdapterParameters.mHandleComp,
    170                                     mCameraAdapterParameters.mVideoInPortIndex,
    171                                     (OMX_BUFFERHEADERTYPE*)portData->mBufferHeader[index]);
    172             GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
    173         }
    174     }
    175     CAMHAL_LOGDA("Waiting for port disable");
    176     ret = mStopReprocSem.WaitTimeout(OMX_CMD_TIMEOUT);
    177     if (mComponentState == OMX_StateInvalid) {
    178         CAMHAL_LOGEA("Invalid State after Disable Image Port Exitting!!!");
    179         goto EXIT;
    180     }
    181     if (NO_ERROR == ret) {
    182         CAMHAL_LOGDA("Port disabled");
    183     } else {
    184         ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
    185                            OMX_EventCmdComplete,
    186                            OMX_CommandPortDisable,
    187                            mCameraAdapterParameters.mVideoInPortIndex,
    188                            NULL);
    189         CAMHAL_LOGDA("Timeout expired on port disable");
    190         goto EXIT;
    191     }
    192 
    193     deinitInternalBuffers(mCameraAdapterParameters.mVideoInPortIndex);
    194 
    195     mReprocConfigured = false;
    196 
    197 EXIT:
    198     CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
    199     LOG_FUNCTION_NAME_EXIT;
    200     return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
    201 }
    202 
    203 status_t OMXCameraAdapter::disableReprocess(){
    204     status_t ret = NO_ERROR;
    205     OMX_ERRORTYPE eError = OMX_ErrorNone;
    206 
    207     // no-op..for now
    208 
    209 EXIT:
    210     return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
    211 }
    212 
    213 status_t OMXCameraAdapter::UseBuffersReprocess(CameraBuffer *bufArr, int num)
    214 {
    215     LOG_FUNCTION_NAME;
    216 
    217     status_t ret = NO_ERROR;
    218     OMX_ERRORTYPE eError = OMX_ErrorNone;
    219     OMXCameraPortParameters *portData = NULL;
    220 
    221     portData = &mCameraAdapterParameters.mCameraPortParams[mCameraAdapterParameters.mVideoInPortIndex];
    222 
    223     if ( 0 != mUseReprocessSem.Count() ) {
    224         CAMHAL_LOGEB("Error mUseReprocessSem semaphore count %d", mUseReprocessSem.Count());
    225         return BAD_VALUE;
    226     }
    227 
    228     CAMHAL_ASSERT(num > 0);
    229 
    230     if (mAdapterState == REPROCESS_STATE) {
    231         stopReprocess();
    232     } else if (mAdapterState == CAPTURE_STATE) {
    233         stopImageCapture();
    234         stopReprocess();
    235     }
    236 
    237 #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
    238 
    239     CameraHal::PPM("Reprocess stopping image capture and disabling image port: ", &bufArr->ppmStamp);
    240 
    241 #endif
    242 
    243     portData->mNumBufs = num;
    244 
    245     // Configure
    246     ret = setParametersReprocess(mParams, bufArr, mAdapterState);
    247 
    248     if (mReprocConfigured) {
    249         if (mPendingReprocessSettings & ECaptureParamSettings) {
    250             stopReprocess();
    251         } else {
    252             // Tap in port has been already configured.
    253             return NO_ERROR;
    254         }
    255     }
    256 
    257     if (mPendingReprocessSettings & SetFormat) {
    258         mPendingReprocessSettings &= ~SetFormat;
    259         ret = setFormat(OMX_CAMERA_PORT_VIDEO_IN_VIDEO, *portData);
    260         if ( ret != NO_ERROR ) {
    261             CAMHAL_LOGEB("setFormat() failed %d", ret);
    262             LOG_FUNCTION_NAME_EXIT;
    263             return ret;
    264         }
    265     }
    266 
    267     // Configure DOMX to use either gralloc handles or vptrs
    268     OMX_TI_PARAMUSENATIVEBUFFER domxUseGrallocHandles;
    269     OMX_INIT_STRUCT_PTR (&domxUseGrallocHandles, OMX_TI_PARAMUSENATIVEBUFFER);
    270 
    271     domxUseGrallocHandles.nPortIndex = mCameraAdapterParameters.mVideoInPortIndex;
    272     if (bufArr[0].type == CAMERA_BUFFER_ANW) {
    273         CAMHAL_LOGD("Using ANW");
    274         domxUseGrallocHandles.bEnable = OMX_TRUE;
    275 
    276         // Need to allocate tiler reservation and state we are going to be using
    277         // pagelist buffers. Assuming this happens when buffers if from anw
    278         initInternalBuffers(mCameraAdapterParameters.mVideoInPortIndex);
    279     } else {
    280         CAMHAL_LOGD("Using ION");
    281         domxUseGrallocHandles.bEnable = OMX_FALSE;
    282     }
    283     eError = OMX_SetParameter(mCameraAdapterParameters.mHandleComp,
    284                             (OMX_INDEXTYPE)OMX_TI_IndexUseNativeBuffers, &domxUseGrallocHandles);
    285     if (eError!=OMX_ErrorNone) {
    286         CAMHAL_LOGEB("OMX_SetParameter - %x", eError);
    287     }
    288     GOTO_EXIT_IF((eError!=OMX_ErrorNone), eError);
    289 
    290 #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
    291 
    292     CameraHal::PPM("Reprocess configuration done: ", &bufArr->ppmStamp);
    293 
    294 #endif
    295 
    296     // Enable Port
    297     ret = RegisterForEvent(mCameraAdapterParameters.mHandleComp,
    298                            OMX_EventCmdComplete,
    299                            OMX_CommandPortEnable,
    300                            mCameraAdapterParameters.mVideoInPortIndex,
    301                            mUseReprocessSem);
    302     eError = OMX_SendCommand(mCameraAdapterParameters.mHandleComp,
    303                              OMX_CommandPortEnable,
    304                              mCameraAdapterParameters.mVideoInPortIndex,
    305                              NULL);
    306     GOTO_EXIT_IF(( eError != OMX_ErrorNone ), eError);
    307 
    308     for (int index = 0 ; index < portData->mNumBufs ; index++)
    309     {
    310         OMX_BUFFERHEADERTYPE *pBufferHdr;
    311         CAMHAL_LOGDB("OMX_UseBuffer Capture address: 0x%x, size = %d",
    312                      (unsigned int)bufArr[index].opaque,
    313                      (int)portData->mBufSize);
    314 
    315         eError = OMX_UseBuffer(mCameraAdapterParameters.mHandleComp,
    316                                &pBufferHdr,
    317                                mCameraAdapterParameters.mVideoInPortIndex,
    318                                0,
    319                                portData->mBufSize,
    320                                (OMX_U8*)camera_buffer_get_omx_ptr(&bufArr[index]));
    321 
    322         CAMHAL_LOGDB("OMX_UseBuffer = 0x%x", eError);
    323         GOTO_EXIT_IF(( eError != OMX_ErrorNone ), eError);
    324 
    325         pBufferHdr->pAppPrivate = (OMX_PTR) &bufArr[index];
    326         bufArr[index].index = index;
    327         pBufferHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
    328         pBufferHdr->nVersion.s.nVersionMajor = 1 ;
    329         pBufferHdr->nVersion.s.nVersionMinor = 1 ;
    330         pBufferHdr->nVersion.s.nRevision = 0;
    331         pBufferHdr->nVersion.s.nStep =  0;
    332         pBufferHdr->nOffset = bufArr[index].offset;
    333         pBufferHdr->nFilledLen = bufArr[index].actual_size;
    334         portData->mBufferHeader[index] = pBufferHdr;
    335     }
    336 
    337     // Wait for port enable event
    338     CAMHAL_LOGDA("Waiting for port enable");
    339     ret = mUseReprocessSem.WaitTimeout(OMX_CMD_TIMEOUT);
    340 
    341     // Error out if somethiing bad happened while we wait
    342     if (mComponentState == OMX_StateInvalid) {
    343         CAMHAL_LOGEA("Invalid State while trying to enable port for reprocessing");
    344         goto EXIT;
    345     }
    346 
    347     if (ret == NO_ERROR) {
    348         CAMHAL_LOGDA("Port enabled");
    349     } else {
    350         ret |= RemoveEvent(mCameraAdapterParameters.mHandleComp,
    351                            OMX_EventCmdComplete,
    352                            OMX_CommandPortEnable,
    353                            mCameraAdapterParameters.mVideoInPortIndex,
    354                            NULL);
    355         CAMHAL_LOGDA("Timeout expired on port enable");
    356         goto EXIT;
    357     }
    358 
    359     mReprocConfigured = true;
    360 
    361 #if PPM_INSTRUMENTATION || PPM_INSTRUMENTATION_ABS
    362 
    363     CameraHal::PPM("Reprocess video port enabled and buffers registered: ", &bufArr->ppmStamp);
    364 
    365 #endif
    366 
    367     return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
    368 
    369 EXIT:
    370     CAMHAL_LOGEB("Exiting function %s because of ret %d eError=%x", __FUNCTION__, ret, eError);
    371     // Release image buffers
    372     if ( NULL != mReleaseImageBuffersCallback ) {
    373         mReleaseImageBuffersCallback(mReleaseData);
    374     }
    375     performCleanupAfterError();
    376     LOG_FUNCTION_NAME_EXIT;
    377     return (ret | Utils::ErrorUtils::omxToAndroidError(eError));
    378 
    379 }
    380 
    381 } // namespace Camera
    382 } // namespace Ti
    383