blob: df0fed6878683fddf93090ffb9d413f141267698 [file] [log] [blame]
/*
* Copyright (C) 2017 Intel Corporation.
* Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd
*
* 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.
*/
#define LOG_TAG "SettingsProcessor"
#include "SettingsProcessor.h"
#include "CameraMetadataHelper.h"
#include "PlatformData.h"
#include "Rk3aPlus.h"
#include "LogHelper.h"
namespace android {
namespace camera2 {
SettingsProcessor::SettingsProcessor(int cameraId,
Rk3aPlus *a3aWrapper, IStreamConfigProvider &aStreamCfgProv) :
mCameraId(cameraId),
m3aWrapper(a3aWrapper),
mMinSensorModeFrameTime(INT32_MAX),
mStreamCfgProv(aStreamCfgProv)
{
/**
* cache some static value for later use
*/
mAPA = PlatformData::getActivePixelArray(mCameraId);
cacheStaticMetadata();
CLEAR(mCurrentFrameParams);
CLEAR(mSensorDescriptor);
}
SettingsProcessor::~SettingsProcessor()
{
}
status_t SettingsProcessor::init()
{
HAL_TRACE_CALL(CAMERA_DEBUG_LOG_LEVEL2);
// save state for fix focus;
/* TODO */
/* mFixedFocus = (m3aWrapper->getMinFocusDistance() == 0.0f); */
return OK;
}
/**
* processRequestSettings
*
* Analyze the request control metadata tags and prepare the configuration for
* the AIQ algorithm to run.
* \param settings [IN] settings from the request
* \param reqAiqCfg [OUT] AIQ configuration
*/
status_t
SettingsProcessor::processRequestSettings(const CameraMetadata &settings,
RequestCtrlState &reqAiqCfg)
{
HAL_TRACE_CALL(CAMERA_DEBUG_LOG_LEVEL2);
status_t status = OK;
/**
* Process cropping first since it is used by other settings
* like AE
**/
processCroppingRegion(settings, reqAiqCfg);
if ((status = processAeSettings(settings, reqAiqCfg)) != OK)
return status;
reqAiqCfg.aeState = ALGORITHM_CONFIGURED;
if ((status = processAwbSettings(settings, reqAiqCfg)) != OK)
return status;
reqAiqCfg.awbState = ALGORITHM_CONFIGURED;
if ((status = processIspSettings(settings, reqAiqCfg)) != OK)
return status;
if ((status = processImageEnhancementSettings(settings, reqAiqCfg)) != OK)
return status;
if ((status = processStabilizationSettings(settings, reqAiqCfg)) != OK)
return status;
if ((status = processHotPixelSettings(settings, reqAiqCfg)) != OK)
return status;
if ((status = processTonemapSettings(settings, reqAiqCfg)) != OK)
return status;
return processTestPatternMode(settings, reqAiqCfg);
}
/**
* processCroppingRegion
*
* Checks if cropping region is set in the capture request settings. If it is
* then fills the corresponding region in the capture settings.
* if it is not it sets the default value, the Active Pixel Array
*
* \param settings[IN] metadata buffer where the settings are stored
* \param reqCfg[OUT] the cropping region is stored inside the capture settings
* of this structure
*
*/
void
SettingsProcessor::processCroppingRegion(const CameraMetadata &settings,
RequestCtrlState &reqCfg)
{
CameraWindow &cropRegion = reqCfg.captureSettings->cropRegion;
// If crop region not available, fill active array size as the default value
//# ANDROID_METADATA_Control android.scaler.cropRegion done
camera_metadata_ro_entry entry = settings.find(ANDROID_SCALER_CROP_REGION);
/**
* Cropping region is invalid if width is 0 or if the rectangle is not
* fully defined (you need 4 values)
*/
//# ANDROID_METADATA_Dynamic android.scaler.cropRegion done
if (entry.count < 4 || entry.data.i32[2] == 0) {
//cropRegion is a reference and will alter captureSettings->cropRegion.
cropRegion = mAPA;
int32_t *cropWindow;
ia_coordinate topLeft = {0, 0};
cropRegion.init(topLeft,
mAPA.width(), //width
mAPA.height(), //height
0);
// meteringRectangle is filling 4 coordinates and weight (5 values)
// here crop region only needs the rectangle, so we copy only 4.
cropWindow = (int32_t*)mAPA.meteringRectangle();
reqCfg.ctrlUnitResult->update(ANDROID_SCALER_CROP_REGION, cropWindow, 4);
} else {
ia_coordinate topLeft = {entry.data.i32[0],entry.data.i32[1]};
cropRegion.init(topLeft,
entry.data.i32[2], //width
entry.data.i32[3], //height
0);
reqCfg.ctrlUnitResult->update(ANDROID_SCALER_CROP_REGION, entry.data.i32, 4);
}
// copy the crop region to the processingSettings so that tasks don't have
// to break the Law-Of-Demeter.
reqCfg.processingSettings->cropRegion = cropRegion;
}
// TODO: isp settings is not ready
status_t SettingsProcessor::processIspSettings(const CameraMetadata &settings,
RequestCtrlState &reqAiqCfg)
{
HAL_TRACE_CALL(CAMERA_DEBUG_LOG_LEVEL2);
camera_metadata_ro_entry entry;
CLEAR(entry);
IspSettings *ispSettings = nullptr;
if (reqAiqCfg.captureSettings) {
ispSettings = &reqAiqCfg.captureSettings->ispSettings;
} else {
LOGE("Capture Settings is nullptr!, bug");
return UNKNOWN_ERROR;
}
//# ANDROID_METADATA_Control android.edge.strength done
//# AM FUTURE
entry = settings.find(ANDROID_EDGE_STRENGTH);
if (entry.count == 1) {
// mapping from 1->10 to -127->128
uint8_t strength = entry.data.u8[0];
/* ispSettings->eeSetting.strength = ((strength * UINT8_MAX) / ANDROID_MAX_STRENGTH) - INT8_MIN; */
reqAiqCfg.captureSettings->ispControls.ee.strength = strength;
} else {
// does not affect according to ia_isp specs.
/* ispSettings->eeSetting.strength = 0; */
}
//# ANDROID_METADATA_Control android.noiseReduction.mode done
entry = settings.find(ANDROID_NOISE_REDUCTION_MODE);
uint8_t noiseReductionMode = 0;
MetadataHelper::getSetting(mStaticMetadataCache.availableNoiseReductionModes, entry,
&noiseReductionMode);
reqAiqCfg.captureSettings->ispControls.nr.mode = noiseReductionMode;
switch (noiseReductionMode) {
case ANDROID_NOISE_REDUCTION_MODE_OFF:
/* ispSettings->nrSetting.feature_level = ia_isp_feature_level_off; */
break;
case ANDROID_NOISE_REDUCTION_MODE_FAST:
// the speed of execution is the same for high or low quality
// therefore we apply also high quality in fast.
/* ispSettings->nrSetting.feature_level = ia_isp_feature_level_high; */
break;
case ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY:
/* ispSettings->nrSetting.feature_level = ia_isp_feature_level_high; */
break;
case ANDROID_NOISE_REDUCTION_MODE_MINIMAL:
/* ispSettings->nrSetting.feature_level = ia_isp_feature_level_low; */
break;
case ANDROID_NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG:
/* ispSettings->nrSetting.feature_level = ia_isp_feature_level_low; */
break;
default:
LOGE("ERROR: Unknown noise reduction mode %d", noiseReductionMode);
return BAD_VALUE;
}
//# ANDROID_METADATA_Control android.noiseReduction.strength done
//# AM FUTURE
entry = settings.find(ANDROID_NOISE_REDUCTION_STRENGTH);
if (entry.count == 1) {
// mapping from 1->10 to -127->128
uint8_t strength = entry.data.u8[0];
/* ispSettings->nrSetting.strength = ((strength * UINT8_MAX) / ANDROID_MAX_STRENGTH) - INT8_MIN; */
reqAiqCfg.captureSettings->ispControls.nr.strength = strength;
} else {
// does not affect according to ia_isp specs.
/* ispSettings->nrSetting.strength = 0; */
}
//# ANDROID_METADATA_Control android.control.effectMode done
entry = settings.find(ANDROID_CONTROL_EFFECT_MODE);
uint8_t effectMode = 0;
MetadataHelper::getSetting(mStaticMetadataCache.availableEffectModes, entry, &effectMode);
reqAiqCfg.captureSettings->ispControls.effect = effectMode;
switch (effectMode) {
case ANDROID_CONTROL_EFFECT_MODE_OFF:
/* ispSettings->effects = ia_isp_effect_none; */
break;
case ANDROID_CONTROL_EFFECT_MODE_MONO:
/* ispSettings->effects = ia_isp_effect_grayscale; */
break;
case ANDROID_CONTROL_EFFECT_MODE_NEGATIVE:
/* ispSettings->effects = ia_isp_effect_negative; */
break;
case ANDROID_CONTROL_EFFECT_MODE_SEPIA:
/* ispSettings->effects = ia_isp_effect_sepia; */
break;
case ANDROID_CONTROL_EFFECT_MODE_AQUA:
/* ispSettings->effects = ia_isp_effect_aqua; */
break;
case ANDROID_CONTROL_EFFECT_MODE_SOLARIZE:
case ANDROID_CONTROL_EFFECT_MODE_POSTERIZE:
case ANDROID_CONTROL_EFFECT_MODE_WHITEBOARD:
case ANDROID_CONTROL_EFFECT_MODE_BLACKBOARD:
default:
LOGE("ERROR: Unknown effect mode %d", effectMode);
return BAD_VALUE;
}
return OK;
}
void SettingsProcessor::cacheStaticMetadata()
{
const camera_metadata_t *meta = PlatformData::getStaticMetadata(mCameraId);
mStaticMetadataCache.availableEffectModes =
MetadataHelper::getMetadataEntry(meta, ANDROID_CONTROL_AVAILABLE_EFFECTS);
mStaticMetadataCache.availableNoiseReductionModes =
MetadataHelper::getMetadataEntry(meta, ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES);
mStaticMetadataCache.availableTonemapModes =
MetadataHelper::getMetadataEntry(meta, ANDROID_TONEMAP_AVAILABLE_TONE_MAP_MODES);
mStaticMetadataCache.availableVideoStabilization =
MetadataHelper::getMetadataEntry(meta, ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES);
mStaticMetadataCache.availableOpticalStabilization =
MetadataHelper::getMetadataEntry(meta, ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION);
mStaticMetadataCache.currentAperture =
MetadataHelper::getMetadataEntry(meta, ANDROID_LENS_INFO_AVAILABLE_APERTURES);
mStaticMetadataCache.flashInfoAvailable =
MetadataHelper::getMetadataEntry(meta, ANDROID_FLASH_INFO_AVAILABLE);
mStaticMetadataCache.lensShadingMapSize =
MetadataHelper::getMetadataEntry(meta, ANDROID_LENS_INFO_SHADING_MAP_SIZE);
mStaticMetadataCache.currentFocalLength =
MetadataHelper::getMetadataEntry(meta, ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS);
mStaticMetadataCache.availableHotPixelMapModes =
MetadataHelper::getMetadataEntry(meta, ANDROID_STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES);
mStaticMetadataCache.availableHotPixelModes =
MetadataHelper::getMetadataEntry(meta, ANDROID_HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES);
mStaticMetadataCache.availableEdgeModes =
MetadataHelper::getMetadataEntry(meta, ANDROID_EDGE_AVAILABLE_EDGE_MODES);
mStaticMetadataCache.maxAnalogSensitivity =
MetadataHelper::getMetadataEntry(meta, ANDROID_SENSOR_MAX_ANALOG_SENSITIVITY);
mStaticMetadataCache.pipelineDepth =
MetadataHelper::getMetadataEntry(meta, ANDROID_REQUEST_PIPELINE_MAX_DEPTH);
mStaticMetadataCache.lensSupported =
MetadataHelper::getMetadataEntry(meta, ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE);
mStaticMetadataCache.availableTestPatternModes =
MetadataHelper::getMetadataEntry(meta, ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES);
}
/**
* This function fills ISP settings with manual image enhancement settings
* (brightness, contrast, hue, saturation and sharpness) coming from the app,
* in case they are supported by HAL.
*
* \param settings [IN] settings from the request
* \param reqAiqCfg [OUT] AIQ configuration
*/
status_t SettingsProcessor::processImageEnhancementSettings(const CameraMetadata &settings,
RequestCtrlState &reqAiqCfg)
{
HAL_TRACE_CALL(CAMERA_DEBUG_LOG_LEVEL2);
camera_metadata_ro_entry entry;
CLEAR(entry);
IspSettings *ispSettings = nullptr;
if (reqAiqCfg.captureSettings) {
ispSettings = &reqAiqCfg.captureSettings->ispSettings;
} else {
LOGE("Capture Settings is nullptr!, bug");
return UNKNOWN_ERROR;
}
return OK;
}
/**
* This function reads the COM_RK_IMAGE_ENHANCE values, maps them to
* the range that rk_aiq expects and updates metadata.
*
* \param[in] settings Settings from the request
* \param[in] enhancementName Enhancement name
* \param[in,out] reqAiqCfg AIQ configuration
* \return enhancement value in rk_aiq range
*/
char SettingsProcessor::mapImageEnhancementSettings(const CameraMetadata &settings,
const int enhancementName,
RequestCtrlState &reqAiqCfg)
{
/* TODO */
/* camera_metadata_ro_entry entry; */
/* CLEAR(entry); */
/* entry = settings.find(enhancementName); */
/* if (entry.count == 1) { */
/* int enhancementValue = entry.data.i32[0]; */
/* // The result can be updated immadiately since the enhancement values */
/* // will not change */
/* reqAiqCfg.ctrlUnitResult->update(enhancementName, */
/* &enhancementValue, */
/* 1); */
/* if (abs(enhancementValue) <= UI_IMAGE_ENHANCEMENT_MAX) { */
/* return(m3aWrapper->mapUiImageEnhancement2Aiq(enhancementValue)); */
/* } else { */
/* LOGE("Enhancement value %d outside expected range [%d,%d]", */
/* enhancementValue, -UI_IMAGE_ENHANCEMENT_MAX, */
/* UI_IMAGE_ENHANCEMENT_MAX); */
/* } */
/* } */
return 0;
}
status_t
SettingsProcessor::processAeSettings(const CameraMetadata& settings,
RequestCtrlState &reqAiqCfg)
{
HAL_TRACE_CALL(CAMERA_DEBUG_LOG_LEVEL2);
status_t status = OK;
LOG2("%s:%d: sensorDesc(%f,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)", __func__, __LINE__,
mSensorDescriptor.pixel_clock_freq_mhz,
mSensorDescriptor.pixel_periods_per_line,
mSensorDescriptor.line_periods_per_field,
mSensorDescriptor.line_periods_vertical_blanking,
mSensorDescriptor.fine_integration_time_min,
mSensorDescriptor.fine_integration_time_max_margin,
mSensorDescriptor.coarse_integration_time_min,
mSensorDescriptor.coarse_integration_time_max_margin,
mSensorDescriptor.sensor_output_width,
mSensorDescriptor.sensor_output_height,
mSensorDescriptor.isp_input_width,
mSensorDescriptor.isp_input_height,
mSensorDescriptor.isp_output_width,
mSensorDescriptor.isp_output_height);
AeInputParams aeInputParams;
aeInputParams.aiqInputParams = &reqAiqCfg.aiqInputParams;
aeInputParams.aaaControls = &reqAiqCfg.aaaControls;
aeInputParams.croppingRegion = &reqAiqCfg.captureSettings->cropRegion;
aeInputParams.aeRegion = &reqAiqCfg.captureSettings->aeRegion;
aeInputParams.sensorDescriptor = &mSensorDescriptor;
status = m3aWrapper->fillAeInputParams(&settings, &aeInputParams);
if (status != OK) {
LOGE("%s: fillAeInputParams failed!", __FUNCTION__);
return status;
}
if (aeInputParams.aiqInputParams) {
/*
* apply the sensor limits reported from the exposure sensor descriptor
*
* The exposure sensor descriptor is updated every time we change sensor
* mode.
* Each sensor mode has associated a maximum fps. We should not let AE
* to produce values that drive the sensor at a higher speed.
*
* This operation is already done inside fillAeInputParams, but
* unfortunately the input parameter is an int
* (AeInputParams.maxSupportedFps) therefore we apply the limit here
* with more precision.
*
* In other PSL the AeInputParams.maxSupportedFps passed to 3A is coming
* from the reported min stream duration in static metadata.
*
* In our case we use the limit reported by the sensor mode selected.
* The value mMinSensorModeFrameTime is updated after every stream
* config.
*/
rk_aiq_ae_input_params *aeParams = nullptr;
aeParams = &aeInputParams.aiqInputParams->aeParams;
aeParams->flicker_reduction_mode = rk_aiq_ae_flicker_reduction_off;
if (aeParams->manual_limits->manual_frame_time_us_min < mMinSensorModeFrameTime) {
aeParams->manual_limits->manual_frame_time_us_min = mMinSensorModeFrameTime;
}
if (aeParams->manual_limits->manual_frame_time_us_max < mMinSensorModeFrameTime) {
aeParams->manual_limits->manual_frame_time_us_max = mMinSensorModeFrameTime;
}
}
return status;
}
status_t
SettingsProcessor::handleNewSensorDescriptor(ControlUnit::MessageSensorMode &msg)
{
HAL_TRACE_CALL(CAMERA_DEBUG_LOG_LEVEL1);
mCurrentFrameParams = msg.frameParams;
mSensorDescriptor = msg.exposureDesc;
/*
* store the minimum frame time for this sensor mode.
* This is the maximum fps that the sensor mode supports.
* Use this to limit any frame rate requests from client.
* min frame duration is:
* pix_per_line * lines_per_frame
* ----------------------------------------
* pixel_clock
*/
mMinSensorModeFrameTime = (mSensorDescriptor.pixel_periods_per_line *
mSensorDescriptor.line_periods_per_field)/
mSensorDescriptor.pixel_clock_freq_mhz;
LOG1("---- New Sensor descriptor information received -----");
// todo revert this when graph config works
// The current frame parameters are all wrong, due to incomplete graph
// config implementation which seems to be in a constant flux. Fetch
// the sensor crop area from media ctl while things are as they are
const MediaCtlConfig *mediaCtlConfig = mStreamCfgProv.getMediaCtlConfig(IStreamConfigProvider::CIO2);
for (unsigned int i = 0; i < mediaCtlConfig->mSelectionParams.size(); i++) {
MediaCtlSelectionParams param = mediaCtlConfig->mSelectionParams[i];
if (strstr(param.entityName.c_str(), "pixel array")) {
mCurrentFrameParams.cropped_image_width = param.width;
mCurrentFrameParams.cropped_image_height = param.height;
mCurrentFrameParams.horizontal_crop_offset = param.top;
mCurrentFrameParams.vertical_crop_offset = param.left;
}
}
LOG1("Frame Params: crop offset: %dx%d crop rect: %dx%d"
" v-scale: %d/%d h-scale: %d/%d",
mCurrentFrameParams.horizontal_crop_offset,
mCurrentFrameParams.vertical_crop_offset,
mCurrentFrameParams.cropped_image_width,
mCurrentFrameParams.cropped_image_height,
mCurrentFrameParams.horizontal_scaling_numerator,
mCurrentFrameParams.horizontal_scaling_denominator,
mCurrentFrameParams.vertical_scaling_numerator,
mCurrentFrameParams.vertical_scaling_denominator);
LOG1("Sensor descriptor: pix-clock: %f Mhz ppl: %d lpf: %d lpvb: %d "
"integration time min(margin) fine: %d (%d) coarse:%d(%d)",
mSensorDescriptor.pixel_clock_freq_mhz,
mSensorDescriptor.pixel_periods_per_line,
mSensorDescriptor.line_periods_per_field,
mSensorDescriptor.line_periods_vertical_blanking,
mSensorDescriptor.fine_integration_time_min,
mSensorDescriptor.fine_integration_time_max_margin,
mSensorDescriptor.coarse_integration_time_min,
mSensorDescriptor.coarse_integration_time_max_margin);
return OK;
}
status_t
SettingsProcessor::processAwbSettings(const CameraMetadata &settings,
RequestCtrlState &reqAiqCfg)
{
HAL_TRACE_CALL(CAMERA_DEBUG_LOG_LEVEL2);
AwbInputParams awbInputParams;
awbInputParams.aiqInputParams = &reqAiqCfg.aiqInputParams;
awbInputParams.aaaControls = &reqAiqCfg.aaaControls;
m3aWrapper->fillAwbInputParams(&settings,
&awbInputParams);
rk_aiq_awb_input_params* awbparams = &awbInputParams.aiqInputParams->awbParams;
LOG2("%s:%d: frame_use(%d), scence_mode(%d), manual_cct(%p), window(%p) ", __func__, __LINE__,
awbparams->frame_use, awbparams->scene_mode, awbparams->manual_cct_range, awbparams->window);
return OK;
}
status_t
SettingsProcessor::processStabilizationSettings(const CameraMetadata &settings,
RequestCtrlState &reqAiqCfg)
{
HAL_TRACE_CALL(CAMERA_DEBUG_LOG_LEVEL2);
camera_metadata_ro_entry entry;
//# ANDROID_METADATA_Control android.control.videoStabilizationMode done
entry = settings.find(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE);
MetadataHelper::getSetting(mStaticMetadataCache.availableVideoStabilization, entry,
&(reqAiqCfg.captureSettings->videoStabilizationMode));
//# ANDROID_METADATA_Control android.lens.opticalStabilizationMode done
entry = settings.find(ANDROID_LENS_OPTICAL_STABILIZATION_MODE);
MetadataHelper::getSetting(mStaticMetadataCache.availableOpticalStabilization, entry,
&(reqAiqCfg.captureSettings->opticalStabilizationMode));
return OK;
}
status_t SettingsProcessor::processHotPixelSettings(const CameraMetadata &settings,
RequestCtrlState &reqAiqCfg)
{
HAL_TRACE_CALL(CAMERA_DEBUG_LOG_LEVEL2);
camera_metadata_ro_entry entry;
//# ANDROID_METADATA_Control android.statistics.hotPixelMapMode done
entry = settings.find(ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE);
MetadataHelper::getSetting(mStaticMetadataCache.availableHotPixelMapModes, entry,
&(reqAiqCfg.captureSettings->hotPixelMapMode));
//# ANDROID_METADATA_Control android.hotPixel.mode done
entry = settings.find(ANDROID_HOT_PIXEL_MODE);
MetadataHelper::getSetting(mStaticMetadataCache.availableHotPixelModes, entry,
&(reqAiqCfg.captureSettings->hotPixelMode));
return OK;
}
status_t SettingsProcessor::processTonemapSettings(const CameraMetadata &settings,
RequestCtrlState &reqAiqCfg)
{
HAL_TRACE_CALL(CAMERA_DEBUG_LOG_LEVEL2);
status_t status = OK;
camera_metadata_ro_entry entry;
//# ANDROID_METADATA_Control android.tonemap.mode done
entry = settings.find(ANDROID_TONEMAP_MODE);
MetadataHelper::getSetting(mStaticMetadataCache.availableTonemapModes, entry,
&(reqAiqCfg.captureSettings->tonemapMode));
// ITS test_param_tonemap_mode WA: allow incoming contrast curve, but
// only in manual mode (control mode off).
if (entry.count == 1 &&
entry.data.i32[0] == ANDROID_TONEMAP_MODE_CONTRAST_CURVE &&
IS_CONTROL_MODE_OFF(reqAiqCfg.captureSettings->controlMode))
reqAiqCfg.captureSettings->tonemapMode = entry.data.i32[0];
if (reqAiqCfg.captureSettings->tonemapMode ==
ANDROID_TONEMAP_MODE_CONTRAST_CURVE)
reqAiqCfg.tonemapContrastCurve = true;
if (reqAiqCfg.captureSettings->tonemapMode ==
ANDROID_TONEMAP_MODE_GAMMA_VALUE) {
entry = settings.find(ANDROID_TONEMAP_GAMMA);
if (entry.count == 1) {
reqAiqCfg.captureSettings->gammaValue = entry.data.f[0];
}
}
if (reqAiqCfg.captureSettings->tonemapMode ==
ANDROID_TONEMAP_MODE_PRESET_CURVE) {
entry = settings.find(ANDROID_TONEMAP_PRESET_CURVE);
if (entry.count == 1) {
reqAiqCfg.captureSettings->presetCurve = entry.data.i32[0];
}
}
if (reqAiqCfg.tonemapContrastCurve) {
status = getTonemapCurve(settings, ANDROID_TONEMAP_CURVE_RED,
&(reqAiqCfg.rGammaLutSize),
reqAiqCfg.rGammaLut);
if (status == NO_ERROR)
status |= getTonemapCurve(settings, ANDROID_TONEMAP_CURVE_GREEN,
&(reqAiqCfg.gGammaLutSize),
reqAiqCfg.gGammaLut);
if (status == NO_ERROR)
status |= getTonemapCurve(settings, ANDROID_TONEMAP_CURVE_BLUE,
&(reqAiqCfg.bGammaLutSize),
reqAiqCfg.bGammaLut);
}
return OK;
}
status_t SettingsProcessor::processTestPatternMode(const CameraMetadata &settings,
RequestCtrlState &reqAiqCfg)
{
HAL_TRACE_CALL(CAMERA_DEBUG_LOG_LEVEL2);
camera_metadata_ro_entry entry;
entry = settings.find(ANDROID_SENSOR_TEST_PATTERN_MODE);
MetadataHelper::getSetting(mStaticMetadataCache.availableTestPatternModes, entry,
&(reqAiqCfg.captureSettings->testPatternMode));
return OK;
}
status_t SettingsProcessor::getTonemapCurve(const CameraMetadata settings,
unsigned int tag,
unsigned int *gammaLutSize,
float *gammaLut) const
{
HAL_TRACE_CALL(CAMERA_DEBUG_LOG_LEVEL2);
camera_metadata_ro_entry entry;
entry = settings.find(tag);
if (entry.count < 2 || entry.count > TONEMAP_MAX_CURVE_POINTS) {
LOGE("tonemap curve %d is not available", tag);
return UNKNOWN_ERROR;
}
*gammaLutSize = entry.count;
for (unsigned int i = 0; i < entry.count; i++) {
gammaLut[i] = entry.data.f[i];
}
return OK;
}
} /* namespace camera2 */
} /* namespace android */