/* * cl_csc_handler.cpp - CL csc handler * * Copyright (c) 2015 Intel Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Author: wangfei <feix.w.wang@intel.com> * Author: Wind Yuan <feng.yuan@intel.com> */ #include "cl_utils.h" #include "cl_csc_handler.h" #include "cl_device.h" #include "cl_kernel.h" static const XCamKernelInfo kernel_csc_info[] = { { "kernel_csc_rgbatonv12", #include "kernel_csc.clx" , 0, }, { "kernel_csc_rgbatolab", #include "kernel_csc.clx" , 0, }, { "kernel_csc_rgba64torgba", #include "kernel_csc.clx" , 0, }, { "kernel_csc_yuyvtorgba", #include "kernel_csc.clx" , 0, }, { "kernel_csc_nv12torgba", #include "kernel_csc.clx" , 0, }, }; float default_rgbtoyuv_matrix[XCAM_COLOR_MATRIX_SIZE] = { 0.299f, 0.587f, 0.114f, -0.14713f, -0.28886f, 0.436f, 0.615f, -0.51499f, -0.10001f }; namespace XCam { CLCscImageKernel::CLCscImageKernel (const SmartPtr<CLContext> &context, CLCscType type) : CLImageKernel (context) , _kernel_csc_type (type) { } CLCscImageHandler::CLCscImageHandler ( const SmartPtr<CLContext> &context, const char *name, CLCscType type) : CLImageHandler (context, name) , _output_format (V4L2_PIX_FMT_NV12) , _csc_type (type) { memcpy (_rgbtoyuv_matrix, default_rgbtoyuv_matrix, sizeof (_rgbtoyuv_matrix)); switch (type) { case CL_CSC_TYPE_RGBATONV12: _output_format = V4L2_PIX_FMT_NV12; break; case CL_CSC_TYPE_RGBATOLAB: _output_format = XCAM_PIX_FMT_LAB; break; case CL_CSC_TYPE_RGBA64TORGBA: case CL_CSC_TYPE_YUYVTORGBA: case CL_CSC_TYPE_NV12TORGBA: _output_format = V4L2_PIX_FMT_RGBA32; break; default: break; } } bool CLCscImageHandler::set_csc_kernel (SmartPtr<CLCscImageKernel> &kernel) { SmartPtr<CLImageKernel> image_kernel = kernel; add_kernel (image_kernel); _csc_kernel = kernel; return true; } bool CLCscImageHandler::set_matrix (const XCam3aResultColorMatrix &matrix) { for (int i = 0; i < XCAM_COLOR_MATRIX_SIZE; i++) _rgbtoyuv_matrix[i] = (float)matrix.matrix[i]; return true; } bool CLCscImageHandler::set_output_format (uint32_t fourcc) { XCAM_FAIL_RETURN ( WARNING, V4L2_PIX_FMT_XBGR32 == fourcc || V4L2_PIX_FMT_NV12 == fourcc, false, "CL csc handler doesn't support format: (%s)", xcam_fourcc_to_string (fourcc)); _output_format = fourcc; return true; } XCamReturn CLCscImageHandler::prepare_buffer_pool_video_info ( const VideoBufferInfo &input, VideoBufferInfo &output) { bool format_inited = output.init (_output_format, input.width, input.height); XCAM_FAIL_RETURN ( WARNING, format_inited, XCAM_RETURN_ERROR_PARAM, "CL image handler(%s) output format(%s) unsupported", get_name (), xcam_fourcc_to_string (_output_format)); return XCAM_RETURN_NO_ERROR; } static bool ensure_image_desc (const VideoBufferInfo &info, CLImageDesc &desc) { desc.array_size = 0; desc.slice_pitch = 0; if (info.format == XCAM_PIX_FMT_RGB48_planar || info.format == XCAM_PIX_FMT_RGB24_planar) desc.height = info.aligned_height * 3; return true; } XCamReturn CLCscImageHandler::prepare_parameters (SmartPtr<VideoBuffer> &input, SmartPtr<VideoBuffer> &output) { SmartPtr<CLContext> context = get_context (); const VideoBufferInfo &in_video_info = input->get_video_info (); const VideoBufferInfo &out_video_info = output->get_video_info (); CLArgList args; CLWorkSize work_size; XCamReturn ret = XCAM_RETURN_NO_ERROR; XCAM_ASSERT (_csc_kernel.ptr ()); CLImageDesc in_desc, out_desc; CLImage::video_info_2_cl_image_desc (in_video_info, in_desc); CLImage::video_info_2_cl_image_desc (out_video_info, out_desc); ensure_image_desc (in_video_info, in_desc); ensure_image_desc (out_video_info, out_desc); SmartPtr<CLImage> image_in = convert_to_climage (context, input, in_desc, in_video_info.offsets[0]); SmartPtr<CLImage> image_out = convert_to_climage (context, output, out_desc, out_video_info.offsets[0]); SmartPtr<CLBuffer> matrix_buffer = new CLBuffer ( context, sizeof(float)*XCAM_COLOR_MATRIX_SIZE, CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR , &_rgbtoyuv_matrix); XCAM_FAIL_RETURN ( WARNING, image_in->is_valid () && image_out->is_valid () && matrix_buffer->is_valid(), XCAM_RETURN_ERROR_MEM, "cl image kernel(%s) in/out memory not available", _csc_kernel->get_kernel_name ()); work_size.dim = XCAM_DEFAULT_IMAGE_DIM; work_size.local[0] = 4; work_size.local[1] = 4; args.push_back (new CLMemArgument (image_in)); args.push_back (new CLMemArgument (image_out)); do { if ((_csc_type == CL_CSC_TYPE_RGBATOLAB) || (_csc_type == CL_CSC_TYPE_RGBA64TORGBA) || (_csc_type == CL_CSC_TYPE_YUYVTORGBA)) { work_size.global[0] = out_video_info.width; work_size.global[1] = out_video_info.height; break; } SmartPtr<CLImage> image_uv; if(_csc_type == CL_CSC_TYPE_NV12TORGBA) { in_desc.height /= 2; image_uv = convert_to_climage (context, input, in_desc, in_video_info.offsets[1]); args.push_back (new CLMemArgument (image_uv)); work_size.global[0] = out_video_info.width / 2; work_size.global[1] = out_video_info.height / 2; break; } if (_csc_type == CL_CSC_TYPE_RGBATONV12) { out_desc.height /= 2; image_uv = convert_to_climage (context, output, out_desc, out_video_info.offsets[1]); args.push_back (new CLMemArgument (image_uv)); args.push_back (new CLMemArgument (matrix_buffer)); work_size.global[0] = out_video_info.width / 2; work_size.global[1] = out_video_info.height / 2; break; } } while (0); XCAM_ASSERT (_csc_kernel.ptr ()); ret = _csc_kernel->set_arguments (args, work_size); XCAM_FAIL_RETURN ( WARNING, ret == XCAM_RETURN_NO_ERROR, ret, "csc kernel set arguments failed."); return XCAM_RETURN_NO_ERROR; } SmartPtr<CLImageHandler> create_cl_csc_image_handler (const SmartPtr<CLContext> &context, CLCscType type) { SmartPtr<CLCscImageHandler> csc_handler; SmartPtr<CLCscImageKernel> csc_kernel; XCAM_ASSERT (type < CL_CSC_TYPE_MAX); csc_kernel = new CLCscImageKernel (context, type); XCAM_ASSERT (csc_kernel.ptr ()); XCAM_FAIL_RETURN ( ERROR, csc_kernel->build_kernel (kernel_csc_info[type], NULL) == XCAM_RETURN_NO_ERROR, NULL, "build csc kernel(%s) failed", kernel_csc_info[type].kernel_name); XCAM_ASSERT (csc_kernel->is_valid ()); csc_handler = new CLCscImageHandler (context, "cl_handler_csc", type); csc_handler->set_csc_kernel (csc_kernel); return csc_handler; } };