1 /* 2 * cl_yuv_pipe_handler.cpp - CL YuvPipe 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: Wangfei <feix.w.wang (at) intel.com> 19 * Author: Wind Yuan <feng.yuan (at) intel.com> 20 */ 21 22 #include "cl_utils.h" 23 #include "cl_yuv_pipe_handler.h" 24 25 #define USE_BUFFER_OBJECT 0 26 27 namespace XCam { 28 29 static const XCamKernelInfo kernel_yuv_pipe_info = { 30 "kernel_yuv_pipe", 31 #include "kernel_yuv_pipe.clx" 32 , 0, 33 }; 34 35 float default_matrix[XCAM_COLOR_MATRIX_SIZE] = { 36 0.299f, 0.587f, 0.114f, 37 -0.14713f, -0.28886f, 0.436f, 38 0.615f, -0.51499f, -0.10001f, 39 }; 40 float default_macc[XCAM_CHROMA_AXIS_SIZE * XCAM_CHROMA_MATRIX_SIZE] = { 41 1.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 1.000000f, 42 1.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 1.000000f, 43 1.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 1.000000f, 44 1.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 1.000000f, 45 1.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 1.000000f, 46 1.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 1.000000f, 47 1.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 1.000000f, 48 1.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 1.000000f, 49 }; 50 51 CLYuvPipeImageKernel::CLYuvPipeImageKernel (const SmartPtr<CLContext> &context) 52 : CLImageKernel (context, "kernel_yuv_pipe") 53 54 { 55 } 56 57 CLYuvPipeImageHandler::CLYuvPipeImageHandler (const SmartPtr<CLContext> &context, const char *name) 58 : CLImageHandler (context, name) 59 , _output_format(V4L2_PIX_FMT_NV12) 60 , _enable_tnr_yuv (0) 61 , _gain_yuv (1.0) 62 , _thr_y (0.05) 63 , _thr_uv (0.05) 64 , _enable_tnr_yuv_state (0) 65 66 { 67 memcpy(_macc_table, default_macc, sizeof(float)*XCAM_CHROMA_AXIS_SIZE * XCAM_CHROMA_MATRIX_SIZE); 68 memcpy(_rgbtoyuv_matrix, default_matrix, sizeof(float)*XCAM_COLOR_MATRIX_SIZE); 69 } 70 71 bool 72 CLYuvPipeImageHandler::set_macc_table (const XCam3aResultMaccMatrix &macc) 73 { 74 for(int i = 0; i < XCAM_CHROMA_AXIS_SIZE * XCAM_CHROMA_MATRIX_SIZE; i++) 75 _macc_table[i] = (float)macc.table[i]; 76 return true; 77 } 78 79 bool 80 CLYuvPipeImageHandler::set_rgbtoyuv_matrix (const XCam3aResultColorMatrix &matrix) 81 { 82 for (int i = 0; i < XCAM_COLOR_MATRIX_SIZE; i++) 83 _rgbtoyuv_matrix[i] = (float)matrix.matrix[i]; 84 return true; 85 } 86 87 XCamReturn 88 CLYuvPipeImageHandler::prepare_buffer_pool_video_info ( 89 const VideoBufferInfo &input, 90 VideoBufferInfo &output) 91 { 92 bool format_inited = output.init (_output_format, input.width, input.height); 93 94 XCAM_FAIL_RETURN ( 95 WARNING, 96 format_inited, 97 XCAM_RETURN_ERROR_PARAM, 98 "CL image handler(%s) output format(%s) unsupported", 99 get_name (), xcam_fourcc_to_string (_output_format)); 100 101 return XCAM_RETURN_NO_ERROR; 102 } 103 104 XCamReturn 105 CLYuvPipeImageHandler::prepare_parameters ( 106 SmartPtr<VideoBuffer> &input, SmartPtr<VideoBuffer> &output) 107 { 108 SmartPtr<CLContext> context = get_context (); 109 const VideoBufferInfo & video_info_in = input->get_video_info (); 110 const VideoBufferInfo & video_info_out = output->get_video_info (); 111 CLArgList args; 112 CLWorkSize work_size; 113 114 XCAM_ASSERT (_yuv_pipe_kernel.ptr ()); 115 SmartPtr<CLMemory> buffer_in, buffer_out, buffer_out_UV; 116 117 #if !USE_BUFFER_OBJECT 118 CLImageDesc in_image_info; 119 in_image_info.format.image_channel_order = CL_RGBA; 120 in_image_info.format.image_channel_data_type = CL_UNSIGNED_INT32; 121 in_image_info.width = video_info_in.aligned_width / 8; 122 in_image_info.height = video_info_in.aligned_height * 3; 123 in_image_info.row_pitch = video_info_in.strides[0]; 124 125 CLImageDesc out_image_info; 126 out_image_info.format.image_channel_order = CL_RGBA; 127 out_image_info.format.image_channel_data_type = CL_UNSIGNED_INT16; 128 out_image_info.width = video_info_out.width / 8; 129 out_image_info.height = video_info_out.aligned_height; 130 out_image_info.row_pitch = video_info_out.strides[0]; 131 132 buffer_in = convert_to_climage (context, input, in_image_info); 133 buffer_out = convert_to_climage (context, output, out_image_info, video_info_out.offsets[0]); 134 135 out_image_info.height = video_info_out.aligned_height / 2; 136 out_image_info.row_pitch = video_info_out.strides[1]; 137 buffer_out_UV = convert_to_climage (context, output, out_image_info, video_info_out.offsets[1]); 138 #else 139 buffer_in = convert_to_clbuffer (context, input); 140 buffer_out = convert_to_clbuffer (context, output); 141 #endif 142 SmartPtr<CLBuffer> matrix_buffer = new CLBuffer ( 143 context, sizeof(float)*XCAM_COLOR_MATRIX_SIZE, 144 CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR , &_rgbtoyuv_matrix); 145 SmartPtr<CLBuffer> macc_table_buffer = new CLBuffer( 146 context, sizeof(float)*XCAM_CHROMA_AXIS_SIZE * XCAM_CHROMA_MATRIX_SIZE, 147 CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR , &_macc_table); 148 149 uint32_t plannar_offset = video_info_in.aligned_height; 150 151 if (!_buffer_out_prev.ptr ()) { 152 _buffer_out_prev = buffer_out; 153 _buffer_out_prev_UV = buffer_out_UV; 154 _enable_tnr_yuv_state = _enable_tnr_yuv; 155 _enable_tnr_yuv = 0; 156 } 157 else { 158 if (_enable_tnr_yuv == 0) 159 _enable_tnr_yuv = _enable_tnr_yuv_state; 160 } 161 XCAM_FAIL_RETURN ( 162 WARNING, 163 buffer_in->is_valid () && buffer_out->is_valid (), 164 XCAM_RETURN_ERROR_MEM, 165 "cl image handler(%s) in/out memory not available", XCAM_STR (get_name ())); 166 167 //set args; 168 args.push_back (new CLMemArgument (buffer_out)); 169 170 #if !USE_BUFFER_OBJECT 171 args.push_back (new CLMemArgument (buffer_out_UV)); 172 #endif 173 174 args.push_back (new CLMemArgument (_buffer_out_prev)); 175 176 #if !USE_BUFFER_OBJECT 177 args.push_back (new CLMemArgument (_buffer_out_prev_UV)); 178 #else 179 uint32_t vertical_offset = video_info_out.aligned_height; 180 args.push_back (new CLArgumentT<uint32_t> (vertical_offset)); 181 #endif 182 args.push_back (new CLArgumentT<uint32_t> (plannar_offset)); 183 args.push_back (new CLMemArgument (matrix_buffer)); 184 args.push_back (new CLMemArgument (macc_table_buffer)); 185 args.push_back (new CLArgumentT<float> (_gain_yuv)); 186 args.push_back (new CLArgumentT<float> (_thr_y)); 187 args.push_back (new CLArgumentT<float> (_thr_uv)); 188 args.push_back (new CLArgumentT<uint32_t> (_enable_tnr_yuv)); 189 args.push_back (new CLMemArgument (buffer_in)); 190 191 work_size.dim = XCAM_DEFAULT_IMAGE_DIM; 192 work_size.global[0] = video_info_out.width / 8 ; 193 work_size.global[1] = video_info_out.aligned_height / 2 ; 194 work_size.local[0] = 8; 195 work_size.local[1] = 4; 196 197 XCAM_ASSERT (_yuv_pipe_kernel.ptr ()); 198 XCamReturn ret = _yuv_pipe_kernel->set_arguments (args, work_size); 199 XCAM_FAIL_RETURN ( 200 WARNING, ret == XCAM_RETURN_NO_ERROR, ret, 201 "yuv pipe kernel set arguments failed."); 202 203 if (buffer_out->is_valid ()) { 204 _buffer_out_prev = buffer_out; 205 _buffer_out_prev_UV = buffer_out_UV; 206 } 207 208 return XCAM_RETURN_NO_ERROR; 209 } 210 211 bool 212 CLYuvPipeImageHandler::set_yuv_pipe_kernel(SmartPtr<CLYuvPipeImageKernel> &kernel) 213 { 214 SmartPtr<CLImageKernel> image_kernel = kernel; 215 add_kernel (image_kernel); 216 _yuv_pipe_kernel = kernel; 217 return true; 218 } 219 220 bool 221 CLYuvPipeImageHandler::set_tnr_yuv_config (const XCam3aResultTemporalNoiseReduction& config) 222 { 223 if (!_yuv_pipe_kernel->is_valid ()) { 224 XCAM_LOG_ERROR ("set config error, invalid YUV-Pipe kernel !"); 225 } 226 227 _gain_yuv = (float)config.gain; 228 _thr_y = (float)config.threshold[0]; 229 _thr_uv = (float)config.threshold[1]; 230 XCAM_LOG_DEBUG ("set TNR YUV config: _gain(%f), _thr_y(%f), _thr_uv(%f)", 231 _gain_yuv, _thr_y, _thr_uv); 232 return true; 233 } 234 235 bool 236 CLYuvPipeImageHandler::set_tnr_enable (bool enable_tnr_yuv) 237 { 238 _enable_tnr_yuv = (enable_tnr_yuv ? 1 : 0); 239 return true; 240 } 241 242 SmartPtr<CLImageHandler> 243 create_cl_yuv_pipe_image_handler (const SmartPtr<CLContext> &context) 244 { 245 SmartPtr<CLYuvPipeImageHandler> yuv_pipe_handler; 246 SmartPtr<CLYuvPipeImageKernel> yuv_pipe_kernel; 247 248 yuv_pipe_kernel = new CLYuvPipeImageKernel (context); 249 XCAM_ASSERT (yuv_pipe_kernel.ptr ()); 250 const char * options = USE_BUFFER_OBJECT ? "-DUSE_BUFFER_OBJECT=1" : "-DUSE_BUFFER_OBJECT=0"; 251 XCAM_FAIL_RETURN ( 252 ERROR, yuv_pipe_kernel->build_kernel (kernel_yuv_pipe_info, options) == XCAM_RETURN_NO_ERROR, NULL, 253 "build yuv-pipe kernel(%s) failed", kernel_yuv_pipe_info.kernel_name); 254 255 XCAM_ASSERT (yuv_pipe_kernel->is_valid ()); 256 yuv_pipe_handler = new CLYuvPipeImageHandler (context, "cl_handler_pipe_yuv"); 257 yuv_pipe_handler->set_yuv_pipe_kernel (yuv_pipe_kernel); 258 259 return yuv_pipe_handler; 260 } 261 262 }; 263