• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@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 
CLWaveletDenoiseImageKernel(const SmartPtr<CLContext> & context,const char * name,SmartPtr<CLWaveletDenoiseImageHandler> & handler,uint32_t channel,uint32_t layer)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
prepare_arguments(CLArgList & args,CLWorkSize & work_size)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 
CLWaveletDenoiseImageHandler(const SmartPtr<CLContext> & context,const char * name)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
prepare_output_buf(SmartPtr<VideoBuffer> & input,SmartPtr<VideoBuffer> & output)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
set_denoise_config(const XCam3aResultWaveletNoiseReduction & config)150 CLWaveletDenoiseImageHandler::set_denoise_config (const XCam3aResultWaveletNoiseReduction& config)
151 
152 {
153     _config = config;
154 
155     return true;
156 }
157 
158 SmartPtr<CLImageHandler>
create_cl_wavelet_denoise_image_handler(const SmartPtr<CLContext> & context,uint32_t channel)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