/* * 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 OMXDCC.cpp * * This file contains functionality for loading the DCC binaries. * */ #include "CameraHal.h" #include "OMXCameraAdapter.h" #include "ErrorUtils.h" #include "OMXDCC.h" #include <utils/String8.h> #include <utils/Vector.h> namespace Ti { namespace Camera { android::String8 DCCHandler::DCCPath("/data/misc/camera/"); bool DCCHandler::mDCCLoaded = false; status_t DCCHandler::loadDCC(OMX_HANDLETYPE hComponent) { OMX_ERRORTYPE dccError = OMX_ErrorNone; if (!mDCCLoaded) { dccError = initDCC(hComponent); if (dccError != OMX_ErrorNone) { CAMHAL_LOGE(" Error in DCC Init"); } mDCCLoaded = true; } return Utils::ErrorUtils::omxToAndroidError(dccError); } OMX_ERRORTYPE DCCHandler::initDCC(OMX_HANDLETYPE hComponent) { OMX_TI_PARAM_DCCURIINFO param; OMX_PTR ptempbuf; OMX_U16 nIndex = 0; OMX_ERRORTYPE eError = OMX_ErrorNone; int ret; OMX_S32 status = 0; android::Vector<android::String8 *> dccDirs; OMX_U16 i; MemoryManager memMgr; CameraBuffer *dccBuffer = NULL; int dccbuf_size = 0; OMX_INIT_STRUCT_PTR(¶m, OMX_TI_PARAM_DCCURIINFO); // Read the the DCC URI info for (nIndex = 0; eError != OMX_ErrorNoMore; nIndex++) { param.nIndex = nIndex; eError = OMX_GetParameter(hComponent, ( OMX_INDEXTYPE )OMX_TI_IndexParamDccUriInfo, ¶m); if (eError == OMX_ErrorNone) { CAMHAL_LOGD("DCC URI's %s ", param.sDCCURI); android::String8 *dccDir = new android::String8(); if ( NULL != dccDir ) { dccDir->clear(); dccDir->append(DCCPath); dccDir->append((const char *) param.sDCCURI); dccDir->append("/"); dccDirs.add(dccDir); } else { CAMHAL_LOGE("DCC URI not allocated"); eError = OMX_ErrorInsufficientResources; goto EXIT; } } } // setting back errortype OMX_ErrorNone if (eError == OMX_ErrorNoMore) { eError = OMX_ErrorNone; } dccbuf_size = readDCCdir(NULL, dccDirs); if(dccbuf_size <= 0) { CAMHAL_LOGE("No DCC files found, switching back to default DCC"); eError = OMX_ErrorInsufficientResources; goto EXIT; } dccbuf_size = ((dccbuf_size + 4095 )/4096)*4096; if ( memMgr.initialize() != NO_ERROR ) { CAMHAL_LOGE("DCC memory manager initialization failed!!!"); eError = OMX_ErrorInsufficientResources; goto EXIT; } dccBuffer = memMgr.allocateBufferList(0, 0, NULL, dccbuf_size, 1); if ( NULL == dccBuffer ) { CAMHAL_LOGE("DCC buffer allocation failed!!!"); eError = OMX_ErrorInsufficientResources; goto EXIT; } dccbuf_size = readDCCdir(dccBuffer[0].mapped, dccDirs); CAMHAL_ASSERT_X(dccbuf_size > 0,"ERROR in copy DCC files into buffer"); eError = sendDCCBufPtr(hComponent, dccBuffer); EXIT: for (i = 0; i < dccDirs.size(); i++) { android::String8 *dccDir = dccDirs.itemAt(0); dccDirs.removeAt(0); delete dccDir; } if ( NULL != dccBuffer ) { memMgr.freeBufferList(dccBuffer); } return eError; } OMX_ERRORTYPE DCCHandler::sendDCCBufPtr(OMX_HANDLETYPE hComponent, CameraBuffer *dccBuffer) { OMX_TI_CONFIG_SHAREDBUFFER uribufparam; OMX_ERRORTYPE eError = OMX_ErrorNone; OMX_INIT_STRUCT_PTR(&uribufparam, OMX_TI_CONFIG_SHAREDBUFFER); CAMHAL_ASSERT_X(dccBuffer != NULL,"ERROR invalid DCC buffer"); uribufparam.nPortIndex = OMX_ALL; uribufparam.nSharedBuffSize = dccBuffer->size; uribufparam.pSharedBuff = (OMX_U8 *) camera_buffer_get_omx_ptr(dccBuffer); eError = OMX_SetParameter(hComponent, ( OMX_INDEXTYPE )OMX_TI_IndexParamDccUriBuffer, &uribufparam); if (eError != OMX_ErrorNone) { CAMHAL_LOGEB(" Error in SetParam for DCC Uri Buffer 0x%x", eError); } return eError; } size_t DCCHandler::readDCCdir(OMX_PTR buffer, const android::Vector<android::String8 *> &dirPaths) { FILE *pFile; OMX_S32 lSize; OMX_S32 dcc_buf_size = 0; size_t result; OMX_STRING filename; android::String8 temp; const char *dotdot = ".."; DIR *d; struct dirent *dir; OMX_U16 i = 0; status_t stat = NO_ERROR; size_t ret = 0; for (i = 0; i < dirPaths.size(); i++) { d = opendir(dirPaths.itemAt(i)->string()); if (d) { // read each filename while ((dir = readdir(d)) != NULL) { filename = dir->d_name; temp.clear(); temp.append(dirPaths.itemAt(i)->string()); temp.append(filename); if ((*filename != *dotdot)) { pFile = fopen(temp.string(), "rb"); if (pFile == NULL) { stat = -errno; } else { fseek(pFile, 0, SEEK_END); lSize = ftell(pFile); rewind(pFile); // buffer is not NULL then copy all the DCC profiles into buffer // else return the size of the DCC directory. if (buffer) { // copy file into the buffer: result = fread(buffer, 1, lSize, pFile); if (result != (size_t) lSize) { stat = INVALID_OPERATION; } buffer = buffer + lSize; } // getting the size of the total dcc files available in FS */ dcc_buf_size = dcc_buf_size + lSize; // terminate fclose(pFile); } } } closedir(d); } } if (stat == NO_ERROR) { ret = dcc_buf_size; } return ret; } } // namespace Camera } // namespace Ti