xref: /OK3568_Linux_fs/external/linux-rga/samples/resize_demo/src/rga_resize_uv_downsampling_demo.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright (C) 2022  Rockchip Electronics Co., Ltd.
3  * Authors:
4  *     YuQiaowei <cerf.yu@rock-chips.com>
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 #define LOG_NDEBUG 0
20 #undef LOG_TAG
21 #define LOG_TAG "rga_resize_uv_downsampling_demo"
22 
23 #include <stdint.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <errno.h>
28 #include <time.h>
29 #include <sys/types.h>
30 #include <sys/time.h>
31 #include <sys/mman.h>
32 #include <math.h>
33 #include <fcntl.h>
34 #include <signal.h>
35 #include <unistd.h>
36 #include <linux/stddef.h>
37 
38 #include "RgaUtils.h"
39 #include "im2d.hpp"
40 
41 #include "utils.h"
42 
43 #define USE_DMA_HEAP 1
44 
45 #if USE_DMA_HEAP
46 #include "dma_alloc.h"
47 #endif
48 
49 #define LOCAL_FILE_PATH "/data"
50 
51 /*
52  *   The current sample code is suitable for chips whose RGA hardware does not
53  * support average downsampling, and uses Y400 format for UV downsampling.
54  */
55 
local_downsampling_imcvtcolor(rga_buffer_t & orig_src,rga_buffer_t & orig_dst,int src_fmt,int dst_fmt)56 static IM_STATUS local_downsampling_imcvtcolor(rga_buffer_t &orig_src, rga_buffer_t &orig_dst,
57                                                int src_fmt, int dst_fmt) {
58     int ret = 0;
59     rga_buffer_t src_img, dst_img;
60     im_rect src_rect, dst_rect;
61 
62     memset(&src_img, 0, sizeof(src_img));
63     memset(&dst_img, 0, sizeof(dst_img));
64     memset(&src_rect, 0, sizeof(src_rect));
65     memset(&dst_rect, 0, sizeof(dst_rect));
66 
67     src_img = wrapbuffer_handle(orig_src.handle,
68                                 orig_src.wstride, orig_src.hstride * get_bpp_from_format(orig_src.format),
69                                 RK_FORMAT_YCbCr_400);
70     dst_img = wrapbuffer_handle(orig_dst.handle,
71                                 orig_dst.wstride, orig_dst.hstride * get_bpp_from_format(orig_dst.format),
72                                 RK_FORMAT_YCbCr_400);
73 
74     if (src_img.handle != dst_img.handle) {
75         src_rect.x = 0;
76         src_rect.y = 0;
77         src_rect.width = orig_src.wstride;
78         src_rect.height = orig_src.hstride;
79 
80         dst_rect.x = 0;
81         dst_rect.y = 0;
82         dst_rect.width = orig_dst.wstride;
83         dst_rect.height = orig_dst.hstride;
84 
85         ret = improcess(src_img, dst_img, {}, src_rect, dst_rect, {}, IM_SYNC);
86         if (ret == IM_STATUS_SUCCESS) {
87             printf("%s Y channel running success!\n", LOG_TAG);
88         } else {
89             printf("%s Y channel running failed!\n", LOG_TAG);
90             return (IM_STATUS)ret;
91         }
92     }
93 
94     /*
95      * Scale uv data.
96         --------------    --------------
97         |            |    |            |
98         |   y_data   |    |   y_data   |
99         |            |    |            |
100         |            |    |            |
101         --------------    --------------
102         |            |    |            |
103         | uv422_data | => | uv420_data |
104         |            |    --------------
105         |            |
106         --------------
107      */
108 
109     src_rect.x = 0;
110     src_rect.y = orig_src.hstride;
111     src_rect.width = orig_src.wstride;
112     src_rect.height = orig_src.hstride;
113 
114     dst_rect.x = 0;
115     dst_rect.y = orig_dst.hstride;
116     dst_rect.width = orig_dst.wstride;
117     dst_rect.height = orig_dst.hstride / 2;
118 
119     ret = improcess(src_img, dst_img, {}, src_rect, dst_rect, {}, IM_SYNC);
120     if (ret == IM_STATUS_SUCCESS) {
121         printf("%s UV channel running success!\n", LOG_TAG);
122     } else {
123         printf("%s UV channel running failed!\n", LOG_TAG);
124         return (IM_STATUS)ret;
125     }
126 
127     return IM_STATUS_SUCCESS;
128 }
129 
main()130 int main() {
131     int ret = 0;
132     int src_width, src_height, src_format;
133     int dst_width, dst_height, dst_format;
134     int src_dma_fd, dst_dma_fd;
135     char *src_buf, *dst_buf;
136     int src_buf_size, dst_buf_size;
137 
138     rga_buffer_t src_img, dst_img;
139     im_rect src_rect, dst_rect;
140     rga_buffer_handle_t src_handle, dst_handle;
141 
142     memset(&src_img, 0, sizeof(src_img));
143     memset(&dst_img, 0, sizeof(dst_img));
144     memset(&src_rect, 0, sizeof(src_rect));
145     memset(&dst_rect, 0, sizeof(dst_rect));
146 
147     src_width = 1280;
148     src_height = 720;
149     src_format = RK_FORMAT_YCbCr_422_SP;
150 
151     dst_width = 1280;
152     dst_height = 720;
153     dst_format = RK_FORMAT_YCbCr_420_SP;
154 
155     src_buf_size = src_width * src_height * get_bpp_from_format(src_format);
156     dst_buf_size = dst_width * dst_height * get_bpp_from_format(dst_format);
157 
158 #if USE_DMA_HEAP
159     ret = dma_buf_alloc(DMA_HEAP_DMA32_UNCACHE_PATCH, src_buf_size, &src_dma_fd, (void **)&src_buf);
160     if (ret < 0) {
161         printf("alloc src dma32_heap buffer failed!\n");
162         return -1;
163     }
164 
165     ret = dma_buf_alloc(DMA_HEAP_DMA32_UNCACHE_PATCH, dst_buf_size, &dst_dma_fd, (void **)&dst_buf);
166     if (ret < 0) {
167         printf("alloc dst dma32_heap buffer failed!\n");
168         return -1;
169     }
170 #else
171     (void)(src_dma_fd);
172     (void)(dst_dma_fd);
173 
174     src_buf = (char *)malloc(src_buf_size);
175     dst_buf = (char *)malloc(dst_buf_size);
176     if (src_buf == NULL || dst_buf == NULL) {
177         printf("malloc failed!\n");
178         return -1;
179     }
180 #endif
181 
182     /* fill image data */
183     if (0 != read_image_from_file(src_buf, LOCAL_FILE_PATH, src_width, src_height, src_format, 0)) {
184         printf("src image read err\n");
185         memset(src_buf, 0xaa, src_buf_size);
186     }
187     memset(dst_buf, 0x80, dst_buf_size);
188 
189     src_handle = importbuffer_virtualaddr(src_buf, src_buf_size);
190     dst_handle = importbuffer_virtualaddr(dst_buf, dst_buf_size);
191     if (src_handle == 0 || dst_handle == 0) {
192         printf("importbuffer failed!\n");
193         goto release_buffer;
194     }
195 
196     src_img = wrapbuffer_handle(src_handle, src_width, src_height, src_format);
197     dst_img = wrapbuffer_handle(dst_handle, dst_width, dst_height, dst_format);
198 
199     ret = imcheck(src_img, dst_img, {}, {});
200     if (IM_STATUS_NOERROR != ret) {
201         printf("%d, check error! %s", __LINE__, imStrError((IM_STATUS)ret));
202         return -1;
203     }
204 
205     ret = imcvtcolor(src_img, dst_img, RK_FORMAT_YCbCr_422_SP, RK_FORMAT_YCbCr_420_SP);
206     if (ret == IM_STATUS_SUCCESS) {
207         printf("%s RGA cvtcolor running success!\n", LOG_TAG);
208     } else {
209         printf("%s RGA cvtcolor running failed, %s\n", LOG_TAG, imStrError((IM_STATUS)ret));
210         goto release_buffer;
211     }
212 
213     printf("RGA output [0x%x, 0x%x, 0x%x, 0x%x]\n", dst_buf[0], dst_buf[1], dst_buf[2], dst_buf[3]);
214     write_image_to_file(dst_buf, LOCAL_FILE_PATH, dst_width, dst_height, dst_format, 0);
215 
216     ret = local_downsampling_imcvtcolor(src_img, dst_img, RK_FORMAT_YCbCr_422_SP, RK_FORMAT_YCbCr_420_SP);
217     if (ret == IM_STATUS_SUCCESS) {
218         printf("%s local downsampling cvtcolor running success!\n", LOG_TAG);
219     } else {
220         printf("%s local downsampling cvtcolor running failed, %s\n", LOG_TAG, imStrError((IM_STATUS)ret));
221         goto release_buffer;
222     }
223 
224     printf("local output [0x%x, 0x%x, 0x%x, 0x%x]\n", src_buf[0], src_buf[1], src_buf[2], src_buf[3]);
225     write_image_to_file(dst_buf, LOCAL_FILE_PATH, dst_width, dst_height, dst_format, 1);
226 
227 release_buffer:
228     if (src_handle)
229         releasebuffer_handle(src_handle);
230     if (dst_handle)
231         releasebuffer_handle(dst_handle);
232 
233 #if !USE_DMA_HEAP
234     if(src_buf)
235         free(src_buf);
236     if (dst_buf)
237         free(dst_buf);
238 #endif
239 
240     return ret;
241 }
242