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 (at) intel.com> 19 * Author: Wind Yuan <feng.yuan (at) 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 63 CLCscImageKernel::CLCscImageKernel (const SmartPtr<CLContext> &context, CLCscType type) 64 : CLImageKernel (context) 65 , _kernel_csc_type (type) 66 { 67 } 68 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 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 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 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 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 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 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> 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