| /* |
| * cl_pyramid_blender.h - CL pyramid blender |
| * |
| * Copyright (c) 2016 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 <[email protected]> |
| */ |
| |
| #ifndef XCAM_CL_PYRAMID_BLENDER_H |
| #define XCAM_CL_PYRAMID_BLENDER_H |
| |
| #include <xcam_std.h> |
| #include <ocl/cl_blender.h> |
| |
| #define CL_PYRAMID_ENABLE_DUMP 0 |
| |
| #define XCAM_CL_PYRAMID_MAX_LEVEL 4 |
| |
| namespace XCam { |
| |
| class CLPyramidBlender; |
| |
| enum { |
| BlendImageIndex = 0, |
| ReconstructImageIndex, |
| BlendImageCount |
| }; |
| |
| enum { |
| CLSeamMaskTmp = 0, |
| CLSeamMaskCoeff, |
| CLSeamMaskCount |
| }; |
| |
| struct PyramidLayer { |
| uint32_t blend_width; // blend, gauss, and lap |
| uint32_t blend_height; |
| SmartPtr<CLImage> gauss_image[CLBlenderPlaneMax][XCAM_BLENDER_IMAGE_NUM]; |
| int32_t gauss_offset_x[CLBlenderPlaneMax][XCAM_BLENDER_IMAGE_NUM]; // aligned with XCAM_BLENDER_ALIGNED_WIDTH |
| SmartPtr<CLImage> lap_image[CLBlenderPlaneMax][XCAM_BLENDER_IMAGE_NUM]; |
| int32_t lap_offset_x[CLBlenderPlaneMax][XCAM_BLENDER_IMAGE_NUM]; // aligned with XCAM_BLENDER_ALIGNED_WIDTH |
| SmartPtr<CLImage> blend_image[CLBlenderPlaneMax][BlendImageCount]; // 0 blend-image, 1 reconstruct image |
| uint32_t mask_width[CLBlenderPlaneMax]; |
| SmartPtr<CLBuffer> blend_mask[CLBlenderPlaneMax]; // sizeof(float) * mask_width |
| SmartPtr<CLImage> seam_mask[CLSeamMaskCount]; |
| SmartPtr<CLImage> scale_image[CLBlenderPlaneMax]; |
| |
| #if CL_PYRAMID_ENABLE_DUMP |
| SmartPtr<CLImage> dump_gauss_resize[CLBlenderPlaneMax]; |
| SmartPtr<CLImage> dump_original[CLBlenderPlaneMax][BlendImageCount]; |
| SmartPtr<CLImage> dump_final[CLBlenderPlaneMax]; |
| #endif |
| |
| PyramidLayer (); |
| void bind_buf_to_layer0 ( |
| SmartPtr<CLContext> context, |
| SmartPtr<VideoBuffer> &input0, SmartPtr<VideoBuffer> &input1, SmartPtr<VideoBuffer> &output, |
| const Rect &merge0_rect, const Rect &merge1_rect, bool need_uv, CLBlenderScaleMode scale_mode); |
| void init_layer0 (SmartPtr<CLContext> context, bool last_layer, bool need_uv, int mask_radius, float mask_sigma); |
| void build_cl_images (SmartPtr<CLContext> context, bool need_lap, bool need_uv); |
| bool copy_mask_from_y_to_uv (SmartPtr<CLContext> &context); |
| }; |
| |
| class CLLinearBlenderKernel; |
| |
| class CLPyramidBlendKernel; |
| |
| class CLPyramidBlender |
| : public CLBlender |
| { |
| friend class CLPyramidBlendKernel; |
| |
| public: |
| explicit CLPyramidBlender ( |
| const SmartPtr<CLContext> &context, const char *name, |
| int layers, bool need_uv, bool need_seam, CLBlenderScaleMode scale_mode); |
| ~CLPyramidBlender (); |
| |
| //void set_blend_kernel (SmartPtr<CLLinearBlenderKernel> kernel, int index); |
| SmartPtr<CLImage> get_gauss_image (uint32_t layer, uint32_t buf_index, bool is_uv); |
| SmartPtr<CLImage> get_lap_image (uint32_t layer, uint32_t buf_index, bool is_uv); |
| SmartPtr<CLImage> get_blend_image (uint32_t layer, bool is_uv); |
| SmartPtr<CLImage> get_reconstruct_image (uint32_t layer, bool is_uv); |
| SmartPtr<CLImage> get_scale_image (bool is_uv); |
| SmartPtr<CLBuffer> get_blend_mask (uint32_t layer, bool is_uv); |
| SmartPtr<CLImage> get_seam_mask (uint32_t layer); |
| const PyramidLayer &get_pyramid_layer (uint32_t layer) const; |
| const SmartPtr<CLImage> &get_image_diff () const; |
| void get_seam_info (uint32_t &width, uint32_t &height, uint32_t &stride) const; |
| void get_seam_pos_info (uint32_t &offset_x, uint32_t &valid_width) const; |
| SmartPtr<CLBuffer> &get_seam_pos_buf () { |
| return _seam_pos_buf; |
| } |
| SmartPtr<CLBuffer> &get_seam_sum_buf () { |
| return _seam_sum_buf; |
| } |
| uint32_t get_layers () const { |
| return _layers; |
| } |
| XCamReturn fill_seam_mask (); |
| |
| protected: |
| // from CLImageHandler |
| virtual XCamReturn execute_done (SmartPtr<VideoBuffer> &output); |
| |
| // from CLBlender |
| virtual XCamReturn allocate_cl_buffers ( |
| SmartPtr<CLContext> context, SmartPtr<VideoBuffer> &input0, |
| SmartPtr<VideoBuffer> &input1, SmartPtr<VideoBuffer> &output); |
| |
| private: |
| XCamReturn init_seam_buffers (SmartPtr<CLContext> context); |
| void last_layer_buffer_redirect (); |
| |
| void dump_layer_mask (uint32_t layer, bool is_uv); |
| void dump_buffers (); |
| |
| XCAM_DEAD_COPY (CLPyramidBlender); |
| |
| private: |
| uint32_t _layers; |
| PyramidLayer _pyramid_layers[XCAM_CL_PYRAMID_MAX_LEVEL]; |
| |
| //calculate seam masks |
| bool _need_seam; |
| SmartPtr<CLImage> _image_diff; // image difference in blending area, only Y |
| uint32_t _seam_pos_stride; |
| uint32_t _seam_width, _seam_height; |
| uint32_t _seam_pos_offset_x, _seam_pos_valid_width; |
| SmartPtr<CLBuffer> _seam_pos_buf; // width = _seam_width; height = _seam_height; |
| SmartPtr<CLBuffer> _seam_sum_buf; // size = _seam_width |
| bool _seam_mask_done; |
| //SmartPtr<CLImage> _seam_mask; |
| }; |
| |
| class CLPyramidBlendKernel |
| : public CLImageKernel |
| { |
| public: |
| explicit CLPyramidBlendKernel ( |
| const SmartPtr<CLContext> &context, SmartPtr<CLPyramidBlender> &blender, |
| uint32_t layer, bool is_uv, bool need_seam); |
| |
| protected: |
| virtual XCamReturn prepare_arguments (CLArgList &args, CLWorkSize &work_size); |
| private: |
| SmartPtr<CLImage> get_input_0 () { |
| return _blender->get_lap_image (_layer, 0, _is_uv); |
| } |
| SmartPtr<CLImage> get_input_1 () { |
| return _blender->get_lap_image (_layer, 1, _is_uv); |
| } |
| SmartPtr<CLImage> get_output () { |
| return _blender->get_blend_image (_layer, _is_uv); |
| } |
| SmartPtr<CLBuffer> get_blend_mask () { |
| return _blender->get_blend_mask (_layer, _is_uv); |
| } |
| SmartPtr<CLImage> get_seam_mask () { |
| return _blender->get_seam_mask (_layer); |
| } |
| private: |
| XCAM_DEAD_COPY (CLPyramidBlendKernel); |
| |
| private: |
| SmartPtr<CLPyramidBlender> _blender; |
| uint32_t _layer; |
| bool _is_uv; |
| bool _need_seam; |
| |
| }; |
| |
| class CLPyramidTransformKernel |
| : public CLImageKernel |
| { |
| public: |
| explicit CLPyramidTransformKernel ( |
| const SmartPtr<CLContext> &context, SmartPtr<CLPyramidBlender> &blender, |
| uint32_t layer, uint32_t buf_index, bool is_uv); |
| |
| protected: |
| virtual XCamReturn prepare_arguments (CLArgList &args, CLWorkSize &work_size); |
| |
| private: |
| SmartPtr<CLImage> get_input_gauss () { |
| return _blender->get_gauss_image (_layer, _buf_index, _is_uv); |
| } |
| int32_t get_input_gauss_offset_x (); |
| SmartPtr<CLImage> get_output_gauss () { |
| // need reset format |
| return _blender->get_gauss_image (_layer + 1, _buf_index, _is_uv); |
| } |
| |
| |
| XCAM_DEAD_COPY (CLPyramidTransformKernel); |
| |
| private: |
| SmartPtr<CLPyramidBlender> _blender; |
| uint32_t _layer; |
| uint32_t _buf_index; |
| bool _is_uv; |
| }; |
| |
| class CLSeamDiffKernel |
| : public CLImageKernel |
| { |
| public: |
| explicit CLSeamDiffKernel ( |
| const SmartPtr<CLContext> &context, SmartPtr<CLPyramidBlender> &blender); |
| |
| protected: |
| virtual XCamReturn prepare_arguments (CLArgList &args, CLWorkSize &work_size); |
| |
| private: |
| SmartPtr<CLPyramidBlender> _blender; |
| |
| }; |
| |
| class CLSeamDPKernel |
| : public CLImageKernel |
| { |
| public: |
| explicit CLSeamDPKernel ( |
| const SmartPtr<CLContext> &context, SmartPtr<CLPyramidBlender> &blender); |
| |
| protected: |
| virtual XCamReturn prepare_arguments (CLArgList &args, CLWorkSize &work_size); |
| |
| private: |
| SmartPtr<CLPyramidBlender> _blender; |
| int _seam_stride; |
| int _seam_height; |
| |
| }; |
| |
| class CLPyramidSeamMaskKernel |
| : public CLImageKernel |
| { |
| public: |
| explicit CLPyramidSeamMaskKernel ( |
| const SmartPtr<CLContext> &context, SmartPtr<CLPyramidBlender> &blender, |
| uint32_t layer, bool scale, bool need_slm); |
| |
| protected: |
| virtual XCamReturn prepare_arguments (CLArgList &args, CLWorkSize &work_size); |
| |
| private: |
| SmartPtr<CLPyramidBlender> _blender; |
| int _layer; |
| bool _need_scale; |
| bool _need_slm; |
| }; |
| |
| class CLPyramidLapKernel |
| : public CLImageKernel |
| { |
| public: |
| explicit CLPyramidLapKernel ( |
| const SmartPtr<CLContext> &context, SmartPtr<CLPyramidBlender> &blender, |
| uint32_t layer, uint32_t buf_index, bool is_uv); |
| |
| protected: |
| virtual XCamReturn prepare_arguments (CLArgList &args, CLWorkSize &work_size); |
| |
| private: |
| SmartPtr<CLImage> get_current_gauss () { |
| return _blender->get_gauss_image (_layer, _buf_index, _is_uv); |
| } |
| SmartPtr<CLImage> get_next_gauss () { |
| return _blender->get_gauss_image (_layer + 1, _buf_index, _is_uv); |
| } |
| int32_t get_cur_gauss_offset_x (); |
| int32_t get_output_lap_offset_x (); |
| |
| SmartPtr<CLImage> get_output_lap () { |
| return _blender->get_lap_image (_layer, _buf_index, _is_uv); |
| } |
| |
| XCAM_DEAD_COPY (CLPyramidLapKernel); |
| |
| private: |
| SmartPtr<CLPyramidBlender> _blender; |
| uint32_t _layer; |
| uint32_t _buf_index; |
| bool _is_uv; |
| }; |
| |
| class CLPyramidReconstructKernel |
| : public CLImageKernel |
| { |
| public: |
| explicit CLPyramidReconstructKernel ( |
| const SmartPtr<CLContext> &context, SmartPtr<CLPyramidBlender> &blender, |
| uint32_t layer, bool is_uv); |
| |
| protected: |
| virtual XCamReturn prepare_arguments (CLArgList &args, CLWorkSize &work_size); |
| |
| private: |
| SmartPtr<CLImage> get_input_reconstruct () { |
| return _blender->get_reconstruct_image (_layer + 1, _is_uv); |
| } |
| SmartPtr<CLImage> get_input_lap () { |
| return _blender->get_blend_image (_layer, _is_uv); |
| } |
| SmartPtr<CLImage> get_output_reconstruct () { |
| return _blender->get_reconstruct_image (_layer, _is_uv); |
| } |
| |
| int get_output_reconstrcut_offset_x (); |
| |
| |
| XCAM_DEAD_COPY (CLPyramidReconstructKernel); |
| |
| private: |
| SmartPtr<CLPyramidBlender> _blender; |
| uint32_t _layer; |
| bool _is_uv; |
| }; |
| |
| class CLBlenderLocalScaleKernel |
| : public CLBlenderScaleKernel |
| { |
| public: |
| explicit CLBlenderLocalScaleKernel ( |
| const SmartPtr<CLContext> &context, SmartPtr<CLPyramidBlender> &blender, bool is_uv); |
| |
| protected: |
| virtual SmartPtr<CLImage> get_input_image (); |
| virtual SmartPtr<CLImage> get_output_image (); |
| |
| virtual bool get_output_info (uint32_t &out_width, uint32_t &out_height, int &out_offset_x); |
| |
| private: |
| XCAM_DEAD_COPY (CLBlenderLocalScaleKernel); |
| |
| private: |
| SmartPtr<CLPyramidBlender> _blender; |
| SmartPtr<CLImage> _image_in; |
| }; |
| |
| class CLPyramidCopyKernel |
| : public CLImageKernel |
| { |
| public: |
| explicit CLPyramidCopyKernel ( |
| const SmartPtr<CLContext> &context, SmartPtr<CLPyramidBlender> &blender, |
| uint32_t buf_index, bool is_uv); |
| |
| protected: |
| virtual XCamReturn prepare_arguments (CLArgList &args, CLWorkSize &work_size); |
| |
| private: |
| SmartPtr<CLImage> get_input () { |
| return _blender->get_gauss_image (0, _buf_index, _is_uv); |
| } |
| SmartPtr<CLImage> get_output () { |
| if (_blender->get_scale_mode () == CLBlenderScaleLocal) |
| return _blender->get_scale_image (_is_uv); |
| else |
| return _blender->get_reconstruct_image (0, _is_uv); |
| } |
| |
| XCAM_DEAD_COPY (CLPyramidCopyKernel); |
| |
| private: |
| SmartPtr<CLPyramidBlender> _blender; |
| bool _is_uv; |
| int _buf_index; |
| |
| // parameters |
| int _max_g_x; |
| int _max_g_y; |
| }; |
| |
| }; |
| |
| #endif //XCAM_CL_PYRAMID_BLENDER_H |
| |