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