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@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
X3aIspStatsData(struct atomisp_3a_statistics * isp_data,XCam3AStats * data)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
~X3aIspStatsData()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
fill_standard_stats()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
X3aIspStatistics(const SmartPtr<X3aIspStatsData> & stats_data)109 X3aIspStatistics::X3aIspStatistics (const SmartPtr<X3aIspStatsData> &stats_data)
110 : X3aStats (SmartPtr<X3aStatsData> (stats_data))
111 {
112 }
113
~X3aIspStatistics()114 X3aIspStatistics::~X3aIspStatistics ()
115 {
116 }
117
118 struct atomisp_3a_statistics *
get_isp_stats()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
fill_standard_stats()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
X3aStatisticsQueue()146 X3aStatisticsQueue::X3aStatisticsQueue()
147 {
148 xcam_mem_clear (_grid_info);
149 }
150
~X3aStatisticsQueue()151 X3aStatisticsQueue::~X3aStatisticsQueue()
152 {
153 }
154
155 void
set_grid_info(const struct atomisp_grid_info & info)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 *
alloc_isp_statsictics()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
fixate_video_info(VideoBufferInfo & info)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>
allocate_data(const VideoBufferInfo & buffer_info)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>
create_buffer_from_data(SmartPtr<BufferData> & data)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