Home | History | Annotate | Download | only in isp
      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