1f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons/*
2f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons * Copyright (C) Texas Instruments - http://www.ti.com/
3f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons *
4f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons * Licensed under the Apache License, Version 2.0 (the "License");
5f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons * you may not use this file except in compliance with the License.
6f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons * You may obtain a copy of the License at
7f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons *
8f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons *      http://www.apache.org/licenses/LICENSE-2.0
9f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons *
10f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons * Unless required by applicable law or agreed to in writing, software
11f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons * distributed under the License is distributed on an "AS IS" BASIS,
12f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons * See the License for the specific language governing permissions and
14f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons * limitations under the License.
15f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons */
16f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
17f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons/**
18f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons* @file OMXDccDataSave.cpp
19f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons*
20f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons* This file contains functionality for handling DCC data save
21f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons*
22f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons*/
23f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
24f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons#include "CameraHal.h"
25f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons#include "OMXCameraAdapter.h"
26f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
27f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
28f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsnamespace Ti {
29f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsnamespace Camera {
30f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
31f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsstatus_t OMXCameraAdapter::initDccFileDataSave(OMX_HANDLETYPE* omxHandle, int portIndex)
32f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
33f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    OMX_CONFIG_EXTRADATATYPE extraDataControl;
34f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    status_t ret = NO_ERROR;
35f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    OMX_ERRORTYPE eError = OMX_ErrorNone;
36f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
37f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME;
38f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
39f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    OMX_INIT_STRUCT_PTR (&extraDataControl, OMX_CONFIG_EXTRADATATYPE);
40f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    extraDataControl.nPortIndex = portIndex;
41f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    extraDataControl.eExtraDataType = OMX_TI_DccData;
42f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    extraDataControl.bEnable = OMX_TRUE;
43f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
44f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    eError =  OMX_SetConfig(*omxHandle,
45f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                        ( OMX_INDEXTYPE ) OMX_IndexConfigOtherExtraDataControl,
46f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                        &extraDataControl);
47f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
48f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if ( OMX_ErrorNone != eError )
49f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        {
50f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGEB("Error while configuring dcc data overwrite extra data 0x%x",
51f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                    eError);
52f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
53f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        ret =  NO_INIT;
54f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
55f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
56f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (mDccData.pData) {
57f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        free(mDccData.pData);
58f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mDccData.pData = NULL;
59f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
60f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME_EXIT;
61f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
62f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return ret;
63f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
64f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
65f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsstatus_t OMXCameraAdapter::sniffDccFileDataSave(OMX_BUFFERHEADERTYPE* pBuffHeader)
66f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
67f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    OMX_OTHER_EXTRADATATYPE *extraData;
68f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    OMX_TI_DCCDATATYPE* dccData;
69f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    status_t ret = NO_ERROR;
70f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
71f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME;
72f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
73f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    android::AutoMutex lock(mDccDataLock);
74f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
75f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if ( NULL == pBuffHeader ) {
76f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGEA("Invalid Buffer header");
77f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        LOG_FUNCTION_NAME_EXIT;
78f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        return -EINVAL;
79f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
80f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
81f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    extraData = getExtradata(pBuffHeader->pPlatformPrivate,
82f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                             (OMX_EXTRADATATYPE)OMX_TI_DccData);
83f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
84f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if ( NULL != extraData ) {
85f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGVB("Size = %d, sizeof = %d, eType = 0x%x, nDataSize= %d, nPortIndex = 0x%x, nVersion = 0x%x",
86f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                     extraData->nSize,
87f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                     sizeof(OMX_OTHER_EXTRADATATYPE),
88f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                     extraData->eType,
89f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                     extraData->nDataSize,
90f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                     extraData->nPortIndex,
91f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                     extraData->nVersion);
92f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    } else {
93f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGVA("Invalid OMX_TI_DCCDATATYPE");
94f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        LOG_FUNCTION_NAME_EXIT;
95f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        return NO_ERROR;
96f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
97f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
98f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    dccData = ( OMX_TI_DCCDATATYPE * ) extraData->data;
99f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
100f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (NULL == dccData) {
101f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGVA("OMX_TI_DCCDATATYPE is not found in extra data");
102f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        LOG_FUNCTION_NAME_EXIT;
103f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        return NO_ERROR;
104f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
105f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
106f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (mDccData.pData) {
107f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        free(mDccData.pData);
108f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
109f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
110f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    memcpy(&mDccData, dccData, sizeof(mDccData));
111f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
112f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    int dccDataSize = (int)dccData->nSize - (int)(&(((OMX_TI_DCCDATATYPE*)0)->pData));
113f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
114f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    mDccData.pData = (OMX_PTR)malloc(dccDataSize);
115f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
116f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (NULL == mDccData.pData) {
117f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGVA("not enough memory for DCC data");
118f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        LOG_FUNCTION_NAME_EXIT;
119f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        return NO_ERROR;
120f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
121f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
122f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    memcpy(mDccData.pData, &(dccData->pData), dccDataSize);
123f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
124f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME_EXIT;
125f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
126f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return ret;
127f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
128f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
129f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons// Recursively searches given directory contents for the correct DCC file.
130f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons// The directory must be opened and its stream pointer + path passed
131f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons// as arguments. As this function is called recursively, to avoid excessive
132f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons// stack usage the path param is reused -> this MUST be char array with
133f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons// enough length!!! (260 should suffice). Path must end with "/".
134f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons// The directory must also be closed in the caller function.
135f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons// If the correct camera DCC file is found (based on the OMX measurement data)
136f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons// its file stream pointer is returned. NULL is returned otherwise
137f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason SimmonsFILE * OMXCameraAdapter::parseDCCsubDir(DIR *pDir, char *path)
138f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
139f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    FILE *pFile;
140f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    DIR *pSubDir;
141f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    struct dirent *dirEntry;
142f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    int initialPathLength = strlen(path);
143f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
144f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME;
145f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
146f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    /* check each directory entry */
147f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    while ((dirEntry = readdir(pDir)) != NULL)
148f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    {
149f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if (dirEntry->d_name[0] == '.')
150f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            continue;
151f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
152f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        strcat(path, dirEntry->d_name);
153f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        // dirEntry might be sub directory -> check it
154f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        pSubDir = opendir(path);
155f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if (pSubDir) {
156f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            // dirEntry is sub directory -> parse it
157f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            strcat(path, "/");
158f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            pFile = parseDCCsubDir(pSubDir, path);
159f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            closedir(pSubDir);
160f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            if (pFile) {
161f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                // the correct DCC file found!
162f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                LOG_FUNCTION_NAME_EXIT;
163f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                return pFile;
164f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            }
165f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        } else {
166f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            // dirEntry is file -> open it
167f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            pFile = fopen(path, "rb");
168f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            if (pFile) {
169f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                // now check if this is the correct DCC file for that camera
170f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                OMX_U32 dccFileIDword;
171f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                OMX_U32 *dccFileDesc = (OMX_U32 *) &mDccData.nCameraModuleId;
172f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                int i;
173f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
174f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                // DCC file ID is 3 4-byte words
175f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                for (i = 0; i < 3; i++) {
176f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                    if (fread(&dccFileIDword, sizeof(OMX_U32), 1, pFile) != 1) {
177f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                        // file too short
178f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                        break;
179f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                    }
180f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                    if (dccFileIDword != dccFileDesc[i]) {
181f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                        // DCC file ID word i does not match
182f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                        break;
183f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                    }
184f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                }
185f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
186f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                fclose(pFile);
187f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                if (i == 3) {
188f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                    // the correct DCC file found!
189f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                    CAMHAL_LOGDB("DCC file to be updated: %s", path);
190f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                    // reopen it for modification
191f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                    pFile = fopen(path, "rb+");
192f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                    if (!pFile)
193f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                        CAMHAL_LOGEB("ERROR: DCC file %s failed to open for modification", path);
194f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                    LOG_FUNCTION_NAME_EXIT;
195f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                    return pFile;
196f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                }
197f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            } else {
198f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                CAMHAL_LOGEB("ERROR: Failed to open file %s for reading", path);
199f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            }
200f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
201f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        // restore original path
202f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        path[initialPathLength] = '\0';
203f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
204f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
205f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME_EXIT;
206f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
207f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    // DCC file not found in this directory tree
208f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return NULL;
209f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
210f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
211f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons// Finds the DCC file corresponding to the current camera based on the
212f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons// OMX measurement data, opens it and returns the file stream pointer
213f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons// (NULL on error or if file not found).
214f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons// The folder string dccFolderPath must end with "/"
215f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason SimmonsFILE * OMXCameraAdapter::fopenCameraDCC(const char *dccFolderPath)
216f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
217f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    FILE *pFile;
218f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    DIR *pDir;
219f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    char dccPath[260];
220f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
221f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME;
222f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
223f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    strcpy(dccPath, dccFolderPath);
224f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
225f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    pDir = opendir(dccPath);
226f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (!pDir) {
227f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGEB("ERROR: Opening DCC directory %s failed", dccPath);
228f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        LOG_FUNCTION_NAME_EXIT;
229f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        return NULL;
230f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
231f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
232f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    pFile = parseDCCsubDir(pDir, dccPath);
233f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    closedir(pDir);
234f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (pFile) {
235f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGDB("DCC file %s opened for modification", dccPath);
236f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
237f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
238f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME_EXIT;
239f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
240f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return pFile;
241f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
242f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
243f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons// Positions the DCC file stream pointer to the correct offset within the
244f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons// correct usecase based on the OMX mesurement data. Returns 0 on success
245f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsstatus_t OMXCameraAdapter::fseekDCCuseCasePos(FILE *pFile)
246f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
247f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    OMX_U32 dccNumUseCases = 0;
248f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    OMX_U32 dccUseCaseData[3];
249f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    OMX_U32 i;
250f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
251f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME;
252f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
253f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    // position the file pointer to the DCC use cases section
254f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (fseek(pFile, 80, SEEK_SET)) {
255f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGEA("ERROR: Unexpected end of DCC file");
256f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        LOG_FUNCTION_NAME_EXIT;
257f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        return -EINVAL;
258f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
259f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
260f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (fread(&dccNumUseCases, sizeof(OMX_U32), 1, pFile) != 1 ||
261f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        dccNumUseCases == 0) {
262f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGEA("ERROR: DCC file contains 0 use cases");
263f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        LOG_FUNCTION_NAME_EXIT;
264f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        return -EINVAL;
265f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
266f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
267f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    for (i = 0; i < dccNumUseCases; i++) {
268f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if (fread(dccUseCaseData, sizeof(OMX_U32), 3, pFile) != 3) {
269f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            CAMHAL_LOGEA("ERROR: Unexpected end of DCC file");
270f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            LOG_FUNCTION_NAME_EXIT;
271f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            return -EINVAL;
272f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
273f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
274f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if (dccUseCaseData[0] == mDccData.nUseCaseId) {
275f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            // DCC use case match!
276f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            break;
277f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
278f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
279f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
280f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (i == dccNumUseCases) {
281f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGEB("ERROR: Use case ID %lu not found in DCC file", mDccData.nUseCaseId);
282f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        LOG_FUNCTION_NAME_EXIT;
283f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        return -EINVAL;
284f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
285f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
286f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    // dccUseCaseData[1] is the offset to the beginning of the actual use case
287f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    // from the beginning of the file
288f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    // mDccData.nOffset is the offset within the actual use case (from the
289f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    // beginning of the use case to the data to be modified)
290f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
291f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (fseek(pFile,dccUseCaseData[1] + mDccData.nOffset, SEEK_SET ))
292f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    {
293f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        CAMHAL_LOGEA("ERROR: Error setting the correct offset");
294f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        LOG_FUNCTION_NAME_EXIT;
295f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        return -EINVAL;
296f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
297f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
298f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME_EXIT;
299f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
300f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return NO_ERROR;
301f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
302f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
303f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsstatus_t OMXCameraAdapter::saveDccFileDataSave()
304f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
305f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    status_t ret = NO_ERROR;
306f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
307f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME;
308f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
309f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    android::AutoMutex lock(mDccDataLock);
310f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
311f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (mDccData.pData)
312f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        {
313f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        FILE *fd = fopenCameraDCC(DCC_PATH);
314f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
315f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        if (fd)
316f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            {
317f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            if (!fseekDCCuseCasePos(fd))
318f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                {
319f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                int dccDataSize = (int)mDccData.nSize - (int)(&(((OMX_TI_DCCDATATYPE*)0)->pData));
320f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
321f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                if (fwrite(mDccData.pData, dccDataSize, 1, fd) != 1)
322f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                    {
323f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                    CAMHAL_LOGEA("ERROR: Writing to DCC file failed");
324f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                    }
325f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                else
326f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                    {
327f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                    CAMHAL_LOGDA("DCC file successfully updated");
328f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                    }
329f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons                }
330f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            fclose(fd);
331f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            }
332f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        else
333f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            {
334f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            CAMHAL_LOGEA("ERROR: Correct DCC file not found or failed to open for modification");
335f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons            }
336f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        }
337f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
338f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME_EXIT;
339f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
340f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return ret;
341f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
342f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
343f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmonsstatus_t OMXCameraAdapter::closeDccFileDataSave()
344f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons{
345f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    status_t ret = NO_ERROR;
346f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
347f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME;
348f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
349f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    android::AutoMutex lock(mDccDataLock);
350f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
351f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    if (mDccData.pData) {
352f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        free(mDccData.pData);
353f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons        mDccData.pData = NULL;
354f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    }
355f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    LOG_FUNCTION_NAME_EXIT;
356f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
357f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons    return ret;
358f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons}
359f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons
360f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons} // namespace Camera
361f7a4d11e9f710e2cd0592310ac1baecccb85f1d1Jason Simmons} // namespace Ti
362