mirror of
https://github.com/nyanmisaka/mpp.git
synced 2025-10-05 17:16:50 +08:00
[metadata]: add mpp_meta module for task
git-svn-id: https://10.10.10.66:8443/svn/MediaProcessPlatform/trunk/mpp@1022 6e48237b-75ef-9749-8fc9-41990f28c85a
This commit is contained in:
100
mpp/base/inc/mpp_meta.h
Normal file
100
mpp/base/inc/mpp_meta.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 2015 Rockchip Electronics Co. LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __MPP_META_H__
|
||||
#define __MPP_META_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "rk_type.h"
|
||||
|
||||
#include "mpp_frame.h"
|
||||
#include "mpp_packet.h"
|
||||
|
||||
/*
|
||||
* Mpp Metadata definition
|
||||
*
|
||||
* Metadata is for information transmision in mpp.
|
||||
* Mpp task will contain two meta data:
|
||||
*
|
||||
* 1. Data flow metadata
|
||||
* This metadata contains information of input / output data flow. For example
|
||||
* A. decoder input side task the input packet must be defined and output frame
|
||||
* may not be defined. Then decoder will try malloc or use committed buffer to
|
||||
* complete decoding.
|
||||
* B. decoder output side task
|
||||
*
|
||||
*
|
||||
* 2. Flow control metadata
|
||||
*
|
||||
*/
|
||||
typedef enum MppMetaDataType_e {
|
||||
/*
|
||||
* mpp meta data of data flow
|
||||
* reference counter will be used for these meta data type
|
||||
*/
|
||||
MPP_META_TYPE_FRAME = 'mfrm',
|
||||
MPP_META_TYPE_PACKET = 'mpkt',
|
||||
MPP_META_TYPE_BUFFER = 'mbuf',
|
||||
|
||||
/* mpp meta data of normal data type */
|
||||
MPP_META_TYPE_S32 = 's32 ',
|
||||
MPP_META_TYPE_S64 = 's64 ',
|
||||
MPP_META_TYPE_PTR = 'ptr ',
|
||||
} MppMetaType;
|
||||
|
||||
typedef enum MppMetaKey_e {
|
||||
MPP_META_KEY_INPUT_FRM = 'ifrm',
|
||||
MPP_META_KEY_INPUT_PKT = 'ipkt',
|
||||
MPP_META_KEY_OUTPUT_FRM = 'ofrm',
|
||||
MPP_META_KEY_OUTPUT_PKT = 'opkt',
|
||||
MPP_META_KEY_MOTION_INFO = 'mvif', /* output motion information for motion detection */
|
||||
|
||||
MPP_META_KEY_INPUT_BLOCK = 'iblk',
|
||||
MPP_META_KEY_OUTPUT_BLOCK = 'oblk',
|
||||
MPP_META_KEY_INPUT_IDR_REQ = 'iidr', /* input idr frame request flag */
|
||||
MPP_META_KEY_OUTPUT_INTRA = 'oidr', /* output intra frame indicator */
|
||||
} MppMetaKey;
|
||||
|
||||
typedef void* MppMeta;
|
||||
|
||||
#define mpp_meta_get(meta) mpp_meta_get_with_tag(meta, MODULE_TAG, __FUNCTION__)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
MPP_RET mpp_meta_get_with_tag(MppMeta *meta, const char *tag, const char *caller);
|
||||
MPP_RET mpp_meta_put(MppMeta meta);
|
||||
|
||||
MPP_RET mpp_meta_set_s32(MppMeta meta, MppMetaKey key, RK_S32 val);
|
||||
MPP_RET mpp_meta_set_s64(MppMeta meta, MppMetaKey key, RK_S64 val);
|
||||
MPP_RET mpp_meta_set_ptr(MppMeta meta, MppMetaKey key, void *val);
|
||||
MPP_RET mpp_meta_get_s32(MppMeta meta, MppMetaKey key, RK_S32 *val);
|
||||
MPP_RET mpp_meta_get_s64(MppMeta meta, MppMetaKey key, RK_S64 *val);
|
||||
MPP_RET mpp_meta_get_ptr(MppMeta meta, MppMetaKey key, void **val);
|
||||
|
||||
MPP_RET mpp_meta_set_frame (MppMeta meta, MppMetaKey key, MppFrame *frame);
|
||||
MPP_RET mpp_meta_set_packet(MppMeta meta, MppMetaKey key, MppPacket *packet);
|
||||
MPP_RET mpp_meta_set_buffer(MppMeta meta, MppMetaKey key, MppBuffer *buffer);
|
||||
MPP_RET mpp_meta_get_frame (MppMeta meta, MppMetaKey key, MppFrame *frame);
|
||||
MPP_RET mpp_meta_get_packet(MppMeta meta, MppMetaKey key, MppPacket *packet);
|
||||
MPP_RET mpp_meta_get_buffer(MppMeta meta, MppMetaKey key, MppBuffer *buffer);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__MPP_META_H__*/
|
372
mpp/base/mpp_meta.cpp
Normal file
372
mpp/base/mpp_meta.cpp
Normal file
@@ -0,0 +1,372 @@
|
||||
/*
|
||||
* Copyright 2015 Rockchip Electronics Co. LTD
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define MODULE_TAG "mpp_meta"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "mpp_mem.h"
|
||||
#include "mpp_list.h"
|
||||
#include "mpp_frame.h"
|
||||
#include "mpp_packet.h"
|
||||
#include "mpp_common.h"
|
||||
|
||||
#include "mpp_meta.h"
|
||||
|
||||
typedef struct MppMetaDef_t {
|
||||
MppMetaKey key;
|
||||
MppMetaType type;
|
||||
} MppMetaDef;
|
||||
|
||||
typedef struct MppMetaImpl_t {
|
||||
char tag[MPP_TAG_SIZE];
|
||||
const char *caller;
|
||||
RK_S32 meta_id;
|
||||
|
||||
struct list_head list_meta;
|
||||
struct list_head list_node;
|
||||
RK_S32 node_count;
|
||||
} MppMetaImpl;
|
||||
|
||||
typedef union MppMetaVal_u {
|
||||
RK_S32 val_s32;
|
||||
RK_S64 val_s64;
|
||||
void *val_ptr;
|
||||
MppFrame frame;
|
||||
MppPacket packet;
|
||||
MppBuffer buffer;
|
||||
} MppMetaVal;
|
||||
|
||||
typedef struct MppMetaNode_t {
|
||||
struct list_head list_meta;
|
||||
struct list_head list_node;
|
||||
MppMetaImpl *meta;
|
||||
RK_S32 node_id;
|
||||
|
||||
RK_S32 type_id;
|
||||
MppMetaVal val;
|
||||
} MppMetaNode;
|
||||
|
||||
static MppMetaDef meta_defs[] = {
|
||||
/* categorized by type */
|
||||
/* data flow type */
|
||||
{ MPP_META_KEY_INPUT_FRM, MPP_META_TYPE_FRAME, },
|
||||
{ MPP_META_KEY_OUTPUT_FRM, MPP_META_TYPE_FRAME, },
|
||||
{ MPP_META_KEY_INPUT_PKT, MPP_META_TYPE_PACKET, },
|
||||
{ MPP_META_KEY_OUTPUT_PKT, MPP_META_TYPE_PACKET, },
|
||||
{ MPP_META_KEY_MOTION_INFO, MPP_META_TYPE_BUFFER, }, /* buffer for motion detection */
|
||||
|
||||
{ MPP_META_KEY_INPUT_BLOCK, MPP_META_TYPE_S32, },
|
||||
{ MPP_META_KEY_OUTPUT_BLOCK, MPP_META_TYPE_S32, },
|
||||
};
|
||||
|
||||
class MppMetaService
|
||||
{
|
||||
private:
|
||||
// avoid any unwanted function
|
||||
MppMetaService();
|
||||
~MppMetaService();
|
||||
MppMetaService(const MppMetaService &);
|
||||
MppMetaService &operator=(const MppMetaService &);
|
||||
|
||||
struct list_head mlist_meta;
|
||||
struct list_head mlist_node;
|
||||
|
||||
RK_U32 meta_id;
|
||||
RK_U32 meta_count;
|
||||
RK_U32 node_count;
|
||||
|
||||
public:
|
||||
static MppMetaService *get_instance()
|
||||
{
|
||||
static MppMetaService instance;
|
||||
return &instance;
|
||||
}
|
||||
static Mutex *get_lock()
|
||||
{
|
||||
static Mutex lock;
|
||||
return &lock;
|
||||
}
|
||||
|
||||
/*
|
||||
* get_index_of_key does two things:
|
||||
* 1. Check the key / type pair is correct or not.
|
||||
* If failed on check return negative value
|
||||
* 2. Compare all exsisting meta data defines to find the non-negative index
|
||||
*/
|
||||
RK_S32 get_index_of_key(MppMetaKey key, MppMetaType type);
|
||||
|
||||
MppMetaImpl *get_meta(const char *tag, const char *caller);
|
||||
void put_meta(MppMetaImpl *meta);
|
||||
|
||||
MppMetaNode *get_node(MppMetaImpl *meta, RK_S32 index);
|
||||
void put_node(MppMetaNode *node);
|
||||
};
|
||||
|
||||
RK_S32 get_index_of_key(MppMetaKey key, MppMetaKey type)
|
||||
{
|
||||
RK_S32 i = 0;
|
||||
RK_S32 num = MPP_ARRAY_ELEMS(meta_defs);
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
if ((meta_defs[i].key == key) && (meta_defs[i].type == type))
|
||||
break;
|
||||
}
|
||||
|
||||
return (i < num) ? (i) : (-1);
|
||||
}
|
||||
|
||||
MppMetaImpl *MppMetaService::get_meta(const char *tag, const char *caller)
|
||||
{
|
||||
MppMetaImpl *impl = mpp_malloc(MppMetaImpl, 1);
|
||||
if (impl) {
|
||||
const char *tag_src = (tag) ? (tag) : (MODULE_TAG);
|
||||
strncpy(impl->tag, tag_src, sizeof(impl->tag));
|
||||
impl->caller = caller;
|
||||
impl->meta_id = meta_id++;
|
||||
INIT_LIST_HEAD(&impl->list_meta);
|
||||
INIT_LIST_HEAD(&impl->list_node);
|
||||
impl->node_count = 0;
|
||||
|
||||
list_add_tail(&impl->list_meta, &mlist_meta);
|
||||
meta_count++;
|
||||
} else {
|
||||
mpp_err_f("failed to malloc meta data\n");
|
||||
}
|
||||
return impl;
|
||||
}
|
||||
|
||||
void MppMetaService::put_meta(MppMetaImpl *meta)
|
||||
{
|
||||
while (meta->node_count) {
|
||||
MppMetaNode *node = list_entry(meta->list_node.next, MppMetaNode, list_meta);
|
||||
put_node(node);
|
||||
meta->node_count--;
|
||||
}
|
||||
list_del_init(&meta->list_meta);
|
||||
meta_count--;
|
||||
mpp_free(meta);
|
||||
}
|
||||
|
||||
MppMetaNode *MppMetaService::get_node(MppMetaImpl *meta, RK_S32 type_id)
|
||||
{
|
||||
MppMetaNode *node = NULL;
|
||||
if (meta->node_count) {
|
||||
MppMetaNode *n, *pos;
|
||||
|
||||
list_for_each_entry_safe(pos, n, &meta->list_node, MppMetaNode, list_node) {
|
||||
if (pos->type_id == type_id) {
|
||||
node = pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
node = mpp_malloc(MppMetaNode, 1);
|
||||
if (node) {
|
||||
INIT_LIST_HEAD(&node->list_meta);
|
||||
INIT_LIST_HEAD(&node->list_node);
|
||||
node->meta = meta;
|
||||
node->node_id = meta->meta_id++;
|
||||
node->type_id = type_id;
|
||||
memset(&node->val, 0, sizeof(node->val));
|
||||
|
||||
meta->node_count++;
|
||||
list_add_tail(&node->list_meta, &meta->list_node);
|
||||
list_add_tail(&node->list_node, &mlist_node);
|
||||
node_count++;
|
||||
} else {
|
||||
mpp_err_f("failed to malloc meta data node\n");
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
void MppMetaService::put_node(MppMetaNode *node)
|
||||
{
|
||||
MppMetaImpl *meta = node->meta;
|
||||
list_del_init(&node->list_meta);
|
||||
list_del_init(&node->list_node);
|
||||
meta->node_count--;
|
||||
node_count--;
|
||||
// TODO: may be we need to release MppFrame / MppPacket / MppBuffer here
|
||||
switch (meta_defs[node->type_id].type) {
|
||||
case MPP_META_TYPE_FRAME : {
|
||||
mpp_frame_deinit(&node->val.frame);
|
||||
} break;
|
||||
case MPP_META_TYPE_PACKET : {
|
||||
mpp_packet_deinit(node->val.packet);
|
||||
} break;
|
||||
case MPP_META_TYPE_BUFFER : {
|
||||
mpp_buffer_put(node->val.buffer);
|
||||
} break;
|
||||
default : {
|
||||
} break;
|
||||
}
|
||||
mpp_free(node);
|
||||
}
|
||||
|
||||
MPP_RET mpp_meta_get_with_tag(MppMeta *meta, const char *tag, const char *caller)
|
||||
{
|
||||
if (NULL == meta) {
|
||||
mpp_err_f("found NULL input\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
MppMetaService *service = MppMetaService::get_instance();
|
||||
AutoMutex auto_lock(service->get_lock());
|
||||
MppMetaImpl *impl = service->get_meta(tag, caller);
|
||||
*meta = (MppMeta) impl;
|
||||
return (impl) ? (MPP_OK) : (MPP_NOK);
|
||||
}
|
||||
|
||||
MPP_RET mpp_meta_put(MppMeta meta)
|
||||
{
|
||||
if (NULL == meta) {
|
||||
mpp_err_f("found NULL input\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
MppMetaService *service = MppMetaService::get_instance();
|
||||
AutoMutex auto_lock(service->get_lock());
|
||||
MppMetaImpl *impl = (MppMetaImpl *)meta;
|
||||
service->put_meta(impl);
|
||||
return MPP_OK;
|
||||
}
|
||||
|
||||
static MPP_RET set_val_by_key(MppMetaImpl *meta, MppMetaKey key, MppMetaType type, MppMetaVal *val)
|
||||
{
|
||||
MPP_RET ret = MPP_NOK;
|
||||
MppMetaService *service = MppMetaService::get_instance();
|
||||
AutoMutex auto_lock(service->get_lock());
|
||||
RK_S32 index = service->get_index_of_key(key, type);
|
||||
if (index < 0)
|
||||
return ret;
|
||||
|
||||
MppMetaNode *node = service->get_node(meta, index);
|
||||
if (node) {
|
||||
node->val = *val;
|
||||
ret = MPP_OK;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static MPP_RET get_val_by_key(MppMetaImpl *meta, MppMetaKey key, MppMetaType type, MppMetaVal *val)
|
||||
{
|
||||
MPP_RET ret = MPP_NOK;
|
||||
MppMetaService *service = MppMetaService::get_instance();
|
||||
AutoMutex auto_lock(service->get_lock());
|
||||
RK_S32 index = service->get_index_of_key(key, type);
|
||||
if (index < 0)
|
||||
return ret;
|
||||
|
||||
MppMetaNode *node = service->get_node(meta, index);
|
||||
if (node) {
|
||||
*val = node->val;
|
||||
ret = MPP_OK;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
MPP_RET mpp_meta_set_s32(MppMeta meta, MppMetaKey key, RK_S32 val)
|
||||
{
|
||||
if (NULL == meta) {
|
||||
mpp_err_f("found NULL input\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
MppMetaImpl *impl = (MppMetaImpl *)meta;
|
||||
MppMetaVal meta_val;
|
||||
meta_val.val_s32 = val;
|
||||
return set_val_by_key(impl, key, MPP_META_TYPE_S32, &meta_val);
|
||||
}
|
||||
|
||||
MPP_RET mpp_meta_set_s64(MppMeta meta, MppMetaKey key, RK_S64 val)
|
||||
{
|
||||
if (NULL == meta) {
|
||||
mpp_err_f("found NULL input\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
MppMetaImpl *impl = (MppMetaImpl *)meta;
|
||||
MppMetaVal meta_val;
|
||||
meta_val.val_s64 = val;
|
||||
return set_val_by_key(impl, key, MPP_META_TYPE_S64, &meta_val);
|
||||
}
|
||||
|
||||
MPP_RET mpp_meta_set_ptr(MppMeta meta, MppMetaKey key, void *val)
|
||||
{
|
||||
if (NULL == meta) {
|
||||
mpp_err_f("found NULL input\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
MppMetaImpl *impl = (MppMetaImpl *)meta;
|
||||
MppMetaVal meta_val;
|
||||
meta_val.val_ptr = val;
|
||||
return set_val_by_key(impl, key, MPP_META_TYPE_PTR, &meta_val);
|
||||
}
|
||||
|
||||
MPP_RET mpp_meta_get_u32(MppMeta meta, MppMetaKey key, RK_S32 *val)
|
||||
{
|
||||
if (NULL == meta) {
|
||||
mpp_err_f("found NULL input\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
MppMetaImpl *impl = (MppMetaImpl *)meta;
|
||||
MppMetaVal meta_val;
|
||||
MPP_RET ret = get_val_by_key(impl, key, MPP_META_TYPE_S32, &meta_val);
|
||||
if (MPP_OK == ret)
|
||||
*val = meta_val.val_s32;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
MPP_RET mpp_meta_get_u64(MppMeta meta, MppMetaKey key, RK_S64 *val)
|
||||
{
|
||||
if (NULL == meta) {
|
||||
mpp_err_f("found NULL input\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
MppMetaImpl *impl = (MppMetaImpl *)meta;
|
||||
MppMetaVal meta_val;
|
||||
MPP_RET ret = get_val_by_key(impl, key, MPP_META_TYPE_S64, &meta_val);
|
||||
if (MPP_OK == ret)
|
||||
*val = meta_val.val_s64;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
MPP_RET mpp_meta_get_ptr(MppMeta meta, MppMetaKey key, void **val)
|
||||
{
|
||||
if (NULL == meta) {
|
||||
mpp_err_f("found NULL input\n");
|
||||
return MPP_ERR_NULL_PTR;
|
||||
}
|
||||
|
||||
MppMetaImpl *impl = (MppMetaImpl *)meta;
|
||||
MppMetaVal meta_val;
|
||||
MPP_RET ret = get_val_by_key(impl, key, MPP_META_TYPE_PTR, &meta_val);
|
||||
if (MPP_OK == ret)
|
||||
*val = meta_val.val_ptr;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user