149 lines
3.7 KiB
C
149 lines
3.7 KiB
C
|
|
#include "basic_include.h"
|
|||
|
|
#include "lib/multimedia/msi.h"
|
|||
|
|
|
|||
|
|
static void fb_free(struct framebuff *fb)
|
|||
|
|
{
|
|||
|
|
int32 ret = 0;
|
|||
|
|
struct msi *msi;
|
|||
|
|
|
|||
|
|
if (fb) {
|
|||
|
|
ASSERT(atomic_read(&fb->users) > 0);
|
|||
|
|
if (!atomic_dec_and_test(&fb->users)) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
msi = fb->msi;
|
|||
|
|
ret = msi_do_cmd(fb->msi, MSI_CMD_FREE_FB, (uint32)fb, 0);
|
|||
|
|
msi_put(msi);
|
|||
|
|
if (ret == RET_OK) { //不等于OK表示模块自己管理fb,例如预分配的fb
|
|||
|
|
ASSERT(!fb->pool); //预分配的framebuff不能执行到这里
|
|||
|
|
FB_FREE(fb);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//framebuff 引用计数加1
|
|||
|
|
void fb_get(struct framebuff *fb)
|
|||
|
|
{
|
|||
|
|
if (fb) {
|
|||
|
|
fb_get(fb->next);
|
|||
|
|
atomic_inc(&fb->users);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
struct framebuff *fb_alloc(uint8 *data, int32 size, uint16 type, struct msi *msi)
|
|||
|
|
{
|
|||
|
|
int32 len = data ? 0 : size;
|
|||
|
|
struct framebuff *fb = FB_ALLOC(sizeof(struct framebuff) + len);
|
|||
|
|
if (fb) {
|
|||
|
|
os_memset(fb, 0, sizeof(struct framebuff));
|
|||
|
|
atomic_set(&fb->users, 1);
|
|||
|
|
fb->len = size;
|
|||
|
|
fb->msi = msi;
|
|||
|
|
fb->mtype = (type >> 8) & 0xff;
|
|||
|
|
fb->stype = type & 0xff;
|
|||
|
|
msi_get(fb->msi);
|
|||
|
|
if (data) {
|
|||
|
|
fb->data = data;
|
|||
|
|
} else if (size) {
|
|||
|
|
fb->data = (uint8 *)(fb + 1);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return fb;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
struct framebuff *fb_clone(struct framebuff *fb, uint16 type, struct msi *msi)
|
|||
|
|
{
|
|||
|
|
struct framebuff *fb_n = FB_ALLOC(sizeof(struct framebuff));
|
|||
|
|
if (fb_n) {
|
|||
|
|
os_memset(fb_n, 0, sizeof(struct framebuff));
|
|||
|
|
atomic_set(&fb_n->users, 1);
|
|||
|
|
fb_n->clone = 1;
|
|||
|
|
fb_n->msi = msi;
|
|||
|
|
fb_n->mtype = (type >> 8) & 0xff;
|
|||
|
|
fb_n->stype = type & 0xff;
|
|||
|
|
msi_get(fb_n->msi);
|
|||
|
|
fb_n->data = fb->data;
|
|||
|
|
fb_n->len = fb->len;
|
|||
|
|
fb_n->time = fb->time;
|
|||
|
|
fb_n->priv = fb->priv;
|
|||
|
|
fb_n->srcID = fb->srcID;
|
|||
|
|
fb_n->datatag = fb->datatag;
|
|||
|
|
fb_get(fb);
|
|||
|
|
fb_n->next = fb;
|
|||
|
|
}
|
|||
|
|
return fb_n;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//framebuff 引用计数减1,当计数减至0时会释放空间
|
|||
|
|
void fb_put(struct framebuff *fb)
|
|||
|
|
{
|
|||
|
|
if (fb) {
|
|||
|
|
fb_put(fb->next);
|
|||
|
|
fb_free(fb);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//使用新的framebuff引用关联另1个framebuff,fb_old引用计数加1
|
|||
|
|
void fb_ref(struct framebuff *fb_new, struct framebuff *fb_old)
|
|||
|
|
{
|
|||
|
|
ASSERT(fb_new->next == NULL);
|
|||
|
|
fb_get(fb_old);
|
|||
|
|
fb_new->next = fb_old;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//获取framebuff链表中指定type的数据的第1个节点
|
|||
|
|
struct framebuff *fb_find(struct framebuff *fb, uint8 mtype, uint8 stype)
|
|||
|
|
{
|
|||
|
|
if (mtype == 0 || fb == NULL || fb->next == NULL) {
|
|||
|
|
return fb;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
while (fb) {
|
|||
|
|
if (fb->mtype == mtype && (fb->stype == stype || stype == 0)) {
|
|||
|
|
return fb;
|
|||
|
|
}
|
|||
|
|
fb = fb->next;
|
|||
|
|
}
|
|||
|
|
return NULL;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//获取framebuff链表中指定type的数据的总长度
|
|||
|
|
uint32 fb_len(struct framebuff *fb, uint8 mtype, uint8 stype)
|
|||
|
|
{
|
|||
|
|
uint32 len = 0;
|
|||
|
|
|
|||
|
|
if (mtype == 0 || fb == NULL) {
|
|||
|
|
return fb ? fb->len : 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (fb->mtype != mtype) {
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
while (fb) {
|
|||
|
|
if (fb->mtype == mtype && (fb->stype == stype || stype == 0)) {
|
|||
|
|
len += fb->len;
|
|||
|
|
}
|
|||
|
|
fb = fb->next;
|
|||
|
|
}
|
|||
|
|
return len;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//根据fb->mtype 识别fb携带的数据为 视频,音频,图片,字幕
|
|||
|
|
MEDIA_DATA_CATEGORY fb_category(struct framebuff *fb)
|
|||
|
|
{
|
|||
|
|
if (fb->mtype < 32) { //video
|
|||
|
|
return MEDIA_DATA_VIDEO;
|
|||
|
|
} else if (fb->mtype < 64) { //audio
|
|||
|
|
return MEDIA_DATA_AUDIO;
|
|||
|
|
} else if (fb->mtype < 96) { //picture
|
|||
|
|
return MEDIA_DATA_PICTURE;
|
|||
|
|
} else if (fb->mtype < 128) { //text
|
|||
|
|
return MEDIA_DATA_TEXT;
|
|||
|
|
} else {
|
|||
|
|
return MEDIA_DATA_MAX;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|