x3a_statistics_queue.cpp revision c64ed59d9173c0d3203cbef4054472b036c404b0
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
26namespace XCam {
27
28X3aIspStatsData::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
35X3aIspStatsData::~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
46bool
47X3aIspStatsData::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
109X3aIspStatistics::X3aIspStatistics (const SmartPtr<X3aIspStatsData> &stats_data)
110    : X3aStats (SmartPtr<X3aStatsData> (stats_data))
111{
112}
113
114X3aIspStatistics::~X3aIspStatistics ()
115{
116}
117
118struct atomisp_3a_statistics *
119X3aIspStatistics::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
132bool
133X3aIspStatistics::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
146X3aStatisticsQueue::X3aStatisticsQueue()
147{
148    xcam_mem_clear (_grid_info);
149}
150
151X3aStatisticsQueue::~X3aStatisticsQueue()
152{
153}
154
155void
156X3aStatisticsQueue::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
174struct atomisp_3a_statistics *
175X3aStatisticsQueue::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
203bool
204X3aStatisticsQueue::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
224SmartPtr<BufferData>
225X3aStatisticsQueue::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
247SmartPtr<BufferProxy>
248X3aStatisticsQueue::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