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