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 OMXDCC.cpp
     19 *
     20 * This file contains functionality for loading the DCC binaries.
     21 *
     22 */
     23 
     24 #include "CameraHal.h"
     25 #include "OMXCameraAdapter.h"
     26 #include "ErrorUtils.h"
     27 #include "OMXDCC.h"
     28 #include <utils/String8.h>
     29 #include <utils/Vector.h>
     30 
     31 namespace Ti {
     32 namespace Camera {
     33 
     34 android::String8 DCCHandler::DCCPath("/data/misc/camera/");
     35 bool DCCHandler::mDCCLoaded = false;
     36 
     37 status_t DCCHandler::loadDCC(OMX_HANDLETYPE hComponent)
     38 {
     39     OMX_ERRORTYPE dccError = OMX_ErrorNone;
     40 
     41     if (!mDCCLoaded) {
     42         dccError = initDCC(hComponent);
     43         if (dccError != OMX_ErrorNone) {
     44             CAMHAL_LOGE(" Error in DCC Init");
     45         }
     46 
     47         mDCCLoaded = true;
     48     }
     49 
     50     return Utils::ErrorUtils::omxToAndroidError(dccError);
     51 }
     52 
     53 OMX_ERRORTYPE DCCHandler::initDCC(OMX_HANDLETYPE hComponent)
     54 {
     55     OMX_TI_PARAM_DCCURIINFO param;
     56     OMX_PTR ptempbuf;
     57     OMX_U16 nIndex = 0;
     58     OMX_ERRORTYPE eError = OMX_ErrorNone;
     59     int ret;
     60     OMX_S32 status = 0;
     61     android::Vector<android::String8 *> dccDirs;
     62     OMX_U16 i;
     63     MemoryManager memMgr;
     64     CameraBuffer *dccBuffer = NULL;
     65     int dccbuf_size = 0;
     66     OMX_INIT_STRUCT_PTR(&param, OMX_TI_PARAM_DCCURIINFO);
     67 
     68     // Read the the DCC URI info
     69     for (nIndex = 0; eError != OMX_ErrorNoMore; nIndex++) {
     70         param.nIndex = nIndex;
     71         eError = OMX_GetParameter(hComponent,
     72                                   ( OMX_INDEXTYPE )OMX_TI_IndexParamDccUriInfo,
     73                                   &param);
     74 
     75         if (eError == OMX_ErrorNone) {
     76             CAMHAL_LOGD("DCC URI's %s ", param.sDCCURI);
     77             android::String8 *dccDir = new android::String8();
     78             if ( NULL != dccDir ) {
     79                 dccDir->clear();
     80                 dccDir->append(DCCPath);
     81                 dccDir->append((const char *) param.sDCCURI);
     82                 dccDir->append("/");
     83                 dccDirs.add(dccDir);
     84             } else {
     85                 CAMHAL_LOGE("DCC URI not allocated");
     86                 eError = OMX_ErrorInsufficientResources;
     87                 goto EXIT;
     88             }
     89         }
     90     }
     91 
     92     // setting  back errortype OMX_ErrorNone
     93     if (eError == OMX_ErrorNoMore) {
     94         eError = OMX_ErrorNone;
     95     }
     96 
     97     dccbuf_size = readDCCdir(NULL, dccDirs);
     98     if(dccbuf_size <= 0) {
     99         CAMHAL_LOGE("No DCC files found, switching back to default DCC");
    100         eError = OMX_ErrorInsufficientResources;
    101         goto EXIT;
    102     }
    103     dccbuf_size = ((dccbuf_size + 4095 )/4096)*4096;
    104 
    105     if ( memMgr.initialize() != NO_ERROR ) {
    106         CAMHAL_LOGE("DCC memory manager initialization failed!!!");
    107         eError = OMX_ErrorInsufficientResources;
    108         goto EXIT;
    109     }
    110 
    111     dccBuffer = memMgr.allocateBufferList(0, 0, NULL, dccbuf_size, 1);
    112     if ( NULL == dccBuffer ) {
    113         CAMHAL_LOGE("DCC buffer allocation failed!!!");
    114         eError = OMX_ErrorInsufficientResources;
    115         goto EXIT;
    116     }
    117 
    118     dccbuf_size = readDCCdir(dccBuffer[0].mapped, dccDirs);
    119     CAMHAL_ASSERT_X(dccbuf_size > 0,"ERROR in copy DCC files into buffer");
    120 
    121     eError = sendDCCBufPtr(hComponent, dccBuffer);
    122 
    123 EXIT:
    124 
    125     for (i = 0; i < dccDirs.size(); i++) {
    126         android::String8 *dccDir = dccDirs.itemAt(0);
    127         dccDirs.removeAt(0);
    128         delete dccDir;
    129     }
    130 
    131     if ( NULL != dccBuffer ) {
    132         memMgr.freeBufferList(dccBuffer);
    133     }
    134 
    135      return eError;
    136 }
    137 
    138 OMX_ERRORTYPE DCCHandler::sendDCCBufPtr(OMX_HANDLETYPE hComponent,
    139                                     CameraBuffer *dccBuffer)
    140 {
    141     OMX_TI_CONFIG_SHAREDBUFFER uribufparam;
    142     OMX_ERRORTYPE eError = OMX_ErrorNone;
    143     OMX_INIT_STRUCT_PTR(&uribufparam, OMX_TI_CONFIG_SHAREDBUFFER);
    144 
    145     CAMHAL_ASSERT_X(dccBuffer != NULL,"ERROR invalid DCC buffer");
    146 
    147     uribufparam.nPortIndex = OMX_ALL;
    148     uribufparam.nSharedBuffSize = dccBuffer->size;
    149     uribufparam.pSharedBuff = (OMX_U8 *) camera_buffer_get_omx_ptr(dccBuffer);
    150 
    151     eError = OMX_SetParameter(hComponent,
    152                                 ( OMX_INDEXTYPE )OMX_TI_IndexParamDccUriBuffer,
    153                                 &uribufparam);
    154     if (eError != OMX_ErrorNone) {
    155         CAMHAL_LOGEB(" Error in SetParam for DCC Uri Buffer 0x%x", eError);
    156     }
    157 
    158     return eError;
    159 }
    160 
    161 size_t DCCHandler::readDCCdir(OMX_PTR buffer,
    162                           const android::Vector<android::String8 *> &dirPaths)
    163 {
    164     FILE *pFile;
    165     OMX_S32 lSize;
    166     OMX_S32 dcc_buf_size = 0;
    167     size_t result;
    168     OMX_STRING filename;
    169     android::String8 temp;
    170     const char *dotdot = "..";
    171     DIR *d;
    172     struct dirent *dir;
    173     OMX_U16 i = 0;
    174     status_t stat = NO_ERROR;
    175     size_t ret = 0;
    176 
    177     for (i = 0; i < dirPaths.size(); i++) {
    178         d = opendir(dirPaths.itemAt(i)->string());
    179         if (d) {
    180             // read each filename
    181             while ((dir = readdir(d)) != NULL) {
    182                 filename = dir->d_name;
    183                 temp.clear();
    184                 temp.append(dirPaths.itemAt(i)->string());
    185                 temp.append(filename);
    186                 if ((*filename != *dotdot)) {
    187                     pFile = fopen(temp.string(), "rb");
    188                     if (pFile == NULL) {
    189                         stat = -errno;
    190                     } else {
    191                         fseek(pFile, 0, SEEK_END);
    192                         lSize = ftell(pFile);
    193                         rewind(pFile);
    194                         // buffer is not NULL then copy all the DCC profiles into buffer
    195                         // else return the size of the DCC directory.
    196                         if (buffer) {
    197                             // copy file into the buffer:
    198                             result = fread(buffer, 1, lSize, pFile);
    199                             if (result != (size_t) lSize) {
    200                                 stat = INVALID_OPERATION;
    201                             }
    202                             buffer = buffer + lSize;
    203                         }
    204                         // getting the size of the total dcc files available in FS */
    205                         dcc_buf_size = dcc_buf_size + lSize;
    206                         // terminate
    207                         fclose(pFile);
    208                     }
    209                 }
    210             }
    211             closedir(d);
    212         }
    213     }
    214 
    215     if (stat == NO_ERROR) {
    216         ret = dcc_buf_size;
    217     }
    218 
    219     return ret;
    220 }
    221 
    222 } // namespace Camera
    223 } // namespace Ti
    224