/* * cl_bayer_pipe_handler.cpp - CL bayer 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: Wind Yuan * Author: wangfei * Author: Shincy Tu */ #include "cl_utils.h" #include "cl_bayer_pipe_handler.h" #define WORKGROUP_PIXEL_WIDTH 128 #define WORKGROUP_PIXEL_HEIGHT 8 #define BAYER_LOCAL_X_SIZE 64 #define BAYER_LOCAL_Y_SIZE 2 namespace XCam { static const float table [XCAM_BNR_TABLE_SIZE] = { 63.661991f, 60.628166f, 52.366924f, 41.023067f, 29.146584f, 18.781729f, 10.976704f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, 6.000000f, }; static const XCamKernelInfo kernel_bayer_pipe_info = { "kernel_bayer_pipe", #include "kernel_bayer_pipe.clx" , 0, }; CLBayerPipeImageKernel::CLBayerPipeImageKernel ( const SmartPtr &context, SmartPtr &handler) : CLImageKernel (context, "kernel_bayer_pipe") , _handler (handler) { } CLBayerPipeImageHandler::CLBayerPipeImageHandler (const SmartPtr &context, const char *name) : CLImageHandler (context, name) , _output_format (XCAM_PIX_FMT_RGB48_planar) , _enable_denoise (0) { memcpy(_bnr_table, table, sizeof(float)*XCAM_BNR_TABLE_SIZE); _ee_config.ee_gain = 0.8; _ee_config.ee_threshold = 0.025; } bool CLBayerPipeImageHandler::set_output_format (uint32_t fourcc) { XCAM_FAIL_RETURN ( WARNING, XCAM_PIX_FMT_RGB48_planar == fourcc || XCAM_PIX_FMT_RGB24_planar == fourcc, false, "CL image handler(%s) doesn't support format(%s) settings", get_name (), xcam_fourcc_to_string (fourcc)); _output_format = fourcc; return true; } bool CLBayerPipeImageHandler::set_bayer_kernel (SmartPtr &kernel) { SmartPtr image_kernel = kernel; add_kernel (image_kernel); _bayer_kernel = kernel; return true; } bool CLBayerPipeImageHandler::enable_denoise (bool enable) { _enable_denoise = (enable ? 1 : 0); return true; } bool CLBayerPipeImageHandler::set_ee_config (const XCam3aResultEdgeEnhancement &ee) { _ee_config.ee_gain = (float)ee.gain; _ee_config.ee_threshold = (float)ee.threshold; return true; } bool CLBayerPipeImageHandler::set_bnr_config (const XCam3aResultBayerNoiseReduction &bnr) { for(int i = 0; i < XCAM_BNR_TABLE_SIZE; i++) _bnr_table[i] = (float)bnr.table[i]; return true; } XCamReturn CLBayerPipeImageHandler::prepare_buffer_pool_video_info ( const VideoBufferInfo &input, VideoBufferInfo &output) { uint32_t format = _output_format; uint32_t width = input.width; uint32_t height = input.height; if (input.format == XCAM_PIX_FMT_SGRBG16_planar) { width *= 2; height *= 2; } bool format_inited = output.init (format, width, 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 (format)); return XCAM_RETURN_NO_ERROR; } XCamReturn CLBayerPipeImageHandler::prepare_parameters ( SmartPtr &input, SmartPtr &output) { SmartPtr 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; XCAM_ASSERT (_bayer_kernel.ptr ()); CLImageDesc in_desc; in_desc.format.image_channel_order = CL_RGBA; in_desc.format.image_channel_data_type = CL_UNORM_INT16; //CL_UNSIGNED_INT32; in_desc.width = in_video_info.width / 4; // 960/4 in_desc.height = in_video_info.aligned_height * 4; //540 in_desc.row_pitch = in_video_info.strides[0]; SmartPtr image_in = convert_to_climage (context, input, in_desc); CLImageDesc out_desc; out_desc.format.image_channel_order = CL_RGBA; if (XCAM_PIX_FMT_RGB48_planar == out_video_info.format) out_desc.format.image_channel_data_type = CL_UNORM_INT16; else out_desc.format.image_channel_data_type = CL_UNORM_INT8; out_desc.width = out_video_info.aligned_width / 4; out_desc.height = out_video_info.aligned_height * 3; out_desc.row_pitch = out_video_info.strides[0]; out_desc.array_size = 3; out_desc.slice_pitch = out_video_info.strides [0] * out_video_info.aligned_height; SmartPtr image_out = convert_to_climage (context, output, out_desc); uint input_height = in_video_info.aligned_height; uint output_height = out_video_info.aligned_height; XCAM_ASSERT (image_in.ptr () && image_out.ptr ()); XCAM_FAIL_RETURN ( WARNING, image_in->is_valid () && image_out->is_valid (), XCAM_RETURN_ERROR_MEM, "cl image kernel(%s) in/out memory not available", _bayer_kernel->get_kernel_name ()); SmartPtr bnr_table_buffer = new CLBuffer( context, sizeof(float) * XCAM_BNR_TABLE_SIZE, CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, &_bnr_table); //set args; args.push_back (new CLMemArgument (image_in)); args.push_back (new CLArgumentT (input_height)); args.push_back (new CLMemArgument (image_out)); args.push_back (new CLArgumentT (output_height)); args.push_back (new CLMemArgument (bnr_table_buffer)); args.push_back (new CLArgumentT (_enable_denoise)); args.push_back (new CLArgumentT (_ee_config)); work_size.dim = XCAM_DEFAULT_IMAGE_DIM; work_size.local[0] = BAYER_LOCAL_X_SIZE; work_size.local[1] = BAYER_LOCAL_Y_SIZE; work_size.global[0] = (XCAM_ALIGN_UP(out_video_info.width, WORKGROUP_PIXEL_WIDTH) / WORKGROUP_PIXEL_WIDTH) * work_size.local[0]; work_size.global[1] = (XCAM_ALIGN_UP(out_video_info.height, WORKGROUP_PIXEL_HEIGHT) / WORKGROUP_PIXEL_HEIGHT) * work_size.local[1]; XCAM_ASSERT (_bayer_kernel.ptr ()); XCamReturn ret = _bayer_kernel->set_arguments (args, work_size); XCAM_FAIL_RETURN ( WARNING, ret == XCAM_RETURN_NO_ERROR, ret, "bayer pipe kernel set arguments failed."); return XCAM_RETURN_NO_ERROR; } SmartPtr create_cl_bayer_pipe_image_handler (const SmartPtr &context) { SmartPtr bayer_pipe_handler; SmartPtr bayer_pipe_kernel; bayer_pipe_handler = new CLBayerPipeImageHandler (context, "cl_handler_bayer_pipe"); bayer_pipe_kernel = new CLBayerPipeImageKernel (context, bayer_pipe_handler); XCAM_ASSERT (bayer_pipe_kernel.ptr ()); XCAM_FAIL_RETURN ( ERROR, bayer_pipe_kernel->build_kernel (kernel_bayer_pipe_info, NULL) == XCAM_RETURN_NO_ERROR, NULL, "build bayer-pipe kernel(%s) failed", kernel_bayer_pipe_info.kernel_name); XCAM_ASSERT (bayer_pipe_kernel->is_valid ()); bayer_pipe_handler->set_bayer_kernel (bayer_pipe_kernel); return bayer_pipe_handler; } };