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(¶m, 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 ¶m); 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