Home | History | Annotate | Download | only in ocl
      1 /*
      2  * cl_csc_handler.cpp - CL csc 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 #include "cl_utils.h"
     22 #include "cl_csc_handler.h"
     23 #include "cl_device.h"
     24 #include "cl_kernel.h"
     25 
     26 static const XCamKernelInfo kernel_csc_info[] = {
     27     {
     28         "kernel_csc_rgbatonv12",
     29 #include "kernel_csc.clx"
     30         , 0,
     31     },
     32     {
     33         "kernel_csc_rgbatolab",
     34 #include "kernel_csc.clx"
     35         , 0,
     36     },
     37     {
     38         "kernel_csc_rgba64torgba",
     39 #include "kernel_csc.clx"
     40         , 0,
     41     },
     42     {
     43         "kernel_csc_yuyvtorgba",
     44 #include "kernel_csc.clx"
     45         , 0,
     46     },
     47     {
     48         "kernel_csc_nv12torgba",
     49 #include "kernel_csc.clx"
     50         , 0,
     51     },
     52 };
     53 
     54 
     55 float default_rgbtoyuv_matrix[XCAM_COLOR_MATRIX_SIZE] = {
     56     0.299f, 0.587f, 0.114f,
     57     -0.14713f, -0.28886f, 0.436f,
     58     0.615f, -0.51499f, -0.10001f
     59 };
     60 
     61 namespace XCam {
     62 
     63 CLCscImageKernel::CLCscImageKernel (const SmartPtr<CLContext> &context, CLCscType type)
     64     : CLImageKernel (context)
     65     , _kernel_csc_type (type)
     66 {
     67 }
     68 
     69 CLCscImageHandler::CLCscImageHandler (
     70     const SmartPtr<CLContext> &context, const char *name, CLCscType type)
     71     : CLImageHandler (context, name)
     72     , _output_format (V4L2_PIX_FMT_NV12)
     73     , _csc_type (type)
     74 {
     75     memcpy (_rgbtoyuv_matrix, default_rgbtoyuv_matrix, sizeof (_rgbtoyuv_matrix));
     76 
     77     switch (type) {
     78     case CL_CSC_TYPE_RGBATONV12:
     79         _output_format = V4L2_PIX_FMT_NV12;
     80         break;
     81     case CL_CSC_TYPE_RGBATOLAB:
     82         _output_format = XCAM_PIX_FMT_LAB;
     83         break;
     84     case CL_CSC_TYPE_RGBA64TORGBA:
     85     case CL_CSC_TYPE_YUYVTORGBA:
     86     case CL_CSC_TYPE_NV12TORGBA:
     87         _output_format = V4L2_PIX_FMT_RGBA32;
     88         break;
     89     default:
     90         break;
     91     }
     92 }
     93 
     94 bool
     95 CLCscImageHandler::set_csc_kernel (SmartPtr<CLCscImageKernel> &kernel)
     96 {
     97     SmartPtr<CLImageKernel> image_kernel = kernel;
     98     add_kernel (image_kernel);
     99     _csc_kernel = kernel;
    100     return true;
    101 }
    102 
    103 bool
    104 CLCscImageHandler::set_matrix (const XCam3aResultColorMatrix &matrix)
    105 {
    106     for (int i = 0; i < XCAM_COLOR_MATRIX_SIZE; i++)
    107         _rgbtoyuv_matrix[i] = (float)matrix.matrix[i];
    108     return true;
    109 }
    110 
    111 bool
    112 CLCscImageHandler::set_output_format (uint32_t fourcc)
    113 {
    114     XCAM_FAIL_RETURN (
    115         WARNING,
    116         V4L2_PIX_FMT_XBGR32 == fourcc || V4L2_PIX_FMT_NV12 == fourcc,
    117         false,
    118         "CL csc handler doesn't support format: (%s)",
    119         xcam_fourcc_to_string (fourcc));
    120 
    121     _output_format = fourcc;
    122     return true;
    123 }
    124 
    125 XCamReturn
    126 CLCscImageHandler::prepare_buffer_pool_video_info (
    127     const VideoBufferInfo &input,
    128     VideoBufferInfo &output)
    129 {
    130     bool format_inited = output.init (_output_format, input.width, input.height);
    131 
    132     XCAM_FAIL_RETURN (
    133         WARNING,
    134         format_inited,
    135         XCAM_RETURN_ERROR_PARAM,
    136         "CL image handler(%s) output format(%s) unsupported",
    137         get_name (), xcam_fourcc_to_string (_output_format));
    138 
    139     return XCAM_RETURN_NO_ERROR;
    140 }
    141 
    142 static bool
    143 ensure_image_desc (const VideoBufferInfo &info, CLImageDesc &desc)
    144 {
    145     desc.array_size = 0;
    146     desc.slice_pitch = 0;
    147     if (info.format == XCAM_PIX_FMT_RGB48_planar || info.format == XCAM_PIX_FMT_RGB24_planar)
    148         desc.height = info.aligned_height * 3;
    149 
    150     return true;
    151 }
    152 
    153 XCamReturn
    154 CLCscImageHandler::prepare_parameters (SmartPtr<VideoBuffer> &input, SmartPtr<VideoBuffer> &output)
    155 {
    156     SmartPtr<CLContext> context = get_context ();
    157 
    158     const VideoBufferInfo &in_video_info = input->get_video_info ();
    159     const VideoBufferInfo &out_video_info = output->get_video_info ();
    160     CLArgList args;
    161     CLWorkSize work_size;
    162     XCamReturn ret = XCAM_RETURN_NO_ERROR;
    163 
    164     XCAM_ASSERT (_csc_kernel.ptr ());
    165 
    166     CLImageDesc in_desc, out_desc;
    167     CLImage::video_info_2_cl_image_desc (in_video_info, in_desc);
    168     CLImage::video_info_2_cl_image_desc (out_video_info, out_desc);
    169     ensure_image_desc (in_video_info, in_desc);
    170     ensure_image_desc (out_video_info, out_desc);
    171 
    172     SmartPtr<CLImage> image_in  = convert_to_climage (context, input, in_desc, in_video_info.offsets[0]);
    173     SmartPtr<CLImage> image_out  = convert_to_climage (context, output, out_desc, out_video_info.offsets[0]);
    174     SmartPtr<CLBuffer> matrix_buffer = new CLBuffer (
    175         context, sizeof(float)*XCAM_COLOR_MATRIX_SIZE,
    176         CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR , &_rgbtoyuv_matrix);
    177 
    178     XCAM_FAIL_RETURN (
    179         WARNING,
    180         image_in->is_valid () && image_out->is_valid () && matrix_buffer->is_valid(),
    181         XCAM_RETURN_ERROR_MEM,
    182         "cl image kernel(%s) in/out memory not available", _csc_kernel->get_kernel_name ());
    183 
    184     work_size.dim = XCAM_DEFAULT_IMAGE_DIM;
    185     work_size.local[0] = 4;
    186     work_size.local[1] = 4;
    187 
    188     args.push_back (new CLMemArgument (image_in));
    189     args.push_back (new CLMemArgument (image_out));
    190 
    191     do {
    192         if ((_csc_type == CL_CSC_TYPE_RGBATOLAB)
    193                 || (_csc_type == CL_CSC_TYPE_RGBA64TORGBA)
    194                 || (_csc_type == CL_CSC_TYPE_YUYVTORGBA)) {
    195             work_size.global[0] = out_video_info.width;
    196             work_size.global[1] = out_video_info.height;
    197             break;
    198         }
    199 
    200         SmartPtr<CLImage> image_uv;
    201         if(_csc_type == CL_CSC_TYPE_NV12TORGBA) {
    202             in_desc.height /= 2;
    203             image_uv = convert_to_climage (context, input, in_desc, in_video_info.offsets[1]);
    204             args.push_back (new CLMemArgument (image_uv));
    205 
    206             work_size.global[0] = out_video_info.width / 2;
    207             work_size.global[1] = out_video_info.height / 2;
    208             break;
    209         }
    210 
    211         if (_csc_type == CL_CSC_TYPE_RGBATONV12) {
    212             out_desc.height /= 2;
    213             image_uv = convert_to_climage (context, output, out_desc, out_video_info.offsets[1]);
    214             args.push_back (new CLMemArgument (image_uv));
    215             args.push_back (new CLMemArgument (matrix_buffer));
    216 
    217             work_size.global[0] = out_video_info.width / 2;
    218             work_size.global[1] = out_video_info.height / 2;
    219             break;
    220         }
    221     } while (0);
    222 
    223     XCAM_ASSERT (_csc_kernel.ptr ());
    224     ret = _csc_kernel->set_arguments (args, work_size);
    225     XCAM_FAIL_RETURN (
    226         WARNING, ret == XCAM_RETURN_NO_ERROR, ret,
    227         "csc kernel set arguments failed.");
    228 
    229     return XCAM_RETURN_NO_ERROR;
    230 }
    231 
    232 SmartPtr<CLImageHandler>
    233 create_cl_csc_image_handler (const SmartPtr<CLContext> &context, CLCscType type)
    234 {
    235     SmartPtr<CLCscImageHandler> csc_handler;
    236     SmartPtr<CLCscImageKernel> csc_kernel;
    237 
    238     XCAM_ASSERT (type < CL_CSC_TYPE_MAX);
    239     csc_kernel = new CLCscImageKernel (context, type);
    240     XCAM_ASSERT (csc_kernel.ptr ());
    241     XCAM_FAIL_RETURN (
    242         ERROR, csc_kernel->build_kernel (kernel_csc_info[type], NULL) == XCAM_RETURN_NO_ERROR, NULL,
    243         "build csc kernel(%s) failed", kernel_csc_info[type].kernel_name);
    244 
    245     XCAM_ASSERT (csc_kernel->is_valid ());
    246 
    247     csc_handler = new CLCscImageHandler (context, "cl_handler_csc", type);
    248     csc_handler->set_csc_kernel (csc_kernel);
    249 
    250     return csc_handler;
    251 }
    252 
    253 };
    254