1 /* 2 * x3a_statistics_queue.c - statistics queue 3 * 4 * Copyright (c) 2014-2015 Intel Corporation 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * 18 * Author: Wind Yuan <feng.yuan (at) intel.com> 19 */ 20 21 #include "x3a_statistics_queue.h" 22 #include <linux/videodev2.h> 23 #include <linux/atomisp.h> 24 #include <math.h> 25 26 namespace XCam { 27 28 X3aIspStatsData::X3aIspStatsData (struct atomisp_3a_statistics *isp_data, XCam3AStats *data) 29 : X3aStatsData (data) 30 , _isp_data (isp_data) 31 { 32 XCAM_ASSERT (_isp_data); 33 } 34 35 X3aIspStatsData::~X3aIspStatsData () 36 { 37 if (_isp_data) { 38 if (_isp_data->data) 39 xcam_free (_isp_data->data); 40 if (_isp_data->rgby_data) 41 xcam_free (_isp_data->rgby_data); 42 xcam_free (_isp_data); 43 } 44 } 45 46 bool 47 X3aIspStatsData::fill_standard_stats () 48 { 49 XCam3AStats *standard_stats = get_stats (); 50 51 XCAM_ASSERT (_isp_data && _isp_data->data); 52 XCAM_ASSERT (standard_stats); 53 XCAM_FAIL_RETURN ( 54 WARNING, 55 _isp_data && _isp_data->data && standard_stats, 56 false, 57 "X3aIspStatsData fill standard stats failed with null data allocated"); 58 59 const struct atomisp_grid_info &isp_info = _isp_data->grid_info; 60 const XCam3AStatsInfo &standard_info = standard_stats->info; 61 const struct atomisp_3a_output *isp_data = _isp_data->data; 62 XCamGridStat *standard_data = standard_stats->stats; 63 uint32_t pixel_count = isp_info.bqs_per_grid_cell * isp_info.bqs_per_grid_cell; 64 uint32_t bit_shift = isp_info.elem_bit_depth - 8; 65 66 XCAM_ASSERT (isp_info.width == standard_info.width); 67 XCAM_ASSERT (isp_info.height == standard_info.height); 68 for (uint32_t i = 0; i < isp_info.height; ++i) { 69 for (uint32_t j = 0; j < isp_info.width; ++j) { 70 standard_data[i * standard_info.aligned_width + j].avg_y = 71 ((isp_data[i * isp_info.aligned_width + j].ae_y / pixel_count) >> bit_shift); 72 standard_data[i * standard_info.aligned_width + j].avg_r = 73 ((isp_data[i * isp_info.aligned_width + j].awb_r / pixel_count) >> bit_shift); 74 standard_data[i * standard_info.aligned_width + j].avg_gr = 75 ((isp_data[i * isp_info.aligned_width + j].awb_gr / pixel_count) >> bit_shift); 76 standard_data[i * standard_info.aligned_width + j].avg_gb = 77 ((isp_data[i * isp_info.aligned_width + j].awb_gb / pixel_count) >> bit_shift); 78 standard_data[i * standard_info.aligned_width + j].avg_b = 79 ((isp_data[i * isp_info.aligned_width + j].awb_b / pixel_count) >> bit_shift); 80 standard_data[i * standard_info.aligned_width + j].valid_wb_count = 81 isp_data[i * isp_info.aligned_width + j].awb_cnt; 82 standard_data[i * standard_info.aligned_width + j].f_value1 = 83 ((isp_data[i * isp_info.aligned_width + j].af_hpf1 / pixel_count) >> bit_shift); 84 standard_data[i * standard_info.aligned_width + j].f_value2 = 85 ((isp_data[i * isp_info.aligned_width + j].af_hpf2 / pixel_count) >> bit_shift); 86 } 87 } 88 89 if (isp_info.has_histogram) { 90 uint32_t hist_bins = standard_info.histogram_bins; 91 // TODO: atom isp hard code histogram to 256 bins 92 XCAM_ASSERT (hist_bins == 256); 93 94 XCamHistogram *hist_rgb = standard_stats->hist_rgb; 95 uint32_t *hist_y = standard_stats->hist_y; 96 const struct atomisp_3a_rgby_output *isp_hist = _isp_data->rgby_data; 97 for (uint32_t i = 0; i < hist_bins; i++) { 98 hist_rgb[i].r = isp_hist[i].r; 99 hist_rgb[i].gr = isp_hist[i].g; 100 hist_rgb[i].gb = isp_hist[i].g; 101 hist_rgb[i].b = isp_hist[i].b; 102 hist_y[i] = isp_hist[i].y; 103 } 104 } 105 106 return true; 107 } 108 109 X3aIspStatistics::X3aIspStatistics (const SmartPtr<X3aIspStatsData> &stats_data) 110 : X3aStats (SmartPtr<X3aStatsData> (stats_data)) 111 { 112 } 113 114 X3aIspStatistics::~X3aIspStatistics () 115 { 116 } 117 118 struct atomisp_3a_statistics * 119 X3aIspStatistics::get_isp_stats () 120 { 121 SmartPtr<X3aIspStatsData> stats = get_buffer_data ().dynamic_cast_ptr<X3aIspStatsData> (); 122 123 XCAM_FAIL_RETURN( 124 WARNING, 125 stats.ptr(), 126 NULL, 127 "X3aIspStatistics get_stats failed with NULL"); 128 129 return stats->get_isp_stats (); 130 } 131 132 bool 133 X3aIspStatistics::fill_standard_stats () 134 { 135 SmartPtr<X3aIspStatsData> stats = get_buffer_data ().dynamic_cast_ptr<X3aIspStatsData> (); 136 137 XCAM_FAIL_RETURN( 138 WARNING, 139 stats.ptr(), 140 false, 141 "X3aIspStatistics fill standard stats failed with NULL stats data"); 142 143 return stats->fill_standard_stats (); 144 } 145 146 X3aStatisticsQueue::X3aStatisticsQueue() 147 { 148 xcam_mem_clear (_grid_info); 149 } 150 151 X3aStatisticsQueue::~X3aStatisticsQueue() 152 { 153 } 154 155 void 156 X3aStatisticsQueue::set_grid_info (const struct atomisp_grid_info &info) 157 { 158 XCam3AStatsInfo stats_info; 159 160 xcam_mem_clear (stats_info); 161 _grid_info = info; 162 163 stats_info.width = info.width; 164 stats_info.height = info.height; 165 stats_info.aligned_width = info.aligned_width; 166 stats_info.aligned_height = info.aligned_height; 167 stats_info.grid_pixel_size = info.bqs_per_grid_cell * 2; 168 stats_info.bit_depth = 8; 169 stats_info.histogram_bins = 256; 170 171 set_stats_info (stats_info); 172 } 173 174 struct atomisp_3a_statistics * 175 X3aStatisticsQueue::alloc_isp_statsictics () 176 { 177 XCAM_ASSERT (_grid_info.width && _grid_info.height); 178 XCAM_ASSERT (_grid_info.aligned_width && _grid_info.aligned_height); 179 180 uint32_t grid_size = _grid_info.aligned_width * _grid_info.aligned_height; 181 //uint32_t grid_size = _grid_info.width * _grid_info.height; 182 183 struct atomisp_3a_statistics *stats = xcam_malloc0_type (struct atomisp_3a_statistics); 184 XCAM_ASSERT (stats); 185 stats->data = (struct atomisp_3a_output*)xcam_malloc0 (grid_size * sizeof(*stats->data)); 186 XCAM_ASSERT (stats->data); 187 if (!stats || !stats->data) 188 return NULL; 189 190 if (_grid_info.has_histogram) { 191 // TODO: atom isp hard code histogram to 256 bins 192 stats->rgby_data = 193 (struct atomisp_3a_rgby_output*)xcam_malloc0 (256 * sizeof(*stats->rgby_data)); 194 XCAM_ASSERT (stats->rgby_data); 195 if (!stats->rgby_data) 196 return NULL; 197 } 198 199 stats->grid_info = _grid_info; 200 return stats; 201 } 202 203 bool 204 X3aStatisticsQueue::fixate_video_info (VideoBufferInfo &info) 205 { 206 X3aStatsPool::fixate_video_info (info); 207 208 XCam3AStatsInfo &stats_info = get_stats_info (); 209 210 _grid_info.enable = 1; 211 _grid_info.use_dmem = 0; 212 _grid_info.has_histogram = 0; 213 _grid_info.width = stats_info.width; 214 _grid_info.height = stats_info.height; 215 _grid_info.aligned_width = stats_info.aligned_width; 216 _grid_info.aligned_height = stats_info.aligned_height; 217 _grid_info.bqs_per_grid_cell = stats_info.grid_pixel_size / 2; 218 _grid_info.deci_factor_log2 = (uint32_t)log2 (_grid_info.bqs_per_grid_cell); 219 _grid_info.elem_bit_depth = stats_info.bit_depth; 220 221 return X3aStatsPool::fixate_video_info (info); 222 } 223 224 SmartPtr<BufferData> 225 X3aStatisticsQueue::allocate_data (const VideoBufferInfo &buffer_info) 226 { 227 XCAM_UNUSED (buffer_info); 228 229 XCam3AStats *stats = NULL; 230 XCam3AStatsInfo stats_info = get_stats_info (); 231 struct atomisp_3a_statistics *isp_stats = alloc_isp_statsictics (); 232 233 stats = (XCam3AStats *) xcam_malloc0 ( 234 sizeof (XCam3AStats) + 235 sizeof (XCamHistogram) * stats_info.histogram_bins + 236 sizeof (uint32_t) * stats_info.histogram_bins + 237 sizeof (XCamGridStat) * stats_info.aligned_width * stats_info.aligned_height); 238 XCAM_ASSERT (isp_stats && stats); 239 stats->info = stats_info; 240 stats->hist_rgb = (XCamHistogram *) (stats->stats + 241 stats_info.aligned_width * stats_info.aligned_height); 242 stats->hist_y = (uint32_t *) (stats->hist_rgb + stats_info.histogram_bins); 243 244 return new X3aIspStatsData (isp_stats, stats); 245 } 246 247 SmartPtr<BufferProxy> 248 X3aStatisticsQueue::create_buffer_from_data (SmartPtr<BufferData> &data) 249 { 250 SmartPtr<X3aIspStatsData> stats_data = data.dynamic_cast_ptr<X3aIspStatsData> (); 251 XCAM_ASSERT (stats_data.ptr ()); 252 253 return new X3aIspStatistics (stats_data); 254 } 255 256 }; 257