/*
* 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