/* * 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 <feng.yuan@intel.com> */ #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