C++程序  |  182行  |  6.31 KB

/*
 * 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