xref: /rockchip-linux_mpp/mpp/base/mpp_frame.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
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