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