1 /* 2 * cl_pyramid_blender.h - CL pyramid blender 3 * 4 * Copyright (c) 2016 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: Wind Yuan <feng.yuan@intel.com> 19 */ 20 21 #ifndef XCAM_CL_PYRAMID_BLENDER_H 22 #define XCAM_CL_PYRAMID_BLENDER_H 23 24 #include <xcam_std.h> 25 #include <ocl/cl_blender.h> 26 27 #define CL_PYRAMID_ENABLE_DUMP 0 28 29 #define XCAM_CL_PYRAMID_MAX_LEVEL 4 30 31 namespace XCam { 32 33 class CLPyramidBlender; 34 35 enum { 36 BlendImageIndex = 0, 37 ReconstructImageIndex, 38 BlendImageCount 39 }; 40 41 enum { 42 CLSeamMaskTmp = 0, 43 CLSeamMaskCoeff, 44 CLSeamMaskCount 45 }; 46 47 struct PyramidLayer { 48 uint32_t blend_width; // blend, gauss, and lap 49 uint32_t blend_height; 50 SmartPtr<CLImage> gauss_image[CLBlenderPlaneMax][XCAM_BLENDER_IMAGE_NUM]; 51 int32_t gauss_offset_x[CLBlenderPlaneMax][XCAM_BLENDER_IMAGE_NUM]; // aligned with XCAM_BLENDER_ALIGNED_WIDTH 52 SmartPtr<CLImage> lap_image[CLBlenderPlaneMax][XCAM_BLENDER_IMAGE_NUM]; 53 int32_t lap_offset_x[CLBlenderPlaneMax][XCAM_BLENDER_IMAGE_NUM]; // aligned with XCAM_BLENDER_ALIGNED_WIDTH 54 SmartPtr<CLImage> blend_image[CLBlenderPlaneMax][BlendImageCount]; // 0 blend-image, 1 reconstruct image 55 uint32_t mask_width[CLBlenderPlaneMax]; 56 SmartPtr<CLBuffer> blend_mask[CLBlenderPlaneMax]; // sizeof(float) * mask_width 57 SmartPtr<CLImage> seam_mask[CLSeamMaskCount]; 58 SmartPtr<CLImage> scale_image[CLBlenderPlaneMax]; 59 60 #if CL_PYRAMID_ENABLE_DUMP 61 SmartPtr<CLImage> dump_gauss_resize[CLBlenderPlaneMax]; 62 SmartPtr<CLImage> dump_original[CLBlenderPlaneMax][BlendImageCount]; 63 SmartPtr<CLImage> dump_final[CLBlenderPlaneMax]; 64 #endif 65 66 PyramidLayer (); 67 void bind_buf_to_layer0 ( 68 SmartPtr<CLContext> context, 69 SmartPtr<VideoBuffer> &input0, SmartPtr<VideoBuffer> &input1, SmartPtr<VideoBuffer> &output, 70 const Rect &merge0_rect, const Rect &merge1_rect, bool need_uv, CLBlenderScaleMode scale_mode); 71 void init_layer0 (SmartPtr<CLContext> context, bool last_layer, bool need_uv, int mask_radius, float mask_sigma); 72 void build_cl_images (SmartPtr<CLContext> context, bool need_lap, bool need_uv); 73 bool copy_mask_from_y_to_uv (SmartPtr<CLContext> &context); 74 }; 75 76 class CLLinearBlenderKernel; 77 78 class CLPyramidBlendKernel; 79 80 class CLPyramidBlender 81 : public CLBlender 82 { 83 friend class CLPyramidBlendKernel; 84 85 public: 86 explicit CLPyramidBlender ( 87 const SmartPtr<CLContext> &context, const char *name, 88 int layers, bool need_uv, bool need_seam, CLBlenderScaleMode scale_mode); 89 ~CLPyramidBlender (); 90 91 //void set_blend_kernel (SmartPtr<CLLinearBlenderKernel> kernel, int index); 92 SmartPtr<CLImage> get_gauss_image (uint32_t layer, uint32_t buf_index, bool is_uv); 93 SmartPtr<CLImage> get_lap_image (uint32_t layer, uint32_t buf_index, bool is_uv); 94 SmartPtr<CLImage> get_blend_image (uint32_t layer, bool is_uv); 95 SmartPtr<CLImage> get_reconstruct_image (uint32_t layer, bool is_uv); 96 SmartPtr<CLImage> get_scale_image (bool is_uv); 97 SmartPtr<CLBuffer> get_blend_mask (uint32_t layer, bool is_uv); 98 SmartPtr<CLImage> get_seam_mask (uint32_t layer); 99 const PyramidLayer &get_pyramid_layer (uint32_t layer) const; 100 const SmartPtr<CLImage> &get_image_diff () const; 101 void get_seam_info (uint32_t &width, uint32_t &height, uint32_t &stride) const; 102 void get_seam_pos_info (uint32_t &offset_x, uint32_t &valid_width) const; get_seam_pos_buf()103 SmartPtr<CLBuffer> &get_seam_pos_buf () { 104 return _seam_pos_buf; 105 } get_seam_sum_buf()106 SmartPtr<CLBuffer> &get_seam_sum_buf () { 107 return _seam_sum_buf; 108 } get_layers()109 uint32_t get_layers () const { 110 return _layers; 111 } 112 XCamReturn fill_seam_mask (); 113 114 protected: 115 // from CLImageHandler 116 virtual XCamReturn execute_done (SmartPtr<VideoBuffer> &output); 117 118 // from CLBlender 119 virtual XCamReturn allocate_cl_buffers ( 120 SmartPtr<CLContext> context, SmartPtr<VideoBuffer> &input0, 121 SmartPtr<VideoBuffer> &input1, SmartPtr<VideoBuffer> &output); 122 123 private: 124 XCamReturn init_seam_buffers (SmartPtr<CLContext> context); 125 void last_layer_buffer_redirect (); 126 127 void dump_layer_mask (uint32_t layer, bool is_uv); 128 void dump_buffers (); 129 130 XCAM_DEAD_COPY (CLPyramidBlender); 131 132 private: 133 uint32_t _layers; 134 PyramidLayer _pyramid_layers[XCAM_CL_PYRAMID_MAX_LEVEL]; 135 136 //calculate seam masks 137 bool _need_seam; 138 SmartPtr<CLImage> _image_diff; // image difference in blending area, only Y 139 uint32_t _seam_pos_stride; 140 uint32_t _seam_width, _seam_height; 141 uint32_t _seam_pos_offset_x, _seam_pos_valid_width; 142 SmartPtr<CLBuffer> _seam_pos_buf; // width = _seam_width; height = _seam_height; 143 SmartPtr<CLBuffer> _seam_sum_buf; // size = _seam_width 144 bool _seam_mask_done; 145 //SmartPtr<CLImage> _seam_mask; 146 }; 147 148 class CLPyramidBlendKernel 149 : public CLImageKernel 150 { 151 public: 152 explicit CLPyramidBlendKernel ( 153 const SmartPtr<CLContext> &context, SmartPtr<CLPyramidBlender> &blender, 154 uint32_t layer, bool is_uv, bool need_seam); 155 156 protected: 157 virtual XCamReturn prepare_arguments (CLArgList &args, CLWorkSize &work_size); 158 private: get_input_0()159 SmartPtr<CLImage> get_input_0 () { 160 return _blender->get_lap_image (_layer, 0, _is_uv); 161 } get_input_1()162 SmartPtr<CLImage> get_input_1 () { 163 return _blender->get_lap_image (_layer, 1, _is_uv); 164 } get_output()165 SmartPtr<CLImage> get_output () { 166 return _blender->get_blend_image (_layer, _is_uv); 167 } get_blend_mask()168 SmartPtr<CLBuffer> get_blend_mask () { 169 return _blender->get_blend_mask (_layer, _is_uv); 170 } get_seam_mask()171 SmartPtr<CLImage> get_seam_mask () { 172 return _blender->get_seam_mask (_layer); 173 } 174 private: 175 XCAM_DEAD_COPY (CLPyramidBlendKernel); 176 177 private: 178 SmartPtr<CLPyramidBlender> _blender; 179 uint32_t _layer; 180 bool _is_uv; 181 bool _need_seam; 182 183 }; 184 185 class CLPyramidTransformKernel 186 : public CLImageKernel 187 { 188 public: 189 explicit CLPyramidTransformKernel ( 190 const SmartPtr<CLContext> &context, SmartPtr<CLPyramidBlender> &blender, 191 uint32_t layer, uint32_t buf_index, bool is_uv); 192 193 protected: 194 virtual XCamReturn prepare_arguments (CLArgList &args, CLWorkSize &work_size); 195 196 private: get_input_gauss()197 SmartPtr<CLImage> get_input_gauss () { 198 return _blender->get_gauss_image (_layer, _buf_index, _is_uv); 199 } 200 int32_t get_input_gauss_offset_x (); get_output_gauss()201 SmartPtr<CLImage> get_output_gauss () { 202 // need reset format 203 return _blender->get_gauss_image (_layer + 1, _buf_index, _is_uv); 204 } 205 206 207 XCAM_DEAD_COPY (CLPyramidTransformKernel); 208 209 private: 210 SmartPtr<CLPyramidBlender> _blender; 211 uint32_t _layer; 212 uint32_t _buf_index; 213 bool _is_uv; 214 }; 215 216 class CLSeamDiffKernel 217 : public CLImageKernel 218 { 219 public: 220 explicit CLSeamDiffKernel ( 221 const SmartPtr<CLContext> &context, SmartPtr<CLPyramidBlender> &blender); 222 223 protected: 224 virtual XCamReturn prepare_arguments (CLArgList &args, CLWorkSize &work_size); 225 226 private: 227 SmartPtr<CLPyramidBlender> _blender; 228 229 }; 230 231 class CLSeamDPKernel 232 : public CLImageKernel 233 { 234 public: 235 explicit CLSeamDPKernel ( 236 const SmartPtr<CLContext> &context, SmartPtr<CLPyramidBlender> &blender); 237 238 protected: 239 virtual XCamReturn prepare_arguments (CLArgList &args, CLWorkSize &work_size); 240 241 private: 242 SmartPtr<CLPyramidBlender> _blender; 243 int _seam_stride; 244 int _seam_height; 245 246 }; 247 248 class CLPyramidSeamMaskKernel 249 : public CLImageKernel 250 { 251 public: 252 explicit CLPyramidSeamMaskKernel ( 253 const SmartPtr<CLContext> &context, SmartPtr<CLPyramidBlender> &blender, 254 uint32_t layer, bool scale, bool need_slm); 255 256 protected: 257 virtual XCamReturn prepare_arguments (CLArgList &args, CLWorkSize &work_size); 258 259 private: 260 SmartPtr<CLPyramidBlender> _blender; 261 int _layer; 262 bool _need_scale; 263 bool _need_slm; 264 }; 265 266 class CLPyramidLapKernel 267 : public CLImageKernel 268 { 269 public: 270 explicit CLPyramidLapKernel ( 271 const SmartPtr<CLContext> &context, SmartPtr<CLPyramidBlender> &blender, 272 uint32_t layer, uint32_t buf_index, bool is_uv); 273 274 protected: 275 virtual XCamReturn prepare_arguments (CLArgList &args, CLWorkSize &work_size); 276 277 private: get_current_gauss()278 SmartPtr<CLImage> get_current_gauss () { 279 return _blender->get_gauss_image (_layer, _buf_index, _is_uv); 280 } get_next_gauss()281 SmartPtr<CLImage> get_next_gauss () { 282 return _blender->get_gauss_image (_layer + 1, _buf_index, _is_uv); 283 } 284 int32_t get_cur_gauss_offset_x (); 285 int32_t get_output_lap_offset_x (); 286 get_output_lap()287 SmartPtr<CLImage> get_output_lap () { 288 return _blender->get_lap_image (_layer, _buf_index, _is_uv); 289 } 290 291 XCAM_DEAD_COPY (CLPyramidLapKernel); 292 293 private: 294 SmartPtr<CLPyramidBlender> _blender; 295 uint32_t _layer; 296 uint32_t _buf_index; 297 bool _is_uv; 298 }; 299 300 class CLPyramidReconstructKernel 301 : public CLImageKernel 302 { 303 public: 304 explicit CLPyramidReconstructKernel ( 305 const SmartPtr<CLContext> &context, SmartPtr<CLPyramidBlender> &blender, 306 uint32_t layer, bool is_uv); 307 308 protected: 309 virtual XCamReturn prepare_arguments (CLArgList &args, CLWorkSize &work_size); 310 311 private: get_input_reconstruct()312 SmartPtr<CLImage> get_input_reconstruct () { 313 return _blender->get_reconstruct_image (_layer + 1, _is_uv); 314 } get_input_lap()315 SmartPtr<CLImage> get_input_lap () { 316 return _blender->get_blend_image (_layer, _is_uv); 317 } get_output_reconstruct()318 SmartPtr<CLImage> get_output_reconstruct () { 319 return _blender->get_reconstruct_image (_layer, _is_uv); 320 } 321 322 int get_output_reconstrcut_offset_x (); 323 324 325 XCAM_DEAD_COPY (CLPyramidReconstructKernel); 326 327 private: 328 SmartPtr<CLPyramidBlender> _blender; 329 uint32_t _layer; 330 bool _is_uv; 331 }; 332 333 class CLBlenderLocalScaleKernel 334 : public CLBlenderScaleKernel 335 { 336 public: 337 explicit CLBlenderLocalScaleKernel ( 338 const SmartPtr<CLContext> &context, SmartPtr<CLPyramidBlender> &blender, bool is_uv); 339 340 protected: 341 virtual SmartPtr<CLImage> get_input_image (); 342 virtual SmartPtr<CLImage> get_output_image (); 343 344 virtual bool get_output_info (uint32_t &out_width, uint32_t &out_height, int &out_offset_x); 345 346 private: 347 XCAM_DEAD_COPY (CLBlenderLocalScaleKernel); 348 349 private: 350 SmartPtr<CLPyramidBlender> _blender; 351 SmartPtr<CLImage> _image_in; 352 }; 353 354 class CLPyramidCopyKernel 355 : public CLImageKernel 356 { 357 public: 358 explicit CLPyramidCopyKernel ( 359 const SmartPtr<CLContext> &context, SmartPtr<CLPyramidBlender> &blender, 360 uint32_t buf_index, bool is_uv); 361 362 protected: 363 virtual XCamReturn prepare_arguments (CLArgList &args, CLWorkSize &work_size); 364 365 private: get_input()366 SmartPtr<CLImage> get_input () { 367 return _blender->get_gauss_image (0, _buf_index, _is_uv); 368 } get_output()369 SmartPtr<CLImage> get_output () { 370 if (_blender->get_scale_mode () == CLBlenderScaleLocal) 371 return _blender->get_scale_image (_is_uv); 372 else 373 return _blender->get_reconstruct_image (0, _is_uv); 374 } 375 376 XCAM_DEAD_COPY (CLPyramidCopyKernel); 377 378 private: 379 SmartPtr<CLPyramidBlender> _blender; 380 bool _is_uv; 381 int _buf_index; 382 383 // parameters 384 int _max_g_x; 385 int _max_g_y; 386 }; 387 388 }; 389 390 #endif //XCAM_CL_PYRAMID_BLENDER_H 391 392