1 /* SPDX-License-Identifier: Apache-2.0 OR MIT */
2 /*
3 * Copyright (c) 2015 Rockchip Electronics Co., Ltd.
4 */
5
6 #define MODULE_TAG "mpp_frame"
7
8 #include <string.h>
9
10 #include "mpp_debug.h"
11 #include "mpp_mem_pool.h"
12 #include "mpp_singleton.h"
13
14 #include "mpp_meta_impl.h"
15 #include "mpp_frame_impl.h"
16
17 static const char *module_name = MODULE_TAG;
18 static MppMemPool pool_frame = NULL;
19
setup_mpp_frame_name(MppFrameImpl * frame)20 static void setup_mpp_frame_name(MppFrameImpl *frame)
21 {
22 frame->name = module_name;
23 }
24
setup_mpp_frame_defaults(MppFrameImpl * frame)25 static void setup_mpp_frame_defaults(MppFrameImpl *frame)
26 {
27 frame->color_range = MPP_FRAME_RANGE_UNSPECIFIED;
28 frame->color_primaries = MPP_FRAME_PRI_UNSPECIFIED;
29 frame->color_trc = MPP_FRAME_TRC_UNSPECIFIED;
30 frame->colorspace = MPP_FRAME_SPC_UNSPECIFIED;
31 }
32
33 #define check_is_mpp_frame(frame) _check_is_mpp_frame(__FUNCTION__, frame)
34
mpp_frame_srv_init()35 static void mpp_frame_srv_init()
36 {
37 if (pool_frame)
38 return;
39
40 pool_frame = mpp_mem_pool_init_f("MppFrame", sizeof(MppFrameImpl));
41 }
42
mpp_frame_srv_deinit()43 static void mpp_frame_srv_deinit()
44 {
45 if (pool_frame) {
46 mpp_mem_pool_deinit_f(pool_frame);
47 pool_frame = NULL;
48 }
49 }
50
MPP_SINGLETON(MPP_SGLN_FRAME,mpp_frame,mpp_frame_srv_init,mpp_frame_srv_deinit)51 MPP_SINGLETON(MPP_SGLN_FRAME, mpp_frame, mpp_frame_srv_init, mpp_frame_srv_deinit)
52
53 MPP_RET _check_is_mpp_frame(const char *func, void *frame)
54 {
55 if (!__check_is_mpp_frame(frame))
56 return MPP_OK;
57
58 mpp_err("pointer %p failed on %s check mpp_frame\n", frame, func);
59 mpp_abort();
60 return MPP_NOK;
61 }
62
__check_is_mpp_frame(void * frame)63 MPP_RET __check_is_mpp_frame(void *frame)
64 {
65 if (frame && ((MppFrameImpl*)frame)->name == module_name)
66 return MPP_OK;
67
68 return MPP_NOK;
69 }
70
mpp_frame_init(MppFrame * frame)71 MPP_RET mpp_frame_init(MppFrame *frame)
72 {
73 MppFrameImpl *p;
74
75 if (!frame) {
76 mpp_err_f("invalid NULL pointer input\n");
77 return MPP_ERR_NULL_PTR;
78 }
79
80 if (!pool_frame)
81 mpp_frame_srv_init();
82
83 p = (MppFrameImpl*)mpp_mem_pool_get_f(pool_frame);
84 if (!p) {
85 mpp_err_f("malloc failed\n");
86 return MPP_ERR_NULL_PTR;
87 }
88
89 setup_mpp_frame_name(p);
90 setup_mpp_frame_defaults(p);
91 *frame = p;
92
93 return MPP_OK;
94 }
95
mpp_frame_deinit(MppFrame * frame)96 MPP_RET mpp_frame_deinit(MppFrame *frame)
97 {
98 MppFrameImpl *p;
99
100 if (!frame || check_is_mpp_frame(*frame)) {
101 mpp_err_f("invalid NULL pointer input\n");
102 return MPP_ERR_NULL_PTR;
103 }
104
105 p = (MppFrameImpl *)*frame;
106 if (p->buffer)
107 mpp_buffer_put(p->buffer);
108
109 if (p->meta)
110 mpp_meta_put(p->meta);
111
112 if (p->stopwatch)
113 mpp_stopwatch_put(p->stopwatch);
114
115 mpp_mem_pool_put_f(pool_frame, *frame);
116 *frame = NULL;
117 return MPP_OK;
118 }
119
mpp_frame_get_buffer(MppFrame frame)120 MppBuffer mpp_frame_get_buffer(MppFrame frame)
121 {
122 MppFrameImpl *p = (MppFrameImpl *)frame;
123
124 if (check_is_mpp_frame(p))
125 return NULL;
126
127 return (MppFrame)p->buffer;
128 }
129
mpp_frame_set_buffer(MppFrame frame,MppBuffer buffer)130 void mpp_frame_set_buffer(MppFrame frame, MppBuffer buffer)
131 {
132 MppFrameImpl *p = (MppFrameImpl *)frame;
133
134 if (check_is_mpp_frame(p))
135 return;
136
137 if (p->buffer != buffer) {
138 if (buffer)
139 mpp_buffer_inc_ref(buffer);
140
141 if (p->buffer)
142 mpp_buffer_put(p->buffer);
143
144 p->buffer = buffer;
145 }
146 }
147
mpp_frame_has_meta(const MppFrame frame)148 RK_S32 mpp_frame_has_meta(const MppFrame frame)
149 {
150 MppFrameImpl *p = (MppFrameImpl *)frame;
151
152 if (check_is_mpp_frame(p))
153 return 0;
154
155 return (NULL != p->meta);
156 }
157
mpp_frame_get_meta(MppFrame frame)158 MppMeta mpp_frame_get_meta(MppFrame frame)
159 {
160 MppFrameImpl *p = (MppFrameImpl *)frame;
161
162 if (check_is_mpp_frame(p))
163 return NULL;
164
165 if (!p->meta)
166 mpp_meta_get(&p->meta);
167
168 return p->meta;
169 }
170
mpp_frame_set_meta(MppFrame frame,MppMeta meta)171 void mpp_frame_set_meta(MppFrame frame, MppMeta meta)
172 {
173 MppFrameImpl *p = (MppFrameImpl *)frame;
174
175 if (check_is_mpp_frame(p))
176 return;
177
178 if (p->meta) {
179 mpp_meta_put(p->meta);
180 p->meta = NULL;
181 }
182
183 p->meta = meta;
184 }
185
mpp_frame_get_status(MppFrame frame)186 MppFrameStatus *mpp_frame_get_status(MppFrame frame)
187 {
188 MppFrameImpl *p = (MppFrameImpl *)frame;
189
190 return &p->status;
191 }
192
mpp_frame_set_stopwatch_enable(MppFrame frame,RK_S32 enable)193 void mpp_frame_set_stopwatch_enable(MppFrame frame, RK_S32 enable)
194 {
195 MppFrameImpl *p = (MppFrameImpl *)frame;
196
197 if (check_is_mpp_frame(p))
198 return;
199
200 if (enable && !p->stopwatch) {
201 char name[32];
202
203 snprintf(name, sizeof(name) - 1, "frm %8llx", p->pts);
204 p->stopwatch = mpp_stopwatch_get(name);
205 if (p->stopwatch)
206 mpp_stopwatch_set_show_on_exit(p->stopwatch, 1);
207 } else if (!enable && p->stopwatch) {
208 mpp_stopwatch_put(p->stopwatch);
209 p->stopwatch = NULL;
210 }
211 }
212
mpp_frame_get_stopwatch(const MppFrame frame)213 MppStopwatch mpp_frame_get_stopwatch(const MppFrame frame)
214 {
215 MppFrameImpl *p = (MppFrameImpl *)frame;
216
217 if (check_is_mpp_frame(p))
218 return NULL;
219
220 return p->stopwatch;
221 }
222
mpp_frame_dup(MppFrame src)223 MppFrame mpp_frame_dup(MppFrame src)
224 {
225 MppFrameImpl *p = (MppFrameImpl *)src;
226 MppFrameImpl *ret;
227 MppFrame frame = NULL;
228
229 if (check_is_mpp_frame(src)) {
230 mpp_err_f("invalid input src %p\n", src);
231 return NULL;
232 }
233
234 mpp_frame_init(&frame);
235 if (!frame)
236 return NULL;
237
238 ret = (MppFrameImpl *)frame;
239 memcpy(ret, p, sizeof(MppFrameImpl));
240
241 if (p->meta)
242 ret->meta = mpp_meta_dup(p->meta);
243
244 return frame;
245 }
246
mpp_frame_copy(MppFrame dst,MppFrame src)247 MPP_RET mpp_frame_copy(MppFrame dst, MppFrame src)
248 {
249 MppFrameImpl *p = (MppFrameImpl *)dst;
250
251 if (!dst || check_is_mpp_frame(src)) {
252 mpp_err_f("invalid input dst %p src %p\n", dst, src);
253 return MPP_ERR_UNKNOW;
254 }
255
256 if (p->meta)
257 mpp_meta_put(p->meta);
258
259 memcpy(dst, src, sizeof(MppFrameImpl));
260 p = (MppFrameImpl *)src;
261 if (p->meta)
262 mpp_meta_inc_ref(p->meta);
263
264 return MPP_OK;
265 }
266
mpp_frame_info_cmp(MppFrame frame0,MppFrame frame1)267 MPP_RET mpp_frame_info_cmp(MppFrame frame0, MppFrame frame1)
268 {
269 MppFrameImpl *f0 = (MppFrameImpl *)frame0;
270 MppFrameImpl *f1 = (MppFrameImpl *)frame1;
271
272 if (check_is_mpp_frame(f0) || check_is_mpp_frame(f1)) {
273 mpp_err_f("invalid NULL pointer input\n");
274 return MPP_ERR_NULL_PTR;
275 }
276
277 if ((f0->width == f1->width) &&
278 (f0->height == f1->height) &&
279 (f0->hor_stride == f1->hor_stride) &&
280 (f0->ver_stride == f1->ver_stride) &&
281 ((f0->fmt & ~MPP_FRAME_HDR_MASK) == (f1->fmt & ~MPP_FRAME_HDR_MASK)) &&
282 (f0->buf_size == f1->buf_size)) {
283 return MPP_OK;
284 }
285 return MPP_NOK;
286 }
287
mpp_frame_get_fbc_offset(MppFrame frame)288 RK_U32 mpp_frame_get_fbc_offset(MppFrame frame)
289 {
290 MppFrameImpl *p = (MppFrameImpl *)frame;
291
292 if (check_is_mpp_frame(p))
293 return 0;
294
295 if (MPP_FRAME_FMT_IS_FBC(p->fmt)) {
296 RK_U32 fbc_version = p->fmt & MPP_FRAME_FBC_MASK;
297 RK_U32 fbc_offset = 0;
298
299 if (fbc_version == MPP_FRAME_FBC_AFBC_V1) {
300 fbc_offset = MPP_ALIGN(MPP_ALIGN(p->width, 16) *
301 MPP_ALIGN(p->height, 16) / 16, SZ_4K);
302 } else if (fbc_version == MPP_FRAME_FBC_AFBC_V2 ||
303 fbc_version == MPP_FRAME_FBC_RKFBC) {
304 fbc_offset = 0;
305 }
306 p->fbc_offset = fbc_offset;
307 }
308
309 return p->fbc_offset;
310 }
311
mpp_frame_get_fbc_stride(MppFrame frame)312 RK_U32 mpp_frame_get_fbc_stride(MppFrame frame)
313 {
314 MppFrameImpl *p = (MppFrameImpl *)frame;
315
316 if (check_is_mpp_frame(p))
317 return 0;
318
319 return MPP_ALIGN(p->width, 16);
320 }
321
322 /*
323 * object access function macro
324 */
325 #define MPP_FRAME_ACCESSORS(type, field) \
326 type mpp_frame_get_##field(const MppFrame s) \
327 { \
328 check_is_mpp_frame((MppFrameImpl*)s); \
329 return ((MppFrameImpl*)s)->field; \
330 } \
331 void mpp_frame_set_##field(MppFrame s, type v) \
332 { \
333 check_is_mpp_frame((MppFrameImpl*)s); \
334 ((MppFrameImpl*)s)->field = v; \
335 }
336
337 MPP_FRAME_ACCESSORS(RK_U32, width)
338 MPP_FRAME_ACCESSORS(RK_U32, height)
339 MPP_FRAME_ACCESSORS(RK_U32, hor_stride_pixel)
340 MPP_FRAME_ACCESSORS(RK_U32, hor_stride)
341 MPP_FRAME_ACCESSORS(RK_U32, ver_stride)
342 MPP_FRAME_ACCESSORS(RK_U32, fbc_hdr_stride)
343 MPP_FRAME_ACCESSORS(RK_U32, offset_x)
344 MPP_FRAME_ACCESSORS(RK_U32, offset_y)
345 MPP_FRAME_ACCESSORS(RK_U32, mode)
346 MPP_FRAME_ACCESSORS(RK_U32, discard)
347 MPP_FRAME_ACCESSORS(RK_U32, viewid)
348 MPP_FRAME_ACCESSORS(RK_U32, poc)
349 MPP_FRAME_ACCESSORS(RK_S64, pts)
350 MPP_FRAME_ACCESSORS(RK_S64, dts)
351 MPP_FRAME_ACCESSORS(RK_U32, eos)
352 MPP_FRAME_ACCESSORS(RK_U32, info_change)
353 MPP_FRAME_ACCESSORS(MppFrameColorRange, color_range)
354 MPP_FRAME_ACCESSORS(MppFrameColorPrimaries, color_primaries)
355 MPP_FRAME_ACCESSORS(MppFrameColorTransferCharacteristic, color_trc)
356 MPP_FRAME_ACCESSORS(MppFrameColorSpace, colorspace)
357 MPP_FRAME_ACCESSORS(MppFrameChromaLocation, chroma_location)
358 MPP_FRAME_ACCESSORS(MppFrameFormat, fmt)
359 MPP_FRAME_ACCESSORS(MppFrameRational, sar)
360 MPP_FRAME_ACCESSORS(MppFrameMasteringDisplayMetadata, mastering_display)
361 MPP_FRAME_ACCESSORS(MppFrameContentLightMetadata, content_light)
362 MPP_FRAME_ACCESSORS(MppFrameHdrDynamicMeta*, hdr_dynamic_meta)
363 MPP_FRAME_ACCESSORS(size_t, buf_size)
364 MPP_FRAME_ACCESSORS(RK_U32, errinfo)
365 MPP_FRAME_ACCESSORS(MppTask, task)
366 MPP_FRAME_ACCESSORS(RK_U32, thumbnail_en)
367 MPP_FRAME_ACCESSORS(size_t, fbc_size)
368