Home | History | Annotate | Download | only in ocl
      1 /*
      2  * cl_bayer_pipe_handler.cpp - CL bayer pipe handler
      3  *
      4  *  Copyright (c) 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  * Author: wangfei <feix.w.wang (at) intel.com>
     20  * Author: Shincy Tu <shincy.tu (at) intel.com>
     21  */
     22 
     23 #include "cl_utils.h"
     24 #include "cl_bayer_pipe_handler.h"
     25 
     26 #define WORKGROUP_PIXEL_WIDTH 128
     27 #define WORKGROUP_PIXEL_HEIGHT 8
     28 
     29 #define BAYER_LOCAL_X_SIZE 64
     30 #define BAYER_LOCAL_Y_SIZE 2
     31 
     32 namespace XCam {
     33 
     34 static const float table [XCAM_BNR_TABLE_SIZE] = {
     35     63.661991f, 60.628166f, 52.366924f, 41.023067f, 29.146584f, 18.781729f, 10.976704f,
     36     6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f,
     37     6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f,
     38     6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f,
     39     6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f,
     40     6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f,
     41     6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f,
     42     6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f,
     43     6.000000f,
     44 };
     45 
     46 static const XCamKernelInfo kernel_bayer_pipe_info = {
     47     "kernel_bayer_pipe",
     48 #include "kernel_bayer_pipe.clx"
     49     , 0,
     50 };
     51 
     52 CLBayerPipeImageKernel::CLBayerPipeImageKernel (
     53     const SmartPtr<CLContext> &context,
     54     SmartPtr<CLBayerPipeImageHandler> &handler)
     55     : CLImageKernel (context, "kernel_bayer_pipe")
     56     , _handler (handler)
     57 {
     58 
     59 }
     60 
     61 CLBayerPipeImageHandler::CLBayerPipeImageHandler (const SmartPtr<CLContext> &context, const char *name)
     62     : CLImageHandler (context, name)
     63     , _output_format (XCAM_PIX_FMT_RGB48_planar)
     64     , _enable_denoise (0)
     65 {
     66     memcpy(_bnr_table, table, sizeof(float)*XCAM_BNR_TABLE_SIZE);
     67     _ee_config.ee_gain = 0.8;
     68     _ee_config.ee_threshold = 0.025;
     69 }
     70 
     71 bool
     72 CLBayerPipeImageHandler::set_output_format (uint32_t fourcc)
     73 {
     74     XCAM_FAIL_RETURN (
     75         WARNING,
     76         XCAM_PIX_FMT_RGB48_planar == fourcc || XCAM_PIX_FMT_RGB24_planar == fourcc,
     77         false,
     78         "CL image handler(%s) doesn't support format(%s) settings",
     79         get_name (), xcam_fourcc_to_string (fourcc));
     80 
     81     _output_format = fourcc;
     82     return true;
     83 }
     84 
     85 bool
     86 CLBayerPipeImageHandler::set_bayer_kernel (SmartPtr<CLBayerPipeImageKernel> &kernel)
     87 {
     88     SmartPtr<CLImageKernel> image_kernel = kernel;
     89     add_kernel (image_kernel);
     90     _bayer_kernel = kernel;
     91     return true;
     92 }
     93 
     94 bool
     95 CLBayerPipeImageHandler::enable_denoise (bool enable)
     96 {
     97     _enable_denoise = (enable ? 1 : 0);
     98     return true;
     99 
    100 }
    101 
    102 bool
    103 CLBayerPipeImageHandler::set_ee_config (const XCam3aResultEdgeEnhancement &ee)
    104 {
    105     _ee_config.ee_gain = (float)ee.gain;
    106     _ee_config.ee_threshold = (float)ee.threshold;
    107     return true;
    108 }
    109 bool
    110 CLBayerPipeImageHandler::set_bnr_config (const XCam3aResultBayerNoiseReduction &bnr)
    111 {
    112     for(int i = 0; i < XCAM_BNR_TABLE_SIZE; i++)
    113         _bnr_table[i] = (float)bnr.table[i];
    114     return true;
    115 }
    116 
    117 XCamReturn
    118 CLBayerPipeImageHandler::prepare_buffer_pool_video_info (
    119     const VideoBufferInfo &input,
    120     VideoBufferInfo &output)
    121 {
    122     uint32_t format = _output_format;
    123     uint32_t width = input.width;
    124     uint32_t height = input.height;
    125     if (input.format == XCAM_PIX_FMT_SGRBG16_planar) {
    126         width *= 2;
    127         height *= 2;
    128     }
    129     bool format_inited = output.init (format, width, height);
    130 
    131     XCAM_FAIL_RETURN (
    132         WARNING,
    133         format_inited,
    134         XCAM_RETURN_ERROR_PARAM,
    135         "CL image handler(%s) output format(%s) unsupported",
    136         get_name (), xcam_fourcc_to_string (format));
    137 
    138     return XCAM_RETURN_NO_ERROR;
    139 }
    140 
    141 XCamReturn
    142 CLBayerPipeImageHandler::prepare_parameters (
    143     SmartPtr<VideoBuffer> &input, SmartPtr<VideoBuffer> &output)
    144 {
    145     SmartPtr<CLContext> context = get_context ();
    146     const VideoBufferInfo & in_video_info = input->get_video_info ();
    147     const VideoBufferInfo & out_video_info = output->get_video_info ();
    148     CLArgList args;
    149     CLWorkSize work_size;
    150 
    151     XCAM_ASSERT (_bayer_kernel.ptr ());
    152 
    153     CLImageDesc in_desc;
    154     in_desc.format.image_channel_order = CL_RGBA;
    155     in_desc.format.image_channel_data_type = CL_UNORM_INT16; //CL_UNSIGNED_INT32;
    156     in_desc.width = in_video_info.width / 4; // 960/4
    157     in_desc.height = in_video_info.aligned_height * 4;  //540
    158     in_desc.row_pitch = in_video_info.strides[0];
    159 
    160     SmartPtr<CLImage> image_in = convert_to_climage (context, input, in_desc);
    161 
    162     CLImageDesc out_desc;
    163     out_desc.format.image_channel_order = CL_RGBA;
    164     if (XCAM_PIX_FMT_RGB48_planar == out_video_info.format)
    165         out_desc.format.image_channel_data_type = CL_UNORM_INT16;
    166     else
    167         out_desc.format.image_channel_data_type = CL_UNORM_INT8;
    168     out_desc.width = out_video_info.aligned_width / 4;
    169     out_desc.height = out_video_info.aligned_height * 3;
    170     out_desc.row_pitch = out_video_info.strides[0];
    171     out_desc.array_size = 3;
    172     out_desc.slice_pitch = out_video_info.strides [0] * out_video_info.aligned_height;
    173 
    174     SmartPtr<CLImage> image_out = convert_to_climage (context, output, out_desc);
    175 
    176     uint input_height = in_video_info.aligned_height;
    177     uint output_height = out_video_info.aligned_height;
    178 
    179     XCAM_ASSERT (image_in.ptr () && image_out.ptr ());
    180     XCAM_FAIL_RETURN (
    181         WARNING,
    182         image_in->is_valid () && image_out->is_valid (),
    183         XCAM_RETURN_ERROR_MEM,
    184         "cl image kernel(%s) in/out memory not available", _bayer_kernel->get_kernel_name ());
    185 
    186     SmartPtr<CLBuffer> bnr_table_buffer = new CLBuffer(
    187         context, sizeof(float) * XCAM_BNR_TABLE_SIZE,
    188         CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, &_bnr_table);
    189 
    190     //set args;
    191     args.push_back (new CLMemArgument (image_in));
    192     args.push_back (new CLArgumentT<uint> (input_height));
    193     args.push_back (new CLMemArgument (image_out));
    194     args.push_back (new CLArgumentT<uint> (output_height));
    195     args.push_back (new CLMemArgument (bnr_table_buffer));
    196     args.push_back (new CLArgumentT<uint32_t> (_enable_denoise));
    197     args.push_back (new CLArgumentT<CLEeConfig> (_ee_config));
    198 
    199     work_size.dim = XCAM_DEFAULT_IMAGE_DIM;
    200     work_size.local[0] = BAYER_LOCAL_X_SIZE;
    201     work_size.local[1] = BAYER_LOCAL_Y_SIZE;
    202     work_size.global[0] = (XCAM_ALIGN_UP(out_video_info.width, WORKGROUP_PIXEL_WIDTH) / WORKGROUP_PIXEL_WIDTH) *
    203                           work_size.local[0];
    204     work_size.global[1] = (XCAM_ALIGN_UP(out_video_info.height, WORKGROUP_PIXEL_HEIGHT) / WORKGROUP_PIXEL_HEIGHT) *
    205                           work_size.local[1];
    206 
    207     XCAM_ASSERT (_bayer_kernel.ptr ());
    208     XCamReturn ret = _bayer_kernel->set_arguments (args, work_size);
    209     XCAM_FAIL_RETURN (
    210         WARNING, ret == XCAM_RETURN_NO_ERROR, ret,
    211         "bayer pipe kernel set arguments failed.");
    212 
    213     return XCAM_RETURN_NO_ERROR;
    214 }
    215 
    216 
    217 SmartPtr<CLImageHandler>
    218 create_cl_bayer_pipe_image_handler (const SmartPtr<CLContext> &context)
    219 {
    220     SmartPtr<CLBayerPipeImageHandler> bayer_pipe_handler;
    221     SmartPtr<CLBayerPipeImageKernel> bayer_pipe_kernel;
    222 
    223     bayer_pipe_handler = new CLBayerPipeImageHandler (context, "cl_handler_bayer_pipe");
    224     bayer_pipe_kernel = new CLBayerPipeImageKernel (context, bayer_pipe_handler);
    225     XCAM_ASSERT (bayer_pipe_kernel.ptr ());
    226     XCAM_FAIL_RETURN (
    227         ERROR, bayer_pipe_kernel->build_kernel (kernel_bayer_pipe_info, NULL) == XCAM_RETURN_NO_ERROR, NULL,
    228         "build bayer-pipe kernel(%s) failed", kernel_bayer_pipe_info.kernel_name);
    229 
    230     XCAM_ASSERT (bayer_pipe_kernel->is_valid ());
    231     bayer_pipe_handler->set_bayer_kernel (bayer_pipe_kernel);
    232 
    233     return bayer_pipe_handler;
    234 }
    235 
    236 };
    237