[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:
ChenHengming
2016-07-14 10:01:41 +00:00
parent 195acfdb33
commit 84c5412b7f
2 changed files with 472 additions and 0 deletions

100
mpp/base/inc/mpp_meta.h Normal file
View 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
View 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;
}