1 /* 2 * cl_fisheye_handler.cpp - CL fisheye 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: Wind Yuan <feng.yuan (at) intel.com> 19 */ 20 21 #include "cl_utils.h" 22 #include "cl_fisheye_handler.h" 23 #include "cl_device.h" 24 25 #define XCAM_LSC_ARRAY_SIZE 64 26 27 static const float max_gray_threshold = 220.0f; 28 static const float min_gray_threshold = 80.0f; 29 30 static const float lsc_array[XCAM_LSC_ARRAY_SIZE] = { 31 1.000000f, 1.000150f, 1.000334f, 1.000523f, 1.000761f, 1.001317f, 1.002109f, 1.003472f, 32 1.004502f, 1.008459f, 1.011816f, 1.014686f, 1.016767f, 1.018425f, 1.020455f, 1.022125f, 33 1.023080f, 1.025468f, 1.029810f, 1.035422f, 1.041943f, 1.047689f, 1.054206f, 1.059395f, 34 1.063541f, 1.068729f, 1.074158f, 1.082766f, 1.088606f, 1.095224f, 1.102773f, 1.112865f, 35 1.117108f, 1.132849f, 1.140659f, 1.147847f, 1.157544f, 1.165002f, 1.175248f, 1.181730f, 36 1.196203f, 1.205452f, 1.216974f, 1.236338f, 1.251963f, 1.269212f, 1.293479f, 1.311051f, 37 1.336007f, 1.357711f, 1.385124f, 1.409937f, 1.448611f, 1.473716f, 1.501837f, 1.525721f, 38 1.555186f, 1.602372f, 1.632105f, 1.698443f, 1.759641f, 1.836303f, 1.939085f, 2.066358f 39 }; 40 41 namespace XCam { 42 43 #define DEFAULT_FISHEYE_TABLE_SCALE 8.0f 44 45 enum { 46 KernelFisheye2GPS, 47 KernelFisheyeTable, 48 KernelLSCTable 49 }; 50 51 const XCamKernelInfo kernel_fisheye_info[] = { 52 { 53 "kernel_fisheye_2_gps", 54 #include "kernel_fisheye.clx" 55 , 0, 56 }, 57 { 58 "kernel_fisheye_table", 59 #include "kernel_fisheye.clx" 60 , 0, 61 }, 62 { 63 "kernel_lsc_table", 64 #include "kernel_fisheye.clx" 65 , 0, 66 }, 67 }; 68 69 CLFisheye2GPSKernel::CLFisheye2GPSKernel ( 70 const SmartPtr<CLContext> &context, SmartPtr<CLFisheyeHandler> &handler) 71 : CLImageKernel (context) 72 , _handler (handler) 73 { 74 XCAM_ASSERT (handler.ptr ()); 75 } 76 77 XCamReturn 78 CLFisheye2GPSKernel::prepare_arguments (CLArgList &args, CLWorkSize &work_size) 79 { 80 SmartPtr<CLImage> input_y = _handler->get_input_image (NV12PlaneYIdx); 81 SmartPtr<CLImage> input_uv = _handler->get_input_image (NV12PlaneUVIdx); 82 SmartPtr<CLImage> output_y = _handler->get_output_image (NV12PlaneYIdx); 83 SmartPtr<CLImage> output_uv = _handler->get_output_image (NV12PlaneUVIdx); 84 const CLImageDesc &input_y_desc = input_y->get_image_desc (); 85 const CLImageDesc &outuv_desc = output_uv->get_image_desc (); 86 FisheyeInfo fisheye_info; 87 float input_y_size[2]; 88 float out_center[2]; //width/height 89 float radian_per_pixel[2]; 90 91 input_y_size[0] = input_y_desc.width; 92 input_y_size[1] = input_y_desc.height; 93 94 uint32_t dst_w, dst_h; 95 float dst_range_x, dst_range_y; 96 _handler->get_output_size (dst_w, dst_h); 97 out_center[0] = (float)dst_w / 2.0f; 98 out_center[1] = (float)dst_h / 2.0f; 99 100 _handler->get_dst_range (dst_range_x, dst_range_y); 101 radian_per_pixel[0] = degree2radian (dst_range_x) / (float)dst_w; 102 radian_per_pixel[1] = degree2radian (dst_range_y) / (float)dst_h; 103 104 fisheye_info = _handler->get_fisheye_info (); 105 fisheye_info.wide_angle = degree2radian (fisheye_info.wide_angle); 106 fisheye_info.rotate_angle = degree2radian (fisheye_info.rotate_angle); 107 108 XCAM_LOG_DEBUG ("@CLFisheye2GPSKernel input size(%d, %d), out_center:(%d, %d), range:(%d,%d)", 109 (int)input_y_size[0], (int)input_y_size[1], 110 (int)out_center[0], (int)out_center[1], 111 (int)dst_range_x, (int)dst_range_y); 112 113 args.push_back (new CLMemArgument (input_y)); 114 args.push_back (new CLMemArgument (input_uv)); 115 args.push_back (new CLArgumentTArray<float, 2> (input_y_size)); 116 args.push_back (new CLArgumentT<FisheyeInfo> (fisheye_info)); 117 args.push_back (new CLMemArgument (output_y)); 118 args.push_back (new CLMemArgument (output_uv)); 119 args.push_back (new CLArgumentTArray<float, 2> (out_center)); 120 args.push_back (new CLArgumentTArray<float, 2> (radian_per_pixel)); 121 122 work_size.dim = XCAM_DEFAULT_IMAGE_DIM; 123 work_size.local[0] = 16; 124 work_size.local[1] = 4; 125 work_size.global[0] = XCAM_ALIGN_UP (outuv_desc.width, work_size.local[0]); 126 work_size.global[1] = XCAM_ALIGN_UP (outuv_desc.height, work_size.local[1]); 127 128 return XCAM_RETURN_NO_ERROR; 129 } 130 131 CLFisheyeHandler::CLFisheyeHandler (const SmartPtr<CLContext> &context, SurroundMode surround_mode, bool use_map, bool need_lsc) 132 : CLImageHandler (context, "CLFisheyeHandler") 133 , _output_width (0) 134 , _output_height (0) 135 , _range_longitude (180.0f) 136 , _range_latitude (180.0f) 137 , _map_factor (DEFAULT_FISHEYE_TABLE_SCALE) 138 , _use_map (use_map) 139 , _need_lsc (need_lsc ? 1 : 0) 140 , _lsc_array_size (0) 141 , _lsc_array (NULL) 142 , _surround_mode (surround_mode) 143 { 144 xcam_mem_clear (_gray_threshold); 145 } 146 147 CLFisheyeHandler::~CLFisheyeHandler() 148 { 149 if (_lsc_array) 150 xcam_free (_lsc_array); 151 } 152 153 void 154 CLFisheyeHandler::set_output_size (uint32_t width, uint32_t height) 155 { 156 _output_width = width; 157 _output_height = height; 158 } 159 160 void 161 CLFisheyeHandler::get_output_size (uint32_t &width, uint32_t &height) const 162 { 163 width = _output_width; 164 height = _output_height; 165 } 166 167 void 168 CLFisheyeHandler::set_dst_range (float longitude, float latitude) 169 { 170 _range_longitude = longitude; 171 _range_latitude = latitude; 172 } 173 174 void 175 CLFisheyeHandler::get_dst_range (float &longitude, float &latitude) const 176 { 177 longitude = _range_longitude; 178 latitude = _range_latitude; 179 } 180 181 void 182 CLFisheyeHandler::set_fisheye_info (const FisheyeInfo &info) 183 { 184 _fisheye_info = info; 185 } 186 187 void 188 CLFisheyeHandler::set_lsc_table (float *table, uint32_t table_size) 189 { 190 if (_lsc_array) 191 xcam_free (_lsc_array); 192 193 _lsc_array_size = table_size; 194 _lsc_array = (float *) xcam_malloc0 (_lsc_array_size * sizeof (float)); 195 XCAM_ASSERT (_lsc_array); 196 memcpy (_lsc_array, table, _lsc_array_size * sizeof (float)); 197 } 198 199 void 200 CLFisheyeHandler::set_lsc_gray_threshold (float min_threshold, float max_threshold) 201 { 202 _gray_threshold[0] = min_threshold; 203 _gray_threshold[1] = max_threshold; 204 } 205 206 XCamReturn 207 CLFisheyeHandler::prepare_buffer_pool_video_info ( 208 const VideoBufferInfo &input, 209 VideoBufferInfo &output) 210 { 211 XCAM_FAIL_RETURN ( 212 WARNING, input.format == V4L2_PIX_FMT_NV12, XCAM_RETURN_ERROR_PARAM, 213 "CLFisheyeHandler(%s) input buffer format(%s) is not supported, try NV12", 214 get_name (), xcam_fourcc_to_string (input.format)); 215 216 if (!_output_width || !_output_height) { 217 return XCAM_RETURN_ERROR_PARAM; 218 } 219 XCAM_FAIL_RETURN ( 220 WARNING, _output_width && _output_height, XCAM_RETURN_ERROR_PARAM, 221 "CLFisheyeHandler output size(%d, %d) should > 0", 222 _output_width, _output_height); 223 224 output.init ( 225 input.format, _output_width, _output_height, 226 XCAM_ALIGN_UP (_output_width, 16), XCAM_ALIGN_UP (_output_height, 16)); 227 return XCAM_RETURN_NO_ERROR; 228 } 229 230 XCamReturn 231 CLFisheyeHandler::prepare_parameters (SmartPtr<VideoBuffer> &input, SmartPtr<VideoBuffer> &output) 232 { 233 const VideoBufferInfo &in_info = input->get_video_info (); 234 const VideoBufferInfo &out_info = output->get_video_info (); 235 SmartPtr<CLContext> context = get_context (); 236 uint32_t input_image_w = XCAM_ALIGN_DOWN (in_info.width, 2); 237 uint32_t input_image_h = XCAM_ALIGN_DOWN (in_info.height, 2); 238 239 XCAM_FAIL_RETURN ( 240 WARNING, _fisheye_info.is_valid (), XCAM_RETURN_ERROR_PARAM, 241 "CLFisheyeHandler fisheye info is not valid, please check"); 242 243 CLImageDesc cl_desc; 244 cl_desc.format.image_channel_data_type = CL_UNORM_INT8; 245 cl_desc.format.image_channel_order = CL_R; 246 cl_desc.width = input_image_w; 247 cl_desc.height = input_image_h; 248 cl_desc.row_pitch = in_info.strides[NV12PlaneYIdx]; 249 _input[NV12PlaneYIdx] = convert_to_climage (context, input, cl_desc, in_info.offsets[NV12PlaneYIdx]); 250 251 cl_desc.format.image_channel_data_type = CL_UNORM_INT8; 252 cl_desc.format.image_channel_order = CL_RG; 253 cl_desc.width = input_image_w / 2; 254 cl_desc.height = input_image_h / 2; 255 cl_desc.row_pitch = in_info.strides[NV12PlaneUVIdx]; 256 _input[NV12PlaneUVIdx] = convert_to_climage (context, input, cl_desc, in_info.offsets[NV12PlaneUVIdx]); 257 258 if (_use_map) { 259 cl_desc.format.image_channel_data_type = CL_UNSIGNED_INT16; 260 cl_desc.format.image_channel_order = CL_RGBA; 261 cl_desc.width = XCAM_ALIGN_DOWN (out_info.width, 8) / 8; //CL_RGBA * CL_UNSIGNED_INT16 = 8 262 cl_desc.height = XCAM_ALIGN_DOWN (out_info.height, 2); 263 cl_desc.row_pitch = out_info.strides[NV12PlaneYIdx]; 264 _output[NV12PlaneYIdx] = convert_to_climage (context, output, cl_desc, out_info.offsets[NV12PlaneYIdx]); 265 cl_desc.height /= 2; 266 cl_desc.row_pitch = out_info.strides[NV12PlaneUVIdx]; 267 _output[NV12PlaneUVIdx] = convert_to_climage (context, output, cl_desc, out_info.offsets[NV12PlaneUVIdx]); 268 } else { 269 cl_desc.format.image_channel_data_type = CL_UNSIGNED_INT8; 270 cl_desc.format.image_channel_order = CL_RGBA; 271 cl_desc.width = XCAM_ALIGN_DOWN (out_info.width, 4) / 4; //CL_RGBA * CL_UNSIGNED_INT8 = 4 272 cl_desc.height = XCAM_ALIGN_DOWN (out_info.height, 2); 273 cl_desc.row_pitch = out_info.strides[NV12PlaneYIdx]; 274 _output[NV12PlaneYIdx] = convert_to_climage (context, output, cl_desc, out_info.offsets[NV12PlaneYIdx]); 275 cl_desc.height /= 2; 276 cl_desc.row_pitch = out_info.strides[NV12PlaneUVIdx]; 277 _output[NV12PlaneUVIdx] = convert_to_climage (context, output, cl_desc, out_info.offsets[NV12PlaneUVIdx]); 278 } 279 280 XCAM_ASSERT ( 281 _input[NV12PlaneYIdx].ptr () && _input[NV12PlaneYIdx]->is_valid () && 282 _input[NV12PlaneUVIdx].ptr () && _input[NV12PlaneUVIdx]->is_valid () && 283 _output[NV12PlaneYIdx].ptr () && _output[NV12PlaneYIdx]->is_valid () && 284 _output[NV12PlaneUVIdx].ptr () && _output[NV12PlaneUVIdx]->is_valid ()); 285 286 if (_use_map && !_geo_table.ptr ()) { 287 generate_fisheye_table (input_image_w, input_image_h, _fisheye_info); 288 } 289 290 if (!_lsc_table.ptr () && _need_lsc) 291 generate_lsc_table (input_image_w, input_image_h, _fisheye_info); 292 293 return XCAM_RETURN_NO_ERROR; 294 } 295 296 SmartPtr<CLImage> 297 CLFisheyeHandler::create_cl_image ( 298 uint32_t width, uint32_t height, cl_channel_order order, cl_channel_type type) 299 { 300 CLImageDesc cl_desc; 301 cl_desc.format.image_channel_data_type = type; 302 cl_desc.format.image_channel_order = order; 303 cl_desc.width = width; 304 cl_desc.height = height; 305 306 SmartPtr<CLContext> context = get_context (); 307 XCAM_ASSERT (context.ptr ()); 308 SmartPtr<CLImage> image = new CLImage2D (context, cl_desc); 309 XCAM_FAIL_RETURN ( 310 ERROR, image.ptr () && image->is_valid (), 311 NULL, "[%s] create cl image failed", get_name ()); 312 return image; 313 } 314 315 #if 0 316 static void 317 dump_geo_table (SmartPtr<CLImage> table) 318 { 319 const CLImageDesc &desc = table->get_image_desc (); 320 void *ptr = NULL; 321 size_t origin[3] = {0, 0, 0}; 322 size_t region[3] = {desc.width, desc.height, 1}; 323 size_t row_pitch; 324 size_t slice_pitch; 325 326 char name[1024]; 327 snprintf (name, 1024, "geo_table_x_%dx%d.x", desc.width, desc.height); 328 FILE *fp = fopen (name, "wb"); 329 XCamReturn ret = table->enqueue_map (ptr, origin, region, &row_pitch, &slice_pitch, CL_MAP_READ); 330 XCAM_ASSERT (ret == XCAM_RETURN_NO_ERROR); 331 332 for (uint32_t i = 0; i < desc.height; ++i) { 333 float * line = (float*)((uint8_t*)ptr + row_pitch * i); 334 for (uint32_t j = 0; j < desc.width; ++j) { 335 float *buf = line + j * 4; 336 if (i == 120) 337 printf ("%.02f,", *buf); 338 uint8_t val = *buf * 255; 339 fwrite (&val, sizeof (val), 1, fp); 340 } 341 } 342 printf ("\n"); 343 fclose (fp); 344 table->enqueue_unmap (ptr); 345 } 346 #endif 347 348 XCamReturn 349 CLFisheyeHandler::generate_fisheye_table ( 350 uint32_t fisheye_width, uint32_t fisheye_height, const FisheyeInfo &fisheye_info) 351 { 352 SmartPtr<CLContext> context = get_context (); 353 XCAM_ASSERT (context.ptr ()); 354 SmartPtr<CLKernel> table_kernel = new CLKernel (context, "fisheye_table_temp"); 355 XCAM_FAIL_RETURN ( 356 ERROR, table_kernel->build_kernel (kernel_fisheye_info[KernelFisheyeTable], NULL) == XCAM_RETURN_NO_ERROR, 357 XCAM_RETURN_ERROR_CL, "[%s] build fisheye table kernel failed", get_name ()); 358 359 float longitude, latitude; 360 get_dst_range (longitude, latitude); 361 XCAM_FAIL_RETURN ( 362 ERROR, longitude > 0.0f && latitude > 0.0f, 363 XCAM_RETURN_ERROR_PARAM, "[%s] dest latitude and longitude were not set", get_name ()); 364 365 uint32_t output_width, output_height; 366 get_output_size (output_width, output_height); 367 368 uint32_t table_width, table_height; 369 table_width = output_width / _map_factor; 370 table_width = XCAM_ALIGN_UP (table_width, 4); 371 table_height = output_height / _map_factor; 372 table_height = XCAM_ALIGN_UP (table_height, 2); 373 _geo_table = create_cl_image (table_width, table_height, CL_RGBA, CL_FLOAT); 374 XCAM_FAIL_RETURN ( 375 ERROR, _geo_table.ptr () && _geo_table->is_valid (), 376 XCAM_RETURN_ERROR_MEM, "[%s] check geo map buffer failed", get_name ()); 377 378 if(_surround_mode == BowlView) { 379 BowlDataConfig bowl_data_config = get_bowl_config(); 380 IntrinsicParameter intrinsic_param = get_intrinsic_param(); 381 ExtrinsicParameter extrinsic_param = get_extrinsic_param(); 382 383 SurViewFisheyeDewarp::MapTable map_table(table_width * table_height * 2); 384 PolyFisheyeDewarp fd; 385 fd.set_intrinsic_param(intrinsic_param); 386 fd.set_extrinsic_param(extrinsic_param); 387 388 fd.fisheye_dewarp(map_table, table_width, table_height, output_width, output_height, bowl_data_config); 389 390 float *map_ptr = NULL; 391 size_t origin[3] = {0, 0, 0}; 392 size_t region[3] = {table_width, table_height, 1}; 393 size_t row_pitch; 394 size_t slice_pitch; 395 XCamReturn ret = _geo_table->enqueue_map ((void *&)map_ptr, origin, region, &row_pitch, &slice_pitch, CL_MAP_WRITE); 396 XCAM_FAIL_RETURN (ERROR, xcam_ret_is_ok (ret), ret, "CLFisheyeHandler mesh table failed in enqueue_map"); 397 398 for (uint32_t row = 0; row < table_height; row++) { 399 for(uint32_t col = 0; col < table_width; col++) { 400 map_ptr[row * row_pitch / 4 + col * 4] = map_table[row * table_width + col].x / fisheye_width; 401 map_ptr[row * row_pitch / 4 + col * 4 + 1] = map_table[row * table_width + col].y / fisheye_height; 402 } 403 } 404 _geo_table->enqueue_unmap ((void *&)map_ptr); 405 } else { 406 CLArgList args; 407 CLWorkSize work_size; 408 409 FisheyeInfo fisheye_arg1 = fisheye_info; 410 fisheye_arg1.wide_angle = degree2radian (fisheye_info.wide_angle); 411 fisheye_arg1.rotate_angle = degree2radian (fisheye_info.rotate_angle); 412 args.push_back (new CLArgumentT<FisheyeInfo> (fisheye_arg1)); 413 414 float fisheye_image_size[2]; 415 fisheye_image_size[0] = fisheye_width; 416 fisheye_image_size[1] = fisheye_height; 417 args.push_back (new CLArgumentTArray<float, 2> (fisheye_image_size)); 418 args.push_back (new CLMemArgument (_geo_table)); 419 420 float radian_per_pixel[2]; 421 radian_per_pixel[0] = degree2radian (longitude / table_width); 422 radian_per_pixel[1] = degree2radian (latitude / table_height); 423 args.push_back (new CLArgumentTArray<float, 2> (radian_per_pixel)); 424 425 float table_center[2]; 426 table_center[0] = table_width / 2.0f; 427 table_center[1] = table_height / 2.0f; 428 args.push_back (new CLArgumentTArray<float, 2> (table_center)); 429 430 work_size.dim = 2; 431 work_size.local[0] = 8; 432 work_size.local[1] = 4; 433 work_size.global[0] = XCAM_ALIGN_UP (table_width, work_size.local[0]); 434 work_size.global[1] = XCAM_ALIGN_UP (table_height, work_size.local[1]); 435 436 XCAM_FAIL_RETURN ( 437 ERROR, table_kernel->set_arguments (args, work_size) == XCAM_RETURN_NO_ERROR, 438 XCAM_RETURN_ERROR_CL, "kernel_fisheye_table set arguments failed"); 439 440 XCAM_FAIL_RETURN ( 441 ERROR, table_kernel->execute (table_kernel, true) == XCAM_RETURN_NO_ERROR, 442 XCAM_RETURN_ERROR_CL, "[%s] execute kernel_fisheye_table failed", get_name ()); 443 } 444 //dump_geo_table (_geo_table); 445 446 return XCAM_RETURN_NO_ERROR; 447 } 448 449 void 450 CLFisheyeHandler::ensure_lsc_params () 451 { 452 if (_lsc_array) 453 return; 454 455 _lsc_array_size = XCAM_LSC_ARRAY_SIZE; 456 _lsc_array = (float *) xcam_malloc0 (_lsc_array_size * sizeof (float)); 457 XCAM_ASSERT (_lsc_array); 458 memcpy (_lsc_array, lsc_array, _lsc_array_size * sizeof (float)); 459 460 _gray_threshold[1] = max_gray_threshold; 461 _gray_threshold[0] = min_gray_threshold; 462 } 463 464 XCamReturn 465 CLFisheyeHandler::generate_lsc_table ( 466 uint32_t fisheye_width, uint32_t fisheye_height, FisheyeInfo &fisheye_info) 467 { 468 if (!_need_lsc) { 469 XCAM_LOG_WARNING ("lsc is not needed, don't generate lsc table"); 470 return XCAM_RETURN_NO_ERROR; 471 } 472 473 if (!_geo_table.ptr ()) { 474 XCAM_LOG_ERROR ("generate lsc table failed, need generate fisheye table first"); 475 return XCAM_RETURN_ERROR_MEM; 476 } 477 478 ensure_lsc_params (); 479 480 SmartPtr<CLContext> context = get_context (); 481 XCAM_ASSERT (context.ptr ()); 482 SmartPtr<CLKernel> table_kernel = new CLKernel (context, "lsc_table"); 483 XCAM_FAIL_RETURN ( 484 ERROR, table_kernel->build_kernel (kernel_fisheye_info[KernelLSCTable], NULL) == XCAM_RETURN_NO_ERROR, 485 XCAM_RETURN_ERROR_CL, "[%s] build lsc table kernel failed", get_name ()); 486 487 SmartPtr<CLBuffer> array_buf = new CLBuffer ( 488 context, _lsc_array_size * sizeof (float), 489 CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, _lsc_array); 490 xcam_free (_lsc_array); 491 492 CLImageDesc desc = _geo_table->get_image_desc (); 493 _lsc_table = create_cl_image (desc.width, desc.height, CL_R, CL_FLOAT); 494 XCAM_FAIL_RETURN ( 495 ERROR, _lsc_table.ptr () && _lsc_table->is_valid (), 496 XCAM_RETURN_ERROR_MEM, "[%s] create lsc image failed", get_name ()); 497 498 CLArgList args; 499 args.push_back (new CLMemArgument (_geo_table)); 500 args.push_back (new CLMemArgument (_lsc_table)); 501 args.push_back (new CLMemArgument (array_buf)); 502 args.push_back (new CLArgumentT<uint32_t> (_lsc_array_size)); 503 args.push_back (new CLArgumentT<FisheyeInfo> (fisheye_info)); 504 505 float fisheye_image_size[2]; 506 fisheye_image_size[0] = fisheye_width; 507 fisheye_image_size[1] = fisheye_height; 508 args.push_back (new CLArgumentTArray<float, 2> (fisheye_image_size)); 509 510 CLWorkSize work_size; 511 work_size.dim = 2; 512 work_size.local[0] = 8; 513 work_size.local[1] = 4; 514 work_size.global[0] = XCAM_ALIGN_UP (desc.width, work_size.local[0]); 515 work_size.global[1] = XCAM_ALIGN_UP (desc.height, work_size.local[1]); 516 517 XCAM_FAIL_RETURN ( 518 ERROR, table_kernel->set_arguments (args, work_size) == XCAM_RETURN_NO_ERROR, 519 XCAM_RETURN_ERROR_CL, "kernel_lsc_table set arguments failed"); 520 521 XCAM_FAIL_RETURN ( 522 ERROR, table_kernel->execute (table_kernel, true) == XCAM_RETURN_NO_ERROR, 523 XCAM_RETURN_ERROR_CL, "[%s] execute kernel_lsc_table failed", get_name ()); 524 525 return XCAM_RETURN_NO_ERROR; 526 } 527 528 XCamReturn 529 CLFisheyeHandler::execute_done (SmartPtr<VideoBuffer> &output) 530 { 531 XCAM_UNUSED (output); 532 533 for (int i = 0; i < NV12PlaneMax; ++i) { 534 _input[i].release (); 535 _output[i].release (); 536 } 537 538 return XCAM_RETURN_NO_ERROR; 539 } 540 541 SmartPtr<CLImage> 542 CLFisheyeHandler::get_geo_input_image (NV12PlaneIdx index) { 543 return get_input_image(index); 544 } 545 546 SmartPtr<CLImage> 547 CLFisheyeHandler::get_geo_output_image (NV12PlaneIdx index) { 548 return get_output_image (index); 549 } 550 551 void 552 CLFisheyeHandler::get_geo_equivalent_out_size (float &width, float &height) 553 { 554 width = _output_width; 555 height = _output_height; 556 } 557 558 void 559 CLFisheyeHandler::get_geo_pixel_out_size (float &width, float &height) 560 { 561 width = _output_width; 562 height = _output_height; 563 } 564 565 SmartPtr<CLImage> 566 CLFisheyeHandler::get_lsc_table () { 567 XCAM_ASSERT (_lsc_table.ptr ()); 568 return _lsc_table; 569 } 570 571 float* 572 CLFisheyeHandler::get_lsc_gray_threshold () { 573 return _gray_threshold; 574 } 575 576 static SmartPtr<CLImageKernel> 577 create_fishey_gps_kernel (const SmartPtr<CLContext> &context, SmartPtr<CLFisheyeHandler> handler) 578 { 579 SmartPtr<CLImageKernel> kernel = new CLFisheye2GPSKernel (context, handler); 580 XCAM_ASSERT (kernel.ptr ()); 581 XCAM_FAIL_RETURN ( 582 ERROR, kernel->build_kernel (kernel_fisheye_info[KernelFisheye2GPS], NULL) == XCAM_RETURN_NO_ERROR, 583 NULL, "build fisheye kernel failed"); 584 return kernel; 585 } 586 587 SmartPtr<CLImageHandler> 588 create_fisheye_handler (const SmartPtr<CLContext> &context, SurroundMode surround_mode, bool use_map, bool need_lsc) 589 { 590 SmartPtr<CLFisheyeHandler> handler; 591 SmartPtr<CLImageKernel> kernel; 592 593 handler = new CLFisheyeHandler (context, surround_mode, use_map, need_lsc); 594 XCAM_ASSERT (handler.ptr ()); 595 596 if (use_map) { 597 kernel = create_geo_map_kernel (context, handler, need_lsc); 598 } else { 599 kernel = create_fishey_gps_kernel (context, handler); 600 } 601 XCAM_FAIL_RETURN ( 602 ERROR, kernel.ptr (), NULL, "Fisheye handler create kernel failed."); 603 604 handler->add_kernel (kernel); 605 return handler; 606 } 607 608 609 } 610