Home | History | Annotate | Download | only in ocl
      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