/*
* 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 OMX3A.cpp
*
* This file contains functionality for handling 3A configurations.
*
*/
#undef LOG_TAG
#define LOG_TAG "OMXMetaData"
#include "OMXCameraAdapter.h"
#include <camera/CameraMetadata.h>
namespace Ti {
namespace Camera {
#ifdef OMAP_ENHANCEMENT_CPCAM
camera_memory_t * OMXCameraAdapter::getMetaData(const OMX_PTR plat_pvt,
camera_request_memory allocator) const
{
camera_memory_t * ret = NULL;
OMX_OTHER_EXTRADATATYPE *extraData;
OMX_FACEDETECTIONTYPE *faceData = NULL;
OMX_TI_WHITEBALANCERESULTTYPE * WBdata = NULL;
OMX_TI_VECTSHOTINFOTYPE *shotInfo = NULL;
OMX_TI_LSCTABLETYPE *lscTbl = NULL;
camera_metadata_t *metaData;
size_t offset = 0;
size_t metaDataSize = sizeof(camera_metadata_t);
extraData = getExtradata(plat_pvt, (OMX_EXTRADATATYPE) OMX_FaceDetection);
if ( NULL != extraData ) {
faceData = ( OMX_FACEDETECTIONTYPE * ) extraData->data;
metaDataSize += faceData->ulFaceCount * sizeof(camera_metadata_face_t);
}
extraData = getExtradata(plat_pvt, (OMX_EXTRADATATYPE) OMX_WhiteBalance);
if ( NULL != extraData ) {
WBdata = ( OMX_TI_WHITEBALANCERESULTTYPE * ) extraData->data;
}
extraData = getExtradata(plat_pvt, (OMX_EXTRADATATYPE) OMX_TI_VectShotInfo);
if ( NULL != extraData ) {
shotInfo = ( OMX_TI_VECTSHOTINFOTYPE * ) extraData->data;
}
extraData = getExtradata(plat_pvt, (OMX_EXTRADATATYPE) OMX_TI_LSCTable);
if ( NULL != extraData ) {
lscTbl = ( OMX_TI_LSCTABLETYPE * ) extraData->data;
metaDataSize += OMX_TI_LSC_GAIN_TABLE_SIZE;
}
ret = allocator(-1, metaDataSize, 1, NULL);
if ( NULL == ret ) {
return NULL;
} else {
metaData = static_cast<camera_metadata_t *> (ret->data);
offset += sizeof(camera_metadata_t);
}
if ( NULL != faceData ) {
metaData->number_of_faces = 0;
int idx = 0;
metaData->faces_offset = offset;
struct camera_metadata_face *faces = reinterpret_cast<struct camera_metadata_face *> (static_cast<char*>(ret->data) + offset);
for ( int j = 0; j < faceData->ulFaceCount ; j++ ) {
if(faceData->tFacePosition[j].nScore <= FACE_DETECTION_THRESHOLD) {
continue;
}
idx = metaData->number_of_faces;
metaData->number_of_faces++;
// TODO: Rework and re-use encodeFaceCoordinates()
faces[idx].left = faceData->tFacePosition[j].nLeft;
faces[idx].top = faceData->tFacePosition[j].nTop;
faces[idx].bottom = faceData->tFacePosition[j].nWidth;
faces[idx].right = faceData->tFacePosition[j].nHeight;
}
offset += sizeof(camera_metadata_face_t) * metaData->number_of_faces;
}
if ( NULL != WBdata ) {
metaData->awb_temp = WBdata->nColorTemperature;
metaData->gain_b = WBdata->nGainB;
metaData->gain_gb = WBdata->nGainGB;
metaData->gain_gr = WBdata->nGainGR;
metaData->gain_r = WBdata->nGainR;
metaData->offset_b = WBdata->nOffsetB;
metaData->offset_gb = WBdata->nOffsetGB;
metaData->offset_gr = WBdata->nOffsetGR;
metaData->offset_r = WBdata->nOffsetR;
}
if ( NULL != lscTbl ) {
metaData->lsc_table_applied = lscTbl->bApplied;
metaData->lsc_table_size = OMX_TI_LSC_GAIN_TABLE_SIZE;
metaData->lsc_table_offset = offset;
uint8_t *lsc_table = reinterpret_cast<uint8_t *> (static_cast<char*>(ret->data) + offset);
memcpy(lsc_table, lscTbl->pGainTable, OMX_TI_LSC_GAIN_TABLE_SIZE);
offset += metaData->lsc_table_size;
}
if ( NULL != shotInfo ) {
metaData->frame_number = shotInfo->nFrameNum;
metaData->shot_number = shotInfo->nConfigId;
metaData->analog_gain = shotInfo->nAGain;
metaData->analog_gain_req = shotInfo->nReqGain;
metaData->analog_gain_min = shotInfo->nGainMin;
metaData->analog_gain_max = shotInfo->nGainMax;
metaData->analog_gain_error = shotInfo->nSenAGainErr;
metaData->analog_gain_dev = shotInfo->nDevAGain;
metaData->exposure_time = shotInfo->nExpTime;
metaData->exposure_time_req = shotInfo->nReqExpTime;
metaData->exposure_time_min = shotInfo->nExpMin;
metaData->exposure_time_max = shotInfo->nExpMax;
metaData->exposure_time_dev = shotInfo->nDevExpTime;
metaData->exposure_time_error = shotInfo->nSenExpTimeErr;
metaData->exposure_compensation_req = shotInfo->nReqEC;
metaData->exposure_dev = shotInfo->nDevEV;
}
return ret;
}
#endif
status_t OMXCameraAdapter::encodePreviewMetadata(camera_frame_metadata_t *meta, const OMX_PTR plat_pvt)
{
status_t ret = NO_ERROR;
#ifdef OMAP_ENHANCEMENT_CPCAM
OMX_OTHER_EXTRADATATYPE *extraData = NULL;
extraData = getExtradata(plat_pvt, (OMX_EXTRADATATYPE) OMX_TI_VectShotInfo);
if ( (NULL != extraData) && (NULL != extraData->data) ) {
OMX_TI_VECTSHOTINFOTYPE *shotInfo;
shotInfo = (OMX_TI_VECTSHOTINFOTYPE*) extraData->data;
meta->analog_gain = shotInfo->nAGain;
meta->exposure_time = shotInfo->nExpTime;
} else {
meta->analog_gain = -1;
meta->exposure_time = -1;
}
// Send metadata event only after any value has been changed
if ((metadataLastAnalogGain == meta->analog_gain) &&
(metadataLastExposureTime == meta->exposure_time)) {
ret = NOT_ENOUGH_DATA;
} else {
metadataLastAnalogGain = meta->analog_gain;
metadataLastExposureTime = meta->exposure_time;
}
#else
// no-op in non enhancement mode
CAMHAL_UNUSED(meta);
CAMHAL_UNUSED(plat_pvt);
#endif
return ret;
}
} // namespace Camera
} // namespace Ti