blob: 0f82d87348944b21a471bd58dc9b3c80726541e9 [file] [log] [blame]
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001/*
Michele Di Giorgiod9eaf612020-07-08 11:12:57 +01002 * Copyright (c) 2016-2020 Arm Limited.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003 *
4 * SPDX-License-Identifier: MIT
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24#include "arm_compute/core/CL/kernels/CLColorConvertKernel.h"
25
26#include "arm_compute/core/CL/CLKernelLibrary.h"
27#include "arm_compute/core/CL/ICLMultiImage.h"
28#include "arm_compute/core/CL/ICLTensor.h"
29#include "arm_compute/core/CL/OpenCL.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010030#include "arm_compute/core/Helpers.h"
31#include "arm_compute/core/MultiImageInfo.h"
32#include "arm_compute/core/TensorInfo.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010033#include "arm_compute/core/Utils.h"
34#include "arm_compute/core/Validate.h"
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +010035#include "src/core/helpers/WindowHelpers.h"
Matthew Bentham758b5ba2020-03-05 23:37:48 +000036#include "support/StringSupport.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010037
38#include <sstream>
39
40using namespace arm_compute;
41
42CLColorConvertKernel::CLColorConvertKernel()
43 : _input(nullptr), _output(nullptr), _multi_input(nullptr), _multi_output(nullptr)
44{
45}
46
47void CLColorConvertKernel::configure(const ICLTensor *input, ICLTensor *output)
48{
Manuel Bottini4c6bd512020-04-08 10:15:51 +010049 configure(CLKernelLibrary::get().get_compile_context(), input, output);
50}
51
Manuel Bottini256c0b92020-04-21 13:29:30 +010052void CLColorConvertKernel::configure(const CLCompileContext &compile_context, const ICLTensor *input, ICLTensor *output)
Manuel Bottini4c6bd512020-04-08 10:15:51 +010053{
Anthony Barbier6ff3b192017-09-04 18:44:23 +010054 ARM_COMPUTE_ERROR_ON(input == nullptr);
55 ARM_COMPUTE_ERROR_ON(output == nullptr);
56
57 unsigned int num_elems_processed_per_iteration = 0;
58 switch(input->info()->format())
59 {
60 case Format::RGBA8888:
61 {
62 switch(output->info()->format())
63 {
64 case Format::RGB888:
65 num_elems_processed_per_iteration = 16;
66 break;
67 default:
Manuel Bottiniacaf21d2018-09-26 17:38:19 +010068 ARM_COMPUTE_ERROR("Not supported");
Anthony Barbier6ff3b192017-09-04 18:44:23 +010069 break;
70 }
71 break;
72 }
73 case Format::UYVY422:
74 case Format::YUYV422:
75 {
76 switch(output->info()->format())
77 {
78 case Format::RGB888:
79 case Format::RGBA8888:
80 num_elems_processed_per_iteration = 8;
81 break;
82 default:
Manuel Bottiniacaf21d2018-09-26 17:38:19 +010083 ARM_COMPUTE_ERROR("Not supported");
Anthony Barbier6ff3b192017-09-04 18:44:23 +010084 break;
85 }
86 break;
87 }
88 case Format::RGB888:
89 {
90 switch(output->info()->format())
91 {
92 case Format::RGBA8888:
Manuel Bottiniacaf21d2018-09-26 17:38:19 +010093 case Format::U8:
Anthony Barbier6ff3b192017-09-04 18:44:23 +010094 num_elems_processed_per_iteration = 16;
95 break;
96 default:
Manuel Bottiniacaf21d2018-09-26 17:38:19 +010097 ARM_COMPUTE_ERROR("Not supported");
Anthony Barbier6ff3b192017-09-04 18:44:23 +010098 break;
99 }
100 break;
101 }
102 default:
103 break;
104 }
Michalis Spyrou7c60c992019-10-10 14:33:47 +0100105 ARM_COMPUTE_ERROR_ON_MSG_VAR(num_elems_processed_per_iteration == 0, "Conversion from %s to %s not supported",
106 string_from_format(input->info()->format()).c_str(),
107 string_from_format(output->info()->format()).c_str());
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100108
109 std::stringstream kernel_name;
110
111 kernel_name << string_from_format(input->info()->format());
112 kernel_name << "_to_";
113 kernel_name << string_from_format(output->info()->format());
114 kernel_name << "_bt709";
115
116 _input = input;
117 _output = output;
118
119 // Create kernel
Manuel Bottini4c6bd512020-04-08 10:15:51 +0100120 _kernel = create_kernel(compile_context, kernel_name.str());
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100121
122 // Configure kernel window
123 Window win = calculate_max_window(*input->info(), Steps(num_elems_processed_per_iteration));
124 AccessWindowHorizontal input_access(input->info(), 0, num_elems_processed_per_iteration);
125 AccessWindowHorizontal output_access(output->info(), 0, num_elems_processed_per_iteration);
126
127 update_window_and_padding(win, input_access, output_access);
128
129 output_access.set_valid_region(win, input->info()->valid_region());
130
Anthony Barbierb6eb3532018-08-08 13:20:04 +0100131 ICLKernel::configure_internal(win);
Gary Antcliffefffbdbc2019-05-28 11:40:21 +0100132
133 // Set config_id for enabling LWS tuning
134 _config_id = kernel_name.str();
135 _config_id += "_";
136 _config_id += lower_string(string_from_data_type(input->info()->data_type()));
137 _config_id += "_";
138 _config_id += support::cpp11::to_string(input->info()->dimension(0));
139 _config_id += "_";
140 _config_id += support::cpp11::to_string(input->info()->dimension(1));
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100141}
142
143void CLColorConvertKernel::configure(const ICLMultiImage *input, ICLImage *output)
144{
Manuel Bottini4c6bd512020-04-08 10:15:51 +0100145 configure(CLKernelLibrary::get().get_compile_context(), input, output);
146}
147
Manuel Bottini256c0b92020-04-21 13:29:30 +0100148void CLColorConvertKernel::configure(const CLCompileContext &compile_context, const ICLMultiImage *input, ICLImage *output)
Manuel Bottini4c6bd512020-04-08 10:15:51 +0100149{
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100150 ARM_COMPUTE_ERROR_ON_TENSOR_NOT_2D(output);
151 ARM_COMPUTE_ERROR_ON(output == nullptr);
152
153 unsigned int num_elems_processed_per_iteration = 0;
154
155 switch(input->info()->format())
156 {
157 case Format::NV12:
158 case Format::NV21:
159 case Format::IYUV:
160 {
161 switch(output->info()->format())
162 {
163 case Format::RGB888:
164 case Format::RGBA8888:
165 num_elems_processed_per_iteration = 4;
166 break;
167 default:
Manuel Bottiniacaf21d2018-09-26 17:38:19 +0100168 ARM_COMPUTE_ERROR("Not supported");
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100169 break;
170 }
171 break;
172 }
173 default:
174 break;
175 }
Michalis Spyrou7c60c992019-10-10 14:33:47 +0100176 ARM_COMPUTE_ERROR_ON_MSG_VAR(num_elems_processed_per_iteration == 0, "Conversion from %s to %s not supported",
177 string_from_format(input->info()->format()).c_str(),
178 string_from_format(output->info()->format()).c_str());
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100179
180 std::stringstream kernel_name;
181
182 kernel_name << string_from_format(input->info()->format());
183 kernel_name << "_to_";
184 kernel_name << string_from_format(output->info()->format());
185 kernel_name << "_bt709";
186
187 _multi_input = input;
188 _output = output;
189
190 // Create kernel
Manuel Bottini4c6bd512020-04-08 10:15:51 +0100191 _kernel = create_kernel(compile_context, kernel_name.str());
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100192
193 // Configure kernel window
194 const bool has_two_planes = (input->info()->format() == Format::NV12) || (input->info()->format() == Format::NV21);
195 const float sub_sampling = (has_two_planes || (input->info()->format() == Format::IYUV)) ? 0.5f : 1;
196
197 Window win = calculate_max_window(*output->info(), Steps(num_elems_processed_per_iteration));
198 win.set_dimension_step(Window::DimY, 2);
199
200 AccessWindowHorizontal plane0_access(input->plane(0)->info(), 0, num_elems_processed_per_iteration);
201 AccessWindowRectangle plane1_access(input->plane(1)->info(), 0, 0, num_elems_processed_per_iteration, 1,
202 sub_sampling, sub_sampling);
203 AccessWindowRectangle plane2_access(has_two_planes ? nullptr : input->plane(2)->info(), 0, 0, num_elems_processed_per_iteration, 1,
204 sub_sampling, sub_sampling);
205 AccessWindowHorizontal output_access(output->info(), 0, num_elems_processed_per_iteration);
206
207 update_window_and_padding(win,
208 plane0_access, plane1_access, plane2_access,
209 output_access);
210
211 ValidRegion intersect_region = intersect_valid_regions(input->plane(0)->info()->valid_region(), input->plane(1)->info()->valid_region(),
212 input->plane(2)->info()->valid_region());
213 output_access.set_valid_region(win, ValidRegion(intersect_region.anchor, output->info()->tensor_shape()));
214
Anthony Barbierb6eb3532018-08-08 13:20:04 +0100215 ICLKernel::configure_internal(win);
Gary Antcliffefffbdbc2019-05-28 11:40:21 +0100216
217 // Set config_id for enabling LWS tuning
218 _config_id = kernel_name.str();
219 _config_id += "_";
220 _config_id += lower_string(string_from_data_type(input->plane(0)->info()->data_type()));
221 _config_id += "_";
222 _config_id += support::cpp11::to_string(input->plane(0)->info()->dimension(0));
223 _config_id += "_";
224 _config_id += support::cpp11::to_string(input->plane(0)->info()->dimension(1));
225 _config_id += "_";
226 _config_id += lower_string(string_from_data_type(input->plane(1)->info()->data_type()));
227 _config_id += "_";
228 _config_id += support::cpp11::to_string(input->plane(1)->info()->dimension(0));
229 _config_id += "_";
230 _config_id += support::cpp11::to_string(input->plane(1)->info()->dimension(1));
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100231}
232
233void CLColorConvertKernel::configure(const ICLImage *input, ICLMultiImage *output)
234{
Manuel Bottini4c6bd512020-04-08 10:15:51 +0100235 configure(CLKernelLibrary::get().get_compile_context(), input, output);
236}
237
Manuel Bottini256c0b92020-04-21 13:29:30 +0100238void CLColorConvertKernel::configure(const CLCompileContext &compile_context, const ICLImage *input, ICLMultiImage *output)
Manuel Bottini4c6bd512020-04-08 10:15:51 +0100239{
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100240 ARM_COMPUTE_ERROR_ON_TENSOR_NOT_2D(input);
241 ARM_COMPUTE_ERROR_ON(output == nullptr);
242
243 unsigned int num_elems_processed_per_iteration = 0;
Pablo Tello96fc1d62018-07-17 17:10:59 +0100244 unsigned int num_elems_read_per_iteration_x = 0;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100245
246 bool has_two_planes = (output->info()->format() == Format::NV12) || (output->info()->format() == Format::NV21);
247 float sub_sampling = (has_two_planes || (output->info()->format() == Format::IYUV)) ? 0.5f : 1;
248
249 switch(input->info()->format())
250 {
251 case Format::RGB888:
252 case Format::RGBA8888:
253 {
254 switch(output->info()->format())
255 {
256 case Format::NV12:
257 case Format::IYUV:
258 num_elems_processed_per_iteration = 2;
Pablo Tello96fc1d62018-07-17 17:10:59 +0100259 num_elems_read_per_iteration_x = 8;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100260 break;
261 case Format::YUV444:
262 num_elems_processed_per_iteration = 4;
Pablo Tello96fc1d62018-07-17 17:10:59 +0100263 num_elems_read_per_iteration_x = 16;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100264 break;
265 default:
Manuel Bottiniacaf21d2018-09-26 17:38:19 +0100266 ARM_COMPUTE_ERROR("Not supported");
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100267 break;
268 }
269 break;
270 }
271 case Format::UYVY422:
272 case Format::YUYV422:
273 {
274 switch(output->info()->format())
275 {
276 case Format::NV12:
277 case Format::IYUV:
278 num_elems_processed_per_iteration = 8;
Pablo Tello96fc1d62018-07-17 17:10:59 +0100279 num_elems_read_per_iteration_x = 8;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100280 break;
281 default:
Manuel Bottiniacaf21d2018-09-26 17:38:19 +0100282 ARM_COMPUTE_ERROR("Not supported");
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100283 break;
284 }
285 break;
286 }
287 default:
288 break;
289 }
Pablo Tello96fc1d62018-07-17 17:10:59 +0100290
Michalis Spyrou7c60c992019-10-10 14:33:47 +0100291 ARM_COMPUTE_ERROR_ON_MSG_VAR(num_elems_processed_per_iteration == 0, "Conversion from %s to %s not supported",
292 string_from_format(input->info()->format()).c_str(),
293 string_from_format(output->info()->format()).c_str());
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100294
295 std::stringstream kernel_name;
296
297 kernel_name << string_from_format(input->info()->format());
298 kernel_name << "_to_";
299 kernel_name << string_from_format(output->info()->format());
300 kernel_name << "_bt709";
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100301 _input = input;
302 _multi_output = output;
303
304 // Create kernel
Manuel Bottini4c6bd512020-04-08 10:15:51 +0100305 _kernel = create_kernel(compile_context, kernel_name.str());
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100306
307 // Configure kernel window
308 Window win = calculate_max_window(*input->info(), Steps(num_elems_processed_per_iteration));
309 if((input->info()->format() != Format::RGB888 || output->info()->format() != Format::YUV444) && (input->info()->format() != Format::RGBA8888 || output->info()->format() != Format::YUV444))
310 {
311 win.set_dimension_step(Window::DimY, 2);
312 }
313
314 AccessWindowHorizontal output_plane0_access(output->plane(0)->info(), 0, num_elems_processed_per_iteration);
315 AccessWindowRectangle output_plane1_access(output->plane(1)->info(), 0, 0, num_elems_processed_per_iteration, 1, sub_sampling, sub_sampling);
316 AccessWindowRectangle output_plane2_access(has_two_planes ? nullptr : output->plane(2)->info(), 0, 0,
317 num_elems_processed_per_iteration, 1, sub_sampling, sub_sampling);
318
Pablo Tello96fc1d62018-07-17 17:10:59 +0100319 AccessWindowHorizontal input_access(input->info(), 0, num_elems_read_per_iteration_x);
320
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100321 update_window_and_padding(win,
Pablo Tello96fc1d62018-07-17 17:10:59 +0100322 input_access,
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100323 output_plane0_access,
324 output_plane1_access,
325 output_plane2_access);
326
327 ValidRegion input_region = input->info()->valid_region();
328
329 output_plane0_access.set_valid_region(win, ValidRegion(input_region.anchor, output->plane(0)->info()->tensor_shape()));
330 output_plane1_access.set_valid_region(win, ValidRegion(input_region.anchor, output->plane(1)->info()->tensor_shape()));
331 output_plane2_access.set_valid_region(win, ValidRegion(input_region.anchor, output->plane(2)->info()->tensor_shape()));
332
Anthony Barbierb6eb3532018-08-08 13:20:04 +0100333 ICLKernel::configure_internal(win);
Gary Antcliffefffbdbc2019-05-28 11:40:21 +0100334
335 // Set config_id for enabling LWS tuning
336 _config_id = kernel_name.str();
337 _config_id += "_";
338 _config_id += lower_string(string_from_data_type(input->info()->data_type()));
339 _config_id += "_";
340 _config_id += support::cpp11::to_string(input->info()->dimension(0));
341 _config_id += "_";
342 _config_id += support::cpp11::to_string(input->info()->dimension(1));
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100343}
344
345void CLColorConvertKernel::configure(const ICLMultiImage *input, ICLMultiImage *output)
346{
Manuel Bottini4c6bd512020-04-08 10:15:51 +0100347 configure(CLKernelLibrary::get().get_compile_context(), input, output);
348}
349
Manuel Bottini256c0b92020-04-21 13:29:30 +0100350void CLColorConvertKernel::configure(const CLCompileContext &compile_context, const ICLMultiImage *input, ICLMultiImage *output)
Manuel Bottini4c6bd512020-04-08 10:15:51 +0100351{
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100352 unsigned int num_elems_processed_per_iteration = 0;
353 switch(input->info()->format())
354 {
355 case Format::NV12:
356 case Format::NV21:
357 {
358 switch(output->info()->format())
359 {
360 case Format::IYUV:
361 case Format::YUV444:
362 num_elems_processed_per_iteration = 16;
363 break;
364 default:
Manuel Bottiniacaf21d2018-09-26 17:38:19 +0100365 ARM_COMPUTE_ERROR("Not supported");
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100366 break;
367 }
368 break;
369 }
370 case Format::IYUV:
371 {
372 switch(output->info()->format())
373 {
374 case Format::YUV444:
375 case Format::NV12:
376 num_elems_processed_per_iteration = 16;
377 break;
378 default:
Manuel Bottiniacaf21d2018-09-26 17:38:19 +0100379 ARM_COMPUTE_ERROR("Not supported");
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100380 break;
381 }
382 break;
383 }
384 default:
385 break;
386 }
Michalis Spyrou7c60c992019-10-10 14:33:47 +0100387 ARM_COMPUTE_ERROR_ON_MSG_VAR(num_elems_processed_per_iteration == 0, "Conversion from %s to %s not supported",
388 string_from_format(input->info()->format()).c_str(),
389 string_from_format(output->info()->format()).c_str());
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100390
391 std::stringstream kernel_name;
392
393 kernel_name << string_from_format(input->info()->format());
394 kernel_name << "_to_";
395 kernel_name << string_from_format(output->info()->format());
396 kernel_name << "_bt709";
397
398 _multi_input = input;
399 _multi_output = output;
400
401 // Create kernel
402 bool has_two_input_planars = (input->info()->format() == Format::NV12) || (input->info()->format() == Format::NV21);
403 bool has_two_output_planars = (output->info()->format() == Format::NV12) || (output->info()->format() == Format::NV21);
404
405 float sub_sampling_input = (has_two_input_planars || (input->info()->format() == Format::IYUV)) ? 0.5f : 1;
406 float sub_sampling_output = (has_two_output_planars || (output->info()->format() == Format::IYUV)) ? 0.5f : 1;
407
Manuel Bottini4c6bd512020-04-08 10:15:51 +0100408 _kernel = create_kernel(compile_context, kernel_name.str());
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100409
410 Window win = calculate_max_window(*input->cl_plane(0)->info(), Steps(num_elems_processed_per_iteration));
411 win.set_dimension_step(Window::DimY, 2);
412
413 AccessWindowHorizontal input_plane0_access(input->plane(0)->info(), 0, num_elems_processed_per_iteration);
414 AccessWindowRectangle input_plane1_access(input->plane(1)->info(), 0, 0, num_elems_processed_per_iteration, 1,
415 sub_sampling_input, sub_sampling_input);
416 AccessWindowRectangle input_plane2_access(has_two_input_planars ? nullptr : input->plane(2)->info(), 0, 0, num_elems_processed_per_iteration, 1,
417 sub_sampling_input, sub_sampling_input);
418 AccessWindowHorizontal output_plane0_access(output->plane(0)->info(), 0, num_elems_processed_per_iteration);
419 AccessWindowRectangle output_plane1_access(output->plane(1)->info(), 0, 0, num_elems_processed_per_iteration, 1, sub_sampling_output, sub_sampling_output);
420 AccessWindowRectangle output_plane2_access(has_two_output_planars ? nullptr : output->plane(2)->info(), 0, 0,
421 num_elems_processed_per_iteration, 1, sub_sampling_output, sub_sampling_output);
422
423 update_window_and_padding(win,
424 input_plane0_access, input_plane1_access, input_plane2_access,
425 output_plane0_access, output_plane1_access, output_plane2_access);
426
427 ValidRegion intersect_region = intersect_valid_regions(input->plane(0)->info()->valid_region(), input->plane(1)->info()->valid_region(),
428 input->plane(2)->info()->valid_region());
429 output_plane0_access.set_valid_region(win, ValidRegion(intersect_region.anchor, output->plane(0)->info()->tensor_shape()));
430 output_plane1_access.set_valid_region(win, ValidRegion(intersect_region.anchor, output->plane(1)->info()->tensor_shape()));
431 output_plane2_access.set_valid_region(win, ValidRegion(intersect_region.anchor, output->plane(2)->info()->tensor_shape()));
432
Anthony Barbierb6eb3532018-08-08 13:20:04 +0100433 ICLKernel::configure_internal(win);
Gary Antcliffefffbdbc2019-05-28 11:40:21 +0100434
435 // Set config_id for enabling LWS tuning
436 _config_id = kernel_name.str();
437 _config_id += "_";
438 _config_id += lower_string(string_from_data_type(input->plane(0)->info()->data_type()));
439 _config_id += "_";
440 _config_id += support::cpp11::to_string(input->plane(0)->info()->dimension(0));
441 _config_id += "_";
442 _config_id += support::cpp11::to_string(input->plane(0)->info()->dimension(1));
443 _config_id += "_";
444 _config_id += lower_string(string_from_data_type(input->plane(1)->info()->data_type()));
445 _config_id += "_";
446 _config_id += support::cpp11::to_string(input->plane(1)->info()->dimension(0));
447 _config_id += "_";
448 _config_id += support::cpp11::to_string(input->plane(1)->info()->dimension(1));
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100449}
450
451void CLColorConvertKernel::run(const Window &window, cl::CommandQueue &queue)
452{
453 ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(this);
454 ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(ICLKernel::window(), window);
455
456 Window slice = window.first_slice_window_2D();
457
458 if(nullptr != _input && nullptr != _output)
459 {
460 do
461 {
462 unsigned int idx = 0;
463 add_2D_tensor_argument(idx, _input, slice);
464 add_2D_tensor_argument(idx, _output, slice);
Michele Di Giorgio6b9f3882019-07-01 16:37:04 +0100465 enqueue(queue, *this, slice, lws_hint());
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100466 }
467 while(window.slide_window_slice_2D(slice));
468 }
469 else if(nullptr != _input && nullptr != _multi_output)
470 {
471 Format format = _multi_output->info()->format();
472 do
473 {
474 Window win_uv(slice);
475
476 if((Format::NV12 == format) || (Format::NV21 == format) || (Format::IYUV == format))
477 {
478 win_uv.set(Window::DimX, Window::Dimension(win_uv.x().start() / 2, win_uv.x().end() / 2, win_uv.x().step() / 2));
479 win_uv.set(Window::DimY, Window::Dimension(win_uv.y().start() / 2, win_uv.y().end() / 2, 1));
480 }
481 unsigned int idx = 0;
482 add_2D_tensor_argument(idx, _input, slice);
483 add_2D_tensor_argument(idx, _multi_output->cl_plane(0), slice);
484 for(int i = 1; i < 3 && (0 != _multi_output->cl_plane(i)->info()->num_dimensions()); ++i)
485 {
486 add_2D_tensor_argument(idx, _multi_output->cl_plane(i), win_uv);
487 }
Michele Di Giorgio6b9f3882019-07-01 16:37:04 +0100488 enqueue(queue, *this, slice, lws_hint());
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100489 }
490 while(window.slide_window_slice_2D(slice));
491 }
492 else if(nullptr != _multi_input && nullptr != _output)
493 {
494 Format format = _multi_input->info()->format();
495 do
496 {
497 Window win_uv(slice);
498
499 if((Format::NV12 == format) || (Format::NV21 == format) || (Format::IYUV == format))
500 {
501 win_uv.set(Window::DimX, Window::Dimension(win_uv.x().start() / 2, win_uv.x().end() / 2, win_uv.x().step() / 2));
502 win_uv.set(Window::DimY, Window::Dimension(win_uv.y().start() / 2, win_uv.y().end() / 2, 1));
503 }
504
505 unsigned int idx = 0;
506 add_2D_tensor_argument(idx, _multi_input->cl_plane(0), slice);
507
508 for(int i = 1; i < 3 && (0 != _multi_input->cl_plane(i)->info()->num_dimensions()); ++i)
509 {
510 add_2D_tensor_argument(idx, _multi_input->cl_plane(i), win_uv);
511 }
512 add_2D_tensor_argument(idx, _output, slice);
Michele Di Giorgio6b9f3882019-07-01 16:37:04 +0100513 enqueue(queue, *this, slice, lws_hint());
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100514 }
515 while(window.slide_window_slice_2D(slice));
516 }
517 else if(nullptr != _multi_input && nullptr != _multi_output)
518 {
519 Format in_format = _multi_input->info()->format();
520 Format out_format = _multi_output->info()->format();
521 do
522 {
523 Window win_in_uv(slice);
524 if((Format::NV12 == in_format) || (Format::NV21 == in_format) || (Format::IYUV == in_format))
525 {
526 win_in_uv.set(Window::DimX, Window::Dimension(win_in_uv.x().start() / 2,
527 win_in_uv.x().end() / 2, win_in_uv.x().step() / 2));
528 win_in_uv.set(Window::DimY, Window::Dimension(win_in_uv.y().start() / 2, win_in_uv.y().end() / 2, 1));
529 }
530 unsigned int idx = 0;
531 add_2D_tensor_argument(idx, _multi_input->cl_plane(0), slice);
532 for(int i = 1; i < 3 && (0 != _multi_input->cl_plane(i)->info()->num_dimensions()); ++i)
533 {
534 add_2D_tensor_argument(idx, _multi_input->cl_plane(i), win_in_uv);
535 }
536
537 Window win_out_uv(slice);
538 if((Format::NV12 == out_format) || (Format::NV21 == out_format) || (Format::IYUV == out_format))
539 {
540 win_out_uv.set(Window::DimX, Window::Dimension(win_out_uv.x().start() / 2,
541 win_out_uv.x().end() / 2, win_out_uv.x().step() / 2));
542 win_out_uv.set(Window::DimY, Window::Dimension(win_out_uv.y().start() / 2, win_out_uv.y().end() / 2, 1));
543 }
544
545 add_2D_tensor_argument(idx, _multi_output->cl_plane(0), slice);
546 for(int i = 1; i < 3 && (0 != _multi_output->cl_plane(i)->info()->num_dimensions()); ++i)
547 {
548 add_2D_tensor_argument(idx, _multi_output->cl_plane(i), win_out_uv);
549 }
Michele Di Giorgio6b9f3882019-07-01 16:37:04 +0100550 enqueue(queue, *this, slice, lws_hint());
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100551 }
552 while(window.slide_window_slice_2D(slice));
553 }
554 else
555 {
556 ARM_COMPUTE_ERROR("Not supported");
557 }
558}