Home | History | Annotate | Download | only in ocl
      1 /*
      2   * cl_wire_frame_handler.cpp - CL wire frame handler
      3   *
      4   *  Copyright (c) 2016 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: Yinhang Liu <yinhangx.liu (at) intel.com>
     19   */
     20 
     21 #include "cl_utils.h"
     22 #include "cl_wire_frame_handler.h"
     23 
     24 namespace XCam {
     25 
     26 static const XCamKernelInfo kernel_info = {
     27     "kernel_wire_frame",
     28 #include "kernel_wire_frame.clx"
     29     , 0,
     30 };
     31 
     32 static float border_y = 120.0f;
     33 static float border_u = -58.0f;
     34 static float border_v = -104.0f;
     35 static uint32_t border_size = 2;
     36 
     37 CLWireFrameImageKernel::CLWireFrameImageKernel (
     38     const SmartPtr<CLContext> &context,
     39     const SmartPtr<CLWireFrameImageHandler> &handler,
     40     const char *name)
     41     : CLImageKernel (context, name)
     42     , _handler (handler)
     43     , _wire_frames_coords_num (0)
     44     , _wire_frames_coords (NULL)
     45 {
     46 }
     47 
     48 CLWireFrameImageKernel::~CLWireFrameImageKernel ()
     49 {
     50     xcam_free (_wire_frames_coords);
     51 }
     52 
     53 
     54 bool
     55 CLWireFrameImageHandler::set_wire_frame_config (const XCamFDResult *config, double scaler_factor)
     56 {
     57     if (!config) {
     58         XCAM_LOG_ERROR ("set wire frame config error, invalid config parameters !");
     59         return false;
     60     }
     61 
     62     _wire_frames_num = config->face_num;
     63     xcam_mem_clear (_wire_frames);
     64     for (uint32_t i = 0; i < _wire_frames_num && i < XCAM_WIRE_FRAME_MAX_COUNT; i++) {
     65         _wire_frames [i].pos_x = (uint32_t)(config->faces [i].pos_x / scaler_factor / 2) * 2;
     66         _wire_frames [i].pos_y = (uint32_t)(config->faces [i].pos_y / scaler_factor / 2) * 2;
     67         _wire_frames [i].width = (uint32_t)(config->faces [i].width / scaler_factor / 2) * 2;
     68         _wire_frames [i].height = (uint32_t)(config->faces [i].height / scaler_factor / 2) * 2;
     69     }
     70 
     71     return true;
     72 }
     73 
     74 bool
     75 CLWireFrameImageHandler::check_wire_frames_validity (uint32_t image_width, uint32_t image_height)
     76 {
     77     for (uint32_t i = 0; i < _wire_frames_num; i++) {
     78         if (_wire_frames [i].pos_x > image_width) {
     79             XCAM_LOG_ERROR ("check_wire_frames_validity: invalid pos_x (%d)", _wire_frames [i].pos_x);
     80             return false;
     81         }
     82         if (_wire_frames [i].pos_y > image_height) {
     83             XCAM_LOG_ERROR ("check_wire_frames_validity: invalid pos_y (%d)", _wire_frames [i].pos_y);
     84             return false;
     85         }
     86         if (_wire_frames [i].pos_x + _wire_frames [i].width > image_width) {
     87             XCAM_LOG_ERROR ("check_wire_frames_validity: invalid width (%d)", _wire_frames [i].width);
     88             return false;
     89         }
     90         if (_wire_frames [i].pos_y + _wire_frames [i].height > image_width) {
     91             XCAM_LOG_ERROR ("check_wire_frames_validity: invalid height (%d)", _wire_frames [i].height);
     92             return false;
     93         }
     94     }
     95 
     96     return true;
     97 }
     98 
     99 uint32_t
    100 CLWireFrameImageHandler::get_border_coordinates_num ()
    101 {
    102     uint32_t coords_num = 0;
    103     for (uint32_t i = 0; i < _wire_frames_num; i++) {
    104         coords_num += _wire_frames [i].width * _wire_frames [i].height
    105                       - (_wire_frames [i].width - 2 * border_size) * (_wire_frames [i].height - 2 * border_size);
    106     }
    107 
    108     return coords_num / 2;
    109 }
    110 
    111 bool
    112 CLWireFrameImageHandler::get_border_coordinates (uint32_t *coords)
    113 {
    114     uint32_t index = 0;
    115     for (uint32_t i = 0; i < _wire_frames_num; i++) {
    116         for (uint32_t j = 0; j < border_size; j++) {
    117             for (uint32_t k = 0; k < _wire_frames [i].width; k += 2) {
    118                 coords [index++] = _wire_frames [i].pos_x + k;
    119                 coords [index++] = _wire_frames [i].pos_y + j;
    120             }
    121         }
    122 
    123         for (uint32_t j = 0; j < border_size; j++) {
    124             for (uint32_t k = 0; k < _wire_frames [i].width; k += 2) {
    125                 coords [index++] = _wire_frames [i].pos_x + k;
    126                 coords [index++] = _wire_frames [i].pos_y + _wire_frames [i].height - border_size + j;
    127             }
    128         }
    129 
    130         for (uint32_t j = 0; j < _wire_frames [i].height - 2 * border_size; j++) {
    131             for (uint32_t k = 0; k < border_size; k += 2) {
    132                 coords [index++] = _wire_frames [i].pos_x + k;
    133                 coords [index++] = _wire_frames [i].pos_y + border_size + j;
    134             }
    135         }
    136 
    137         for (uint32_t j = 0; j < _wire_frames [i].height - 2 * border_size; j++) {
    138             for (uint32_t k = 0; k < border_size; k += 2) {
    139                 coords [index++] = _wire_frames [i].pos_x + _wire_frames [i].width - border_size + k;
    140                 coords [index++] = _wire_frames [i].pos_y + border_size + j;
    141             }
    142         }
    143     }
    144 
    145     return true;
    146 }
    147 
    148 XCamReturn
    149 CLWireFrameImageKernel::prepare_arguments (
    150     CLArgList &args, CLWorkSize &work_size)
    151 {
    152     SmartPtr<VideoBuffer> output = _handler->get_output_buf ();
    153     SmartPtr<CLContext> context = get_context ();
    154     const VideoBufferInfo &video_info_out = output->get_video_info ();
    155     CLImageDesc cl_desc_out;
    156 
    157     cl_desc_out.format.image_channel_data_type = CL_UNORM_INT8;
    158     cl_desc_out.format.image_channel_order = CL_RG;
    159     cl_desc_out.width = video_info_out.width / 2;
    160     cl_desc_out.height = video_info_out.height;
    161     cl_desc_out.row_pitch = video_info_out.strides [0];
    162     SmartPtr<CLImage> image_out = convert_to_climage (context, output, cl_desc_out, video_info_out.offsets [0]);
    163 
    164     cl_desc_out.height = video_info_out.height / 2;
    165     cl_desc_out.row_pitch = video_info_out.strides [1];
    166     SmartPtr<CLImage> image_out_uv = convert_to_climage (context, output, cl_desc_out, video_info_out.offsets [1]);
    167 
    168     XCAM_FAIL_RETURN (
    169         WARNING,
    170         image_out->is_valid () && image_out_uv->is_valid (),
    171         XCAM_RETURN_ERROR_MEM,
    172         "cl image kernel (%s) in/out memory not available", get_kernel_name ());
    173 
    174     XCAM_FAIL_RETURN (
    175         ERROR,
    176         _handler->check_wire_frames_validity (video_info_out.width, video_info_out.height),
    177         XCAM_RETURN_ERROR_PARAM,
    178         "prepare_arguments: invalid wire frames parameters");
    179     _wire_frames_coords_num = _handler->get_border_coordinates_num ();
    180     xcam_free (_wire_frames_coords);
    181     _wire_frames_coords = (uint32_t *) xcam_malloc0 (_wire_frames_coords_num * sizeof (uint32_t) * 2 + 1);
    182     XCAM_ASSERT (_wire_frames_coords);
    183     _handler->get_border_coordinates (_wire_frames_coords);
    184 
    185     SmartPtr<CLBuffer> wire_frames_coords_buf = new CLBuffer (
    186         context,
    187         _wire_frames_coords_num * sizeof (uint32_t) * 2 + 1,
    188         CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, _wire_frames_coords);
    189 
    190     /* set args */
    191     args.push_back (new CLMemArgument (image_out));
    192     args.push_back (new CLMemArgument (image_out_uv));
    193     args.push_back (new CLMemArgument (wire_frames_coords_buf));
    194     args.push_back (new CLArgumentT<uint32_t> (_wire_frames_coords_num));
    195     args.push_back (new CLArgumentT<float> (border_y));
    196     args.push_back (new CLArgumentT<float> (border_u));
    197     args.push_back (new CLArgumentT<float> (border_v));
    198 
    199     work_size.dim = 1;
    200     work_size.local [0] = 16;
    201     work_size.global [0] = _wire_frames_coords_num ? XCAM_ALIGN_UP (_wire_frames_coords_num, work_size.local [0]) : work_size.local [0];
    202 
    203     return XCAM_RETURN_NO_ERROR;
    204 }
    205 
    206 CLWireFrameImageHandler::CLWireFrameImageHandler (const SmartPtr<CLContext> &context, const char *name)
    207     : CLImageHandler (context, name)
    208     , _wire_frames_num (0)
    209 {
    210 }
    211 
    212 bool
    213 CLWireFrameImageHandler::set_wire_frame_kernel (SmartPtr<CLWireFrameImageKernel> &kernel)
    214 {
    215     SmartPtr<CLImageKernel> image_kernel = kernel;
    216     add_kernel (image_kernel);
    217     _wire_frame_kernel = kernel;
    218     return true;
    219 }
    220 
    221 XCamReturn
    222 CLWireFrameImageHandler::prepare_output_buf (SmartPtr<VideoBuffer> &input, SmartPtr<VideoBuffer> &output)
    223 {
    224     output = input;
    225     return XCAM_RETURN_NO_ERROR;
    226 }
    227 
    228 SmartPtr<CLImageHandler>
    229 create_cl_wire_frame_image_handler (const SmartPtr<CLContext> &context)
    230 {
    231     SmartPtr<CLWireFrameImageHandler> wire_frame_handler;
    232     SmartPtr<CLWireFrameImageKernel> wire_frame_kernel;
    233 
    234     wire_frame_handler = new CLWireFrameImageHandler (context, "cl_handler_wire_frame");
    235     wire_frame_kernel = new CLWireFrameImageKernel (context, wire_frame_handler, "kernel_wire_frame");
    236 
    237     XCAM_FAIL_RETURN (
    238         ERROR, wire_frame_kernel->build_kernel (kernel_info, NULL) == XCAM_RETURN_NO_ERROR, NULL,
    239         "build wire_frame kernel(%s) failed", kernel_info.kernel_name);
    240     XCAM_ASSERT (wire_frame_kernel->is_valid ());
    241     wire_frame_handler->set_wire_frame_kernel (wire_frame_kernel);
    242 
    243     return wire_frame_handler;
    244 }
    245 
    246 };
    247