1c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan/*
2c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan * cl_image_360_stitch.cpp - CL Image 360 stitch
3c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan *
4c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan *  Copyright (c) 2016 Intel Corporation
5c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan *
6c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan * Licensed under the Apache License, Version 2.0 (the "License");
7c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan * you may not use this file except in compliance with the License.
8c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan * You may obtain a copy of the License at
9c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan *
10c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan *      http://www.apache.org/licenses/LICENSE-2.0
11c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan *
12c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan * Unless required by applicable law or agreed to in writing, software
13c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan * distributed under the License is distributed on an "AS IS" BASIS,
14c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan * See the License for the specific language governing permissions and
16c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan * limitations under the License.
17c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan *
18c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan * Author: Wind Yuan <feng.yuan@intel.com>
19c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan */
20c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan
216b5f71042b969ae41362e07660181a676685702bYinhang Liu#include "cl_utils.h"
22c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan#include "cl_image_360_stitch.h"
239fbfce6bd98f1d790f75215932de854892a58154Wind Yuan#if HAVE_OPENCV
249fbfce6bd98f1d790f75215932de854892a58154Wind Yuan#include "cv_feature_match.h"
259fbfce6bd98f1d790f75215932de854892a58154Wind Yuan#endif
26c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan
270c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu#define XCAM_BLENDER_GLOBAL_SCALE_EXT_WIDTH 64
280c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu
2952d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu#define STITCH_CHECK(ret, msg, ...) \
3052d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu    if ((ret) != XCAM_RETURN_NO_ERROR) {        \
3152d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu        XCAM_LOG_WARNING (msg, ## __VA_ARGS__); \
3252d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu        return ret;                             \
3352d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu    }
3452d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu
35c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuannamespace XCam {
36c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan
37be505049e0d0cd218324c728b840652ac54bd19fWind YuanCLBlenderGlobalScaleKernel::CLBlenderGlobalScaleKernel (
38be505049e0d0cd218324c728b840652ac54bd19fWind Yuan    const SmartPtr<CLContext> &context, SmartPtr<CLImage360Stitch> &stitch, bool is_uv)
390c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    : CLBlenderScaleKernel (context, is_uv)
40be505049e0d0cd218324c728b840652ac54bd19fWind Yuan    , _stitch (stitch)
410c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu{
420c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu}
430c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu
440c3b87fb4f0706485c03bef97800d8840d236354Yinhang LiuSmartPtr<CLImage>
45be505049e0d0cd218324c728b840652ac54bd19fWind YuanCLBlenderGlobalScaleKernel::get_input_image () {
460c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    SmartPtr<CLContext> context = get_context ();
476b5f71042b969ae41362e07660181a676685702bYinhang Liu    SmartPtr<VideoBuffer> input = _stitch->get_global_scale_input ();
480c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu
490c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    CLImageDesc cl_desc;
500c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    SmartPtr<CLImage> cl_image;
510c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    const VideoBufferInfo &buf_info = input->get_video_info ();
520c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu
530c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    cl_desc.format.image_channel_data_type = CL_UNORM_INT8;
540c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    if (_is_uv) {
550c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu        cl_desc.format.image_channel_order = CL_RG;
560c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu        cl_desc.width = buf_info.width / 2;
570c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu        cl_desc.height = buf_info.height / 2;
580c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu        cl_desc.row_pitch = buf_info.strides[1];
596b5f71042b969ae41362e07660181a676685702bYinhang Liu        cl_image = convert_to_climage (context, input, cl_desc, buf_info.offsets[1]);
600c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    } else {
610c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu        cl_desc.format.image_channel_order = CL_R;
620c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu        cl_desc.width = buf_info.width;
630c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu        cl_desc.height = buf_info.height;
640c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu        cl_desc.row_pitch = buf_info.strides[0];
656b5f71042b969ae41362e07660181a676685702bYinhang Liu        cl_image = convert_to_climage (context, input, cl_desc, buf_info.offsets[0]);
660c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    }
670c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu
680c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    return cl_image;
690c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu}
700c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu
710c3b87fb4f0706485c03bef97800d8840d236354Yinhang LiuSmartPtr<CLImage>
72be505049e0d0cd218324c728b840652ac54bd19fWind YuanCLBlenderGlobalScaleKernel::get_output_image () {
730c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    SmartPtr<CLContext> context = get_context ();
746b5f71042b969ae41362e07660181a676685702bYinhang Liu    SmartPtr<VideoBuffer> output = _stitch->get_global_scale_output ();
750c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu
760c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    CLImageDesc cl_desc;
770c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    SmartPtr<CLImage> cl_image;
780c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    const VideoBufferInfo &buf_info = output->get_video_info ();
790c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu
800c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    cl_desc.format.image_channel_data_type = CL_UNSIGNED_INT16;
810c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    cl_desc.format.image_channel_order = CL_RGBA;
820c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    if (_is_uv) {
830c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu        cl_desc.width = buf_info.width / 8;
840c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu        cl_desc.height = buf_info.height / 2;
850c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu        cl_desc.row_pitch = buf_info.strides[1];
866b5f71042b969ae41362e07660181a676685702bYinhang Liu        cl_image = convert_to_climage (context, output, cl_desc, buf_info.offsets[1]);
870c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    } else {
880c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu        cl_desc.width = buf_info.width / 8;
890c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu        cl_desc.height = buf_info.height;
900c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu        cl_desc.row_pitch = buf_info.strides[0];
916b5f71042b969ae41362e07660181a676685702bYinhang Liu        cl_image = convert_to_climage (context, output, cl_desc, buf_info.offsets[0]);
920c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    }
930c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu
940c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    return cl_image;
950c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu}
960c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu
970c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liubool
980c3b87fb4f0706485c03bef97800d8840d236354Yinhang LiuCLBlenderGlobalScaleKernel::get_output_info (
990c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    uint32_t &out_width, uint32_t &out_height, int &out_offset_x)
1000c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu{
1016b5f71042b969ae41362e07660181a676685702bYinhang Liu    SmartPtr<VideoBuffer> output = _stitch->get_global_scale_output ();
1020c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    const VideoBufferInfo &output_info = output->get_video_info ();
1030c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu
1040c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    out_width = output_info.width / 8;
1050c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    out_height = _is_uv ? output_info.height / 2 : output_info.height;
1060c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    out_offset_x = 0;
1070c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu
1080c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    return true;
1090c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu}
1100c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu
111d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu#if HAVE_OPENCV
112d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liustatic CVFMConfig
1130995e53b9064a563b343a9bdcd50ecf88bf84becWind Yuanget_fm_default_config (StitchResMode res_mode)
114d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu{
115d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu    CVFMConfig config;
116d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu
117d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu    switch (res_mode) {
1180995e53b9064a563b343a9bdcd50ecf88bf84becWind Yuan    case StitchRes1080P: {
119d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        config.sitch_min_width = 56;
120d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        config.min_corners = 8;
121d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        config.offset_factor = 0.8f;
122d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        config.delta_mean_offset = 5.0f;
1232a54829b2e0851133645ae499470e8eb8baab9f3Yinhang Liu        config.recur_offset_error = 8.0f;
124d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        config.max_adjusted_offset = 12.0f;
1252a54829b2e0851133645ae499470e8eb8baab9f3Yinhang Liu        config.max_valid_offset_y = 8.0f;
1262a54829b2e0851133645ae499470e8eb8baab9f3Yinhang Liu        config.max_track_error = 24.0f;
127d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu
128d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        break;
129d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu    }
13077853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    case StitchRes1080P4: {
1312a54829b2e0851133645ae499470e8eb8baab9f3Yinhang Liu        config.sitch_min_width = 128;
1322a54829b2e0851133645ae499470e8eb8baab9f3Yinhang Liu        config.min_corners = 4;
13377853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        config.offset_factor = 0.8f;
1342a54829b2e0851133645ae499470e8eb8baab9f3Yinhang Liu        config.delta_mean_offset = 24.0f;
1352a54829b2e0851133645ae499470e8eb8baab9f3Yinhang Liu        config.recur_offset_error = 12.0f;
1362a54829b2e0851133645ae499470e8eb8baab9f3Yinhang Liu        config.max_adjusted_offset = 24.0f;
1372a54829b2e0851133645ae499470e8eb8baab9f3Yinhang Liu        config.max_valid_offset_y = 64.0f;
1382a54829b2e0851133645ae499470e8eb8baab9f3Yinhang Liu        config.max_track_error = 32.0f;
13977853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu
14077853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        break;
14177853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    }
1420995e53b9064a563b343a9bdcd50ecf88bf84becWind Yuan    case StitchRes4K: {
143d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        config.sitch_min_width = 160;
144d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        config.min_corners = 8;
145d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        config.offset_factor = 0.8f;
146d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        config.delta_mean_offset = 5.0f;
1472a54829b2e0851133645ae499470e8eb8baab9f3Yinhang Liu        config.recur_offset_error = 8.0f;
148d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        config.max_adjusted_offset = 12.0f;
1492a54829b2e0851133645ae499470e8eb8baab9f3Yinhang Liu        config.max_valid_offset_y = 8.0f;
1502a54829b2e0851133645ae499470e8eb8baab9f3Yinhang Liu        config.max_track_error = 24.0f;
151d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu
152d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        break;
153d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu    }
154d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu    default:
155d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        XCAM_LOG_DEBUG ("unknown reslution mode (%d)", res_mode);
156d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        break;
157d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu    }
158d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu
159d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu    return config;
160d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu}
161d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu#endif
162d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu
1630995e53b9064a563b343a9bdcd50ecf88bf84becWind Yuanstatic StitchInfo
1640995e53b9064a563b343a9bdcd50ecf88bf84becWind Yuanget_default_stitch_info (StitchResMode res_mode)
165680275749a2b29042b169e7b35cf4534a638115cYinhang Liu{
1660995e53b9064a563b343a9bdcd50ecf88bf84becWind Yuan    StitchInfo stitch_info;
167680275749a2b29042b169e7b35cf4534a638115cYinhang Liu
168d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu    switch (res_mode) {
1690995e53b9064a563b343a9bdcd50ecf88bf84becWind Yuan    case StitchRes1080P: {
170d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.merge_width[0] = 56;
171d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.merge_width[1] = 56;
172d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu
173d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.crop[0].left = 96;
174d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.crop[0].right = 96;
175d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.crop[0].top = 0;
176d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.crop[0].bottom = 0;
177d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.crop[1].left = 96;
178d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.crop[1].right = 96;
179d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.crop[1].top = 0;
180d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.crop[1].bottom = 0;
181d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu
182d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.fisheye_info[0].center_x = 480.0f;
183d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.fisheye_info[0].center_y = 480.0f;
184d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.fisheye_info[0].wide_angle = 202.8f;
185d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.fisheye_info[0].radius = 480.0f;
186d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.fisheye_info[0].rotate_angle = -90.0f;
187d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.fisheye_info[1].center_x = 1440.0f;
188d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.fisheye_info[1].center_y = 480.0f;
189d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.fisheye_info[1].wide_angle = 202.8f;
190d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.fisheye_info[1].radius = 480.0f;
191d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.fisheye_info[1].rotate_angle = 89.4f;
19277853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        break;
19377853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    }
19477853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    case StitchRes1080P4: {
19572e7164bfc1e8a159f5fc3a05b29815c1cae3c26Junkai Wu        stitch_info.merge_width[0] = 288;
19672e7164bfc1e8a159f5fc3a05b29815c1cae3c26Junkai Wu        stitch_info.merge_width[1] = 288;
19772e7164bfc1e8a159f5fc3a05b29815c1cae3c26Junkai Wu        stitch_info.merge_width[2] = 288;
19872e7164bfc1e8a159f5fc3a05b29815c1cae3c26Junkai Wu        stitch_info.merge_width[3] = 288;
19977853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu
20072e7164bfc1e8a159f5fc3a05b29815c1cae3c26Junkai Wu        stitch_info.crop[0].left = 0;
20172e7164bfc1e8a159f5fc3a05b29815c1cae3c26Junkai Wu        stitch_info.crop[0].right = 0;
20277853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        stitch_info.crop[0].top = 0;
20377853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        stitch_info.crop[0].bottom = 0;
20472e7164bfc1e8a159f5fc3a05b29815c1cae3c26Junkai Wu        stitch_info.crop[1].left = 0;
20572e7164bfc1e8a159f5fc3a05b29815c1cae3c26Junkai Wu        stitch_info.crop[1].right = 0;
20677853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        stitch_info.crop[1].top = 0;
20777853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        stitch_info.crop[1].bottom = 0;
20872e7164bfc1e8a159f5fc3a05b29815c1cae3c26Junkai Wu        stitch_info.crop[2].left = 0;
20972e7164bfc1e8a159f5fc3a05b29815c1cae3c26Junkai Wu        stitch_info.crop[2].right = 0;
21077853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        stitch_info.crop[2].top = 0;
21177853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        stitch_info.crop[2].bottom = 0;
21272e7164bfc1e8a159f5fc3a05b29815c1cae3c26Junkai Wu        stitch_info.crop[3].left = 0;
21372e7164bfc1e8a159f5fc3a05b29815c1cae3c26Junkai Wu        stitch_info.crop[3].right = 0;
21477853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        stitch_info.crop[3].top = 0;
21577853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        stitch_info.crop[3].bottom = 0;
21677853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu
21777853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        stitch_info.fisheye_info[0].center_x = 640.0f;
21877853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        stitch_info.fisheye_info[0].center_y = 400.0f;
21977853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        stitch_info.fisheye_info[0].wide_angle = 120.0f;
22077853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        stitch_info.fisheye_info[0].radius = 640.0f;
22177853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        stitch_info.fisheye_info[0].rotate_angle = 0.0f;
22277853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        stitch_info.fisheye_info[1].center_x = 640.0f;
22377853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        stitch_info.fisheye_info[1].center_y = 400.0f;
22477853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        stitch_info.fisheye_info[1].wide_angle = 120.0f;
22577853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        stitch_info.fisheye_info[1].radius = 640.0f;
22677853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        stitch_info.fisheye_info[1].rotate_angle = 0.0f;
22777853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        stitch_info.fisheye_info[2].center_x = 640.0f;
22877853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        stitch_info.fisheye_info[2].center_y = 400.0f;
22977853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        stitch_info.fisheye_info[2].wide_angle = 120.0f;
23077853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        stitch_info.fisheye_info[2].radius = 640.0f;
23177853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        stitch_info.fisheye_info[2].rotate_angle = 0.0f;
23277853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        stitch_info.fisheye_info[3].center_x = 640.0f;
23377853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        stitch_info.fisheye_info[3].center_y = 400.0f;
23477853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        stitch_info.fisheye_info[3].wide_angle = 120.0f;
23577853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        stitch_info.fisheye_info[3].radius = 640.0f;
23677853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        stitch_info.fisheye_info[3].rotate_angle = 0.0f;
237d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        break;
238d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu    }
2390995e53b9064a563b343a9bdcd50ecf88bf84becWind Yuan    case StitchRes4K: {
240d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.merge_width[0] = 160;
241d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.merge_width[1] = 160;
242d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu
243d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.crop[0].left = 64;
244d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.crop[0].right = 64;
245d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.crop[0].top = 0;
246d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.crop[0].bottom = 0;
247d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.crop[1].left = 64;
248d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.crop[1].right = 64;
249d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.crop[1].top = 0;
250d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.crop[1].bottom = 0;
251d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu
252d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.fisheye_info[0].center_x = 1024.0f;
253d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.fisheye_info[0].center_y = 1024.0f;
254d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.fisheye_info[0].wide_angle = 195.0f;
255d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.fisheye_info[0].radius = 1040.0f;
256d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.fisheye_info[0].rotate_angle = 0.0f;
257d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu
258d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.fisheye_info[1].center_x = 3072.0f;
259d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.fisheye_info[1].center_y = 1016.0f;
260d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.fisheye_info[1].wide_angle = 192.0f;
261d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.fisheye_info[1].radius = 1040.0f;
262d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        stitch_info.fisheye_info[1].rotate_angle = 0.4f;
263d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        break;
264d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu    }
265d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu    default:
266d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        XCAM_LOG_DEBUG ("unknown reslution mode (%d)", res_mode);
267d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu        break;
268d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu    }
269680275749a2b29042b169e7b35cf4534a638115cYinhang Liu
270680275749a2b29042b169e7b35cf4534a638115cYinhang Liu    return stitch_info;
271680275749a2b29042b169e7b35cf4534a638115cYinhang Liu}
272680275749a2b29042b169e7b35cf4534a638115cYinhang Liu
273d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang LiuCLImage360Stitch::CLImage360Stitch (
274a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu    const SmartPtr<CLContext> &context, CLBlenderScaleMode scale_mode, SurroundMode surround_mode,
275a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu    StitchResMode res_mode, int fisheye_num, bool all_in_one_img)
276be505049e0d0cd218324c728b840652ac54bd19fWind Yuan    : CLMultiImageHandler (context, "CLImage360Stitch")
27752d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu    , _context (context)
278c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan    , _output_width (0)
279c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan    , _output_height (0)
280ee0b305f646fdab2011c9f1e4f2ca0bc275f33b2Yinhang Liu    , _scale_mode (scale_mode)
281a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu    , _surround_mode (surround_mode)
2822bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu    , _res_mode (res_mode)
283d502149dd9e27e8b6617ea5ee4659c5d75b3baf6Yinhang Liu    , _is_stitch_inited (false)
28477853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    , _fisheye_num (fisheye_num)
28577853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    , _all_in_one_img (all_in_one_img)
286c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan{
28752d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu#if HAVE_OPENCV
28877853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    for (int i = 0; i < fisheye_num; i++) {
28977853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        _feature_match[i] = new CVFeatureMatch ();
29077853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        XCAM_ASSERT (_feature_match[i].ptr ());
29177853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        _feature_match[i]->set_config (get_fm_default_config (res_mode));
29277853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        _feature_match[i]->set_fm_index (i);
29377853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    }
29452d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu#endif
29552d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu}
29652d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu
29752d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liubool
2980995e53b9064a563b343a9bdcd50ecf88bf84becWind YuanCLImage360Stitch::set_stitch_info (StitchInfo stitch_info)
2992bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu{
3002bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu    if (_is_stitch_inited) {
3012bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu        XCAM_LOG_WARNING ("stitching info was initialized and can't be set twice");
3022bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu        return false;
3032bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu    }
3042bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu
30577853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    for (int index = 0; index < _fisheye_num; ++index) {
3062bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu        _fisheye[index].handler->set_fisheye_info (stitch_info.fisheye_info[index]);
3072bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu    }
3082bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu
3092bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu    _stitch_info = stitch_info;
3102bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu    _is_stitch_inited = true;
3112bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu
3122bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu    return true;
3132bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu}
3142bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu
3150995e53b9064a563b343a9bdcd50ecf88bf84becWind YuanStitchInfo
3162bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang LiuCLImage360Stitch::get_stitch_info ()
3172bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu{
3182bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu    if (!_is_stitch_inited) {
3192bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu        XCAM_LOG_WARNING ("stitch-info was not initialized, return default parameters");
3202bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu        return get_default_stitch_info (_res_mode);
3212bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu    }
3222bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu
3232bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu    return _stitch_info;
3242bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu}
3252bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu
3262bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liubool
32752d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang LiuCLImage360Stitch::set_fisheye_handler (SmartPtr<CLFisheyeHandler> fisheye, int index)
32852d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu{
32977853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    XCAM_ASSERT (index < _fisheye_num);
33052d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu
331bacdd3eda84631066bb12247d57765c8047dcbbcYinhang Liu    _fisheye[index].handler = fisheye;
33252d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu    SmartPtr<CLImageHandler> handler = fisheye;
33352d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu    return add_image_handler (handler);
334c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan}
335c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan
336c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuanbool
33777853bb1f742485447495bf7f384a8abe8669c52Yinhang LiuCLImage360Stitch::set_blender (SmartPtr<CLBlender> blender, int idx)
338c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan{
33977853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    _blender[idx] = blender;
340c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan
341c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan    SmartPtr<CLImageHandler> handler = blender;
342c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan    return add_image_handler (handler);
343c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan}
344c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan
345a07666d12bfd94b076db1b966d2d10846622309dJunkai Wuvoid
346a07666d12bfd94b076db1b966d2d10846622309dJunkai WuCLImage360Stitch::set_fisheye_intrinsic (IntrinsicParameter intrinsic_param, int index)
347a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu{
348a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu    _fisheye[index].handler->set_intrinsic_param(intrinsic_param);
349a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu}
350a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu
351a07666d12bfd94b076db1b966d2d10846622309dJunkai Wuvoid
352a07666d12bfd94b076db1b966d2d10846622309dJunkai WuCLImage360Stitch::set_fisheye_extrinsic (ExtrinsicParameter extrinsic_param, int index)
353a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu{
354a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu    _fisheye[index].handler->set_extrinsic_param(extrinsic_param);
355a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu}
356a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu
3574a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liuconst BowlDataConfig &
3584a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang LiuCLImage360Stitch::get_fisheye_bowl_config (int index)
3594a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu{
3604a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu    XCAM_ASSERT (index < _fisheye_num);
3614a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu    return _fisheye[index].handler->get_bowl_config ();
3624a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu}
3634a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu
364c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuanbool
365c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind YuanCLImage360Stitch::set_image_overlap (const int idx, const Rect &overlap0, const Rect &overlap1)
366c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan{
36777853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    XCAM_ASSERT (idx < _fisheye_num);
368c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan    _overlaps[idx][0] = overlap0;
369c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan    _overlaps[idx][1] = overlap1;
370c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan    return true;
371c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan}
372c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan
37352d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liuvoid
374c13d2c54fb3648b27aa1f4b67887fbfe23b2272dYinhang LiuCLImage360Stitch::set_feature_match_ocl (bool fm_ocl)
375c13d2c54fb3648b27aa1f4b67887fbfe23b2272dYinhang Liu{
376c13d2c54fb3648b27aa1f4b67887fbfe23b2272dYinhang Liu#if HAVE_OPENCV
37777853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    for (int i = 0; i < _fisheye_num; i++) {
37877853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        _feature_match[i]->set_ocl (fm_ocl);
37977853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    }
380c13d2c54fb3648b27aa1f4b67887fbfe23b2272dYinhang Liu#else
381c13d2c54fb3648b27aa1f4b67887fbfe23b2272dYinhang Liu    XCAM_UNUSED (fm_ocl);
382c13d2c54fb3648b27aa1f4b67887fbfe23b2272dYinhang Liu    XCAM_LOG_WARNING ("non-OpenCV mode, failed to set ocl for feature match");
383c13d2c54fb3648b27aa1f4b67887fbfe23b2272dYinhang Liu#endif
384c13d2c54fb3648b27aa1f4b67887fbfe23b2272dYinhang Liu}
385c13d2c54fb3648b27aa1f4b67887fbfe23b2272dYinhang Liu
3862bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu#if HAVE_OPENCV
3872bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liuvoid
38877853bb1f742485447495bf7f384a8abe8669c52Yinhang LiuCLImage360Stitch::set_feature_match_config (const int idx, CVFMConfig config)
3892bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu{
39077853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    _feature_match[idx]->set_config (config);
3912bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu}
3922bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu
3932bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang LiuCVFMConfig
39477853bb1f742485447495bf7f384a8abe8669c52Yinhang LiuCLImage360Stitch::get_feature_match_config (const int idx)
3952bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu{
39677853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    return _feature_match[idx]->get_config ();
3972bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu}
3982bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu#endif
3992bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu
400c13d2c54fb3648b27aa1f4b67887fbfe23b2272dYinhang Liuvoid
4016b5f71042b969ae41362e07660181a676685702bYinhang LiuCLImage360Stitch::calc_fisheye_initial_info (SmartPtr<VideoBuffer> &output)
40252d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu{
40352d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu    const VideoBufferInfo &out_info = output->get_video_info ();
40477853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu
405a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu    if(_surround_mode == SphereView) {
406a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu        uint32_t fisheye_width_sum = out_info.width;
407a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu        for (int i = 0; i < _fisheye_num; i++) {
408a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu            fisheye_width_sum += _stitch_info.merge_width[i] + _stitch_info.crop[i].left + _stitch_info.crop[i].right;
409a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu        }
410a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu        _fisheye[0].width = fisheye_width_sum / _fisheye_num;
411a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu        _fisheye[0].width = XCAM_ALIGN_UP (_fisheye[0].width, 16);
412a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu        _fisheye[0].height = out_info.height + _stitch_info.crop[0].top + _stitch_info.crop[0].bottom;
413a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu        XCAM_LOG_INFO (
414a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu            "fisheye correction output size width:%d height:%d",
415a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu            _fisheye[0].width, _fisheye[0].height);
416a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu
417a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu        for (int i = 1; i < _fisheye_num; i++) {
418a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu            _fisheye[i].width = _fisheye[0].width;
419a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu            _fisheye[i].height = _fisheye[0].height;
420a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu        }
42177853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu
422a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu        float max_dst_longitude, max_dst_latitude;
423a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu        for (int i = 0; i < _fisheye_num; ++i) {
424a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu            max_dst_latitude = (_stitch_info.fisheye_info[i].wide_angle > 180.0f) ?
425a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu                               180.0f : _stitch_info.fisheye_info[i].wide_angle;
426a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu            max_dst_longitude = max_dst_latitude * _fisheye[i].width / _fisheye[i].height;
427bacdd3eda84631066bb12247d57765c8047dcbbcYinhang Liu
428a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu            _fisheye[i].handler->set_dst_range (max_dst_longitude, max_dst_latitude);
429a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu            _fisheye[i].handler->set_output_size (_fisheye[i].width, _fisheye[i].height);
430a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu        }
431a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu    } else {
432a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu        _fisheye[0].height = out_info.height + _stitch_info.crop[0].top + _stitch_info.crop[0].bottom;
433a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu
434a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu        float view_angle[XCAM_STITCH_FISHEYE_MAX_NUM];
435a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu
436d6703decad390380e8f8706c35a04d829e93a571Wind Yuan        view_angle[0] = 68.0f;
437d6703decad390380e8f8706c35a04d829e93a571Wind Yuan        _fisheye[0].width = view_angle[0] / 360.0f * out_info.width;
43872e7164bfc1e8a159f5fc3a05b29815c1cae3c26Junkai Wu        _fisheye[0].width = XCAM_ALIGN_UP (_fisheye[0].width, 32);
43972e7164bfc1e8a159f5fc3a05b29815c1cae3c26Junkai Wu
440d6703decad390380e8f8706c35a04d829e93a571Wind Yuan        view_angle[1] = 152.0f;
441d6703decad390380e8f8706c35a04d829e93a571Wind Yuan        _fisheye[1].width = view_angle[1] / 360.0f * out_info.width;
44272e7164bfc1e8a159f5fc3a05b29815c1cae3c26Junkai Wu        _fisheye[1].width = XCAM_ALIGN_UP (_fisheye[1].width, 32);
44372e7164bfc1e8a159f5fc3a05b29815c1cae3c26Junkai Wu
444d6703decad390380e8f8706c35a04d829e93a571Wind Yuan        view_angle[2] = 68.0f;
445d6703decad390380e8f8706c35a04d829e93a571Wind Yuan        _fisheye[2].width = view_angle[2] / 360.0f * out_info.width;
44672e7164bfc1e8a159f5fc3a05b29815c1cae3c26Junkai Wu        _fisheye[2].width = XCAM_ALIGN_UP (_fisheye[2].width, 32);
44772e7164bfc1e8a159f5fc3a05b29815c1cae3c26Junkai Wu
448d6703decad390380e8f8706c35a04d829e93a571Wind Yuan        view_angle[3] = 152.0f;
449d6703decad390380e8f8706c35a04d829e93a571Wind Yuan        _fisheye[3].width = view_angle[3] / 360.0f * out_info.width;
45072e7164bfc1e8a159f5fc3a05b29815c1cae3c26Junkai Wu        _fisheye[3].width = XCAM_ALIGN_UP (_fisheye[3].width, 32);
451a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu
452a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu        XCAM_LOG_INFO (
453a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu            "fisheye correction output size width:%d height:%d",
454a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu            _fisheye[0].width, _fisheye[0].height);
455a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu
456a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu        BowlDataConfig bowl_data_config[XCAM_STITCH_FISHEYE_MAX_NUM];
457a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu
4586b4feff8f245e415b3c33122c6b9bdd64289cd4aJunkai Wu        bowl_data_config[0].angle_start = -view_angle[0] / 2;
4596b4feff8f245e415b3c33122c6b9bdd64289cd4aJunkai Wu        bowl_data_config[0].angle_end = view_angle[0] / 2;
460a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu
461a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu        for (int i = 1; i < _fisheye_num; i++) {
462a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu            _fisheye[i].height = _fisheye[0].height;
463e9a207124bdbf7dc7127d9d68cec89ed860195c7Junkai Wu            float angle_center = 360.0f / _fisheye_num * i;
4646b4feff8f245e415b3c33122c6b9bdd64289cd4aJunkai Wu            bowl_data_config[i].angle_start = angle_center - view_angle[i] / 2;
4656b4feff8f245e415b3c33122c6b9bdd64289cd4aJunkai Wu            bowl_data_config[i].angle_end = angle_center + view_angle[i] / 2;
466a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu        }
467a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu
468a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu        for(int i = 0; i < _fisheye_num; i++) {
469a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu            _fisheye[i].handler->set_bowl_config(bowl_data_config[i]);
470a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu            _fisheye[i].handler->set_output_size (_fisheye[i].width, _fisheye[i].height);
471a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu        }
4726b4feff8f245e415b3c33122c6b9bdd64289cd4aJunkai Wu
4736b4feff8f245e415b3c33122c6b9bdd64289cd4aJunkai Wu        for(int i = 0; i < _fisheye_num; i++) {
4746b4feff8f245e415b3c33122c6b9bdd64289cd4aJunkai Wu            _stitch_info.merge_width[i] = XCAM_ALIGN_UP((uint32_t)(20.0f / 360.0f * out_info.width), 32);
4756b4feff8f245e415b3c33122c6b9bdd64289cd4aJunkai Wu        }
47652d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu    }
47752d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu}
47852d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu
47952d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liuvoid
48052d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang LiuCLImage360Stitch::update_image_overlap ()
48152d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu{
4822bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu    static bool is_merge_info_inited = false;
4832bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu    if (!is_merge_info_inited) {
48477853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        int idx_next = 1;
48577853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        for (int i = 0; i < _fisheye_num; i++) {
48677853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            idx_next = (i == (_fisheye_num - 1)) ? 0 : (i + 1);
48777853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu
48877853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            _img_merge_info[i].left.pos_x = _stitch_info.crop[i].left;
48977853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            _img_merge_info[i].left.pos_y = _stitch_info.crop[i].top;
49077853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            _img_merge_info[i].left.width = _stitch_info.merge_width[i];
49177853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            _img_merge_info[i].left.height = _fisheye[i].height - _stitch_info.crop[i].top
49277853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu                                             - _stitch_info.crop[i].bottom;
49377853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu
49477853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            _img_merge_info[i].right.pos_x = _fisheye[i].width - _stitch_info.crop[i].right
49577853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu                                             - _stitch_info.merge_width[idx_next];
49677853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            _img_merge_info[i].right.pos_y = _stitch_info.crop[i].top;
49777853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            _img_merge_info[i].right.width = _stitch_info.merge_width[idx_next];
49877853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            _img_merge_info[i].right.height = _fisheye[i].height - _stitch_info.crop[i].top
49977853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu                                              - _stitch_info.crop[i].bottom;
50077853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        }
5012bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu
5022bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu        is_merge_info_inited = true;
50352d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu    }
50452d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu
50577853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    for (int i = 0; i < _fisheye_num; i++) {
50677853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        set_image_overlap (i, _img_merge_info[i].left, _img_merge_info[i].right);
50777853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    }
50852d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu}
50952d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu
510c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind YuanXCamReturn
511c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind YuanCLImage360Stitch::prepare_buffer_pool_video_info (
51252d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu    const VideoBufferInfo &input, VideoBufferInfo &output)
513c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan{
514680275749a2b29042b169e7b35cf4534a638115cYinhang Liu    if (_output_width == 0 || _output_height == 0) {
51577853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        XCAM_LOG_ERROR ("incorrect output size: width:%d height:%d", _output_width, _output_height);
51677853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        return XCAM_RETURN_ERROR_PARAM;
517680275749a2b29042b169e7b35cf4534a638115cYinhang Liu    }
518c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan
519af9df6be52ea20d58d6ad17fc770d207407880e6Wind Yuan    // aligned at least XCAM_CL_BLENDER_ALIGNMENT_X
520af9df6be52ea20d58d6ad17fc770d207407880e6Wind Yuan    uint32_t aligned_width = XCAM_MAX (16, XCAM_CL_BLENDER_ALIGNMENT_X);
521c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan    output.init (
522680275749a2b29042b169e7b35cf4534a638115cYinhang Liu        input.format, _output_width, _output_height,
523680275749a2b29042b169e7b35cf4534a638115cYinhang Liu        XCAM_ALIGN_UP(_output_width, aligned_width), XCAM_ALIGN_UP(_output_height, 16));
524680275749a2b29042b169e7b35cf4534a638115cYinhang Liu
525c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan    return XCAM_RETURN_NO_ERROR;
526c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan}
527c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan
528c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind YuanXCamReturn
529be505049e0d0cd218324c728b840652ac54bd19fWind YuanCLImage360Stitch::ensure_fisheye_parameters (
5306b5f71042b969ae41362e07660181a676685702bYinhang Liu    SmartPtr<VideoBuffer> &input, SmartPtr<VideoBuffer> &output)
53152d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu{
53252d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu    static bool is_fisheye_inited = false;
533be505049e0d0cd218324c728b840652ac54bd19fWind Yuan
53452d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu    if (!is_fisheye_inited) {
53552d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu        calc_fisheye_initial_info (output);
53652d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu        is_fisheye_inited = true;
53752d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu    }
53852d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu
5396b5f71042b969ae41362e07660181a676685702bYinhang Liu    SmartPtr<VideoBuffer> pre_buf;
5406b5f71042b969ae41362e07660181a676685702bYinhang Liu    SmartPtr<VideoBuffer> cur_buf = input;
54177853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    for (int i = 0; i < _fisheye_num; i++) {
54277853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        if (!_fisheye[i].pool.ptr ())
54377853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            create_buffer_pool (_fisheye[i].pool, _fisheye[i].width, _fisheye[i].height);
54477853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu
5456b5f71042b969ae41362e07660181a676685702bYinhang Liu        _fisheye[i].buf = _fisheye[i].pool->get_buffer (_fisheye[i].pool);
54677853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        XCAM_ASSERT (_fisheye[i].buf.ptr ());
54777853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu
54877853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        XCamReturn ret = ensure_handler_parameters (_fisheye[i].handler, cur_buf, _fisheye[i].buf);
54977853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        STITCH_CHECK (ret, "execute fisheye prepare_parameters failed");
55077853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu
55177853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        if (!_all_in_one_img) {
55277853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            pre_buf = cur_buf;
5536b5f71042b969ae41362e07660181a676685702bYinhang Liu            cur_buf = cur_buf->find_typed_attach<VideoBuffer> ();
55477853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            if (!cur_buf.ptr () && (i != (_fisheye_num - 1))) {
55577853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu                XCAM_LOG_ERROR ("conflicting attached buffers and fisheye number");
55677853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu                return XCAM_RETURN_ERROR_PARAM;
55777853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            }
55877853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            pre_buf->detach_buffer (cur_buf);
55977853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        }
56077853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    }
561be505049e0d0cd218324c728b840652ac54bd19fWind Yuan
56252d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu    return XCAM_RETURN_NO_ERROR;
56352d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu}
56452d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu
56552d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang LiuXCamReturn
566ee0b305f646fdab2011c9f1e4f2ca0bc275f33b2Yinhang LiuCLImage360Stitch::prepare_global_scale_blender_parameters (
5676b5f71042b969ae41362e07660181a676685702bYinhang Liu    SmartPtr<VideoBuffer> &input0, SmartPtr<VideoBuffer> &input1, SmartPtr<VideoBuffer> &output,
56877853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    int idx, int idx_next, int &cur_start_pos)
569c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan{
570c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan    const VideoBufferInfo &in0_info = input0->get_video_info ();
571c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan    const VideoBufferInfo &in1_info = input1->get_video_info ();
572c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan    const VideoBufferInfo &out_info = output->get_video_info ();
573c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan
574c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan    XCAM_ASSERT (in0_info.height == in1_info.height);
575c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan    XCAM_ASSERT (in0_info.width <= out_info.width && in1_info.width <= out_info.width);
576c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan
57777853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    Rect left_lap = get_image_overlap (idx, 1);
57877853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    Rect right_lap = get_image_overlap (idx_next, 0);
57977853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu
580af9df6be52ea20d58d6ad17fc770d207407880e6Wind Yuan    int left_img_mid = XCAM_ALIGN_DOWN (in0_info.width / 2, XCAM_CL_BLENDER_ALIGNMENT_X);
581af9df6be52ea20d58d6ad17fc770d207407880e6Wind Yuan    int right_img_mid = XCAM_ALIGN_DOWN (in1_info.width / 2, XCAM_CL_BLENDER_ALIGNMENT_X);
58277853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu
58377853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    int32_t prev_pos;
58477853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    prev_pos = left_lap.pos_x;
585af9df6be52ea20d58d6ad17fc770d207407880e6Wind Yuan    left_lap.pos_x = XCAM_ALIGN_AROUND (left_lap.pos_x, XCAM_CL_BLENDER_ALIGNMENT_X);
586af9df6be52ea20d58d6ad17fc770d207407880e6Wind Yuan    left_lap.width = XCAM_ALIGN_UP (left_lap.width, XCAM_CL_BLENDER_ALIGNMENT_X);
58777853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    right_lap.pos_x += left_lap.pos_x - prev_pos;
588af9df6be52ea20d58d6ad17fc770d207407880e6Wind Yuan    right_lap.pos_x = XCAM_ALIGN_AROUND (right_lap.pos_x, XCAM_CL_BLENDER_ALIGNMENT_X);
58977853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    right_lap.width = left_lap.width;
59077853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu
59177853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    Rect area;
59277853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    area.pos_y = left_lap.pos_y;
59377853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    area.height = left_lap.height;
59477853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    area.pos_x = left_img_mid;
59577853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    area.width = left_lap.pos_x + left_lap.width - left_img_mid;
59677853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    _blender[idx]->set_input_valid_area (area, 0);
59777853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu
59877853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    area.pos_y = right_lap.pos_y;
59977853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    area.height = right_lap.height;
60077853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    area.pos_x = right_lap.pos_x;
60177853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    area.width = right_img_mid - right_lap.pos_x;
60277853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    _blender[idx]->set_input_valid_area (area, 1);
60377853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu
60477853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    Rect out_merge_window;
60577853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    out_merge_window.width = left_lap.width;
60677853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    out_merge_window.pos_x = cur_start_pos + (left_lap.pos_x - left_img_mid);
60777853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    out_merge_window.pos_y = 0;
60877853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    out_merge_window.height = out_info.height;
60977853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    _blender[idx]->set_merge_window (out_merge_window);
61077853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu
61177853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    _blender[idx]->set_input_merge_area (left_lap, 0);
61277853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    _blender[idx]->set_input_merge_area (right_lap, 1);
61377853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu
61477853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    cur_start_pos += left_lap.pos_x - left_img_mid + right_img_mid - right_lap.pos_x;
61577853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    return XCAM_RETURN_NO_ERROR;
616c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan}
617c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan
618c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind YuanXCamReturn
619ee0b305f646fdab2011c9f1e4f2ca0bc275f33b2Yinhang LiuCLImage360Stitch::prepare_local_scale_blender_parameters (
6206b5f71042b969ae41362e07660181a676685702bYinhang Liu    SmartPtr<VideoBuffer> &input0, SmartPtr<VideoBuffer> &input1, SmartPtr<VideoBuffer> &output, int idx, int idx_next)
621ee0b305f646fdab2011c9f1e4f2ca0bc275f33b2Yinhang Liu{
622ee0b305f646fdab2011c9f1e4f2ca0bc275f33b2Yinhang Liu    const VideoBufferInfo &in0_info = input0->get_video_info ();
623ee0b305f646fdab2011c9f1e4f2ca0bc275f33b2Yinhang Liu    const VideoBufferInfo &in1_info = input1->get_video_info ();
624ee0b305f646fdab2011c9f1e4f2ca0bc275f33b2Yinhang Liu    const VideoBufferInfo &out_info = output->get_video_info ();
625ee0b305f646fdab2011c9f1e4f2ca0bc275f33b2Yinhang Liu
626ee0b305f646fdab2011c9f1e4f2ca0bc275f33b2Yinhang Liu    XCAM_ASSERT (in0_info.height == in1_info.height);
627ee0b305f646fdab2011c9f1e4f2ca0bc275f33b2Yinhang Liu    XCAM_ASSERT (in0_info.width <= out_info.width && in1_info.width <= out_info.width);
628ee0b305f646fdab2011c9f1e4f2ca0bc275f33b2Yinhang Liu
62977853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    Rect left_lap = get_image_overlap (idx, 1);
63077853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    Rect right_lap = get_image_overlap (idx_next, 0);
63177853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu
632af9df6be52ea20d58d6ad17fc770d207407880e6Wind Yuan    int left_img_mid = XCAM_ALIGN_DOWN (in0_info.width / 2, XCAM_CL_BLENDER_ALIGNMENT_X);
633af9df6be52ea20d58d6ad17fc770d207407880e6Wind Yuan    int right_img_mid = XCAM_ALIGN_DOWN (in1_info.width / 2, XCAM_CL_BLENDER_ALIGNMENT_X);
634af9df6be52ea20d58d6ad17fc770d207407880e6Wind Yuan    int cur_start_pos = XCAM_ALIGN_DOWN (out_info.width / _fisheye_num * idx, XCAM_CL_BLENDER_ALIGNMENT_X);
635af9df6be52ea20d58d6ad17fc770d207407880e6Wind Yuan    int merge_std_width = XCAM_ALIGN_DOWN (out_info.width / _fisheye_num, XCAM_CL_BLENDER_ALIGNMENT_X);
63677853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu
63777853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    int32_t prev_pos;
63877853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    prev_pos = left_lap.pos_x;
639af9df6be52ea20d58d6ad17fc770d207407880e6Wind Yuan    left_lap.pos_x = XCAM_ALIGN_AROUND (left_lap.pos_x, XCAM_CL_BLENDER_ALIGNMENT_X);
640af9df6be52ea20d58d6ad17fc770d207407880e6Wind Yuan    left_lap.width = XCAM_ALIGN_UP (left_lap.width, XCAM_CL_BLENDER_ALIGNMENT_X);
64177853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    right_lap.pos_x += left_lap.pos_x - prev_pos;
642af9df6be52ea20d58d6ad17fc770d207407880e6Wind Yuan    right_lap.pos_x = XCAM_ALIGN_AROUND (right_lap.pos_x, XCAM_CL_BLENDER_ALIGNMENT_X);
64377853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    right_lap.width = left_lap.width;
64477853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu
64577853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    Rect area;
64677853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    area.pos_y = left_lap.pos_y;
64777853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    area.height = left_lap.height;
64877853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    area.pos_x = left_img_mid;
64977853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    area.width = left_lap.pos_x + left_lap.width - left_img_mid;
65077853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    _blender[idx]->set_input_valid_area (area, 0);
65177853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu
65277853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    area.pos_y = right_lap.pos_y;
65377853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    area.height = right_lap.height;
65477853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    area.pos_x = right_lap.pos_x;
65577853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    area.width = right_img_mid - right_lap.pos_x;
65677853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    _blender[idx]->set_input_valid_area (area, 1);
65777853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu
65877853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    Rect out_merge_window;
65977853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    int delta_width = merge_std_width - (right_img_mid - right_lap.pos_x) - (left_lap.pos_x - left_img_mid);
66077853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    out_merge_window.width = left_lap.width + delta_width;
66177853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    out_merge_window.pos_x = cur_start_pos + (left_lap.pos_x - left_img_mid);
66277853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    out_merge_window.pos_y = 0;
66377853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    out_merge_window.height = out_info.height;
66477853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    _blender[idx]->set_merge_window (out_merge_window);
66577853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu
66677853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    _blender[idx]->set_input_merge_area (left_lap, 0);
66777853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    _blender[idx]->set_input_merge_area (right_lap, 1);
66877853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu
66977853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    return XCAM_RETURN_NO_ERROR;
670ee0b305f646fdab2011c9f1e4f2ca0bc275f33b2Yinhang Liu}
671ee0b305f646fdab2011c9f1e4f2ca0bc275f33b2Yinhang Liu
672bacdd3eda84631066bb12247d57765c8047dcbbcYinhang Liubool
673bacdd3eda84631066bb12247d57765c8047dcbbcYinhang LiuCLImage360Stitch::create_buffer_pool (SmartPtr<BufferPool> &buf_pool, uint32_t width, uint32_t height)
6740c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu{
6750c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    VideoBufferInfo buf_info;
67652d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu    width = XCAM_ALIGN_UP (width, 16);
67752d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu    buf_info.init (V4L2_PIX_FMT_NV12, width, height,
67852d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu                   XCAM_ALIGN_UP (width, 16), XCAM_ALIGN_UP (height, 16));
6790c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu
680cff638b59385036cbc91873a9965282c8861a306Yinhang Liu    buf_pool = new CLVideoBufferPool ();
6810c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    XCAM_ASSERT (buf_pool.ptr ());
6820c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    buf_pool->set_video_info (buf_info);
683bacdd3eda84631066bb12247d57765c8047dcbbcYinhang Liu    if (!buf_pool->reserve (6)) {
684bacdd3eda84631066bb12247d57765c8047dcbbcYinhang Liu        XCAM_LOG_ERROR ("CLImage360Stitch init buffer pool failed");
685bacdd3eda84631066bb12247d57765c8047dcbbcYinhang Liu        return false;
6860c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    }
6870c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu
688bacdd3eda84631066bb12247d57765c8047dcbbcYinhang Liu    return true;
6890c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu}
6900c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu
6910c3b87fb4f0706485c03bef97800d8840d236354Yinhang LiuXCamReturn
6926b5f71042b969ae41362e07660181a676685702bYinhang LiuCLImage360Stitch::reset_buffer_info (SmartPtr<VideoBuffer> &input)
6930c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu{
6940c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    VideoBufferInfo reset_info;
6950c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    const VideoBufferInfo &buf_info = input->get_video_info ();
6960c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu
69777853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    uint32_t reset_width = 0;
69877853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    for (int i = 0; i < _fisheye_num; i++) {
69977853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        Rect img_left = get_image_overlap (i, 0);
70077853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        Rect img_right = get_image_overlap (i, 1);
70177853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu
70277853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        reset_width += img_right.pos_x - img_left.pos_x;
70377853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    }
7040c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu
705af9df6be52ea20d58d6ad17fc770d207407880e6Wind Yuan    reset_width = XCAM_ALIGN_UP (reset_width, XCAM_CL_BLENDER_ALIGNMENT_X);
7060c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    reset_info.init (buf_info.format, reset_width, buf_info.height,
7070c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu                     buf_info.aligned_width, buf_info.aligned_height);
7080c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu
7090c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    input->set_video_info (reset_info);
7100c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    return XCAM_RETURN_NO_ERROR;
7110c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu}
7120c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu
713ee0b305f646fdab2011c9f1e4f2ca0bc275f33b2Yinhang LiuXCamReturn
7146b5f71042b969ae41362e07660181a676685702bYinhang LiuCLImage360Stitch::prepare_parameters (SmartPtr<VideoBuffer> &input, SmartPtr<VideoBuffer> &output)
715c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan{
716ee0b305f646fdab2011c9f1e4f2ca0bc275f33b2Yinhang Liu    XCamReturn ret = XCAM_RETURN_NO_ERROR;
7172bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu    if (!_is_stitch_inited)
7182bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu        set_stitch_info (get_default_stitch_info (_res_mode));
719ee0b305f646fdab2011c9f1e4f2ca0bc275f33b2Yinhang Liu
720be505049e0d0cd218324c728b840652ac54bd19fWind Yuan    ret = ensure_fisheye_parameters (input, output);
721be505049e0d0cd218324c728b840652ac54bd19fWind Yuan    STITCH_CHECK (ret, "ensure fisheye parameters failed");
722bacdd3eda84631066bb12247d57765c8047dcbbcYinhang Liu
7232bacd01edad31590fb37d1fc0c9bf4722418ae46Yinhang Liu    update_image_overlap ();
7240c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    if (_scale_mode == CLBlenderScaleLocal) {
72577853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        int idx_next = 1;
72677853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        for (int i = 0; i < _fisheye_num; i++) {
72777853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            idx_next = (i == (_fisheye_num - 1)) ? 0 : (i + 1);
72877853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu
72977853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            ret = prepare_local_scale_blender_parameters (
730af9df6be52ea20d58d6ad17fc770d207407880e6Wind Yuan                      _fisheye[i].buf, _fisheye[idx_next].buf, output, i, idx_next);
73177853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            STITCH_CHECK (ret, "prepare local scale blender parameters failed");
73277853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu
73377853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            _fisheye[i].buf->attach_buffer (_fisheye[idx_next].buf);
73477853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            ret = ensure_handler_parameters (_blender[i], _fisheye[i].buf, output);
73577853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            STITCH_CHECK (ret, "blender: execute ensure_parameters failed");
73677853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            _fisheye[i].buf->detach_buffer (_fisheye[idx_next].buf);
73777853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        }
738be505049e0d0cd218324c728b840652ac54bd19fWind Yuan    } else { //global scale
73952d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu        const VideoBufferInfo &buf_info = output->get_video_info ();
740bacdd3eda84631066bb12247d57765c8047dcbbcYinhang Liu        if (!_scale_buf_pool.ptr ())
741bacdd3eda84631066bb12247d57765c8047dcbbcYinhang Liu            create_buffer_pool (_scale_buf_pool, buf_info.width + XCAM_BLENDER_GLOBAL_SCALE_EXT_WIDTH, buf_info.height);
7426b5f71042b969ae41362e07660181a676685702bYinhang Liu        SmartPtr<VideoBuffer> scale_input = _scale_buf_pool->get_buffer (_scale_buf_pool);
74352d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu        XCAM_ASSERT (scale_input.ptr ());
74452d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu
74577853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        int idx_next = 1;
74677853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        int cur_start_pos = 0;
74777853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        for (int i = 0; i < _fisheye_num; i++) {
74877853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            idx_next = (i == (_fisheye_num - 1)) ? 0 : (i + 1);
74977853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu
75077853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            ret = prepare_global_scale_blender_parameters (
75177853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu                      _fisheye[i].buf, _fisheye[idx_next].buf, scale_input, i, idx_next, cur_start_pos);
75277853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            STITCH_CHECK (ret, "prepare global scale blender parameters failed");
75352d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu
75477853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            _fisheye[i].buf->attach_buffer (_fisheye[idx_next].buf);
75577853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            ret = ensure_handler_parameters (_blender[i], _fisheye[i].buf, scale_input);
75677853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            STITCH_CHECK (ret, "blender: execute ensure_parameters failed");
75777853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            _fisheye[i].buf->detach_buffer (_fisheye[idx_next].buf);
75877853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        }
7590c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu
760be505049e0d0cd218324c728b840652ac54bd19fWind Yuan        reset_buffer_info (scale_input);
761be505049e0d0cd218324c728b840652ac54bd19fWind Yuan        _scale_global_input = scale_input;
762be505049e0d0cd218324c728b840652ac54bd19fWind Yuan        _scale_global_output = output;
7630c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    }
7640c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu
76552d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu    return XCAM_RETURN_NO_ERROR;
76652d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu}
76752d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu
768c13d2c54fb3648b27aa1f4b67887fbfe23b2272dYinhang LiuXCamReturn
7696b5f71042b969ae41362e07660181a676685702bYinhang LiuCLImage360Stitch::execute_done (SmartPtr<VideoBuffer> &output)
77052d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu{
771c13d2c54fb3648b27aa1f4b67887fbfe23b2272dYinhang Liu#if HAVE_OPENCV
77277853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    for (int i = 0; i < _fisheye_num; i++) {
77377853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        if (!_feature_match[i]->is_ocl_path ()) {
77477853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            get_context ()->finish ();
77577853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            break;
77677853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        }
77777853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    }
778c13d2c54fb3648b27aa1f4b67887fbfe23b2272dYinhang Liu#endif
779c13d2c54fb3648b27aa1f4b67887fbfe23b2272dYinhang Liu
780be505049e0d0cd218324c728b840652ac54bd19fWind Yuan    _scale_global_input.release ();
781be505049e0d0cd218324c728b840652ac54bd19fWind Yuan    _scale_global_output.release ();
782be505049e0d0cd218324c728b840652ac54bd19fWind Yuan
783c13d2c54fb3648b27aa1f4b67887fbfe23b2272dYinhang Liu    return CLMultiImageHandler::execute_done (output);
78452d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu}
78552d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu
78652d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liustatic void
787b0926c34382d0823424a5bb212b5ae6ecfdd7ae6zongwaveconvert_to_stitch_rect (Rect xcam_rect, Rect &stitch_rect)
78852d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu{
789b0926c34382d0823424a5bb212b5ae6ecfdd7ae6zongwave    stitch_rect.pos_x = xcam_rect.pos_x;
790b0926c34382d0823424a5bb212b5ae6ecfdd7ae6zongwave    stitch_rect.pos_y = xcam_rect.pos_y + xcam_rect.height / 3;
791b0926c34382d0823424a5bb212b5ae6ecfdd7ae6zongwave    stitch_rect.width = xcam_rect.width;
792b0926c34382d0823424a5bb212b5ae6ecfdd7ae6zongwave    stitch_rect.height = xcam_rect.height / 3;
79352d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu}
79452d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu
79552d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liustatic void
796b0926c34382d0823424a5bb212b5ae6ecfdd7ae6zongwaveconvert_to_xcam_rect (Rect stitch_rect, Rect &xcam_rect)
79752d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu{
798b0926c34382d0823424a5bb212b5ae6ecfdd7ae6zongwave    xcam_rect.pos_x = stitch_rect.pos_x;
799b0926c34382d0823424a5bb212b5ae6ecfdd7ae6zongwave    xcam_rect.width = stitch_rect.width;
80052d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu}
801b0926c34382d0823424a5bb212b5ae6ecfdd7ae6zongwave
80252d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu
80352d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang LiuXCamReturn
80452d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang LiuCLImage360Stitch::sub_handler_execute_done (SmartPtr<CLImageHandler> &handler)
80552d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu{
80652d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu#if HAVE_OPENCV
80752d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu    XCAM_ASSERT (handler.ptr ());
80852d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu
80977853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    if (handler.ptr () == _fisheye[_fisheye_num - 1].handler.ptr ()) {
81077853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        int idx_next = 1;
811b0926c34382d0823424a5bb212b5ae6ecfdd7ae6zongwave        Rect crop_left, crop_right;
81277853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu
81377853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        for (int i = 0; i < _fisheye_num; i++) {
81477853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            idx_next = (i == (_fisheye_num - 1)) ? 0 : (i + 1);
815c13d2c54fb3648b27aa1f4b67887fbfe23b2272dYinhang Liu
816b0926c34382d0823424a5bb212b5ae6ecfdd7ae6zongwave            convert_to_stitch_rect (_img_merge_info[i].right, crop_left);
817b0926c34382d0823424a5bb212b5ae6ecfdd7ae6zongwave            convert_to_stitch_rect (_img_merge_info[idx_next].left, crop_right);
818c13d2c54fb3648b27aa1f4b67887fbfe23b2272dYinhang Liu
81977853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            _feature_match[i]->optical_flow_feature_match (
82077853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu                _fisheye[i].buf, _fisheye[idx_next].buf, crop_left, crop_right, _fisheye[i].width);
82152d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu
82277853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            convert_to_xcam_rect (crop_left, _img_merge_info[i].right);
82377853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu            convert_to_xcam_rect (crop_right, _img_merge_info[idx_next].left);
82477853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        }
82552d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu    }
82652d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu#else
82752d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu    XCAM_UNUSED (handler);
82852d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu#endif
82952d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu
83052d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu    return XCAM_RETURN_NO_ERROR;
8310c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu}
8320c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu
8330c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liustatic SmartPtr<CLImageKernel>
834be505049e0d0cd218324c728b840652ac54bd19fWind Yuancreate_blender_global_scale_kernel (
835be505049e0d0cd218324c728b840652ac54bd19fWind Yuan    const SmartPtr<CLContext> &context,
836be505049e0d0cd218324c728b840652ac54bd19fWind Yuan    SmartPtr<CLImage360Stitch> &stitch,
837be505049e0d0cd218324c728b840652ac54bd19fWind Yuan    bool is_uv)
8380c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu{
8390c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    char transform_option[1024];
8400c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    snprintf (transform_option, sizeof(transform_option), "-DPYRAMID_UV=%d", is_uv ? 1 : 0);
8410c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu
842be505049e0d0cd218324c728b840652ac54bd19fWind Yuan    static const XCamKernelInfo &kernel_info = {
8430c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu        "kernel_pyramid_scale",
8440c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu#include "kernel_gauss_lap_pyramid.clx"
8450c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu        , 0
8460c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    };
8470c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu
8480c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    SmartPtr<CLImageKernel> kernel;
849be505049e0d0cd218324c728b840652ac54bd19fWind Yuan    kernel = new CLBlenderGlobalScaleKernel (context, stitch, is_uv);
8500c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    XCAM_ASSERT (kernel.ptr ());
8510c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    XCAM_FAIL_RETURN (
8520c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu        ERROR,
8530c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu        kernel->build_kernel (kernel_info, transform_option) == XCAM_RETURN_NO_ERROR,
8540c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu        NULL,
8550c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu        "load blender global scaling kernel(%s) failed", is_uv ? "UV" : "Y");
8560c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu
8570c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    return kernel;
858c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan}
859c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan
860c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind YuanSmartPtr<CLImageHandler>
861be505049e0d0cd218324c728b840652ac54bd19fWind Yuancreate_image_360_stitch (
862be505049e0d0cd218324c728b840652ac54bd19fWind Yuan    const SmartPtr<CLContext> &context, bool need_seam,
863a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu    CLBlenderScaleMode scale_mode, bool fisheye_map, bool need_lsc, SurroundMode surround_mode,
864a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu    StitchResMode res_mode, int fisheye_num, bool all_in_one_img)
865c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan{
866c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan    const int layer = 2;
867c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan    const bool need_uv = true;
86852d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu    SmartPtr<CLFisheyeHandler> fisheye;
86977853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    SmartPtr<CLBlender> blender;
87077853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    SmartPtr<CLImage360Stitch> stitch = new CLImage360Stitch (
871a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu        context, scale_mode, surround_mode, res_mode, fisheye_num, all_in_one_img);
872c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan    XCAM_ASSERT (stitch.ptr ());
873c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan
87477853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    for (int index = 0; index < fisheye_num; ++index) {
875a07666d12bfd94b076db1b966d2d10846622309dJunkai Wu        fisheye = create_fisheye_handler (context, surround_mode, fisheye_map, need_lsc).dynamic_cast_ptr<CLFisheyeHandler> ();
87652d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu        XCAM_FAIL_RETURN (ERROR, fisheye.ptr (), NULL, "image_360_stitch create fisheye handler failed");
87752d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu        fisheye->disable_buf_pool (true);
87852d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu        stitch->set_fisheye_handler (fisheye, index);
87952d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu    }
88052d45b347e46f480662e5233aec21ec8ca4e6b84Yinhang Liu
88177853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    for (int index = 0; index < fisheye_num; ++index) {
88277853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        blender = create_pyramid_blender (context, layer, need_uv, need_seam, scale_mode).dynamic_cast_ptr<CLBlender> ();
88377853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        XCAM_FAIL_RETURN (ERROR, blender.ptr (), NULL, "image_360_stitch create blender failed");
88477853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        blender->disable_buf_pool (true);
88577853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu        stitch->set_blender (blender, index);
88677853bb1f742485447495bf7f384a8abe8669c52Yinhang Liu    }
887c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan
8880c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    if (scale_mode == CLBlenderScaleGlobal) {
8890c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu        int max_plane = need_uv ? 2 : 1;
8900c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu        bool uv_status[2] = {false, true};
8910c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu        for (int plane = 0; plane < max_plane; ++plane) {
892be505049e0d0cd218324c728b840652ac54bd19fWind Yuan            SmartPtr<CLImageKernel> kernel = create_blender_global_scale_kernel (context, stitch, uv_status[plane]);
8930c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu            XCAM_FAIL_RETURN (ERROR, kernel.ptr (), NULL, "create blender global scaling kernel failed");
8940c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu            stitch->add_kernel (kernel);
8950c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu        }
8960c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu    }
8970c3b87fb4f0706485c03bef97800d8840d236354Yinhang Liu
898c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan    return stitch;
899c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan}
900c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan
901c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan}
902c9e84b47af5e6634ec7fd2d7ba830b75d8501760Wind Yuan
903