1 /* 2 * cl_wavelet_denoise_handler.cpp - CL wavelet denoise 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: Wei Zong <wei.zong (at) intel.com> 19 */ 20 #include "cl_utils.h" 21 #include "x3a_stats_pool.h" 22 #include "cl_context.h" 23 #include "cl_device.h" 24 #include "cl_wavelet_denoise_handler.h" 25 26 #define WAVELET_DECOMPOSITION_LEVELS 4 27 28 namespace XCam { 29 30 static const XCamKernelInfo kernel_wavelet_denoise_info = { 31 "kernel_wavelet_denoise", 32 #include "kernel_wavelet_denoise.clx" 33 , 0, 34 }; 35 36 CLWaveletDenoiseImageKernel::CLWaveletDenoiseImageKernel ( 37 const SmartPtr<CLContext> &context, 38 const char *name, 39 SmartPtr<CLWaveletDenoiseImageHandler> &handler, 40 uint32_t channel, 41 uint32_t layer) 42 : CLImageKernel (context, name) 43 , _channel (channel) 44 , _current_layer (layer) 45 , _handler (handler) 46 { 47 } 48 49 XCamReturn 50 CLWaveletDenoiseImageKernel::prepare_arguments ( 51 CLArgList &args, CLWorkSize &work_size) 52 { 53 SmartPtr<CLContext> context = get_context (); 54 SmartPtr<VideoBuffer> input = _handler->get_input_buf (); 55 SmartPtr<VideoBuffer> output = _handler->get_output_buf (); 56 57 const VideoBufferInfo &video_info_in = input->get_video_info (); 58 const VideoBufferInfo &video_info_out = output->get_video_info (); 59 60 SmartPtr<CLMemory> input_image = convert_to_clbuffer (context, input); 61 SmartPtr<CLMemory> reconstruct_image = convert_to_clbuffer (context, output); 62 63 SmartPtr<CLMemory> details_image = _handler->get_details_image (); 64 SmartPtr<CLMemory> approx_image = _handler->get_approx_image (); 65 66 uint32_t decomposition_levels = WAVELET_DECOMPOSITION_LEVELS; 67 float soft_threshold = _handler->get_denoise_config ().threshold[0]; 68 float hard_threshold = _handler->get_denoise_config ().threshold[1]; 69 70 uint32_t input_y_offset = video_info_in.offsets[0] / 4; 71 uint32_t output_y_offset = video_info_out.offsets[0] / 4; 72 73 uint32_t input_uv_offset = video_info_in.aligned_height; 74 uint32_t output_uv_offset = video_info_out.aligned_height; 75 76 XCAM_FAIL_RETURN ( 77 WARNING, 78 input_image->is_valid () && reconstruct_image->is_valid (), 79 XCAM_RETURN_ERROR_MEM, 80 "cl image kernel(%s) in/out memory not available", XCAM_STR(get_kernel_name ())); 81 82 //set args; 83 work_size.dim = XCAM_DEFAULT_IMAGE_DIM; 84 work_size.local[0] = 8; 85 work_size.local[1] = 4; 86 87 if (_current_layer % 2) { 88 args.push_back (new CLMemArgument (input_image)); 89 args.push_back (new CLMemArgument (approx_image)); 90 } else { 91 args.push_back (new CLMemArgument (approx_image)); 92 args.push_back (new CLMemArgument (input_image)); 93 } 94 args.push_back (new CLMemArgument (details_image)); 95 args.push_back (new CLMemArgument (reconstruct_image)); 96 args.push_back (new CLArgumentT<uint32_t> (input_y_offset)); 97 args.push_back (new CLArgumentT<uint32_t> (output_y_offset)); 98 args.push_back (new CLArgumentT<uint32_t> (input_uv_offset)); 99 args.push_back (new CLArgumentT<uint32_t> (output_uv_offset)); 100 args.push_back (new CLArgumentT<uint32_t> (_current_layer)); 101 args.push_back (new CLArgumentT<uint32_t> (decomposition_levels)); 102 args.push_back (new CLArgumentT<float> (hard_threshold)); 103 args.push_back (new CLArgumentT<float> (soft_threshold)); 104 105 if (_channel & CL_IMAGE_CHANNEL_UV) { 106 work_size.global[0] = video_info_in.width / 16; 107 work_size.global[1] = video_info_in.height / 2; 108 } else { 109 work_size.global[0] = video_info_in.width / 16; 110 work_size.global[1] = video_info_in.height; 111 } 112 113 return XCAM_RETURN_NO_ERROR; 114 } 115 116 CLWaveletDenoiseImageHandler::CLWaveletDenoiseImageHandler ( 117 const SmartPtr<CLContext> &context, const char *name) 118 : CLImageHandler (context, name) 119 { 120 _config.decomposition_levels = 5; 121 _config.threshold[0] = 0.5; 122 _config.threshold[1] = 5.0; 123 } 124 125 XCamReturn 126 CLWaveletDenoiseImageHandler::prepare_output_buf (SmartPtr<VideoBuffer> &input, SmartPtr<VideoBuffer> &output) 127 { 128 XCamReturn ret = XCAM_RETURN_NO_ERROR; 129 CLImageHandler::prepare_output_buf(input, output); 130 131 if (!_approx_image.ptr ()) { 132 const VideoBufferInfo & video_info = input->get_video_info (); 133 uint32_t buffer_size = video_info.width * video_info.aligned_height; 134 135 _approx_image = new CLBuffer (get_context (), buffer_size, 136 CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, NULL); 137 } 138 139 if (!_details_image.ptr ()) { 140 const VideoBufferInfo & video_info = input->get_video_info (); 141 uint32_t buffer_size = sizeof(float) * video_info.width * video_info.height; 142 143 _details_image = new CLBuffer (get_context (), buffer_size, 144 CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, NULL); 145 } 146 return ret; 147 } 148 149 bool 150 CLWaveletDenoiseImageHandler::set_denoise_config (const XCam3aResultWaveletNoiseReduction& config) 151 152 { 153 _config = config; 154 155 return true; 156 } 157 158 SmartPtr<CLImageHandler> 159 create_cl_wavelet_denoise_image_handler (const SmartPtr<CLContext> &context, uint32_t channel) 160 { 161 SmartPtr<CLWaveletDenoiseImageHandler> wavelet_handler; 162 SmartPtr<CLWaveletDenoiseImageKernel> wavelet_kernel; 163 164 wavelet_handler = new CLWaveletDenoiseImageHandler (context, "cl_handler_wavelet_denoise"); 165 XCAM_ASSERT (wavelet_handler.ptr ()); 166 167 for (int layer = 1; layer <= WAVELET_DECOMPOSITION_LEVELS; layer++) { 168 wavelet_kernel = new CLWaveletDenoiseImageKernel ( 169 context, "kernel_wavelet_denoise", wavelet_handler, channel, layer); 170 const char *build_options = 171 (channel & CL_IMAGE_CHANNEL_UV) ? "-DWAVELET_DENOISE_UV=1" : "-DWAVELET_DENOISE_UV=0"; 172 173 XCAM_ASSERT (wavelet_kernel.ptr ()); 174 XCAM_FAIL_RETURN ( 175 ERROR, wavelet_kernel->build_kernel (kernel_wavelet_denoise_info, build_options) == XCAM_RETURN_NO_ERROR, NULL, 176 "build wavelet denoise kernel(%s) failed", kernel_wavelet_denoise_info.kernel_name); 177 XCAM_ASSERT (wavelet_kernel->is_valid ()); 178 179 wavelet_handler->add_kernel (wavelet_kernel); 180 } 181 return wavelet_handler; 182 } 183 184 }; 185