/* * x3a_statistics_queue.c - statistics queue * * Copyright (c) 2014-2015 Intel Corporation * * 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. * * Author: Wind Yuan */ #include "x3a_statistics_queue.h" #include #include #include namespace XCam { X3aIspStatsData::X3aIspStatsData (struct atomisp_3a_statistics *isp_data, XCam3AStats *data) : X3aStatsData (data) , _isp_data (isp_data) { XCAM_ASSERT (_isp_data); } X3aIspStatsData::~X3aIspStatsData () { if (_isp_data) { if (_isp_data->data) xcam_free (_isp_data->data); if (_isp_data->rgby_data) xcam_free (_isp_data->rgby_data); xcam_free (_isp_data); } } bool X3aIspStatsData::fill_standard_stats () { XCam3AStats *standard_stats = get_stats (); XCAM_ASSERT (_isp_data && _isp_data->data); XCAM_ASSERT (standard_stats); XCAM_FAIL_RETURN ( WARNING, _isp_data && _isp_data->data && standard_stats, false, "X3aIspStatsData fill standard stats failed with null data allocated"); const struct atomisp_grid_info &isp_info = _isp_data->grid_info; const XCam3AStatsInfo &standard_info = standard_stats->info; const struct atomisp_3a_output *isp_data = _isp_data->data; XCamGridStat *standard_data = standard_stats->stats; uint32_t pixel_count = isp_info.bqs_per_grid_cell * isp_info.bqs_per_grid_cell; uint32_t bit_shift = isp_info.elem_bit_depth - 8; XCAM_ASSERT (isp_info.width == standard_info.width); XCAM_ASSERT (isp_info.height == standard_info.height); for (uint32_t i = 0; i < isp_info.height; ++i) { for (uint32_t j = 0; j < isp_info.width; ++j) { standard_data[i * standard_info.aligned_width + j].avg_y = ((isp_data[i * isp_info.aligned_width + j].ae_y / pixel_count) >> bit_shift); standard_data[i * standard_info.aligned_width + j].avg_r = ((isp_data[i * isp_info.aligned_width + j].awb_r / pixel_count) >> bit_shift); standard_data[i * standard_info.aligned_width + j].avg_gr = ((isp_data[i * isp_info.aligned_width + j].awb_gr / pixel_count) >> bit_shift); standard_data[i * standard_info.aligned_width + j].avg_gb = ((isp_data[i * isp_info.aligned_width + j].awb_gb / pixel_count) >> bit_shift); standard_data[i * standard_info.aligned_width + j].avg_b = ((isp_data[i * isp_info.aligned_width + j].awb_b / pixel_count) >> bit_shift); standard_data[i * standard_info.aligned_width + j].valid_wb_count = isp_data[i * isp_info.aligned_width + j].awb_cnt; standard_data[i * standard_info.aligned_width + j].f_value1 = ((isp_data[i * isp_info.aligned_width + j].af_hpf1 / pixel_count) >> bit_shift); standard_data[i * standard_info.aligned_width + j].f_value2 = ((isp_data[i * isp_info.aligned_width + j].af_hpf2 / pixel_count) >> bit_shift); } } if (isp_info.has_histogram) { uint32_t hist_bins = standard_info.histogram_bins; // TODO: atom isp hard code histogram to 256 bins XCAM_ASSERT (hist_bins == 256); XCamHistogram *hist_rgb = standard_stats->hist_rgb; uint32_t *hist_y = standard_stats->hist_y; const struct atomisp_3a_rgby_output *isp_hist = _isp_data->rgby_data; for (uint32_t i = 0; i < hist_bins; i++) { hist_rgb[i].r = isp_hist[i].r; hist_rgb[i].gr = isp_hist[i].g; hist_rgb[i].gb = isp_hist[i].g; hist_rgb[i].b = isp_hist[i].b; hist_y[i] = isp_hist[i].y; } } return true; } X3aIspStatistics::X3aIspStatistics (const SmartPtr &stats_data) : X3aStats (SmartPtr (stats_data)) { } X3aIspStatistics::~X3aIspStatistics () { } struct atomisp_3a_statistics * X3aIspStatistics::get_isp_stats () { SmartPtr stats = get_buffer_data ().dynamic_cast_ptr (); XCAM_FAIL_RETURN( WARNING, stats.ptr(), NULL, "X3aIspStatistics get_stats failed with NULL"); return stats->get_isp_stats (); } bool X3aIspStatistics::fill_standard_stats () { SmartPtr stats = get_buffer_data ().dynamic_cast_ptr (); XCAM_FAIL_RETURN( WARNING, stats.ptr(), false, "X3aIspStatistics fill standard stats failed with NULL stats data"); return stats->fill_standard_stats (); } X3aStatisticsQueue::X3aStatisticsQueue() { xcam_mem_clear (_grid_info); } X3aStatisticsQueue::~X3aStatisticsQueue() { } void X3aStatisticsQueue::set_grid_info (const struct atomisp_grid_info &info) { XCam3AStatsInfo stats_info; xcam_mem_clear (stats_info); _grid_info = info; stats_info.width = info.width; stats_info.height = info.height; stats_info.aligned_width = info.aligned_width; stats_info.aligned_height = info.aligned_height; stats_info.grid_pixel_size = info.bqs_per_grid_cell * 2; stats_info.bit_depth = 8; stats_info.histogram_bins = 256; set_stats_info (stats_info); } struct atomisp_3a_statistics * X3aStatisticsQueue::alloc_isp_statsictics () { XCAM_ASSERT (_grid_info.width && _grid_info.height); XCAM_ASSERT (_grid_info.aligned_width && _grid_info.aligned_height); uint32_t grid_size = _grid_info.aligned_width * _grid_info.aligned_height; //uint32_t grid_size = _grid_info.width * _grid_info.height; struct atomisp_3a_statistics *stats = xcam_malloc0_type (struct atomisp_3a_statistics); XCAM_ASSERT (stats); stats->data = (struct atomisp_3a_output*)xcam_malloc0 (grid_size * sizeof(*stats->data)); XCAM_ASSERT (stats->data); if (!stats || !stats->data) return NULL; if (_grid_info.has_histogram) { // TODO: atom isp hard code histogram to 256 bins stats->rgby_data = (struct atomisp_3a_rgby_output*)xcam_malloc0 (256 * sizeof(*stats->rgby_data)); XCAM_ASSERT (stats->rgby_data); if (!stats->rgby_data) return NULL; } stats->grid_info = _grid_info; return stats; } bool X3aStatisticsQueue::fixate_video_info (VideoBufferInfo &info) { X3aStatsPool::fixate_video_info (info); XCam3AStatsInfo &stats_info = get_stats_info (); _grid_info.enable = 1; _grid_info.use_dmem = 0; _grid_info.has_histogram = 0; _grid_info.width = stats_info.width; _grid_info.height = stats_info.height; _grid_info.aligned_width = stats_info.aligned_width; _grid_info.aligned_height = stats_info.aligned_height; _grid_info.bqs_per_grid_cell = stats_info.grid_pixel_size / 2; _grid_info.deci_factor_log2 = (uint32_t)log2 (_grid_info.bqs_per_grid_cell); _grid_info.elem_bit_depth = stats_info.bit_depth; return X3aStatsPool::fixate_video_info (info); } SmartPtr X3aStatisticsQueue::allocate_data (const VideoBufferInfo &buffer_info) { XCAM_UNUSED (buffer_info); XCam3AStats *stats = NULL; XCam3AStatsInfo stats_info = get_stats_info (); struct atomisp_3a_statistics *isp_stats = alloc_isp_statsictics (); stats = (XCam3AStats *) xcam_malloc0 ( sizeof (XCam3AStats) + sizeof (XCamHistogram) * stats_info.histogram_bins + sizeof (uint32_t) * stats_info.histogram_bins + sizeof (XCamGridStat) * stats_info.aligned_width * stats_info.aligned_height); XCAM_ASSERT (isp_stats && stats); stats->info = stats_info; stats->hist_rgb = (XCamHistogram *) (stats->stats + stats_info.aligned_width * stats_info.aligned_height); stats->hist_y = (uint32_t *) (stats->hist_rgb + stats_info.histogram_bins); return new X3aIspStatsData (isp_stats, stats); } SmartPtr X3aStatisticsQueue::create_buffer_from_data (SmartPtr &data) { SmartPtr stats_data = data.dynamic_cast_ptr (); XCAM_ASSERT (stats_data.ptr ()); return new X3aIspStatistics (stats_data); } };