hc
2025-02-14 bbb9540dc49f70f6b703d1c8d1b85fa5f602d86e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
/*
 * image_processor.cpp - 2D Image Process Hardware Implementation
 *
 *  Copyright (c) 2021 Rockchip Electronics Co., Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
#include "image_processor.h"
 
#include <xcam_log.h>
 
#include <map>
#include <memory>
#include <string>
 
#ifdef HAS_LIBRGA
#ifdef HAS_LIBDL
#include <dlfcn.h>
#endif
#include "rga/im2d.h"
#include "rga/rga.h"
#endif
 
namespace RkCam {
 
#ifdef HAS_LIBRGA
#define RGA_LIBRARY_NAME "librga.so"
 
using fp_imresize_t   = int (*)(const rga_buffer_t src, rga_buffer_t dst, double fx, double fy,
                              int interpolation, int sync);
using fp_imcrop_t     = int (*)(const rga_buffer_t src, rga_buffer_t dst, im_rect rect, int sync);
using fp_imcvtcolor_t = int (*)(rga_buffer_t src, rga_buffer_t dst, int sfmt, int dfmt, int mode,
                                int sync);
using fp_imrotate_t   = int (*)(const rga_buffer_t src, rga_buffer_t dst, int rotation, int sync);
using fp_imflip_t     = int (*)(const rga_buffer_t src, rga_buffer_t dst, int mode, int sync);
using fp_imcopy_t     = int (*)(const rga_buffer_t src, rga_buffer_t dst, int sync);
using fp_wrapbuffer_virtualaddr_t  = rga_buffer_t (*)(void* vir_addr, int width, int height,
                                                     int wstride, int hstride, int format);
using fp_wrapbuffer_physicaladdr_t = rga_buffer_t (*)(void* phy_addr, int width, int height,
                                                      int wstride, int hstride, int format);
using fp_wrapbuffer_fd_t = rga_buffer_t (*)(int fd, int width, int height, int wstride, int hstride,
                                            int format);
 
struct rga_ops_s {
    fp_imresize_t imresize_t;
    fp_imcrop_t imcrop_t;
    fp_imcvtcolor_t imcvtcolor_t;
    fp_imrotate_t imrotate_t;
    fp_imflip_t imflip_t;
    fp_imcopy_t imcopy_t;
    fp_wrapbuffer_virtualaddr_t wrapbuffer_virtualaddr_t;
    fp_wrapbuffer_physicaladdr_t wrapbuffer_physicaladdr_t;
    fp_wrapbuffer_fd_t wrapbuffer_fd_t;
};
 
class RGAOperator : public ImageOperator {
 public:
    RGAOperator() : ImageOperator("rga"){};
 
    virtual ~RGAOperator() {
#ifdef HAS_LIBDL
        if (handle_) {
            dlclose(handle_);
        }
#endif
    };
 
    RGAOperator(const RGAOperator&) = delete;
    RGAOperator& operator=(const RGAOperator&) = delete;
 
    int WrapFormat(rk_aiq_format_t fmt) {
        std::map<rk_aiq_format_t, int> rga_format_map = {
            {RK_PIX_FMT_Y4, RK_FORMAT_Y4},
            {RK_PIX_FMT_GREY, RK_FORMAT_YCbCr_400},
            {RK_PIX_FMT_NV12, RK_FORMAT_YCbCr_420_SP},
            {RK_PIX_FMT_NV21, RK_FORMAT_YCrCb_420_SP},
            {RK_PIX_FMT_NV16, RK_FORMAT_YCbCr_422_SP},
            {RK_PIX_FMT_NV61, RK_FORMAT_YCrCb_422_SP},
            {RK_PIX_FMT_YVYU, RK_FORMAT_YVYU_422},
            {RK_PIX_FMT_YVU420, RK_FORMAT_YVYU_420},
            {RK_PIX_FMT_YUYV, RK_FORMAT_YUYV_422},
            {RK_PIX_FMT_UYVY, RK_FORMAT_UYVY_422},
        };
        auto it = rga_format_map.find(fmt);
        if (it != rga_format_map.end()) {
            return it->second;
        }
        return -1;
    }
 
    XCamReturn resolve_symbles(void) {
#ifdef HAS_LIBDL
        char* error;
        handle_ = dlopen(RGA_LIBRARY_NAME, RTLD_LAZY);
        if (!handle_) {
            LOGE("Failed to dlopen librga.so : %s", dlerror());
            return XCAM_RETURN_ERROR_UNKNOWN;
        }
        dlerror();
        rga_ops_.wrapbuffer_virtualaddr_t =
            (fp_wrapbuffer_virtualaddr_t)dlsym(handle_, "wrapbuffer_virtualaddr_t");
        error = dlerror();
        if (error != NULL) {
            LOGE("Failed to resolve symble wrapbuffer_virtualaddr_t: %s", error);
        }
 
        rga_ops_.wrapbuffer_physicaladdr_t =
            (fp_wrapbuffer_physicaladdr_t)dlsym(handle_, "wrapbuffer_physicaladdr_t");
        error = dlerror();
        if (error != NULL) {
            LOGE("Failed to resolve symble wrapbuffer_physicaladdr_t: %s", error);
        }
 
        rga_ops_.wrapbuffer_fd_t = (fp_wrapbuffer_fd_t)dlsym(handle_, "wrapbuffer_fd_t");
        error                    = dlerror();
        if (error != NULL) {
            LOGE("Failed to resolve symble wrapbuffer_fd_t : %s", error);
        }
 
        rga_ops_.imresize_t = (fp_imresize_t)dlsym(handle_, "imresize_t");
        error               = dlerror();
        if (error != NULL) {
            LOGE("Failed to resolve symble imreize_t : %s", error);
        }
 
        rga_ops_.imcrop_t = (fp_imcrop_t)dlsym(handle_, "imcrop_t");
        error             = dlerror();
        if (error != NULL) {
            LOGE("Failed to resolve symble imcrop_t: %s", error);
        }
 
        rga_ops_.imcvtcolor_t = (fp_imcvtcolor_t)dlsym(handle_, "imcvtcolor_t");
        error                 = dlerror();
        if (error != NULL) {
            LOGE("Failed to resolve symble imcvtcolor_t : %s", error);
        }
 
        rga_ops_.imrotate_t = (fp_imrotate_t)dlsym(handle_, "imrotate_t");
        error               = dlerror();
        if (error != NULL) {
            LOGE("Failed to resolve symble imrotete_t : %s", error);
        }
 
        rga_ops_.imflip_t = (fp_imflip_t)dlsym(handle_, "imflip_t");
        error             = dlerror();
        if (error != NULL) {
            LOGE("Failed to resolve symble imflip_t : %s", error);
        }
 
        rga_ops_.imcopy_t = (fp_imcopy_t)dlsym(handle_, "imcopy_t");
        error             = dlerror();
        if (error != NULL) {
            LOGE("Failed to resolve symble imcopy_t : %s", error);
        }
#endif  // HAS_LIBDL
 
        return XCAM_RETURN_NO_ERROR;
    };
 
    virtual XCamReturn resize(const img_buffer_t& src, img_buffer_t& dst, double factor_x,
                              double factor_y, int interpolation, int sync) final {
        if (rga_ops_.imresize_t) {
            rga_buffer_t rga_src = rga_ops_.wrapbuffer_fd_t(
                src.fd, src.width, src.height, src.wstride, src.hstride, WrapFormat(src.format));
            rga_buffer_t rga_dst = rga_ops_.wrapbuffer_fd_t(
                dst.fd, dst.width, dst.height, dst.wstride, dst.hstride, WrapFormat(dst.format));
 
            if (0 > rga_ops_.imresize_t(rga_src, rga_dst, factor_x, factor_y, interpolation, sync)) {
                return XCAM_RETURN_ERROR_FAILED;
            }
 
            return XCAM_RETURN_NO_ERROR;
        }
        LOGE("%s : Not implemented", __func__);
        return XCAM_RETURN_ERROR_UNKNOWN;
    };
 
    virtual XCamReturn crop(const img_buffer_t& src, img_buffer_t& dst, img_rect_t rect,
                            int sync) final {
        LOGE("%s : Not implemented", __func__);
        return XCAM_RETURN_ERROR_UNKNOWN;
    };
 
    virtual XCamReturn cvtcolor(img_buffer_t& src, img_buffer_t& dst, int sfmt, int dfmt, int mode,
                                int sync) final {
        LOGE("%s : Not implemented", __func__);
        return XCAM_RETURN_ERROR_UNKNOWN;
    };
 
    virtual XCamReturn rotate(const img_buffer_t& src, img_buffer_t& dst, int rotation,
                              int sync) final {
        LOGE("%s : Not implemented", __func__);
        return XCAM_RETURN_ERROR_UNKNOWN;
    };
 
    virtual XCamReturn flip(const img_buffer_t& src, img_buffer_t& dst, int mode, int sync) final {
        LOGE("%s : Not implemented", __func__);
        return XCAM_RETURN_ERROR_UNKNOWN;
    };
 
    virtual XCamReturn copy(const img_buffer_t& src, img_buffer_t& dst, int sync) final {
        LOGE("%s : Not implemented", __func__);
        return XCAM_RETURN_ERROR_UNKNOWN;
    };
 
 private:
    void* handle_;
    struct rga_ops_s rga_ops_;
};
#endif  // HAS_LIBRGA
 
ImageOperator::ImageOperator(const std::string name) : name_(name) {}
 
XCamReturn ImageOperator::resize(const img_buffer_t& src, img_buffer_t& dst, double fx, double fy,
                                 int interpolation, int sync) {
    LOGE("%s : Not implemented", __func__);
    return XCAM_RETURN_ERROR_UNKNOWN;
}
 
XCamReturn ImageOperator::crop(const img_buffer_t& src, img_buffer_t& dst, img_rect_t rect,
                               int sync) {
    LOGE("%s : Not implemented", __func__);
    return XCAM_RETURN_ERROR_UNKNOWN;
}
 
XCamReturn ImageOperator::cvtcolor(img_buffer_t& src, img_buffer_t& dst, int sfmt, int dfmt,
                                   int mode, int sync) {
    LOGE("%s : Not implemented", __func__);
    return XCAM_RETURN_ERROR_UNKNOWN;
}
 
XCamReturn ImageOperator::rotate(const img_buffer_t& src, img_buffer_t& dst, int rotation,
                                 int sync) {
    LOGE("%s : Not implemented", __func__);
    return XCAM_RETURN_ERROR_UNKNOWN;
}
 
XCamReturn ImageOperator::flip(const img_buffer_t& src, img_buffer_t& dst, int mode, int sync) {
    LOGE("%s : Not implemented", __func__);
    return XCAM_RETURN_ERROR_UNKNOWN;
}
 
XCamReturn ImageOperator::copy(const img_buffer_t& src, img_buffer_t& dst, int sync) {
    LOGE("%s : Not implemented", __func__);
    return XCAM_RETURN_ERROR_UNKNOWN;
}
 
void ImageProcessor::set_operator(const std::string& name) {
    if (operator_ != nullptr && !name.compare(operator_->get_name())) {
        return;
    }
#ifdef HAS_LIBRGA
#ifdef HAS_LIBDL
    if (!name.compare("rga")) {
        auto ops = std::unique_ptr<RGAOperator>{new RGAOperator};
        ops->resolve_symbles();
        operator_ = std::move(ops);
    }
#else
#warning "Using RGA without dynamic loading is NOT implemented yet!!!"
#endif
#endif
}
 
XCamReturn ImageProcessor::resize(const img_buffer_t& src, img_buffer_t& dst, double factor_x,
                                  double factor_y) {
    if (operator_) {
        return operator_->resize(src, dst, factor_x, factor_y);
    } else {
        LOGE("%s : Not implemented", __func__);
        return XCAM_RETURN_ERROR_UNKNOWN;
    }
}
 
XCamReturn ImageProcessor::crop(const img_buffer_t& src, img_buffer_t& dst,
                                const img_rect_t& rect) {
    LOGE("%s : Not implemented", __func__);
    return XCAM_RETURN_ERROR_UNKNOWN;
}
 
}  // namespace RkCam