| /* |
| * cl_yuv_pipe_handler.cpp - CL YuvPipe Pipe 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_yuv_pipe_handler.h" |
| |
| #define USE_BUFFER_OBJECT 0 |
| |
| namespace XCam { |
| |
| static const XCamKernelInfo kernel_yuv_pipe_info = { |
| "kernel_yuv_pipe", |
| #include "kernel_yuv_pipe.clx" |
| , 0, |
| }; |
| |
| float default_matrix[XCAM_COLOR_MATRIX_SIZE] = { |
| 0.299f, 0.587f, 0.114f, |
| -0.14713f, -0.28886f, 0.436f, |
| 0.615f, -0.51499f, -0.10001f, |
| }; |
| float default_macc[XCAM_CHROMA_AXIS_SIZE * XCAM_CHROMA_MATRIX_SIZE] = { |
| 1.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 1.000000f, |
| 1.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 1.000000f, |
| 1.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 1.000000f, |
| 1.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 1.000000f, |
| 1.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 1.000000f, |
| 1.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 1.000000f, |
| 1.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 1.000000f, |
| 1.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 1.000000f, |
| }; |
| |
| CLYuvPipeImageKernel::CLYuvPipeImageKernel (const SmartPtr<CLContext> &context) |
| : CLImageKernel (context, "kernel_yuv_pipe") |
| |
| { |
| } |
| |
| CLYuvPipeImageHandler::CLYuvPipeImageHandler (const SmartPtr<CLContext> &context, const char *name) |
| : CLImageHandler (context, name) |
| , _output_format(V4L2_PIX_FMT_NV12) |
| , _enable_tnr_yuv (0) |
| , _gain_yuv (1.0) |
| , _thr_y (0.05) |
| , _thr_uv (0.05) |
| , _enable_tnr_yuv_state (0) |
| |
| { |
| memcpy(_macc_table, default_macc, sizeof(float)*XCAM_CHROMA_AXIS_SIZE * XCAM_CHROMA_MATRIX_SIZE); |
| memcpy(_rgbtoyuv_matrix, default_matrix, sizeof(float)*XCAM_COLOR_MATRIX_SIZE); |
| } |
| |
| bool |
| CLYuvPipeImageHandler::set_macc_table (const XCam3aResultMaccMatrix &macc) |
| { |
| for(int i = 0; i < XCAM_CHROMA_AXIS_SIZE * XCAM_CHROMA_MATRIX_SIZE; i++) |
| _macc_table[i] = (float)macc.table[i]; |
| return true; |
| } |
| |
| bool |
| CLYuvPipeImageHandler::set_rgbtoyuv_matrix (const XCam3aResultColorMatrix &matrix) |
| { |
| for (int i = 0; i < XCAM_COLOR_MATRIX_SIZE; i++) |
| _rgbtoyuv_matrix[i] = (float)matrix.matrix[i]; |
| return true; |
| } |
| |
| XCamReturn |
| CLYuvPipeImageHandler::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; |
| } |
| |
| XCamReturn |
| CLYuvPipeImageHandler::prepare_parameters ( |
| SmartPtr<VideoBuffer> &input, SmartPtr<VideoBuffer> &output) |
| { |
| SmartPtr<CLContext> context = get_context (); |
| const VideoBufferInfo & video_info_in = input->get_video_info (); |
| const VideoBufferInfo & video_info_out = output->get_video_info (); |
| CLArgList args; |
| CLWorkSize work_size; |
| |
| XCAM_ASSERT (_yuv_pipe_kernel.ptr ()); |
| SmartPtr<CLMemory> buffer_in, buffer_out, buffer_out_UV; |
| |
| #if !USE_BUFFER_OBJECT |
| CLImageDesc in_image_info; |
| in_image_info.format.image_channel_order = CL_RGBA; |
| in_image_info.format.image_channel_data_type = CL_UNSIGNED_INT32; |
| in_image_info.width = video_info_in.aligned_width / 8; |
| in_image_info.height = video_info_in.aligned_height * 3; |
| in_image_info.row_pitch = video_info_in.strides[0]; |
| |
| CLImageDesc out_image_info; |
| out_image_info.format.image_channel_order = CL_RGBA; |
| out_image_info.format.image_channel_data_type = CL_UNSIGNED_INT16; |
| out_image_info.width = video_info_out.width / 8; |
| out_image_info.height = video_info_out.aligned_height; |
| out_image_info.row_pitch = video_info_out.strides[0]; |
| |
| buffer_in = convert_to_climage (context, input, in_image_info); |
| buffer_out = convert_to_climage (context, output, out_image_info, video_info_out.offsets[0]); |
| |
| out_image_info.height = video_info_out.aligned_height / 2; |
| out_image_info.row_pitch = video_info_out.strides[1]; |
| buffer_out_UV = convert_to_climage (context, output, out_image_info, video_info_out.offsets[1]); |
| #else |
| buffer_in = convert_to_clbuffer (context, input); |
| buffer_out = convert_to_clbuffer (context, output); |
| #endif |
| SmartPtr<CLBuffer> matrix_buffer = new CLBuffer ( |
| context, sizeof(float)*XCAM_COLOR_MATRIX_SIZE, |
| CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR , &_rgbtoyuv_matrix); |
| SmartPtr<CLBuffer> macc_table_buffer = new CLBuffer( |
| context, sizeof(float)*XCAM_CHROMA_AXIS_SIZE * XCAM_CHROMA_MATRIX_SIZE, |
| CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR , &_macc_table); |
| |
| uint32_t plannar_offset = video_info_in.aligned_height; |
| |
| if (!_buffer_out_prev.ptr ()) { |
| _buffer_out_prev = buffer_out; |
| _buffer_out_prev_UV = buffer_out_UV; |
| _enable_tnr_yuv_state = _enable_tnr_yuv; |
| _enable_tnr_yuv = 0; |
| } |
| else { |
| if (_enable_tnr_yuv == 0) |
| _enable_tnr_yuv = _enable_tnr_yuv_state; |
| } |
| XCAM_FAIL_RETURN ( |
| WARNING, |
| buffer_in->is_valid () && buffer_out->is_valid (), |
| XCAM_RETURN_ERROR_MEM, |
| "cl image handler(%s) in/out memory not available", XCAM_STR (get_name ())); |
| |
| //set args; |
| args.push_back (new CLMemArgument (buffer_out)); |
| |
| #if !USE_BUFFER_OBJECT |
| args.push_back (new CLMemArgument (buffer_out_UV)); |
| #endif |
| |
| args.push_back (new CLMemArgument (_buffer_out_prev)); |
| |
| #if !USE_BUFFER_OBJECT |
| args.push_back (new CLMemArgument (_buffer_out_prev_UV)); |
| #else |
| uint32_t vertical_offset = video_info_out.aligned_height; |
| args.push_back (new CLArgumentT<uint32_t> (vertical_offset)); |
| #endif |
| args.push_back (new CLArgumentT<uint32_t> (plannar_offset)); |
| args.push_back (new CLMemArgument (matrix_buffer)); |
| args.push_back (new CLMemArgument (macc_table_buffer)); |
| args.push_back (new CLArgumentT<float> (_gain_yuv)); |
| args.push_back (new CLArgumentT<float> (_thr_y)); |
| args.push_back (new CLArgumentT<float> (_thr_uv)); |
| args.push_back (new CLArgumentT<uint32_t> (_enable_tnr_yuv)); |
| args.push_back (new CLMemArgument (buffer_in)); |
| |
| work_size.dim = XCAM_DEFAULT_IMAGE_DIM; |
| work_size.global[0] = video_info_out.width / 8 ; |
| work_size.global[1] = video_info_out.aligned_height / 2 ; |
| work_size.local[0] = 8; |
| work_size.local[1] = 4; |
| |
| XCAM_ASSERT (_yuv_pipe_kernel.ptr ()); |
| XCamReturn ret = _yuv_pipe_kernel->set_arguments (args, work_size); |
| XCAM_FAIL_RETURN ( |
| WARNING, ret == XCAM_RETURN_NO_ERROR, ret, |
| "yuv pipe kernel set arguments failed."); |
| |
| if (buffer_out->is_valid ()) { |
| _buffer_out_prev = buffer_out; |
| _buffer_out_prev_UV = buffer_out_UV; |
| } |
| |
| return XCAM_RETURN_NO_ERROR; |
| } |
| |
| bool |
| CLYuvPipeImageHandler::set_yuv_pipe_kernel(SmartPtr<CLYuvPipeImageKernel> &kernel) |
| { |
| SmartPtr<CLImageKernel> image_kernel = kernel; |
| add_kernel (image_kernel); |
| _yuv_pipe_kernel = kernel; |
| return true; |
| } |
| |
| bool |
| CLYuvPipeImageHandler::set_tnr_yuv_config (const XCam3aResultTemporalNoiseReduction& config) |
| { |
| if (!_yuv_pipe_kernel->is_valid ()) { |
| XCAM_LOG_ERROR ("set config error, invalid YUV-Pipe kernel !"); |
| } |
| |
| _gain_yuv = (float)config.gain; |
| _thr_y = (float)config.threshold[0]; |
| _thr_uv = (float)config.threshold[1]; |
| XCAM_LOG_DEBUG ("set TNR YUV config: _gain(%f), _thr_y(%f), _thr_uv(%f)", |
| _gain_yuv, _thr_y, _thr_uv); |
| return true; |
| } |
| |
| bool |
| CLYuvPipeImageHandler::set_tnr_enable (bool enable_tnr_yuv) |
| { |
| _enable_tnr_yuv = (enable_tnr_yuv ? 1 : 0); |
| return true; |
| } |
| |
| SmartPtr<CLImageHandler> |
| create_cl_yuv_pipe_image_handler (const SmartPtr<CLContext> &context) |
| { |
| SmartPtr<CLYuvPipeImageHandler> yuv_pipe_handler; |
| SmartPtr<CLYuvPipeImageKernel> yuv_pipe_kernel; |
| |
| yuv_pipe_kernel = new CLYuvPipeImageKernel (context); |
| XCAM_ASSERT (yuv_pipe_kernel.ptr ()); |
| const char * options = USE_BUFFER_OBJECT ? "-DUSE_BUFFER_OBJECT=1" : "-DUSE_BUFFER_OBJECT=0"; |
| XCAM_FAIL_RETURN ( |
| ERROR, yuv_pipe_kernel->build_kernel (kernel_yuv_pipe_info, options) == XCAM_RETURN_NO_ERROR, NULL, |
| "build yuv-pipe kernel(%s) failed", kernel_yuv_pipe_info.kernel_name); |
| |
| XCAM_ASSERT (yuv_pipe_kernel->is_valid ()); |
| yuv_pipe_handler = new CLYuvPipeImageHandler (context, "cl_handler_pipe_yuv"); |
| yuv_pipe_handler->set_yuv_pipe_kernel (yuv_pipe_kernel); |
| |
| return yuv_pipe_handler; |
| } |
| |
| }; |