1515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan/*
2515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan * cl_utils.cpp - CL Utilities
3515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan *
4515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan *  Copyright (c) 2016 Intel Corporation
5515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan *
6515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan * Licensed under the Apache License, Version 2.0 (the "License");
7515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan * you may not use this file except in compliance with the License.
8515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan * You may obtain a copy of the License at
9515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan *
10515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan *      http://www.apache.org/licenses/LICENSE-2.0
11515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan *
12515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan * Unless required by applicable law or agreed to in writing, software
13515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan * distributed under the License is distributed on an "AS IS" BASIS,
14515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan * See the License for the specific language governing permissions and
16515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan * limitations under the License.
17515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan *
18515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan * Author: Wind Yuan <feng.yuan@intel.com>
19515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan */
20515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan
21515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan#include "cl_utils.h"
22525a24f142571b66dd477e00958941bdf177bfe9Yinhang Liu#include "image_file_handle.h"
23d656676b8d13980755e6220a3e857ba3c5f5f798Yinhang Liu#if HAVE_LIBDRM
24d656676b8d13980755e6220a3e857ba3c5f5f798Yinhang Liu#include "intel/cl_intel_context.h"
25d656676b8d13980755e6220a3e857ba3c5f5f798Yinhang Liu#include "intel/cl_va_memory.h"
26d656676b8d13980755e6220a3e857ba3c5f5f798Yinhang Liu#endif
27515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan
28515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuannamespace XCam {
29515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan
304a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liustruct NV12Pixel {
314a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu    float x_pos;
324a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu    float y_pos;
334a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu
344a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu    float y;
354a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu    float u;
364a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu    float v;
374a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu
384a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu    NV12Pixel ()
394a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu        : x_pos (0.0f), y_pos (0.0f)
404a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu        , y (0.0f), u (0.0f), v (0.0f)
414a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu    {}
424a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu};
434a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu
444a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liustatic inline void
454a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liuclamp (float &value, float min, float max)
464a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu{
474a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu    value = (value < min) ? min : ((value > max) ? max : value);
484a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu}
494a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu
50515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuanbool
51525a24f142571b66dd477e00958941bdf177bfe9Yinhang Liudump_image (SmartPtr<CLImage> image, const char *file_name)
52515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan{
53515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan    XCAM_ASSERT (file_name);
54515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan
55515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan    const CLImageDesc &desc = image->get_image_desc ();
56515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan    void *ptr = NULL;
57515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan    size_t origin[3] = {0, 0, 0};
58515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan    size_t region[3] = {desc.width, desc.height, 1};
59515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan    size_t row_pitch;
60515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan    size_t slice_pitch;
61515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan
62674d67d5ea78070c591f6ae229639ebfb8fa4952Yinhang Liu    XCamReturn ret = image->enqueue_map (ptr, origin, region, &row_pitch, &slice_pitch, CL_MAP_READ);
63afa54115907d1a8ab2da4c8cf9907c66fee46e35Wind Yuan    XCAM_FAIL_RETURN (ERROR, xcam_ret_is_ok (ret), false, "dump image failed in enqueue_map");
64515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan    XCAM_ASSERT (ptr);
65515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan    XCAM_ASSERT (row_pitch == desc.row_pitch);
66515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan    uint8_t *buf_start = (uint8_t *)ptr;
67515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan    uint32_t width = image->get_pixel_bytes () * desc.width;
68515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan
69515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan    FILE *fp = fopen (file_name, "wb");
70515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan    XCAM_FAIL_RETURN (ERROR, fp, false, "open file(%s) failed", file_name);
71515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan
72515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan    for (uint32_t i = 0; i < desc.height; ++i) {
73515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan        uint8_t *buf_line = buf_start + row_pitch * i;
74515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan        fwrite (buf_line, width, 1, fp);
75515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan    }
76515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan    image->enqueue_unmap (ptr);
77515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan    fclose (fp);
78515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan    XCAM_LOG_INFO ("write image:%s\n", file_name);
79515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan    return true;
80515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan}
81515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan
826b5f71042b969ae41362e07660181a676685702bYinhang LiuSmartPtr<CLBuffer>
836b5f71042b969ae41362e07660181a676685702bYinhang Liuconvert_to_clbuffer (
846b5f71042b969ae41362e07660181a676685702bYinhang Liu    const SmartPtr<CLContext> &context,
8587008d9b47e08936ce6ee1e396ea7a218d451f00Yinhang Liu    const SmartPtr<VideoBuffer> &buf)
866b5f71042b969ae41362e07660181a676685702bYinhang Liu{
876b5f71042b969ae41362e07660181a676685702bYinhang Liu    SmartPtr<CLBuffer> cl_buf;
886b5f71042b969ae41362e07660181a676685702bYinhang Liu
898d73ad32492403d20d505a9eeac8fa2a1e88cf0cYinhang Liu    SmartPtr<CLVideoBuffer> cl_video_buf = buf.dynamic_cast_ptr<CLVideoBuffer> ();
908d73ad32492403d20d505a9eeac8fa2a1e88cf0cYinhang Liu    if (cl_video_buf.ptr ()) {
9119bd67df1077142002c8dc1677a67443dc0a138aYinhang Liu        cl_buf = cl_video_buf;
926987f2ba7c159a8916a876f2b4d7505a34c97f10Yinhang Liu    }
936987f2ba7c159a8916a876f2b4d7505a34c97f10Yinhang Liu#if HAVE_LIBDRM
946987f2ba7c159a8916a876f2b4d7505a34c97f10Yinhang Liu    else {
958d73ad32492403d20d505a9eeac8fa2a1e88cf0cYinhang Liu        SmartPtr<DrmBoBuffer> bo_buf = buf.dynamic_cast_ptr<DrmBoBuffer> ();
96d656676b8d13980755e6220a3e857ba3c5f5f798Yinhang Liu        SmartPtr<CLIntelContext> ctx = context.dynamic_cast_ptr<CLIntelContext> ();
97d656676b8d13980755e6220a3e857ba3c5f5f798Yinhang Liu        XCAM_ASSERT (bo_buf.ptr () && ctx.ptr ());
98d656676b8d13980755e6220a3e857ba3c5f5f798Yinhang Liu
99d656676b8d13980755e6220a3e857ba3c5f5f798Yinhang Liu        cl_buf = new CLVaBuffer (ctx, bo_buf);
1008d73ad32492403d20d505a9eeac8fa2a1e88cf0cYinhang Liu    }
1016987f2ba7c159a8916a876f2b4d7505a34c97f10Yinhang Liu#else
1026987f2ba7c159a8916a876f2b4d7505a34c97f10Yinhang Liu    XCAM_UNUSED (context);
1036987f2ba7c159a8916a876f2b4d7505a34c97f10Yinhang Liu#endif
1046b5f71042b969ae41362e07660181a676685702bYinhang Liu
1050199a5e905b67ce7eaf6c69f97f810a5a6159e39Wind Yuan    XCAM_FAIL_RETURN (WARNING, cl_buf.ptr (), NULL, "convert to clbuffer failed");
1066b5f71042b969ae41362e07660181a676685702bYinhang Liu    return cl_buf;
1076b5f71042b969ae41362e07660181a676685702bYinhang Liu}
1086b5f71042b969ae41362e07660181a676685702bYinhang Liu
1096b5f71042b969ae41362e07660181a676685702bYinhang LiuSmartPtr<CLImage>
1106b5f71042b969ae41362e07660181a676685702bYinhang Liuconvert_to_climage (
1116b5f71042b969ae41362e07660181a676685702bYinhang Liu    const SmartPtr<CLContext> &context,
1126b5f71042b969ae41362e07660181a676685702bYinhang Liu    SmartPtr<VideoBuffer> &buf,
1136b5f71042b969ae41362e07660181a676685702bYinhang Liu    const CLImageDesc &desc,
1146b5f71042b969ae41362e07660181a676685702bYinhang Liu    uint32_t offset,
1156b5f71042b969ae41362e07660181a676685702bYinhang Liu    cl_mem_flags flags)
1166b5f71042b969ae41362e07660181a676685702bYinhang Liu{
1176b5f71042b969ae41362e07660181a676685702bYinhang Liu    SmartPtr<CLImage> cl_image;
1186b5f71042b969ae41362e07660181a676685702bYinhang Liu
1198d73ad32492403d20d505a9eeac8fa2a1e88cf0cYinhang Liu    SmartPtr<CLVideoBuffer> cl_video_buf = buf.dynamic_cast_ptr<CLVideoBuffer> ();
1208d73ad32492403d20d505a9eeac8fa2a1e88cf0cYinhang Liu    if (cl_video_buf.ptr ()) {
121cff638b59385036cbc91873a9965282c8861a306Yinhang Liu        SmartPtr<CLBuffer> cl_buf;
122cff638b59385036cbc91873a9965282c8861a306Yinhang Liu
123cff638b59385036cbc91873a9965282c8861a306Yinhang Liu        if (offset == 0) {
124cff638b59385036cbc91873a9965282c8861a306Yinhang Liu            cl_buf = cl_video_buf;
125cff638b59385036cbc91873a9965282c8861a306Yinhang Liu        } else {
126cff638b59385036cbc91873a9965282c8861a306Yinhang Liu            uint32_t row_pitch = CLImage::calculate_pixel_bytes (desc.format) *
1276b4feff8f245e415b3c33122c6b9bdd64289cd4aJunkai Wu                                 XCAM_ALIGN_UP (desc.width, XCAM_CL_IMAGE_ALIGNMENT_X);
128cff638b59385036cbc91873a9965282c8861a306Yinhang Liu            uint32_t size = row_pitch * desc.height;
129cff638b59385036cbc91873a9965282c8861a306Yinhang Liu
130cff638b59385036cbc91873a9965282c8861a306Yinhang Liu            cl_buf = new CLSubBuffer (context, cl_video_buf, flags, offset, size);
131cff638b59385036cbc91873a9965282c8861a306Yinhang Liu        }
132cff638b59385036cbc91873a9965282c8861a306Yinhang Liu
1338d73ad32492403d20d505a9eeac8fa2a1e88cf0cYinhang Liu        cl_image = new CLImage2D (context, desc, flags, cl_buf);
1346987f2ba7c159a8916a876f2b4d7505a34c97f10Yinhang Liu    }
1356987f2ba7c159a8916a876f2b4d7505a34c97f10Yinhang Liu#if HAVE_LIBDRM
1366987f2ba7c159a8916a876f2b4d7505a34c97f10Yinhang Liu    else {
1378d73ad32492403d20d505a9eeac8fa2a1e88cf0cYinhang Liu        SmartPtr<DrmBoBuffer> bo_buf = buf.dynamic_cast_ptr<DrmBoBuffer> ();
138d656676b8d13980755e6220a3e857ba3c5f5f798Yinhang Liu        SmartPtr<CLIntelContext> ctx = context.dynamic_cast_ptr<CLIntelContext> ();
139d656676b8d13980755e6220a3e857ba3c5f5f798Yinhang Liu        XCAM_ASSERT (bo_buf.ptr () && ctx.ptr ());
140d656676b8d13980755e6220a3e857ba3c5f5f798Yinhang Liu
141d656676b8d13980755e6220a3e857ba3c5f5f798Yinhang Liu        cl_image = new CLVaImage (ctx, bo_buf, desc, offset);
1428d73ad32492403d20d505a9eeac8fa2a1e88cf0cYinhang Liu    }
1436987f2ba7c159a8916a876f2b4d7505a34c97f10Yinhang Liu#endif
1446b5f71042b969ae41362e07660181a676685702bYinhang Liu
1456b5f71042b969ae41362e07660181a676685702bYinhang Liu    XCAM_FAIL_RETURN (WARNING, cl_image.ptr (), NULL, "convert to climage failed");
1466b5f71042b969ae41362e07660181a676685702bYinhang Liu    return cl_image;
1476b5f71042b969ae41362e07660181a676685702bYinhang Liu}
1486b5f71042b969ae41362e07660181a676685702bYinhang Liu
1494a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang LiuXCamReturn
1504a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liuconvert_nv12_mem_to_video_buffer (
1514a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu    void *nv12_mem, uint32_t width, uint32_t height, uint32_t row_pitch, uint32_t offset_uv,
1524a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu    SmartPtr<VideoBuffer> &buf)
1534a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu{
1544a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu    XCAM_ASSERT (nv12_mem);
1554a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu    XCAM_ASSERT (row_pitch >= width);
1564a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu
1574a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu    VideoBufferPlanarInfo planar;
1584a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu    const VideoBufferInfo info = buf->get_video_info ();
159afa54115907d1a8ab2da4c8cf9907c66fee46e35Wind Yuan    XCAM_FAIL_RETURN (
160afa54115907d1a8ab2da4c8cf9907c66fee46e35Wind Yuan        DEBUG, (width == info.width) && (height == info.height), XCAM_RETURN_ERROR_PARAM,
161afa54115907d1a8ab2da4c8cf9907c66fee46e35Wind Yuan        "convert mem to video buffer failed since image sizes are not matched.");
1624a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu
1634a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu    uint8_t *out_mem = buf->map ();
1644a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu    XCAM_FAIL_RETURN (ERROR, out_mem, XCAM_RETURN_ERROR_MEM, "map buffer failed");
1654a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu
1664a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu    uint8_t *src = (uint8_t *)nv12_mem;
1674a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu    uint8_t *dest = NULL;
1684a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu    for (uint32_t index = 0; index < info.components; index++) {
1694a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu        info.get_planar_info (planar, index);
1704a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu
1714a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu        dest = out_mem + info.offsets[index];
1724a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu        for (uint32_t i = 0; i < planar.height; i++) {
1734a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu            memcpy (dest, src, width);
1744a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu            src += row_pitch;
1754a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu            dest += info.strides[index];
1764a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu        }
1774a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu
1784a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu        src = (uint8_t *)nv12_mem + offset_uv;
1794a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu    }
1804a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu
1814a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu    buf->unmap ();
1824a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu    return XCAM_RETURN_NO_ERROR;
1834a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu}
1844a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu
185cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai WuXCamReturn
186cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wuinterpolate_pixel_value (
187cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    uint8_t* stitch_mem,
188cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    float image_coord_x, float image_coord_y,
189cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    float &y, float &u, float &v,
190cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    const VideoBufferInfo& stitch_info)
191cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu{
192cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    XCAM_ASSERT (image_coord_y < stitch_info.height && image_coord_x < stitch_info.width);
193cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
194cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    uint8_t y00, y01, y10, y11;
195cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    uint8_t u00, u01, u10, u11;
196cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    uint8_t v00, v01, v10, v11;
197cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
198cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    uint32_t x0 = (uint32_t) image_coord_x;
199cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    uint32_t x1 = (x0 < stitch_info.width - 1) ? (x0 + 1) : x0;
200cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    uint32_t y0 = (uint32_t) image_coord_y;
201cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    uint32_t y1 = (y0 < stitch_info.height - 1) ? (y0 + 1) : y0;
2024a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu
203cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    float rate00 = (x0 + 1 - image_coord_x) * (y0 + 1 - image_coord_y);
204cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    float rate01 = (x0 + 1 - image_coord_x) * (image_coord_y - y0);
205cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    float rate10 = (image_coord_x - x0) * (y0 + 1 - image_coord_y);
206cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    float rate11 = (image_coord_x - x0) * (image_coord_y - y0);
2074a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu
208cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    y00 = stitch_mem[y0 * stitch_info.strides[0] + x0];
209cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    y01 = stitch_mem[y1 * stitch_info.strides[0] + x0];
210cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    y10 = stitch_mem[y0 * stitch_info.strides[0] + x1];
211cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    y11 = stitch_mem[y1 * stitch_info.strides[0] + x1];
212cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
213cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    u00 = stitch_mem[stitch_info.offsets[1] + y0 / 2 * stitch_info.strides[1] + XCAM_ALIGN_DOWN (x0, 2)];
214cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    u01 = stitch_mem[stitch_info.offsets[1] + y1 / 2 * stitch_info.strides[1] + XCAM_ALIGN_DOWN (x0, 2)];
215cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    u10 = stitch_mem[stitch_info.offsets[1] + y0 / 2 * stitch_info.strides[1] + XCAM_ALIGN_DOWN (x1, 2)];
216cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    u11 = stitch_mem[stitch_info.offsets[1] + y1 / 2 * stitch_info.strides[1] + XCAM_ALIGN_DOWN (x1, 2)];
217cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
218cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    v00 = stitch_mem[stitch_info.offsets[1] + y0 / 2 * stitch_info.strides[1] + XCAM_ALIGN_DOWN (x0, 2) + 1];
219cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    v01 = stitch_mem[stitch_info.offsets[1] + y1 / 2 * stitch_info.strides[1] + XCAM_ALIGN_DOWN (x0, 2) + 1];
220cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    v10 = stitch_mem[stitch_info.offsets[1] + y0 / 2 * stitch_info.strides[1] + XCAM_ALIGN_DOWN (x1, 2) + 1];
221cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    v11 = stitch_mem[stitch_info.offsets[1] + y1 / 2 * stitch_info.strides[1] + XCAM_ALIGN_DOWN (x1, 2) + 1];
222cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
223cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    y = y00 * rate00 + y01 * rate01 + y10 * rate10 + y11 * rate11;
224cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    u = u00 * rate00 + u01 * rate01 + u10 * rate10 + u11 * rate11;
225cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    v = v00 * rate00 + v01 * rate01 + v10 * rate10 + v11 * rate11;
226cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
227cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    return XCAM_RETURN_NO_ERROR;
2284a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu}
2294a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu
230cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai WuXCamReturn
231cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wumap_to_specific_view (
232cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    uint8_t *specific_view_mem, uint8_t* stitch_mem,
233cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    uint32_t row, uint32_t col,
234cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    float image_coord_x, float image_coord_y,
235cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    const VideoBufferInfo& specific_view_info, const VideoBufferInfo& stitch_info)
2364a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu{
237cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    XCAM_ASSERT (row < specific_view_info.height && col < specific_view_info.width);
238cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
239cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    float y, u, v;
2404a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu
241cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    interpolate_pixel_value (stitch_mem, image_coord_x, image_coord_y, y, u, v, stitch_info);
2424a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu
243cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    uint32_t y_index = row * specific_view_info.strides[0] + col;
244cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    uint32_t u_index = specific_view_info.offsets[1] + row / 2 * specific_view_info.strides[1] + XCAM_ALIGN_DOWN (col, 2);
245cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
246cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    specific_view_mem[y_index] = (uint8_t)y;
247cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    specific_view_mem[u_index] = (uint8_t)u;
248cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    specific_view_mem[u_index + 1] = (uint8_t)v;
249cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
250cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    return XCAM_RETURN_NO_ERROR;
2514a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu}
2524a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu
2534a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang LiuXCamReturn
254cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wugenerate_topview_map_table (
255cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    const VideoBufferInfo &stitch_info,
256cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    const BowlDataConfig &config,
257fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan    std::vector<PointFloat2> &map_table,
258cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    int width, int height)
2594a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu{
260cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    int center_x = width / 2;
261cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    int center_y = height / 2;
2624a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu
263cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    float show_width_mm = 5000.0f;
264cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    float length_per_pixel = show_width_mm / height;
2654a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu
266fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan    map_table.resize (height * width);
267fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan
268cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    for(int row = 0; row < height; row++) {
269cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu        for(int col = 0; col < width; col++) {
270fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan            PointFloat3 world;
271fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan            world.x = (col - center_x) * length_per_pixel;
272fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan            world.y = (center_y - row) * length_per_pixel;
273fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan            world.z = 0.0f;
2744a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu
275fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan            PointFloat2 image_pos =
276fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan                bowl_view_coords_to_image (config, world, stitch_info.width, stitch_info.height);
277cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
278fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan            map_table[row * width + col] = image_pos;
279cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu        }
280cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    }
281cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
282cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    return XCAM_RETURN_NO_ERROR;
283cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu}
284cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
285cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai WuXCamReturn
286cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wugenerate_rectifiedview_map_table (
287cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    const VideoBufferInfo &stitch_info,
288cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    const BowlDataConfig &config,
289fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan    std::vector<PointFloat2> &map_table,
290cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    float angle_start, float angle_end,
291cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    int width, int height)
292cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu{
293cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    float center_x = width / 2;
294cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
295cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    float focal_plane_dist = 6000.0f;
296cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
297cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    float angle_center = (angle_start + angle_end) / 2.0f;
298cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    float theta = degree2radian((angle_end - angle_start)) / 2.0f;
299cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    float length_per_pixel_x = 2 * focal_plane_dist * tan (theta) / width;
300cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
301cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    float fov_up = degree2radian (20.0f);
302cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    float fov_down = degree2radian (35.0f);
303cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
304cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    float length_per_pixel_y = (focal_plane_dist * tan (fov_up) + focal_plane_dist * tan (fov_down)) / height;
305cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
306cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    float center_y = tan (fov_up) / (tan (fov_up) + tan (fov_down)) * height;
307cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
308fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan    PointFloat3 world_pos;
309cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    float plane_center_coords[3];
310cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
311cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    plane_center_coords[0] = focal_plane_dist * cos (degree2radian (angle_center));
312cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    plane_center_coords[1] = -focal_plane_dist * sin (degree2radian (angle_center));
313cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    plane_center_coords[2] = 0.0f;
314cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
315fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan    map_table.resize (width * height);
316fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan
317cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    for (int row = 0; row < height; row++) {
318cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu        for (int col = 0; col < width; col++) {
319cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu            float plane_point_coords[3];
320cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu            plane_point_coords[0] = (center_x - col) * length_per_pixel_x * cos (PI / 2 - degree2radian (angle_center)) + plane_center_coords[0];
321cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu            plane_point_coords[1] = (center_x - col) * length_per_pixel_x * sin (PI / 2 - degree2radian (angle_center)) + plane_center_coords[1];
322cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu            plane_point_coords[2] = (center_y - row) * length_per_pixel_y + plane_center_coords[2];
323cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
324cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu            float rate_xz, rate_yz;
325cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu            if (XCAM_DOUBLE_EQUAL_AROUND (plane_point_coords[2], 0.0f) && XCAM_DOUBLE_EQUAL_AROUND (plane_point_coords[1], 0.0f)) {
326fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan                world_pos.x = config.a;
327fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan                world_pos.y = 0;
328fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan                world_pos.z = 0;
329cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu            } else if (XCAM_DOUBLE_EQUAL_AROUND (plane_point_coords[2], 0.0f)) {
330fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan                world_pos.z = 0.0f;
331cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
332cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu                float rate_xy = plane_point_coords[0] / plane_point_coords[1];
333cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu                float square_y = 1 / (rate_xy * rate_xy / (config.a * config.a) + 1 / (config.b * config.b));
334fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan                world_pos.y = (plane_point_coords[1] > 0) ? sqrt (square_y) : -sqrt (square_y);
335fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan                world_pos.x = rate_xy * world_pos.y;
336cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu            } else {
337cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu                rate_xz = plane_point_coords[0] / plane_point_coords[2];
338cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu                rate_yz = plane_point_coords[1] / plane_point_coords[2];
339cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
340cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu                float square_z = 1 / (rate_xz * rate_xz / (config.a * config.a) + rate_yz * rate_yz / (config.b * config.b) + 1 / (config.c * config.c));
341fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan                world_pos.z = (plane_point_coords[2] > 0) ? sqrt (square_z) : -sqrt (square_z);
342fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan                world_pos.z = (world_pos.z <= -config.center_z) ? -config.center_z : world_pos.z;
343fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan                world_pos.x = rate_xz * world_pos.z;
344fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan                world_pos.y = rate_yz * world_pos.z;
345cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu            }
346cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
347fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan            world_pos.z += config.center_z;
348cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
349fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan            PointFloat2 image_coord =
350fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan                bowl_view_coords_to_image (config, world_pos, stitch_info.width, stitch_info.height);
351cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
352fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan            map_table[row * width + col] = image_coord;
353cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu        }
354cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    }
355cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
356cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    return XCAM_RETURN_NO_ERROR;
357cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu}
358cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
359cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai WuXCamReturn
360cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wusample_generate_top_view (
361cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    SmartPtr<VideoBuffer> &stitch_buf,
362cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    SmartPtr<VideoBuffer> top_view_buf,
363cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    const BowlDataConfig &config,
364fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan    std::vector<PointFloat2> &map_table)
365cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu{
366cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    const VideoBufferInfo top_view_info = top_view_buf->get_video_info ();
367cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    const VideoBufferInfo stitch_info = stitch_buf->get_video_info ();
368cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
369cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    int top_view_resolution_w = top_view_buf->get_video_info ().width;
370cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    int top_view_resolution_h = top_view_buf->get_video_info ().height;
371cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
372fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan    if((int)map_table.size () != top_view_resolution_w * top_view_resolution_h) {
373fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan        map_table.clear ();
374cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu        generate_topview_map_table (stitch_info, config, map_table, top_view_resolution_w, top_view_resolution_h);
375cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    }
376cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
377cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    uint8_t *top_view_mem = NULL;
378cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    uint8_t *stitch_mem = NULL;
379cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    top_view_mem = top_view_buf->map ();
380cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    stitch_mem = stitch_buf->map ();
381cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
382cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    for(int row = 0; row < top_view_resolution_h; row++) {
383cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu        for(int col = 0; col < top_view_resolution_w; col++) {
384fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan            PointFloat2 image_coord = map_table[row * top_view_resolution_w + col];
385cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
386fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan            map_to_specific_view (top_view_mem, stitch_mem, row, col, image_coord.x, image_coord.y, top_view_info, stitch_info);
387cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu        }
388cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    }
389cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
390cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    top_view_buf->unmap();
391cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    stitch_buf->unmap();
392cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
393cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    return XCAM_RETURN_NO_ERROR;
394cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu}
395cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
396cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai WuXCamReturn
397cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wusample_generate_rectified_view (
398cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    SmartPtr<VideoBuffer> &stitch_buf,
399cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    SmartPtr<VideoBuffer> rectified_view_buf,
400cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    const BowlDataConfig &config,
401cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    float angle_start, float angle_end,
402fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan    std::vector<PointFloat2> &map_table)
403cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu{
404cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    const VideoBufferInfo rectified_view_info = rectified_view_buf->get_video_info ();
405cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    const VideoBufferInfo stitch_info = stitch_buf->get_video_info ();
406cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
407cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    int rectified_view_resolution_w = rectified_view_buf->get_video_info ().width;
408cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    int rectified_view_resolution_h = rectified_view_buf->get_video_info ().height;
409cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
410fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan    if((int)map_table.size () != rectified_view_resolution_w * rectified_view_resolution_h) {
411fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan        map_table.clear ();
412cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu        generate_rectifiedview_map_table (stitch_info, config, map_table, angle_start, angle_end, rectified_view_resolution_w, rectified_view_resolution_h);
413cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    }
414cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
415cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    uint8_t *rectified_view_mem = NULL;
416cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    uint8_t *stitch_mem = NULL;
417cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    rectified_view_mem = rectified_view_buf->map ();
418cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    stitch_mem = stitch_buf->map ();
419cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
420cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    for(int row = 0; row < rectified_view_resolution_h; row++) {
421cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu        for(int col = 0; col < rectified_view_resolution_w; col++) {
422fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan            PointFloat2 image_coord = map_table[row * rectified_view_resolution_w + col];
423cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu
424fb20d2157b6e1e6f14bf82fd8e8fc6f8d916a88aWind Yuan            map_to_specific_view (rectified_view_mem, stitch_mem, row, col, image_coord.x, image_coord.y, rectified_view_info, stitch_info);
425cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu        }
426cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    }
4274a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu
428cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    rectified_view_buf->unmap();
429cc03b1cbc43f0918fd131aad9a0c6dd475aa58abJunkai Wu    stitch_buf->unmap();
4304a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu
4314a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu    return XCAM_RETURN_NO_ERROR;
4324a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu}
4334a0e91f560e001aaa44191543dcd4f1b03eda89cYinhang Liu
434515bf82fae90f7babed70ca38b9840039d2f81f7Wind Yuan}
435