| /* |
| * 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 <[email protected]> |
| * Author: Wind Yuan <[email protected]> |
| */ |
| #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; |
| } |
| |
| }; |