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 (at) intel.com> 19 * Author: wangfei <feix.w.wang (at) intel.com> 20 * Author: Shincy Tu <shincy.tu (at) 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 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 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 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 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 95 CLBayerPipeImageHandler::enable_denoise (bool enable) 96 { 97 _enable_denoise = (enable ? 1 : 0); 98 return true; 99 100 } 101 102 bool 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 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 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 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> 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