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 OMX3A.cpp
19*
20* This file contains functionality for handling 3A configurations.
21*
22*/
23
24#undef LOG_TAG
25
26#define LOG_TAG "OMXMetaData"
27
28#include "OMXCameraAdapter.h"
29#include <camera/CameraMetadata.h>
30
31namespace Ti {
32namespace Camera {
33
34#ifdef OMAP_ENHANCEMENT_CPCAM
35camera_memory_t * OMXCameraAdapter::getMetaData(const OMX_PTR plat_pvt,
36                                                camera_request_memory allocator) const
37{
38    camera_memory_t * ret = NULL;
39
40    OMX_OTHER_EXTRADATATYPE *extraData;
41    OMX_FACEDETECTIONTYPE *faceData = NULL;
42    OMX_TI_WHITEBALANCERESULTTYPE * WBdata = NULL;
43    OMX_TI_VECTSHOTINFOTYPE *shotInfo = NULL;
44    OMX_TI_LSCTABLETYPE *lscTbl = NULL;
45    camera_metadata_t *metaData;
46    size_t offset = 0;
47
48    size_t metaDataSize = sizeof(camera_metadata_t);
49
50    extraData = getExtradata(plat_pvt, (OMX_EXTRADATATYPE) OMX_FaceDetection);
51    if ( NULL != extraData ) {
52        faceData = ( OMX_FACEDETECTIONTYPE * ) extraData->data;
53        metaDataSize += faceData->ulFaceCount * sizeof(camera_metadata_face_t);
54    }
55
56    extraData = getExtradata(plat_pvt, (OMX_EXTRADATATYPE) OMX_WhiteBalance);
57    if ( NULL != extraData ) {
58        WBdata = ( OMX_TI_WHITEBALANCERESULTTYPE * ) extraData->data;
59    }
60
61    extraData = getExtradata(plat_pvt, (OMX_EXTRADATATYPE) OMX_TI_VectShotInfo);
62    if ( NULL != extraData ) {
63        shotInfo = ( OMX_TI_VECTSHOTINFOTYPE * ) extraData->data;
64    }
65
66    extraData = getExtradata(plat_pvt, (OMX_EXTRADATATYPE) OMX_TI_LSCTable);
67    if ( NULL != extraData ) {
68        lscTbl = ( OMX_TI_LSCTABLETYPE * ) extraData->data;
69        metaDataSize += OMX_TI_LSC_GAIN_TABLE_SIZE;
70    }
71
72    ret = allocator(-1, metaDataSize, 1, NULL);
73    if ( NULL == ret ) {
74        return NULL;
75    } else {
76        metaData = static_cast<camera_metadata_t *> (ret->data);
77        offset += sizeof(camera_metadata_t);
78    }
79
80    if ( NULL != faceData ) {
81        metaData->number_of_faces = 0;
82        int idx = 0;
83        metaData->faces_offset = offset;
84        struct camera_metadata_face *faces = reinterpret_cast<struct camera_metadata_face *> (static_cast<char*>(ret->data) + offset);
85        for ( int j = 0; j < faceData->ulFaceCount ; j++ ) {
86            if(faceData->tFacePosition[j].nScore <= FACE_DETECTION_THRESHOLD) {
87                continue;
88            }
89            idx = metaData->number_of_faces;
90            metaData->number_of_faces++;
91            // TODO: Rework and re-use encodeFaceCoordinates()
92            faces[idx].left  = faceData->tFacePosition[j].nLeft;
93            faces[idx].top = faceData->tFacePosition[j].nTop;
94            faces[idx].bottom = faceData->tFacePosition[j].nWidth;
95            faces[idx].right = faceData->tFacePosition[j].nHeight;
96        }
97        offset += sizeof(camera_metadata_face_t) * metaData->number_of_faces;
98    }
99
100    if ( NULL != WBdata ) {
101        metaData->awb_temp = WBdata->nColorTemperature;
102        metaData->gain_b = WBdata->nGainB;
103        metaData->gain_gb = WBdata->nGainGB;
104        metaData->gain_gr = WBdata->nGainGR;
105        metaData->gain_r = WBdata->nGainR;
106        metaData->offset_b = WBdata->nOffsetB;
107        metaData->offset_gb = WBdata->nOffsetGB;
108        metaData->offset_gr = WBdata->nOffsetGR;
109        metaData->offset_r = WBdata->nOffsetR;
110    }
111
112    if ( NULL != lscTbl ) {
113        metaData->lsc_table_applied = lscTbl->bApplied;
114        metaData->lsc_table_size = OMX_TI_LSC_GAIN_TABLE_SIZE;
115        metaData->lsc_table_offset = offset;
116        uint8_t *lsc_table = reinterpret_cast<uint8_t *> (static_cast<char*>(ret->data) + offset);
117        memcpy(lsc_table, lscTbl->pGainTable, OMX_TI_LSC_GAIN_TABLE_SIZE);
118        offset += metaData->lsc_table_size;
119    }
120
121    if ( NULL != shotInfo ) {
122        metaData->frame_number = shotInfo->nFrameNum;
123        metaData->shot_number = shotInfo->nConfigId;
124        metaData->analog_gain = shotInfo->nAGain;
125        metaData->analog_gain_req = shotInfo->nReqGain;
126        metaData->analog_gain_min = shotInfo->nGainMin;
127        metaData->analog_gain_max = shotInfo->nGainMax;
128        metaData->analog_gain_error = shotInfo->nSenAGainErr;
129        metaData->analog_gain_dev = shotInfo->nDevAGain;
130        metaData->exposure_time = shotInfo->nExpTime;
131        metaData->exposure_time_req = shotInfo->nReqExpTime;
132        metaData->exposure_time_min = shotInfo->nExpMin;
133        metaData->exposure_time_max = shotInfo->nExpMax;
134        metaData->exposure_time_dev = shotInfo->nDevExpTime;
135        metaData->exposure_time_error = shotInfo->nSenExpTimeErr;
136        metaData->exposure_compensation_req = shotInfo->nReqEC;
137        metaData->exposure_dev = shotInfo->nDevEV;
138    }
139
140    return ret;
141}
142#endif
143
144status_t OMXCameraAdapter::encodePreviewMetadata(camera_frame_metadata_t *meta, const OMX_PTR plat_pvt)
145{
146    status_t ret = NO_ERROR;
147#ifdef OMAP_ENHANCEMENT_CPCAM
148    OMX_OTHER_EXTRADATATYPE *extraData = NULL;
149
150    extraData = getExtradata(plat_pvt, (OMX_EXTRADATATYPE) OMX_TI_VectShotInfo);
151
152    if ( (NULL != extraData) && (NULL != extraData->data) ) {
153        OMX_TI_VECTSHOTINFOTYPE *shotInfo;
154        shotInfo = (OMX_TI_VECTSHOTINFOTYPE*) extraData->data;
155
156        meta->analog_gain = shotInfo->nAGain;
157        meta->exposure_time = shotInfo->nExpTime;
158    } else {
159        meta->analog_gain = -1;
160        meta->exposure_time = -1;
161    }
162
163    // Send metadata event only after any value has been changed
164    if ((metadataLastAnalogGain == meta->analog_gain) &&
165        (metadataLastExposureTime == meta->exposure_time)) {
166        ret = NOT_ENOUGH_DATA;
167    } else {
168        metadataLastAnalogGain = meta->analog_gain;
169        metadataLastExposureTime = meta->exposure_time;
170    }
171#else
172    // no-op in non enhancement mode
173    CAMHAL_UNUSED(meta);
174    CAMHAL_UNUSED(plat_pvt);
175#endif
176
177    return ret;
178}
179
180} // namespace Camera
181} // namespace Ti
182