xref: /rockchip-linux_mpp/mpp/base/mpp_meta.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_meta"
7 
8 #include <string.h>
9 #include <endian.h>
10 
11 #include "mpp_env.h"
12 #include "mpp_lock.h"
13 #include "mpp_debug.h"
14 #include "mpp_mem_pool.h"
15 #include "mpp_singleton.h"
16 
17 #include "mpp_trie.h"
18 #include "mpp_meta_impl.h"
19 
20 #define META_DBG_FLOW               (0x00000001)
21 #define META_DBG_KEYS               (0x00000002)
22 
23 #define meta_dbg(flag, fmt, ...)    _mpp_dbg(mpp_meta_debug, flag, fmt, ## __VA_ARGS__)
24 #define meta_dbg_f(flag, fmt, ...)  _mpp_dbg_f(mpp_meta_debug, flag, fmt, ## __VA_ARGS__)
25 
26 #define meta_dbg_flow(fmt, ...)     meta_dbg(META_DBG_FLOW, fmt, ## __VA_ARGS__)
27 
28 #define META_VAL_INVALID            (0x00000000)
29 #define META_VAL_VALID              (0x00000001)
30 #define META_VAL_READY              (0x00000002)
31 
32 #define WRITE_ONCE(x, val)          ((*(volatile typeof(x) *) &(x)) = (val))
33 #define READ_ONCE(var)              (*((volatile typeof(var) *)(&(var))))
34 
35 #define get_srv_meta(caller) \
36     ({ \
37         MppMetaSrv *__tmp; \
38         if (srv_meta || srv_finalized) { \
39             __tmp = srv_meta; \
40         } else { \
41             mpp_meta_srv_init(); \
42             __tmp = srv_meta; \
43             if (!__tmp) { \
44                 mpp_err("mpp meta srv not init at %s : %s\n", __FUNCTION__, caller); \
45             } \
46         } \
47         __tmp; \
48     })
49 
50 #define get_srv_meta_f() \
51     ({ \
52         MppMetaSrv *__tmp; \
53         if (srv_meta || srv_finalized) { \
54             __tmp = srv_meta; \
55         } else { \
56             mpp_meta_srv_init(); \
57             __tmp = srv_meta; \
58             if (!__tmp) { \
59                 mpp_err("mpp meta srv not init at %s\n", __FUNCTION__); \
60             } \
61         } \
62         __tmp; \
63     })
64 
65 typedef enum MppMetaDataType_e {
66     /* mpp meta data of normal data type */
67     TYPE_VAL_32 = '3',
68     TYPE_VAL_64 = '6',
69     TYPE_KPTR   = 'k',
70     TYPE_UPTR   = 'u',
71     TYPE_SPTR   = 's',
72 } MppMetaType;
73 
META_KEY_TO_U64(RK_U32 key,RK_U32 type)74 static inline RK_U64 META_KEY_TO_U64(RK_U32 key, RK_U32 type)
75 {
76     return (RK_U64)((RK_U32)htobe32(key)) | ((RK_U64)type << 32);
77 }
78 
79 #define EXPAND_AS_TRIE(key, type) \
80     do { \
81         RK_U64 val = META_KEY_TO_U64(key, type); \
82         mpp_trie_add_info(srv->trie, (const char *)&val, NULL, 0); \
83         meta_key_count++; \
84     } while (0);
85 
86 #define EXPAND_AS_LOG(key, type) \
87     do { \
88         RK_U32 key_val = htobe32(key); \
89         char *str = (char *)&key_val; \
90         mpp_logi("%2d - %-24s (%c%c%c%c) : %-12s\n", \
91                  i++, #key, str[0], str[1], str[2], str[3], #type); \
92     } while (0);
93 
94 #define META_ENTRY_TABLE(ENTRY) \
95     /* categorized by type */ \
96     /* data flow type */ \
97     ENTRY(KEY_INPUT_FRAME,          TYPE_SPTR) \
98     ENTRY(KEY_OUTPUT_FRAME,         TYPE_SPTR) \
99     ENTRY(KEY_INPUT_PACKET,         TYPE_SPTR) \
100     ENTRY(KEY_OUTPUT_PACKET,        TYPE_SPTR) \
101     /* buffer for motion detection */ \
102     ENTRY(KEY_MOTION_INFO,          TYPE_SPTR) \
103     /* buffer storing the HDR information for current frame*/ \
104     ENTRY(KEY_HDR_INFO,             TYPE_SPTR) \
105     /* the offset of HDR meta data in frame buffer */ \
106     ENTRY(KEY_HDR_META_OFFSET,      TYPE_VAL_32) \
107     ENTRY(KEY_HDR_META_SIZE,        TYPE_VAL_32) \
108     \
109     ENTRY(KEY_OUTPUT_INTRA,         TYPE_VAL_32) \
110     ENTRY(KEY_INPUT_BLOCK,          TYPE_VAL_32) \
111     ENTRY(KEY_OUTPUT_BLOCK,         TYPE_VAL_32) \
112     ENTRY(KEY_INPUT_IDR_REQ,        TYPE_VAL_32) \
113     \
114     /* extra information for tsvc */ \
115     ENTRY(KEY_TEMPORAL_ID,          TYPE_VAL_32) \
116     ENTRY(KEY_LONG_REF_IDX,         TYPE_VAL_32) \
117     ENTRY(KEY_ENC_AVERAGE_QP,       TYPE_VAL_32) \
118     ENTRY(KEY_ENC_START_QP,         TYPE_VAL_32) \
119     ENTRY(KEY_ENC_BPS_RT,           TYPE_VAL_32) \
120     \
121     ENTRY(KEY_ROI_DATA,             TYPE_UPTR) \
122     ENTRY(KEY_ROI_DATA2,            TYPE_UPTR) \
123     ENTRY(KEY_JPEG_ROI_DATA,        TYPE_UPTR) \
124     ENTRY(KEY_OSD_DATA,             TYPE_UPTR) \
125     ENTRY(KEY_OSD_DATA2,            TYPE_UPTR) \
126     ENTRY(KEY_OSD_DATA3,            TYPE_UPTR) \
127     ENTRY(KEY_USER_DATA,            TYPE_UPTR) \
128     ENTRY(KEY_USER_DATAS,           TYPE_UPTR) \
129     ENTRY(KEY_QPMAP0,               TYPE_SPTR) \
130     /* buffer for super encode v3 */ \
131     ENTRY(KEY_NPU_SOBJ_FLAG,        TYPE_SPTR) \
132     ENTRY(KEY_NPU_UOBJ_FLAG,        TYPE_UPTR) \
133     ENTRY(KEY_BUFFER_UPSCALE,       TYPE_SPTR) \
134     ENTRY(KEY_BUFFER_DOWNSCALE,     TYPE_SPTR) \
135     \
136     ENTRY(KEY_LVL64_INTER_NUM,      TYPE_VAL_32) \
137     ENTRY(KEY_LVL32_INTER_NUM,      TYPE_VAL_32) \
138     ENTRY(KEY_LVL16_INTER_NUM,      TYPE_VAL_32) \
139     ENTRY(KEY_LVL8_INTER_NUM,       TYPE_VAL_32) \
140     ENTRY(KEY_LVL32_INTRA_NUM,      TYPE_VAL_32) \
141     ENTRY(KEY_LVL16_INTRA_NUM,      TYPE_VAL_32) \
142     ENTRY(KEY_LVL8_INTRA_NUM,       TYPE_VAL_32) \
143     ENTRY(KEY_LVL4_INTRA_NUM,       TYPE_VAL_32) \
144     ENTRY(KEY_INPUT_PSKIP,          TYPE_VAL_32) \
145     ENTRY(KEY_OUTPUT_PSKIP,         TYPE_VAL_32) \
146     ENTRY(KEY_INPUT_PSKIP_NON_REF,  TYPE_VAL_32) \
147     ENTRY(KEY_ENC_SSE,              TYPE_VAL_64) \
148     \
149     ENTRY(KEY_ENC_MARK_LTR,         TYPE_VAL_32) \
150     ENTRY(KEY_ENC_USE_LTR,          TYPE_VAL_32) \
151     ENTRY(KEY_ENC_FRAME_QP,         TYPE_VAL_32) \
152     ENTRY(KEY_ENC_BASE_LAYER_PID,   TYPE_VAL_32) \
153     \
154     ENTRY(KEY_DEC_TBN_EN,           TYPE_VAL_32) \
155     ENTRY(KEY_DEC_TBN_Y_OFFSET,     TYPE_VAL_32) \
156     ENTRY(KEY_DEC_TBN_UV_OFFSET,    TYPE_VAL_32)
157 
158 typedef struct MppMetaSrv_t {
159     spinlock_t          lock;
160     struct list_head    list_meta;
161     MppTrie             trie;
162 
163     RK_U32              meta_id;
164     RK_S32              meta_count;
165 } MppMetaSrv;
166 
167 static MppMetaSrv *srv_meta = NULL;
168 static MppMemPool pool_meta = NULL;
169 static RK_U32 srv_finalized = 0;
170 static RK_U32 meta_key_count = 0;
171 static RK_U32 mpp_meta_debug = 0;
172 static RK_S32 user_data_index = -1;
173 static RK_S32 user_datas_index = -1;
174 
175 RK_S32 meta_hdr_offset_index = -1;
176 RK_S32 meta_hdr_size_index = -1;
177 
178 static void put_meta(MppMetaSrv *srv, MppMetaImpl *meta);
179 static inline RK_S32 get_index_of_key(MppMetaKey key, MppMetaType type, const char *caller);
180 #define get_index_of_key_f(key, type) get_index_of_key(key, type, __FUNCTION__);
181 
mpp_meta_srv_init()182 static void mpp_meta_srv_init()
183 {
184     MppMetaSrv *srv = srv_meta;
185 
186     mpp_env_get_u32("mpp_meta_debug", &mpp_meta_debug, 0);
187 
188     if (srv)
189         return;
190 
191     srv = mpp_calloc(MppMetaSrv, 1);
192     if (!srv) {
193         mpp_err_f("failed to malloc meta service\n");
194         return;
195     }
196 
197     srv_meta = srv;
198 
199     mpp_spinlock_init(&srv->lock);
200     INIT_LIST_HEAD(&srv->list_meta);
201 
202     mpp_trie_init(&srv->trie, "MppMetaDef");
203     if (srv->trie) {
204         meta_key_count = 0;
205         META_ENTRY_TABLE(EXPAND_AS_TRIE)
206         mpp_trie_add_info(srv->trie, NULL, NULL, 0);
207         user_data_index = get_index_of_key_f(KEY_USER_DATA, TYPE_UPTR);
208         user_datas_index = get_index_of_key_f(KEY_USER_DATAS, TYPE_UPTR);
209         meta_hdr_offset_index = get_index_of_key_f(KEY_HDR_META_OFFSET, TYPE_VAL_32);
210         meta_hdr_size_index = get_index_of_key_f(KEY_HDR_META_SIZE, TYPE_VAL_32);
211     }
212 
213     pool_meta = mpp_mem_pool_init_f("MppMeta", sizeof(MppMetaImpl) +
214                                     sizeof(MppMetaVal) * meta_key_count);
215 
216     meta_dbg_flow("meta key count %d\n", meta_key_count);
217     if (mpp_meta_debug & META_DBG_KEYS) {
218         RK_S32 i = 0;
219 
220         META_ENTRY_TABLE(EXPAND_AS_LOG)
221     }
222 }
223 
mpp_meta_srv_deinit()224 static void mpp_meta_srv_deinit()
225 {
226     MppMetaSrv *srv = srv_meta;
227 
228     if (!srv)
229         return;
230 
231     if (!list_empty(&srv->list_meta)) {
232         MppMetaImpl *pos, *n;
233 
234         mpp_log_f("cleaning leaked metadata\n");
235 
236         list_for_each_entry_safe(pos, n, &srv->list_meta, MppMetaImpl, list_meta) {
237             put_meta(srv, pos);
238         }
239     }
240 
241     mpp_assert(srv->meta_count == 0);
242 
243     if (srv->trie) {
244         mpp_trie_deinit(srv->trie);
245         srv->trie = NULL;
246     }
247 
248     MPP_FREE(srv_meta);
249 
250     if (pool_meta) {
251         mpp_mem_pool_deinit_f(pool_meta);
252         pool_meta = NULL;
253     }
254 
255     srv_finalized = 1;
256 
257     meta_dbg_flow("meta srv deinited\n");
258 }
259 
MPP_SINGLETON(MPP_SGLN_META,mpp_meta,mpp_meta_srv_init,mpp_meta_srv_deinit)260 MPP_SINGLETON(MPP_SGLN_META, mpp_meta, mpp_meta_srv_init, mpp_meta_srv_deinit)
261 
262 static inline RK_S32 get_index_of_key(MppMetaKey key, MppMetaType type, const char *caller)
263 {
264     MppMetaSrv *srv = get_srv_meta(caller);
265     MppTrieInfo *info = NULL;
266 
267     if (srv) {
268         RK_U64 val = META_KEY_TO_U64(key, type);
269 
270         info = mpp_trie_get_info(srv->trie, (const char *)&val);
271     }
272 
273     return info ? info->index : -1;
274 }
275 
get_meta(MppMetaSrv * srv,const char * tag,const char * caller)276 static MppMetaImpl *get_meta(MppMetaSrv *srv, const char *tag, const char *caller)
277 {
278     MppMetaImpl *impl = (MppMetaImpl *)mpp_mem_pool_get(pool_meta, caller);
279 
280     if (impl) {
281         const char *tag_src = (tag) ? (tag) : (MODULE_TAG);
282         RK_U32 i;
283 
284         strncpy(impl->tag, tag_src, sizeof(impl->tag) - 1);
285         impl->caller = caller;
286         impl->meta_id = MPP_FETCH_ADD(&srv->meta_id, 1);
287         INIT_LIST_HEAD(&impl->list_meta);
288         impl->ref_count = 1;
289         impl->node_count = 0;
290 
291         for (i = 0; i < meta_key_count; i++)
292             impl->vals[i].state = 0;
293 
294         mpp_spinlock_lock(&srv->lock);
295         list_add_tail(&impl->list_meta, &srv->list_meta);
296         mpp_spinlock_unlock(&srv->lock);
297         MPP_FETCH_ADD(&srv->meta_count, 1);
298     } else {
299         mpp_err_f("failed to malloc meta data\n");
300     }
301 
302     return impl;
303 }
304 
clean_user_data(MppMetaImpl * impl)305 static void clean_user_data(MppMetaImpl *impl)
306 {
307     MPP_FREE(impl->user_data.pdata);
308     impl->user_data.len = 0;
309 }
310 
clean_user_datas(MppMetaImpl * impl)311 static void clean_user_datas(MppMetaImpl *impl)
312 {
313     MPP_FREE(impl->user_data_set.datas);
314     impl->user_data_set.count = 0;
315     impl->datas_buf_size = 0;
316 }
317 
put_meta(MppMetaSrv * srv,MppMetaImpl * meta)318 static void put_meta(MppMetaSrv *srv, MppMetaImpl *meta)
319 {
320     RK_S32 ref_count;
321 
322     if (!srv)
323         return;
324 
325     ref_count = MPP_SUB_FETCH(&meta->ref_count, 1);
326     if (ref_count > 0)
327         return;
328 
329     if (ref_count < 0) {
330         mpp_err_f("invalid negative ref_count %d\n", ref_count);
331         return;
332     }
333 
334     mpp_spinlock_lock(&srv->lock);
335     clean_user_data(meta);
336     clean_user_datas(meta);
337     list_del_init(&meta->list_meta);
338     mpp_spinlock_unlock(&srv->lock);
339     MPP_FETCH_SUB(&srv->meta_count, 1);
340 
341     if (pool_meta)
342         mpp_mem_pool_put_f(pool_meta, meta);
343 }
344 
mpp_meta_get_with_tag(MppMeta * meta,const char * tag,const char * caller)345 MPP_RET mpp_meta_get_with_tag(MppMeta *meta, const char *tag, const char *caller)
346 {
347     MppMetaSrv *srv = get_srv_meta(caller);
348     MppMetaImpl *impl;
349 
350     if (!srv)
351         return MPP_NOK;
352 
353     if (!meta) {
354         mpp_err_f("found NULL input\n");
355         return MPP_ERR_NULL_PTR;
356     }
357 
358     impl = get_meta(srv, tag, caller);
359     *meta = (MppMeta) impl;
360     return (impl) ? (MPP_OK) : (MPP_NOK);
361 }
362 
mpp_meta_put(MppMeta meta)363 MPP_RET mpp_meta_put(MppMeta meta)
364 {
365     MppMetaImpl *impl = (MppMetaImpl *)meta;
366 
367     if (!impl) {
368         mpp_err_f("found NULL input\n");
369         return MPP_ERR_NULL_PTR;
370     }
371 
372     put_meta(get_srv_meta_f(), impl);
373     return MPP_OK;
374 }
375 
mpp_meta_inc_ref(MppMeta meta)376 MPP_RET mpp_meta_inc_ref(MppMeta meta)
377 {
378     MppMetaImpl *impl = (MppMetaImpl *)meta;
379 
380     if (!impl) {
381         mpp_err_f("found NULL input\n");
382         return MPP_ERR_NULL_PTR;
383     }
384 
385     MPP_FETCH_ADD(&impl->ref_count, 1);
386     return MPP_OK;
387 }
388 
mpp_meta_size(MppMeta meta)389 RK_S32 mpp_meta_size(MppMeta meta)
390 {
391     MppMetaImpl *impl = (MppMetaImpl *)meta;
392 
393     if (!impl) {
394         mpp_err_f("found NULL input\n");
395         return -1;
396     }
397 
398     return MPP_FETCH_ADD(&impl->node_count, 0);
399 }
400 
set_user_data(MppMetaImpl * impl,void * user_data)401 static MPP_RET set_user_data(MppMetaImpl *impl, void *user_data)
402 {
403     MppEncUserData *src = (MppEncUserData *)user_data;
404 
405     if (!src) {
406         clean_user_data(impl);
407         return MPP_OK;
408     }
409 
410     if (!src->pdata || !src->len) {
411         mpp_err_f("invalid user data %p pdata %p len %d\n", user_data, src->pdata, src->len);
412         return MPP_ERR_NULL_PTR;
413     }
414 
415     if (impl->user_data.len < src->len) {
416         void *buf_ptr = mpp_realloc(impl->user_data.pdata, RK_U8, src->len);
417 
418         if (!buf_ptr) {
419             mpp_err_f("failed to realloc user data buf size %d\n", src->len);
420             impl->user_data.len = 0;
421             return MPP_ERR_MALLOC;
422         }
423         impl->user_data.pdata = buf_ptr;
424     }
425 
426     memcpy(impl->user_data.pdata, src->pdata, src->len);
427     impl->user_data.len = src->len;
428 
429     return MPP_OK;
430 }
431 
set_user_datas(MppMetaImpl * impl,void * user_data)432 static MPP_RET set_user_datas(MppMetaImpl *impl, void *user_data)
433 {
434     MppEncUserDataSet *src_set = (MppEncUserDataSet *)user_data;
435     MppEncUserDataFull *dst_set = NULL;
436     void *buf_ptr = NULL;
437     RK_U32 data_size = 0;
438     RK_U32 struct_size = 0;
439     RK_U32 buf_size = 0;
440     RK_U32 i = 0;
441 
442     if (!src_set) {
443         clean_user_datas(impl);
444         return MPP_OK;
445     }
446 
447     if (!src_set->datas || !src_set->count) {
448         mpp_err_f("invalid user data %p datas %p count %d\n", src_set, src_set->datas, src_set->count);
449         return MPP_ERR_NULL_PTR;
450     }
451 
452     struct_size = sizeof(MppEncUserDataFull) * src_set->count;
453     for (i = 0; i < src_set->count; i++) {
454         MppEncUserDataFull *src = &src_set->datas[i];
455 
456         if (src->uuid)
457             data_size += strlen((const char *)src->uuid) + 1;
458         data_size += src->len;
459     }
460     buf_size = struct_size + data_size;
461 
462     if (impl->datas_buf_size < buf_size) {
463         buf_ptr = mpp_realloc(impl->user_data_set.datas, RK_U8, buf_size);
464         if (!buf_ptr) {
465             mpp_err_f("failed to realloc user data buf size %d\n", buf_size);
466             impl->user_data_set.count = 0;
467             impl->datas_buf_size = 0;
468             return MPP_ERR_MALLOC;
469         }
470         impl->user_data_set.datas = (MppEncUserDataFull *)buf_ptr;
471     }
472 
473     impl->datas_buf_size = buf_size;
474     dst_set = impl->user_data_set.datas;
475     buf_ptr = (void *)dst_set + struct_size;
476 
477     for (i = 0; i < src_set->count; i++) {
478         MppEncUserDataFull *src = &src_set->datas[i];
479         MppEncUserDataFull *dst = &dst_set[i];
480 
481         dst->len = src->len;
482         if (src->uuid) {
483             size_t uuid_len = strlen((const char *)src->uuid) + 1;
484 
485             dst->uuid = (RK_U8 *)buf_ptr;
486             memcpy(buf_ptr, src->uuid, uuid_len);
487             buf_ptr += uuid_len;
488         } else {
489             dst->uuid = NULL;
490         }
491         if (src->pdata) {
492             dst->pdata = buf_ptr;
493             memcpy(buf_ptr, src->pdata, src->len);
494             buf_ptr += src->len;
495         } else {
496             dst->pdata = NULL;
497         }
498     }
499     impl->user_data_set.count = src_set->count;
500 
501     return MPP_OK;
502 }
503 
get_user_data(MppMetaImpl * impl,void ** val)504 static MPP_RET get_user_data(MppMetaImpl *impl, void **val)
505 {
506     if (impl->user_data.pdata) {
507         *val = &impl->user_data;
508         return MPP_OK;
509     }
510 
511     *val = NULL;
512     return MPP_NOK;
513 }
514 
get_user_datas(MppMetaImpl * impl,void ** val)515 static MPP_RET get_user_datas(MppMetaImpl *impl, void **val)
516 {
517     if (impl->user_data_set.datas) {
518         *val = &impl->user_data_set;
519         return MPP_OK;
520     }
521 
522     *val = NULL;
523     return MPP_NOK;
524 }
525 
mpp_meta_dup(MppMeta meta)526 MppMeta mpp_meta_dup(MppMeta meta)
527 {
528     MppMetaSrv *srv = get_srv_meta_f();
529     MppMetaImpl *impl = (MppMetaImpl *)meta;
530     MppMetaImpl *ret;
531 
532     if (!srv || !meta)
533         return NULL;
534 
535     ret = get_meta(srv, impl->tag, __FUNCTION__);
536     if (ret) {
537         memcpy(ret->vals, impl->vals, meta_key_count * sizeof(MppMetaVal));
538         if (ret->user_data.len) {
539             memset(&ret->user_data, 0, sizeof(ret->user_data));
540             set_user_data(ret, (void *)(intptr_t)&impl->user_data);
541         }
542         if (ret->user_data_set.count) {
543             memset(&ret->user_data, 0, sizeof(ret->user_data));
544             set_user_datas(impl, (void *)(intptr_t)&impl->user_data_set);
545         }
546         ret->node_count = impl->node_count;
547     }
548 
549     return ret;
550 }
551 
mpp_meta_dump(MppMeta meta)552 MPP_RET mpp_meta_dump(MppMeta meta)
553 {
554     MppMetaSrv *srv = get_srv_meta_f();
555     MppMetaImpl *impl = (MppMetaImpl *)meta;
556     MppTrieInfo *root;
557 
558     if (!impl) {
559         mpp_err_f("found NULL input\n");
560         return MPP_ERR_NULL_PTR;
561     }
562 
563     mpp_logi("dumping meta %d node count %d\n", impl->meta_id, impl->node_count);
564 
565     if (!srv || !srv->trie)
566         return MPP_NOK;
567 
568     root = mpp_trie_get_info_first(srv->trie);
569     if (root) {
570         MppTrieInfo *node = root;
571         const char *key = NULL;
572         char log_str[256];
573         RK_S32 pos;
574 
575         do {
576             if (mpp_trie_info_is_self(node))
577                 continue;
578 
579             key = mpp_trie_info_name(node);
580 
581             pos = snprintf(log_str, sizeof(log_str) - 1, "key %c%c%c%c - ",
582                            key[0], key[1], key[2], key[3]);
583 
584             switch (key[4]) {
585             case '3' : {
586                 snprintf(log_str + pos, sizeof(log_str) - pos - 1, "s32 - %d",
587                          impl->vals[node->index].val_s32);
588             } break;
589             case '6' : {
590                 snprintf(log_str + pos, sizeof(log_str) - pos - 1, "s64 - %lld",
591                          impl->vals[node->index].val_s64);
592             } break;
593             case 'k' :
594             case 'u' :
595             case 's' : {
596                 snprintf(log_str + pos, sizeof(log_str) - pos - 1, "ptr - %p",
597                          impl->vals[node->index].val_ptr);
598             } break;
599             default : {
600             } break;
601             }
602 
603             mpp_logi("%s\n", log_str);
604         } while ((node = mpp_trie_get_info_next(srv->trie, node)));
605     }
606 
607     return MPP_OK;
608 }
609 
610 #define MPP_META_ACCESSOR(func_type, arg_type, key_type, key_field)  \
611     MPP_RET mpp_meta_set_##func_type(MppMeta meta, MppMetaKey key, arg_type val) \
612     { \
613         MppMetaImpl *impl = (MppMetaImpl *)meta; \
614         MppMetaVal *meta_val; \
615         RK_S32 index; \
616         if (!impl) { \
617             mpp_err_f("found NULL input\n"); \
618             return MPP_ERR_NULL_PTR; \
619         } \
620         index = get_index_of_key_f(key, key_type); \
621         if (index < 0) \
622             return MPP_NOK; \
623         meta_val = &impl->vals[index]; \
624         if (MPP_BOOL_CAS(&meta_val->state, META_VAL_INVALID, META_VAL_VALID)) \
625             MPP_FETCH_ADD(&impl->node_count, 1); \
626         if (index == user_data_index) { \
627             set_user_data(impl, (void *)(intptr_t)val); \
628         } else if (index == user_datas_index) { \
629             set_user_datas(impl, (void *)(intptr_t)val); \
630         } else { \
631             meta_val->key_field = val; \
632         } \
633         MPP_FETCH_OR(&meta_val->state, META_VAL_READY); \
634         return MPP_OK; \
635     } \
636     MPP_RET mpp_meta_get_##func_type(MppMeta meta, MppMetaKey key, arg_type *val) \
637     { \
638         MppMetaImpl *impl = (MppMetaImpl *)meta; \
639         MppMetaVal *meta_val; \
640         RK_S32 index; \
641         MPP_RET ret = MPP_NOK; \
642         if (!impl) { \
643             mpp_err_f("found NULL input\n"); \
644             return MPP_ERR_NULL_PTR; \
645         } \
646         index = get_index_of_key_f(key, key_type); \
647         if (index < 0) \
648             return MPP_NOK; \
649         meta_val = &impl->vals[index]; \
650         if (MPP_BOOL_CAS(&meta_val->state, META_VAL_VALID | META_VAL_READY, META_VAL_INVALID)) { \
651             if (index == user_data_index) \
652                 get_user_data(impl, (void**)val); \
653             else if (index == user_datas_index) \
654                 get_user_datas(impl, (void**)val); \
655             else \
656                 *val = meta_val->key_field; \
657             MPP_FETCH_SUB(&impl->node_count, 1); \
658             ret = MPP_OK; \
659         } \
660         return ret; \
661     } \
662     MPP_RET mpp_meta_get_##func_type##_d(MppMeta meta, MppMetaKey key, arg_type *val, arg_type def) \
663     { \
664         MppMetaImpl *impl = (MppMetaImpl *)meta; \
665         MppMetaVal *meta_val; \
666         RK_S32 index; \
667         MPP_RET ret = MPP_NOK; \
668         if (!impl) { \
669             mpp_err_f("found NULL input\n"); \
670             return MPP_ERR_NULL_PTR; \
671         } \
672         index = get_index_of_key_f(key, key_type); \
673         if (index < 0) \
674             return MPP_NOK; \
675         meta_val = &impl->vals[index]; \
676         if (MPP_BOOL_CAS(&meta_val->state, META_VAL_VALID | META_VAL_READY, META_VAL_INVALID)) { \
677             if (index == user_data_index) \
678                 get_user_data(impl, (void**)val); \
679             else if (index == user_datas_index) \
680                 get_user_datas(impl, (void**)val); \
681             else \
682                 *val = meta_val->key_field; \
683             MPP_FETCH_SUB(&impl->node_count, 1); \
684             ret = MPP_OK; \
685         } else { \
686             *val = def; \
687         } \
688         return ret; \
689     }
690 
MPP_META_ACCESSOR(s32,RK_S32,TYPE_VAL_32,val_s32)691 MPP_META_ACCESSOR(s32, RK_S32, TYPE_VAL_32, val_s32)
692 MPP_META_ACCESSOR(s64, RK_S64, TYPE_VAL_64, val_s64)
693 MPP_META_ACCESSOR(ptr, void *, TYPE_UPTR, val_ptr)
694 MPP_META_ACCESSOR(frame, MppFrame, TYPE_SPTR, frame)
695 MPP_META_ACCESSOR(packet, MppPacket, TYPE_SPTR, packet)
696 MPP_META_ACCESSOR(buffer, MppBuffer, TYPE_SPTR, buffer)
697 
698 RK_S32 mpp_meta_s32_read(MppMeta meta, RK_S32 index, RK_S32 *val)
699 {
700     MppMetaImpl *impl = (MppMetaImpl *)meta;
701     MppMetaVal *meta_val;
702     MPP_RET ret = MPP_NOK;
703 
704     if (!impl || index < 0 || index >= meta_key_count) {
705         mpp_err_f("found NULL input meta %p index %d\n", meta, index);
706         return MPP_ERR_NULL_PTR;
707     }
708 
709     meta_val = &impl->vals[index];
710     if (meta_val->state == (META_VAL_VALID | META_VAL_READY)) {
711         *val = meta_val->val_s32;
712         ret = MPP_OK;
713     }
714 
715     return ret;
716 }
717