• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@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 
CLFisheye2GPSKernel(const SmartPtr<CLContext> & context,SmartPtr<CLFisheyeHandler> & handler)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
prepare_arguments(CLArgList & args,CLWorkSize & work_size)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 
CLFisheyeHandler(const SmartPtr<CLContext> & context,SurroundMode surround_mode,bool use_map,bool need_lsc)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 
~CLFisheyeHandler()147 CLFisheyeHandler::~CLFisheyeHandler()
148 {
149     if (_lsc_array)
150         xcam_free (_lsc_array);
151 }
152 
153 void
set_output_size(uint32_t width,uint32_t height)154 CLFisheyeHandler::set_output_size (uint32_t width, uint32_t height)
155 {
156     _output_width = width;
157     _output_height = height;
158 }
159 
160 void
get_output_size(uint32_t & width,uint32_t & height) const161 CLFisheyeHandler::get_output_size (uint32_t &width, uint32_t &height) const
162 {
163     width = _output_width;
164     height = _output_height;
165 }
166 
167 void
set_dst_range(float longitude,float latitude)168 CLFisheyeHandler::set_dst_range (float longitude, float latitude)
169 {
170     _range_longitude = longitude;
171     _range_latitude = latitude;
172 }
173 
174 void
get_dst_range(float & longitude,float & latitude) const175 CLFisheyeHandler::get_dst_range (float &longitude, float &latitude) const
176 {
177     longitude = _range_longitude;
178     latitude = _range_latitude;
179 }
180 
181 void
set_fisheye_info(const FisheyeInfo & info)182 CLFisheyeHandler::set_fisheye_info (const FisheyeInfo &info)
183 {
184     _fisheye_info = info;
185 }
186 
187 void
set_lsc_table(float * table,uint32_t table_size)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
set_lsc_gray_threshold(float min_threshold,float max_threshold)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
prepare_buffer_pool_video_info(const VideoBufferInfo & input,VideoBufferInfo & output)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
prepare_parameters(SmartPtr<VideoBuffer> & input,SmartPtr<VideoBuffer> & output)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>
create_cl_image(uint32_t width,uint32_t height,cl_channel_order order,cl_channel_type type)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
generate_fisheye_table(uint32_t fisheye_width,uint32_t fisheye_height,const FisheyeInfo & fisheye_info)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
ensure_lsc_params()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
generate_lsc_table(uint32_t fisheye_width,uint32_t fisheye_height,FisheyeInfo & fisheye_info)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
execute_done(SmartPtr<VideoBuffer> & output)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>
get_geo_input_image(NV12PlaneIdx index)542 CLFisheyeHandler::get_geo_input_image (NV12PlaneIdx index) {
543     return get_input_image(index);
544 }
545 
546 SmartPtr<CLImage>
get_geo_output_image(NV12PlaneIdx index)547 CLFisheyeHandler::get_geo_output_image (NV12PlaneIdx index) {
548     return get_output_image (index);
549 }
550 
551 void
get_geo_equivalent_out_size(float & width,float & height)552 CLFisheyeHandler::get_geo_equivalent_out_size (float &width, float &height)
553 {
554     width = _output_width;
555     height = _output_height;
556 }
557 
558 void
get_geo_pixel_out_size(float & width,float & height)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>
get_lsc_table()566 CLFisheyeHandler::get_lsc_table () {
567     XCAM_ASSERT (_lsc_table.ptr ());
568     return _lsc_table;
569 }
570 
571 float*
get_lsc_gray_threshold()572 CLFisheyeHandler::get_lsc_gray_threshold () {
573     return _gray_threshold;
574 }
575 
576 static SmartPtr<CLImageKernel>
create_fishey_gps_kernel(const SmartPtr<CLContext> & context,SmartPtr<CLFisheyeHandler> handler)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>
create_fisheye_handler(const SmartPtr<CLContext> & context,SurroundMode surround_mode,bool use_map,bool need_lsc)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