Home | History | Annotate | Download | only in ocl
      1 /*
      2  * cl_yuv_pipe_handler.cpp - CL YuvPipe 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: Wangfei <feix.w.wang (at) intel.com>
     19  * Author: Wind Yuan <feng.yuan (at) intel.com>
     20  */
     21 
     22 #include "cl_utils.h"
     23 #include "cl_yuv_pipe_handler.h"
     24 
     25 #define USE_BUFFER_OBJECT 0
     26 
     27 namespace XCam {
     28 
     29 static const XCamKernelInfo kernel_yuv_pipe_info = {
     30     "kernel_yuv_pipe",
     31 #include "kernel_yuv_pipe.clx"
     32     , 0,
     33 };
     34 
     35 float default_matrix[XCAM_COLOR_MATRIX_SIZE] = {
     36     0.299f, 0.587f, 0.114f,
     37     -0.14713f, -0.28886f, 0.436f,
     38     0.615f, -0.51499f, -0.10001f,
     39 };
     40 float default_macc[XCAM_CHROMA_AXIS_SIZE * XCAM_CHROMA_MATRIX_SIZE] = {
     41     1.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 1.000000f,
     42     1.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 1.000000f,
     43     1.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 1.000000f,
     44     1.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 1.000000f,
     45     1.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 1.000000f,
     46     1.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 1.000000f,
     47     1.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 1.000000f,
     48     1.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 1.000000f,
     49 };
     50 
     51 CLYuvPipeImageKernel::CLYuvPipeImageKernel (const SmartPtr<CLContext> &context)
     52     : CLImageKernel (context, "kernel_yuv_pipe")
     53 
     54 {
     55 }
     56 
     57 CLYuvPipeImageHandler::CLYuvPipeImageHandler (const SmartPtr<CLContext> &context, const char *name)
     58     : CLImageHandler (context, name)
     59     , _output_format(V4L2_PIX_FMT_NV12)
     60     , _enable_tnr_yuv (0)
     61     , _gain_yuv (1.0)
     62     , _thr_y (0.05)
     63     , _thr_uv (0.05)
     64     ,  _enable_tnr_yuv_state (0)
     65 
     66 {
     67     memcpy(_macc_table, default_macc, sizeof(float)*XCAM_CHROMA_AXIS_SIZE * XCAM_CHROMA_MATRIX_SIZE);
     68     memcpy(_rgbtoyuv_matrix, default_matrix, sizeof(float)*XCAM_COLOR_MATRIX_SIZE);
     69 }
     70 
     71 bool
     72 CLYuvPipeImageHandler::set_macc_table (const XCam3aResultMaccMatrix &macc)
     73 {
     74     for(int i = 0; i < XCAM_CHROMA_AXIS_SIZE * XCAM_CHROMA_MATRIX_SIZE; i++)
     75         _macc_table[i] = (float)macc.table[i];
     76     return true;
     77 }
     78 
     79 bool
     80 CLYuvPipeImageHandler::set_rgbtoyuv_matrix (const XCam3aResultColorMatrix &matrix)
     81 {
     82     for (int i = 0; i < XCAM_COLOR_MATRIX_SIZE; i++)
     83         _rgbtoyuv_matrix[i] = (float)matrix.matrix[i];
     84     return true;
     85 }
     86 
     87 XCamReturn
     88 CLYuvPipeImageHandler::prepare_buffer_pool_video_info (
     89     const VideoBufferInfo &input,
     90     VideoBufferInfo &output)
     91 {
     92     bool format_inited = output.init (_output_format, input.width, input.height);
     93 
     94     XCAM_FAIL_RETURN (
     95         WARNING,
     96         format_inited,
     97         XCAM_RETURN_ERROR_PARAM,
     98         "CL image handler(%s) output format(%s) unsupported",
     99         get_name (), xcam_fourcc_to_string (_output_format));
    100 
    101     return XCAM_RETURN_NO_ERROR;
    102 }
    103 
    104 XCamReturn
    105 CLYuvPipeImageHandler::prepare_parameters (
    106     SmartPtr<VideoBuffer> &input, SmartPtr<VideoBuffer> &output)
    107 {
    108     SmartPtr<CLContext> context = get_context ();
    109     const VideoBufferInfo & video_info_in = input->get_video_info ();
    110     const VideoBufferInfo & video_info_out = output->get_video_info ();
    111     CLArgList args;
    112     CLWorkSize work_size;
    113 
    114     XCAM_ASSERT (_yuv_pipe_kernel.ptr ());
    115     SmartPtr<CLMemory> buffer_in, buffer_out, buffer_out_UV;
    116 
    117 #if !USE_BUFFER_OBJECT
    118     CLImageDesc in_image_info;
    119     in_image_info.format.image_channel_order = CL_RGBA;
    120     in_image_info.format.image_channel_data_type = CL_UNSIGNED_INT32;
    121     in_image_info.width = video_info_in.aligned_width / 8;
    122     in_image_info.height = video_info_in.aligned_height * 3;
    123     in_image_info.row_pitch = video_info_in.strides[0];
    124 
    125     CLImageDesc out_image_info;
    126     out_image_info.format.image_channel_order = CL_RGBA;
    127     out_image_info.format.image_channel_data_type = CL_UNSIGNED_INT16;
    128     out_image_info.width = video_info_out.width / 8;
    129     out_image_info.height = video_info_out.aligned_height;
    130     out_image_info.row_pitch = video_info_out.strides[0];
    131 
    132     buffer_in = convert_to_climage (context, input, in_image_info);
    133     buffer_out = convert_to_climage (context, output, out_image_info, video_info_out.offsets[0]);
    134 
    135     out_image_info.height = video_info_out.aligned_height / 2;
    136     out_image_info.row_pitch = video_info_out.strides[1];
    137     buffer_out_UV = convert_to_climage (context, output, out_image_info, video_info_out.offsets[1]);
    138 #else
    139     buffer_in = convert_to_clbuffer (context, input);
    140     buffer_out = convert_to_clbuffer (context, output);
    141 #endif
    142     SmartPtr<CLBuffer> matrix_buffer = new CLBuffer (
    143         context, sizeof(float)*XCAM_COLOR_MATRIX_SIZE,
    144         CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR , &_rgbtoyuv_matrix);
    145     SmartPtr<CLBuffer> macc_table_buffer = new CLBuffer(
    146         context, sizeof(float)*XCAM_CHROMA_AXIS_SIZE * XCAM_CHROMA_MATRIX_SIZE,
    147         CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR , &_macc_table);
    148 
    149     uint32_t plannar_offset = video_info_in.aligned_height;
    150 
    151     if (!_buffer_out_prev.ptr ()) {
    152         _buffer_out_prev = buffer_out;
    153         _buffer_out_prev_UV = buffer_out_UV;
    154         _enable_tnr_yuv_state = _enable_tnr_yuv;
    155         _enable_tnr_yuv = 0;
    156     }
    157     else {
    158         if (_enable_tnr_yuv == 0)
    159             _enable_tnr_yuv = _enable_tnr_yuv_state;
    160     }
    161     XCAM_FAIL_RETURN (
    162         WARNING,
    163         buffer_in->is_valid () && buffer_out->is_valid (),
    164         XCAM_RETURN_ERROR_MEM,
    165         "cl image handler(%s) in/out memory not available", XCAM_STR (get_name ()));
    166 
    167     //set args;
    168     args.push_back (new CLMemArgument (buffer_out));
    169 
    170 #if !USE_BUFFER_OBJECT
    171     args.push_back (new CLMemArgument (buffer_out_UV));
    172 #endif
    173 
    174     args.push_back (new CLMemArgument (_buffer_out_prev));
    175 
    176 #if !USE_BUFFER_OBJECT
    177     args.push_back (new CLMemArgument (_buffer_out_prev_UV));
    178 #else
    179     uint32_t vertical_offset = video_info_out.aligned_height;
    180     args.push_back (new CLArgumentT<uint32_t> (vertical_offset));
    181 #endif
    182     args.push_back (new CLArgumentT<uint32_t> (plannar_offset));
    183     args.push_back (new CLMemArgument (matrix_buffer));
    184     args.push_back (new CLMemArgument (macc_table_buffer));
    185     args.push_back (new CLArgumentT<float> (_gain_yuv));
    186     args.push_back (new CLArgumentT<float> (_thr_y));
    187     args.push_back (new CLArgumentT<float> (_thr_uv));
    188     args.push_back (new CLArgumentT<uint32_t> (_enable_tnr_yuv));
    189     args.push_back (new CLMemArgument (buffer_in));
    190 
    191     work_size.dim = XCAM_DEFAULT_IMAGE_DIM;
    192     work_size.global[0] = video_info_out.width / 8 ;
    193     work_size.global[1] = video_info_out.aligned_height / 2 ;
    194     work_size.local[0] = 8;
    195     work_size.local[1] = 4;
    196 
    197     XCAM_ASSERT (_yuv_pipe_kernel.ptr ());
    198     XCamReturn ret = _yuv_pipe_kernel->set_arguments (args, work_size);
    199     XCAM_FAIL_RETURN (
    200         WARNING, ret == XCAM_RETURN_NO_ERROR, ret,
    201         "yuv pipe kernel set arguments failed.");
    202 
    203     if (buffer_out->is_valid ()) {
    204         _buffer_out_prev = buffer_out;
    205         _buffer_out_prev_UV = buffer_out_UV;
    206     }
    207 
    208     return XCAM_RETURN_NO_ERROR;
    209 }
    210 
    211 bool
    212 CLYuvPipeImageHandler::set_yuv_pipe_kernel(SmartPtr<CLYuvPipeImageKernel> &kernel)
    213 {
    214     SmartPtr<CLImageKernel> image_kernel = kernel;
    215     add_kernel (image_kernel);
    216     _yuv_pipe_kernel = kernel;
    217     return true;
    218 }
    219 
    220 bool
    221 CLYuvPipeImageHandler::set_tnr_yuv_config (const XCam3aResultTemporalNoiseReduction& config)
    222 {
    223     if (!_yuv_pipe_kernel->is_valid ()) {
    224         XCAM_LOG_ERROR ("set config error, invalid YUV-Pipe kernel !");
    225     }
    226 
    227     _gain_yuv = (float)config.gain;
    228     _thr_y = (float)config.threshold[0];
    229     _thr_uv = (float)config.threshold[1];
    230     XCAM_LOG_DEBUG ("set TNR YUV config: _gain(%f), _thr_y(%f), _thr_uv(%f)",
    231                     _gain_yuv, _thr_y, _thr_uv);
    232     return true;
    233 }
    234 
    235 bool
    236 CLYuvPipeImageHandler::set_tnr_enable (bool enable_tnr_yuv)
    237 {
    238     _enable_tnr_yuv = (enable_tnr_yuv ? 1 : 0);
    239     return true;
    240 }
    241 
    242 SmartPtr<CLImageHandler>
    243 create_cl_yuv_pipe_image_handler (const SmartPtr<CLContext> &context)
    244 {
    245     SmartPtr<CLYuvPipeImageHandler> yuv_pipe_handler;
    246     SmartPtr<CLYuvPipeImageKernel> yuv_pipe_kernel;
    247 
    248     yuv_pipe_kernel = new CLYuvPipeImageKernel (context);
    249     XCAM_ASSERT (yuv_pipe_kernel.ptr ());
    250     const char * options = USE_BUFFER_OBJECT ? "-DUSE_BUFFER_OBJECT=1" : "-DUSE_BUFFER_OBJECT=0";
    251     XCAM_FAIL_RETURN (
    252         ERROR, yuv_pipe_kernel->build_kernel (kernel_yuv_pipe_info, options) == XCAM_RETURN_NO_ERROR, NULL,
    253         "build yuv-pipe kernel(%s) failed", kernel_yuv_pipe_info.kernel_name);
    254 
    255     XCAM_ASSERT (yuv_pipe_kernel->is_valid ());
    256     yuv_pipe_handler = new CLYuvPipeImageHandler (context, "cl_handler_pipe_yuv");
    257     yuv_pipe_handler->set_yuv_pipe_kernel (yuv_pipe_kernel);
    258 
    259     return yuv_pipe_handler;
    260 }
    261 
    262 };
    263