1 /*
2 * cl_bayer_pipe_handler.cpp - CL bayer pipe 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: Wind Yuan <feng.yuan@intel.com>
19 * Author: wangfei <feix.w.wang@intel.com>
20 * Author: Shincy Tu <shincy.tu@intel.com>
21 */
22
23 #include "cl_utils.h"
24 #include "cl_bayer_pipe_handler.h"
25
26 #define WORKGROUP_PIXEL_WIDTH 128
27 #define WORKGROUP_PIXEL_HEIGHT 8
28
29 #define BAYER_LOCAL_X_SIZE 64
30 #define BAYER_LOCAL_Y_SIZE 2
31
32 namespace XCam {
33
34 static const float table [XCAM_BNR_TABLE_SIZE] = {
35 63.661991f, 60.628166f, 52.366924f, 41.023067f, 29.146584f, 18.781729f, 10.976704f,
36 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f,
37 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f,
38 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f,
39 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f,
40 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f,
41 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f,
42 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f,
43 6.000000f,
44 };
45
46 static const XCamKernelInfo kernel_bayer_pipe_info = {
47 "kernel_bayer_pipe",
48 #include "kernel_bayer_pipe.clx"
49 , 0,
50 };
51
CLBayerPipeImageKernel(const SmartPtr<CLContext> & context,SmartPtr<CLBayerPipeImageHandler> & handler)52 CLBayerPipeImageKernel::CLBayerPipeImageKernel (
53 const SmartPtr<CLContext> &context,
54 SmartPtr<CLBayerPipeImageHandler> &handler)
55 : CLImageKernel (context, "kernel_bayer_pipe")
56 , _handler (handler)
57 {
58
59 }
60
CLBayerPipeImageHandler(const SmartPtr<CLContext> & context,const char * name)61 CLBayerPipeImageHandler::CLBayerPipeImageHandler (const SmartPtr<CLContext> &context, const char *name)
62 : CLImageHandler (context, name)
63 , _output_format (XCAM_PIX_FMT_RGB48_planar)
64 , _enable_denoise (0)
65 {
66 memcpy(_bnr_table, table, sizeof(float)*XCAM_BNR_TABLE_SIZE);
67 _ee_config.ee_gain = 0.8;
68 _ee_config.ee_threshold = 0.025;
69 }
70
71 bool
set_output_format(uint32_t fourcc)72 CLBayerPipeImageHandler::set_output_format (uint32_t fourcc)
73 {
74 XCAM_FAIL_RETURN (
75 WARNING,
76 XCAM_PIX_FMT_RGB48_planar == fourcc || XCAM_PIX_FMT_RGB24_planar == fourcc,
77 false,
78 "CL image handler(%s) doesn't support format(%s) settings",
79 get_name (), xcam_fourcc_to_string (fourcc));
80
81 _output_format = fourcc;
82 return true;
83 }
84
85 bool
set_bayer_kernel(SmartPtr<CLBayerPipeImageKernel> & kernel)86 CLBayerPipeImageHandler::set_bayer_kernel (SmartPtr<CLBayerPipeImageKernel> &kernel)
87 {
88 SmartPtr<CLImageKernel> image_kernel = kernel;
89 add_kernel (image_kernel);
90 _bayer_kernel = kernel;
91 return true;
92 }
93
94 bool
enable_denoise(bool enable)95 CLBayerPipeImageHandler::enable_denoise (bool enable)
96 {
97 _enable_denoise = (enable ? 1 : 0);
98 return true;
99
100 }
101
102 bool
set_ee_config(const XCam3aResultEdgeEnhancement & ee)103 CLBayerPipeImageHandler::set_ee_config (const XCam3aResultEdgeEnhancement &ee)
104 {
105 _ee_config.ee_gain = (float)ee.gain;
106 _ee_config.ee_threshold = (float)ee.threshold;
107 return true;
108 }
109 bool
set_bnr_config(const XCam3aResultBayerNoiseReduction & bnr)110 CLBayerPipeImageHandler::set_bnr_config (const XCam3aResultBayerNoiseReduction &bnr)
111 {
112 for(int i = 0; i < XCAM_BNR_TABLE_SIZE; i++)
113 _bnr_table[i] = (float)bnr.table[i];
114 return true;
115 }
116
117 XCamReturn
prepare_buffer_pool_video_info(const VideoBufferInfo & input,VideoBufferInfo & output)118 CLBayerPipeImageHandler::prepare_buffer_pool_video_info (
119 const VideoBufferInfo &input,
120 VideoBufferInfo &output)
121 {
122 uint32_t format = _output_format;
123 uint32_t width = input.width;
124 uint32_t height = input.height;
125 if (input.format == XCAM_PIX_FMT_SGRBG16_planar) {
126 width *= 2;
127 height *= 2;
128 }
129 bool format_inited = output.init (format, width, height);
130
131 XCAM_FAIL_RETURN (
132 WARNING,
133 format_inited,
134 XCAM_RETURN_ERROR_PARAM,
135 "CL image handler(%s) output format(%s) unsupported",
136 get_name (), xcam_fourcc_to_string (format));
137
138 return XCAM_RETURN_NO_ERROR;
139 }
140
141 XCamReturn
prepare_parameters(SmartPtr<VideoBuffer> & input,SmartPtr<VideoBuffer> & output)142 CLBayerPipeImageHandler::prepare_parameters (
143 SmartPtr<VideoBuffer> &input, SmartPtr<VideoBuffer> &output)
144 {
145 SmartPtr<CLContext> context = get_context ();
146 const VideoBufferInfo & in_video_info = input->get_video_info ();
147 const VideoBufferInfo & out_video_info = output->get_video_info ();
148 CLArgList args;
149 CLWorkSize work_size;
150
151 XCAM_ASSERT (_bayer_kernel.ptr ());
152
153 CLImageDesc in_desc;
154 in_desc.format.image_channel_order = CL_RGBA;
155 in_desc.format.image_channel_data_type = CL_UNORM_INT16; //CL_UNSIGNED_INT32;
156 in_desc.width = in_video_info.width / 4; // 960/4
157 in_desc.height = in_video_info.aligned_height * 4; //540
158 in_desc.row_pitch = in_video_info.strides[0];
159
160 SmartPtr<CLImage> image_in = convert_to_climage (context, input, in_desc);
161
162 CLImageDesc out_desc;
163 out_desc.format.image_channel_order = CL_RGBA;
164 if (XCAM_PIX_FMT_RGB48_planar == out_video_info.format)
165 out_desc.format.image_channel_data_type = CL_UNORM_INT16;
166 else
167 out_desc.format.image_channel_data_type = CL_UNORM_INT8;
168 out_desc.width = out_video_info.aligned_width / 4;
169 out_desc.height = out_video_info.aligned_height * 3;
170 out_desc.row_pitch = out_video_info.strides[0];
171 out_desc.array_size = 3;
172 out_desc.slice_pitch = out_video_info.strides [0] * out_video_info.aligned_height;
173
174 SmartPtr<CLImage> image_out = convert_to_climage (context, output, out_desc);
175
176 uint input_height = in_video_info.aligned_height;
177 uint output_height = out_video_info.aligned_height;
178
179 XCAM_ASSERT (image_in.ptr () && image_out.ptr ());
180 XCAM_FAIL_RETURN (
181 WARNING,
182 image_in->is_valid () && image_out->is_valid (),
183 XCAM_RETURN_ERROR_MEM,
184 "cl image kernel(%s) in/out memory not available", _bayer_kernel->get_kernel_name ());
185
186 SmartPtr<CLBuffer> bnr_table_buffer = new CLBuffer(
187 context, sizeof(float) * XCAM_BNR_TABLE_SIZE,
188 CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, &_bnr_table);
189
190 //set args;
191 args.push_back (new CLMemArgument (image_in));
192 args.push_back (new CLArgumentT<uint> (input_height));
193 args.push_back (new CLMemArgument (image_out));
194 args.push_back (new CLArgumentT<uint> (output_height));
195 args.push_back (new CLMemArgument (bnr_table_buffer));
196 args.push_back (new CLArgumentT<uint32_t> (_enable_denoise));
197 args.push_back (new CLArgumentT<CLEeConfig> (_ee_config));
198
199 work_size.dim = XCAM_DEFAULT_IMAGE_DIM;
200 work_size.local[0] = BAYER_LOCAL_X_SIZE;
201 work_size.local[1] = BAYER_LOCAL_Y_SIZE;
202 work_size.global[0] = (XCAM_ALIGN_UP(out_video_info.width, WORKGROUP_PIXEL_WIDTH) / WORKGROUP_PIXEL_WIDTH) *
203 work_size.local[0];
204 work_size.global[1] = (XCAM_ALIGN_UP(out_video_info.height, WORKGROUP_PIXEL_HEIGHT) / WORKGROUP_PIXEL_HEIGHT) *
205 work_size.local[1];
206
207 XCAM_ASSERT (_bayer_kernel.ptr ());
208 XCamReturn ret = _bayer_kernel->set_arguments (args, work_size);
209 XCAM_FAIL_RETURN (
210 WARNING, ret == XCAM_RETURN_NO_ERROR, ret,
211 "bayer pipe kernel set arguments failed.");
212
213 return XCAM_RETURN_NO_ERROR;
214 }
215
216
217 SmartPtr<CLImageHandler>
create_cl_bayer_pipe_image_handler(const SmartPtr<CLContext> & context)218 create_cl_bayer_pipe_image_handler (const SmartPtr<CLContext> &context)
219 {
220 SmartPtr<CLBayerPipeImageHandler> bayer_pipe_handler;
221 SmartPtr<CLBayerPipeImageKernel> bayer_pipe_kernel;
222
223 bayer_pipe_handler = new CLBayerPipeImageHandler (context, "cl_handler_bayer_pipe");
224 bayer_pipe_kernel = new CLBayerPipeImageKernel (context, bayer_pipe_handler);
225 XCAM_ASSERT (bayer_pipe_kernel.ptr ());
226 XCAM_FAIL_RETURN (
227 ERROR, bayer_pipe_kernel->build_kernel (kernel_bayer_pipe_info, NULL) == XCAM_RETURN_NO_ERROR, NULL,
228 "build bayer-pipe kernel(%s) failed", kernel_bayer_pipe_info.kernel_name);
229
230 XCAM_ASSERT (bayer_pipe_kernel->is_valid ());
231 bayer_pipe_handler->set_bayer_kernel (bayer_pipe_kernel);
232
233 return bayer_pipe_handler;
234 }
235
236 };
237