1 /*
2 * cl_csc_handler.cpp - CL csc handler
3 *
4 * Copyright (c) 2015 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: wangfei <feix.w.wang@intel.com>
19 * Author: Wind Yuan <feng.yuan@intel.com>
20 */
21 #include "cl_utils.h"
22 #include "cl_csc_handler.h"
23 #include "cl_device.h"
24 #include "cl_kernel.h"
25
26 static const XCamKernelInfo kernel_csc_info[] = {
27 {
28 "kernel_csc_rgbatonv12",
29 #include "kernel_csc.clx"
30 , 0,
31 },
32 {
33 "kernel_csc_rgbatolab",
34 #include "kernel_csc.clx"
35 , 0,
36 },
37 {
38 "kernel_csc_rgba64torgba",
39 #include "kernel_csc.clx"
40 , 0,
41 },
42 {
43 "kernel_csc_yuyvtorgba",
44 #include "kernel_csc.clx"
45 , 0,
46 },
47 {
48 "kernel_csc_nv12torgba",
49 #include "kernel_csc.clx"
50 , 0,
51 },
52 };
53
54
55 float default_rgbtoyuv_matrix[XCAM_COLOR_MATRIX_SIZE] = {
56 0.299f, 0.587f, 0.114f,
57 -0.14713f, -0.28886f, 0.436f,
58 0.615f, -0.51499f, -0.10001f
59 };
60
61 namespace XCam {
62
CLCscImageKernel(const SmartPtr<CLContext> & context,CLCscType type)63 CLCscImageKernel::CLCscImageKernel (const SmartPtr<CLContext> &context, CLCscType type)
64 : CLImageKernel (context)
65 , _kernel_csc_type (type)
66 {
67 }
68
CLCscImageHandler(const SmartPtr<CLContext> & context,const char * name,CLCscType type)69 CLCscImageHandler::CLCscImageHandler (
70 const SmartPtr<CLContext> &context, const char *name, CLCscType type)
71 : CLImageHandler (context, name)
72 , _output_format (V4L2_PIX_FMT_NV12)
73 , _csc_type (type)
74 {
75 memcpy (_rgbtoyuv_matrix, default_rgbtoyuv_matrix, sizeof (_rgbtoyuv_matrix));
76
77 switch (type) {
78 case CL_CSC_TYPE_RGBATONV12:
79 _output_format = V4L2_PIX_FMT_NV12;
80 break;
81 case CL_CSC_TYPE_RGBATOLAB:
82 _output_format = XCAM_PIX_FMT_LAB;
83 break;
84 case CL_CSC_TYPE_RGBA64TORGBA:
85 case CL_CSC_TYPE_YUYVTORGBA:
86 case CL_CSC_TYPE_NV12TORGBA:
87 _output_format = V4L2_PIX_FMT_RGBA32;
88 break;
89 default:
90 break;
91 }
92 }
93
94 bool
set_csc_kernel(SmartPtr<CLCscImageKernel> & kernel)95 CLCscImageHandler::set_csc_kernel (SmartPtr<CLCscImageKernel> &kernel)
96 {
97 SmartPtr<CLImageKernel> image_kernel = kernel;
98 add_kernel (image_kernel);
99 _csc_kernel = kernel;
100 return true;
101 }
102
103 bool
set_matrix(const XCam3aResultColorMatrix & matrix)104 CLCscImageHandler::set_matrix (const XCam3aResultColorMatrix &matrix)
105 {
106 for (int i = 0; i < XCAM_COLOR_MATRIX_SIZE; i++)
107 _rgbtoyuv_matrix[i] = (float)matrix.matrix[i];
108 return true;
109 }
110
111 bool
set_output_format(uint32_t fourcc)112 CLCscImageHandler::set_output_format (uint32_t fourcc)
113 {
114 XCAM_FAIL_RETURN (
115 WARNING,
116 V4L2_PIX_FMT_XBGR32 == fourcc || V4L2_PIX_FMT_NV12 == fourcc,
117 false,
118 "CL csc handler doesn't support format: (%s)",
119 xcam_fourcc_to_string (fourcc));
120
121 _output_format = fourcc;
122 return true;
123 }
124
125 XCamReturn
prepare_buffer_pool_video_info(const VideoBufferInfo & input,VideoBufferInfo & output)126 CLCscImageHandler::prepare_buffer_pool_video_info (
127 const VideoBufferInfo &input,
128 VideoBufferInfo &output)
129 {
130 bool format_inited = output.init (_output_format, input.width, input.height);
131
132 XCAM_FAIL_RETURN (
133 WARNING,
134 format_inited,
135 XCAM_RETURN_ERROR_PARAM,
136 "CL image handler(%s) output format(%s) unsupported",
137 get_name (), xcam_fourcc_to_string (_output_format));
138
139 return XCAM_RETURN_NO_ERROR;
140 }
141
142 static bool
ensure_image_desc(const VideoBufferInfo & info,CLImageDesc & desc)143 ensure_image_desc (const VideoBufferInfo &info, CLImageDesc &desc)
144 {
145 desc.array_size = 0;
146 desc.slice_pitch = 0;
147 if (info.format == XCAM_PIX_FMT_RGB48_planar || info.format == XCAM_PIX_FMT_RGB24_planar)
148 desc.height = info.aligned_height * 3;
149
150 return true;
151 }
152
153 XCamReturn
prepare_parameters(SmartPtr<VideoBuffer> & input,SmartPtr<VideoBuffer> & output)154 CLCscImageHandler::prepare_parameters (SmartPtr<VideoBuffer> &input, SmartPtr<VideoBuffer> &output)
155 {
156 SmartPtr<CLContext> context = get_context ();
157
158 const VideoBufferInfo &in_video_info = input->get_video_info ();
159 const VideoBufferInfo &out_video_info = output->get_video_info ();
160 CLArgList args;
161 CLWorkSize work_size;
162 XCamReturn ret = XCAM_RETURN_NO_ERROR;
163
164 XCAM_ASSERT (_csc_kernel.ptr ());
165
166 CLImageDesc in_desc, out_desc;
167 CLImage::video_info_2_cl_image_desc (in_video_info, in_desc);
168 CLImage::video_info_2_cl_image_desc (out_video_info, out_desc);
169 ensure_image_desc (in_video_info, in_desc);
170 ensure_image_desc (out_video_info, out_desc);
171
172 SmartPtr<CLImage> image_in = convert_to_climage (context, input, in_desc, in_video_info.offsets[0]);
173 SmartPtr<CLImage> image_out = convert_to_climage (context, output, out_desc, out_video_info.offsets[0]);
174 SmartPtr<CLBuffer> matrix_buffer = new CLBuffer (
175 context, sizeof(float)*XCAM_COLOR_MATRIX_SIZE,
176 CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR , &_rgbtoyuv_matrix);
177
178 XCAM_FAIL_RETURN (
179 WARNING,
180 image_in->is_valid () && image_out->is_valid () && matrix_buffer->is_valid(),
181 XCAM_RETURN_ERROR_MEM,
182 "cl image kernel(%s) in/out memory not available", _csc_kernel->get_kernel_name ());
183
184 work_size.dim = XCAM_DEFAULT_IMAGE_DIM;
185 work_size.local[0] = 4;
186 work_size.local[1] = 4;
187
188 args.push_back (new CLMemArgument (image_in));
189 args.push_back (new CLMemArgument (image_out));
190
191 do {
192 if ((_csc_type == CL_CSC_TYPE_RGBATOLAB)
193 || (_csc_type == CL_CSC_TYPE_RGBA64TORGBA)
194 || (_csc_type == CL_CSC_TYPE_YUYVTORGBA)) {
195 work_size.global[0] = out_video_info.width;
196 work_size.global[1] = out_video_info.height;
197 break;
198 }
199
200 SmartPtr<CLImage> image_uv;
201 if(_csc_type == CL_CSC_TYPE_NV12TORGBA) {
202 in_desc.height /= 2;
203 image_uv = convert_to_climage (context, input, in_desc, in_video_info.offsets[1]);
204 args.push_back (new CLMemArgument (image_uv));
205
206 work_size.global[0] = out_video_info.width / 2;
207 work_size.global[1] = out_video_info.height / 2;
208 break;
209 }
210
211 if (_csc_type == CL_CSC_TYPE_RGBATONV12) {
212 out_desc.height /= 2;
213 image_uv = convert_to_climage (context, output, out_desc, out_video_info.offsets[1]);
214 args.push_back (new CLMemArgument (image_uv));
215 args.push_back (new CLMemArgument (matrix_buffer));
216
217 work_size.global[0] = out_video_info.width / 2;
218 work_size.global[1] = out_video_info.height / 2;
219 break;
220 }
221 } while (0);
222
223 XCAM_ASSERT (_csc_kernel.ptr ());
224 ret = _csc_kernel->set_arguments (args, work_size);
225 XCAM_FAIL_RETURN (
226 WARNING, ret == XCAM_RETURN_NO_ERROR, ret,
227 "csc kernel set arguments failed.");
228
229 return XCAM_RETURN_NO_ERROR;
230 }
231
232 SmartPtr<CLImageHandler>
create_cl_csc_image_handler(const SmartPtr<CLContext> & context,CLCscType type)233 create_cl_csc_image_handler (const SmartPtr<CLContext> &context, CLCscType type)
234 {
235 SmartPtr<CLCscImageHandler> csc_handler;
236 SmartPtr<CLCscImageKernel> csc_kernel;
237
238 XCAM_ASSERT (type < CL_CSC_TYPE_MAX);
239 csc_kernel = new CLCscImageKernel (context, type);
240 XCAM_ASSERT (csc_kernel.ptr ());
241 XCAM_FAIL_RETURN (
242 ERROR, csc_kernel->build_kernel (kernel_csc_info[type], NULL) == XCAM_RETURN_NO_ERROR, NULL,
243 "build csc kernel(%s) failed", kernel_csc_info[type].kernel_name);
244
245 XCAM_ASSERT (csc_kernel->is_valid ());
246
247 csc_handler = new CLCscImageHandler (context, "cl_handler_csc", type);
248 csc_handler->set_csc_kernel (csc_kernel);
249
250 return csc_handler;
251 }
252
253 };
254