Initial commit: TXW82x FPV v2.7.0.7-42229 SDK + project sources

This commit is contained in:
2026-07-06 11:30:13 +08:00
commit e76462eeb7
3451 changed files with 1415300 additions and 0 deletions

View File

@@ -0,0 +1,89 @@
#include "basic_include.h"
#include "lib/multimedia/msi.h"
#ifdef MORE_SRAM
#define FBPOOL_MALLOC os_malloc_psram
#define FBPOOL_FREE os_free_psram
#define FBPOOL_ZALLOC os_zalloc_psram
#else
#define FBPOOL_MALLOC os_malloc
#define FBPOOL_FREE os_free
#define FBPOOL_ZALLOC os_zalloc
#endif
int32 fbpool_init(struct fbpool *pool, uint8 size)
{
uint8 i;
if (pool && !pool->inited) {
pool->pool = FBPOOL_ZALLOC(sizeof(struct framebuff) * size);
ASSERT(pool->pool);
pool->inited = 1;
pool->size = size;
for (i = 0; i < size; i++) {
pool->pool[i].index = i;
pool->pool[i].used = 0;
pool->pool[i].pool = 1;
}
}
return RET_OK;
}
struct framebuff *fbpool_get(struct fbpool *pool, uint16 type, struct msi *msi)
{
uint8 i;
uint32 flag;
struct framebuff *fb = NULL;
if (pool && pool->inited) {
flag = disable_irq();
for (i = 0; i < pool->size; i++) {
if (!pool->pool[i].used) {
fb = &pool->pool[i];
fb->mtype = (type >> 8) & 0xff;
fb->stype = type & 0xff;
fb->msi = msi;
fb->used = 1;
fb->next = NULL;
msi_get(fb->msi);
atomic_inc(&fb->users); //GET 加1
break;
}
}
enable_irq(flag);
}
return fb;
}
int32 fbpool_put(struct fbpool *pool, struct framebuff *fb)
{
uint32 flag;
if (pool && pool->inited && fb && fb->pool &&
(fb->index < pool->size) && (&pool->pool[fb->index] == fb)) {
flag = disable_irq();
pool->pool[fb->index].used = 0;
pool->pool[fb->index].msi = NULL;
pool->pool[fb->index].next = NULL;
atomic_set(&fb->users,0);
enable_irq(flag);
return RET_OK;
} else {
os_printf(KERN_ERR"fbpool_put error, pool=%p, fb=%p\r\n", pool, fb);
return RET_ERR;
}
}
int32 fbpool_destroy(struct fbpool *pool)
{
int32 i = 0;
if (pool && pool->inited) {
for (i = 0; i < pool->size; i++) {
msi_discard_fb(pool->pool[i].msi, &pool->pool[i]);
}
FBPOOL_FREE(pool->pool);
pool->inited = 0;
pool->size = 0;
}
return RET_OK;
}

View File

@@ -0,0 +1,268 @@
#include "basic_include.h"
#include "lib/multimedia/msi.h"
#ifdef MORE_SRAM
#define FBQ_MALLOC os_malloc_psram
#define FBQ_FREE os_free_psram
#define FBQ_ZALLOC os_zalloc_psram
#else
#define FBQ_MALLOC os_malloc
#define FBQ_FREE os_free
#define FBQ_ZALLOC os_zalloc
#endif
int32 fbq_init(struct fbqueue *q, uint8 *qbuff, int32 qsize)
{
if (qbuff == NULL && qsize) {
qbuff = (uint8 *)FBQ_MALLOC(sizeof(struct framebuff *) * (qsize + 1));
q->alloc = 1;
}
ASSERT(qbuff);
if (qbuff && qsize) {
RB_INIT_R(&q->rbQ, (qsize + 1), (struct framebuff **)qbuff);
os_sema_init(&q->sema, 0);
q->reader_max = 1;
q->readers = NULL;
q->init = 1;
return RET_OK;
}
return RET_ERR;
}
int32 fbq_destory(struct fbqueue *q)
{
if (q && q->init) {
while (RB_COUNT(&q->rbQ)) {
fb_put(fbq_dequeue(q, 0));
}
if (q->alloc) {
FBQ_FREE(q->rbQ.rbq);
}
if (q->readers) {
FBQ_FREE(q->readers);
}
os_sema_del(&q->sema);
q->init = 0;
}
return RET_OK;
}
int32 fbq_enqueue(struct fbqueue *q, struct framebuff *fb)
{
int32 ret;
uint32 i;
uint32 rpos;
uint32 flags;
struct framebuff *last = NULL;
if (!q || !q->init || !fb) {
return 0;
}
fb_get(fb);
if (q->reader_max > 1) {
flags = disable_irq();
if (RB_FULL(&q->rbQ)) { // FULL ! move rpos.
last = q->rbQ.rbq[q->rbQ.rpos];
rpos = RB_NPOS(&q->rbQ, rpos, 1);
for (i = 0; i < q->reader_max; i++) {
if (q->readers[i] == q->rbQ.rpos) {
q->readers[i] = rpos;
}
}
q->rbQ.rpos = rpos;
}
q->rbQ.rbq[q->rbQ.wpos] = fb;
q->rbQ.wpos = RB_NPOS(&q->rbQ, wpos, 1);
enable_irq(flags);
fb_put(last);
return 1;
} else {
ret = RB_INT_SET(&q->rbQ, fb);
if (ret) {
os_sema_up(&q->sema);
return 1;
} else {
fb_put(fb);
return 0;
}
}
}
static int32 fbq_trace_pos(struct fbqueue *q, struct framebuff *fb, uint32 start, uint32 end, int8 discard)
{
uint32 pos;
for (pos = start; pos < end; pos++) {
if (q->rbQ.rbq[pos] == fb) {
if (discard) {
q->rbQ.rbq[pos] = NULL;
}
return 1;
}
}
return 0;
}
int32 fbq_trace(struct fbqueue *q, struct framebuff *fb, int8 discard)
{
uint32 ret = 0;
uint32 flag;
if (!q || !q->init || !fb) {
return 0;
}
flag = disable_irq();
if (q->rbQ.rpos <= q->rbQ.wpos) {
ret = fbq_trace_pos(q, fb, q->rbQ.rpos, q->rbQ.wpos, discard);
} else {
ret = fbq_trace_pos(q, fb, 0, q->rbQ.wpos, discard);
if (!ret) {
ret = fbq_trace_pos(q, fb, q->rbQ.rpos, q->rbQ.qsize, discard);
}
}
enable_irq(flag);
if (ret && discard) {
fb_put(fb);
}
return 0;
}
struct framebuff *fbq_dequeue(struct fbqueue *q, uint32 tmo_ms)
{
uint64 jiff;
struct framebuff *fb;
if (!q || !q->init) {
return NULL;
}
do {
if (!RB_EMPTY(&q->rbQ)) {
RB_GET(&q->rbQ, fb);
return fb;
}
if(tmo_ms == 0){
return NULL;
}
jiff = os_jiffies();
os_sema_down(&q->sema, tmo_ms);
jiff = DIFF_JIFFIES(jiff, os_jiffies());
jiff = os_jiffies_to_msecs(jiff);
if (jiff >= tmo_ms) {
break;
}
tmo_ms -= jiff;
} while (tmo_ms);
return NULL;
}
struct framebuff *fbq_dequeue_r(struct fbqueue *q, uint8 reader)
{
uint32 i = 0;
uint32 pos;
uint32 flags;
struct framebuff *fb = NULL;
struct framebuff *last = NULL;
if (!q || !q->init) {
return NULL;
}
ASSERT(reader > 0 && reader <= q->reader_max);
ASSERT(q->readers[reader - 1] != 0xffffffff);
reader -= 1;
flags = disable_irq();
pos = q->readers[reader];
if (pos == q->rbQ.wpos) { //no fb for this reader
enable_irq(flags);
return fb;
}
fb = q->rbQ.rbq[pos];
q->readers[reader] = NEXT_RPOS(pos, q->rbQ.qsize, 1);
//move rpos: find min pos.
pos = 0xffffffff;
for (i = 0; i < q->reader_max; i++) {
if (q->readers[i] < pos) {
pos = q->readers[i];
}
}
if (pos != 0xffffffff && q->rbQ.rpos != pos) {
last = q->rbQ.rbq[q->rbQ.rpos];
q->rbQ.rpos = pos;
}
fb_get(fb);
enable_irq(flags);
fb_put(last);
return fb;
}
int32 fbq_conf_readers(struct fbqueue *q, uint16 reader_max)
{
uint32 i;
uint32 *ptr;
if (!q || !q->init || reader_max <= 1 || q->readers) {
return -EINVAL;
}
ptr = (uint32 *)FBQ_MALLOC(reader_max * sizeof(uint32));
if (ptr) {
for (i = 0; i < q->reader_max; i++) {
q->readers[i] = 0xffffffff;
}
q->readers = ptr;
q->reader_max = reader_max;
return RET_OK;
}
return -ENOMEM;
}
int32 fbq_open_reader(struct fbqueue *q)
{
uint32 i;
uint32 flags;
if (!q || !q->init || !q->readers) {
return 0;
}
flags = disable_irq();
for (i = 0; i < q->reader_max; i++) {
if (q->readers[i] == 0xffffffff) {
q->readers[i] = q->rbQ.rpos;
break;
}
}
enable_irq(flags);
return i < q->reader_max ? (i + 1) : 0;
}
int32 fbq_close_reader(struct fbqueue *q, uint8 reader)
{
uint32 flags;
if (!q || !q->init || !q->readers) {
return -EINVAL;
}
ASSERT(reader > 0 && reader <= q->reader_max);
flags = disable_irq();
q->readers[reader - 1] = 0xffffffff;
enable_irq(flags);
return RET_OK;
}

View File

@@ -0,0 +1,148 @@
#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个framebufffb_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;
}
}

View File

@@ -0,0 +1,463 @@
#include "basic_include.h"
#include "lib/multimedia/msi.h"
#define MSI_MATCH(msi, name) (os_strcmp((msi)->name, name)==0)
//媒体流组件列表
struct msi_core {
struct msi *list;
struct os_mutex lock;
} g_MSI;
static void msi_free(struct msi *msi);
/////////////////////////////////////////////////////////////////////////////
//局部函数
void msi_get(struct msi *msi)
{
if (msi) {
atomic_inc(&msi->users);
}
}
void msi_put(struct msi *msi)
{
uint32 bound;
uint32 inited;
if (msi) {
ASSERT(atomic_read(&msi->users) > 0);
bound = atomic_read(&msi->bound);
inited = atomic_read(&msi->inited);
if (atomic_dec_and_test(&msi->users) && inited == 0) {
msi_do_cmd(msi, MSI_CMD_POST_DESTROY, 0, 0);
msi->priv = NULL;
msi->action = NULL;
fbq_destory(&msi->fbQ);
if (bound == 0) {
msi_free(msi);
}else{
msi->deleted = 0;
}
}
}
}
static int32 msi_bound(struct msi *msi, struct msi *o_if)
{
int i;
for (i = 0; i < MSI_OUTIF_MAX; i++) {
if (msi->output_list[i] == o_if) {
return 1;
}
}
return 0;
}
static int32 msi_bind(struct msi *msi, struct msi *o_if)
{
int i;
if (msi_bound(msi, o_if)) {
return RET_OK;
}
for (i = 0; i < MSI_OUTIF_MAX; i++) {
if (msi->output_list[i] == NULL) {
atomic_inc(&o_if->bound);
msi->output_list[i] = o_if;
return RET_OK;
}
}
os_printf(KERN_ERR"msi %s bind %s fail!\r\n", msi->name, o_if->name);
return RET_ERR;
}
static int32 msi_unbind(struct msi *msi, struct msi *o_if)
{
int i;
uint32 flag;
uint32 users;
struct msi *out;
for (i = 0; i < MSI_OUTIF_MAX; i++) {
flag = disable_irq();
out = msi->output_list[i];
if (out && (out == o_if || o_if == NULL)) {
msi->output_list[i] = NULL;
enable_irq(flag);
users = atomic_read(&out->users);
if (atomic_dec_and_test(&out->bound) && users == 0) {
msi_free(out); //引用计数 和 绑定计数都等于0释放msi
}
if (o_if) {
return RET_OK;
}
}
enable_irq(flag);
}
return RET_OK;
}
//该函数需要在lock保护下执行
static struct msi *msi_find_lock(const char *name)
{
uint32 flag = disable_irq();
struct msi *msi = g_MSI.list;
while (msi) {
if (MSI_MATCH(msi, name)) {
break;
}
msi = msi->next;
}
enable_irq(flag);
return msi;
}
//该函数需要在lock保护下执行
static void msi_list_add(struct msi *msi)
{
uint32 flag = disable_irq();
msi->next = g_MSI.list;
g_MSI.list = msi;
enable_irq(flag);
}
//该函数需要在lock保护下执行
static int32 msi_list_del(struct msi *msi)
{
struct msi *ptr, *prev;
uint32 flag = disable_irq();
prev = NULL;
ptr = g_MSI.list;
while (ptr) {
if (ptr == msi) {
if (prev) {
prev->next = ptr->next;
} else {
g_MSI.list = ptr->next;
}
break;
}
prev = ptr;
ptr = ptr->next;
}
enable_irq(flag);
return RET_OK;
}
//该函数需要在lock保护下执行
static void msi_notify_up(struct msi *msi, uint32 cmd, uint32 param1, uint32 param2)
{
struct msi *ptr = g_MSI.list;
while (ptr) {
if (ptr != msi && msi_bound(ptr, msi)) {
msi_do_cmd(ptr, cmd, param1, param2);
msi_notify_up(ptr, cmd, param1, param2);
}
ptr = ptr->next;
}
}
//该函数需要在lock保护下执行
static struct msi *msi_new_lock(const char *name)
{
struct msi *msi = msi_find_lock(name);
if (msi == NULL) {
msi = os_zalloc(sizeof(struct msi));
if (msi) {
msi->name = name;
msi_list_add(msi);
}
}
return msi;
}
static void msi_free(struct msi *msi)
{
if (msi) {
msi_list_del(msi);
msi_unbind(msi, NULL); //取消所有关联的组件
os_free(msi);
}
}
/////////////////////////////////////////////////////////////////////////////
//全局函数
struct msi *msi_new(const char *name, uint32 qsize, uint8 *isnew)
{
struct msi *msi;
os_mutex_lock(&g_MSI.lock, osWaitForever);
msi = msi_new_lock(name);
if(msi && msi->deleted){
os_printf(KERN_ERR"msi %s destory running ....\r\n", name);
msi = NULL;
}
if (msi) {
if(isnew) {
*isnew = msi->inited.counter == 0;
}
atomic_inc(&msi->inited);
atomic_inc(&msi->users);
if (!msi->fbQ.init && qsize) {
fbq_init(&msi->fbQ, NULL, qsize+1);
}
}
os_mutex_unlock(&g_MSI.lock);
return msi;
}
void msi_destroy(struct msi *msi)
{
if (msi) {
os_printf(KERN_ERR"msi %s destory, lr:%x\r\n", msi->name, RETURN_ADDR());
os_mutex_lock(&g_MSI.lock, osWaitForever);
if(atomic_dec_and_test(&msi->inited)){
msi->enable = 0;
msi->deleted = 1;
msi_do_cmd(msi, MSI_CMD_PRE_DESTROY, 0, 0);
msi_put(msi);
}else{
atomic_dec(&msi->users);
}
os_mutex_unlock(&g_MSI.lock);
}
}
//根据ID查找是否存在该组件引用计数为加1使用后需要执行 msi_put
struct msi *msi_find(const char *name, uint8 inited)
{
struct msi *msi;
if(name == NULL){
return NULL;
}
os_mutex_lock(&g_MSI.lock, osWaitForever);
msi = msi_find_lock(name);
if(msi && inited && atomic_read(&msi->inited) == 0){
msi = NULL;
}else{
msi_get(msi);
}
os_mutex_unlock(&g_MSI.lock);
return msi;
}
//设置该组件的输出组件
int32 msi_add_output(struct msi *msi, const char *lname, const char *oname)
{
int32 ret = RET_ERR;
struct msi *l_msi, *o_msi;
os_mutex_lock(&g_MSI.lock, osWaitForever);
l_msi = msi ? msi : msi_new_lock(lname);
o_msi = msi_new_lock(oname);
if (l_msi && o_msi) {
ret = msi_bind(l_msi, o_msi);
}
os_mutex_unlock(&g_MSI.lock);
return ret;
}
//删除该组件的输出组件
int32 msi_del_output(struct msi *msi, const char *lname, const char *oname)
{
int32 ret = RET_ERR;
struct msi *l_msi, *o_msi;
os_mutex_lock(&g_MSI.lock, osWaitForever);
l_msi = msi ? msi : msi_find(lname, 0);
o_msi = msi_find(oname, 0);
if (l_msi && o_msi) {
ret = msi_unbind(l_msi, o_msi);
}
if(msi == NULL){
msi_put(l_msi);
}
msi_put(o_msi);
os_mutex_unlock(&g_MSI.lock);
return ret;
}
//组件输出cmd: 遍历自己的输出组件列表,调用输出组件的 action 接口
int32 msi_output_cmd(struct msi *msi, uint32 cmd, uint32 param1, uint32 param2)
{
int8 i;
if(!msi){
return RET_OK;
}
for (i = 0; i < MSI_OUTIF_MAX; i++) {
msi_do_cmd(msi->output_list[i], cmd, param1, param2);
}
return RET_OK;
}
//组件输出framebuff: 输出framebuff给自己的组件列表
//注意fb参数只能是 framebuff链表的第1个节点不能是中间节点
//如果fb为空,就是检查是否有数据流接收(返回0x80000000)
int32 msi_output_fb(struct msi *msi, struct framebuff *fb)
{
int ret = 0;
int8 i;
uint32 flag;
struct msi *out;
if(!msi || !msi->enable){
fb_put(fb);
return 0;
}
for (i = 0; i < MSI_OUTIF_MAX; i++) {
flag = disable_irq();
out = msi->output_list[i];
if(out && out->enable){
msi_get(out);
}else{
out = NULL;
}
enable_irq(flag);
if(out && out->enable){
if(!fb){
ret = -1;
msi_put(out);
break;
} else {
if(msi_do_cmd(out, MSI_CMD_TRANS_FB, (uint32)fb, 0) == RET_OK){
if(out->fbQ.init && fbq_enqueue(&out->fbQ, fb)){
msi_do_cmd(out, MSI_CMD_TRANS_FB_END, (uint32)fb, 0);
ret++;
}
}
}
}
msi_put(out);
}
fb_put(fb);
return ret;
}
//组件不输出framebuff需要删除framebuff
//注意fb参数只能是 framebuff链表的第1个节点不能是中间节点
int32 msi_delete_fb(struct msi *msi, struct framebuff *fb)
{
fb_put(fb);
return RET_OK;
}
struct framebuff *msi_get_fb(struct msi *msi, uint32 tmo_ms)
{
if(msi && msi->fbQ.init){
return fbq_dequeue(&msi->fbQ, tmo_ms);
}
return NULL;
}
struct framebuff *msi_get_fb_r(struct msi *msi, uint32 reader)
{
if(msi && msi->fbQ.init){
return fbq_dequeue_r(&msi->fbQ, reader);
}
return NULL;
}
//追踪某个framebuff当前在被哪些模块处理
static int32 msi_fb_trace_discard(struct msi *msi, struct framebuff *fb, uint8 discard)
{
int8 i;
uint32 flag;
struct msi *out;
if(msi == NULL){
return RET_OK;
}
if(fbq_trace(&msi->fbQ, fb, discard)){
os_printf(KERN_ERR"MSI:%s framebuff %p is here!\r\n", msi->name, fb);
}
for (i = 0; i < MSI_OUTIF_MAX; i++) {
flag = disable_irq();
out = msi->output_list[i];
msi_get(out);
enable_irq(flag);
if(out && out->fbQ.init && fbq_trace(&msi->fbQ, fb, discard)){
os_printf(KERN_ERR"MSI:%s framebuff %p is here!\r\n", msi->name, fb);
}
msi_put(out);
}
return RET_OK;
}
//追踪framebuff查看指定的framebuff当前在被哪些模块处理
int32 msi_trace_fb(struct msi *msi, struct framebuff *fb)
{
return msi_fb_trace_discard(msi, fb, 0);
}
//通知通路中的各个模块丢弃指定的framebuff
int32 msi_discard_fb(struct msi *msi, struct framebuff *fb)
{
return msi_fb_trace_discard(msi, fb, 1);
}
//组件产生notify操作可以向上/向下传递
void msi_notify(struct msi *msi, uint32 cmd, uint32 param1, uint32 param2)
{
os_mutex_lock(&g_MSI.lock, osWaitForever);
msi_notify_up(msi, cmd, param1, param2); //向上
os_mutex_unlock(&g_MSI.lock);
msi_output_cmd(msi, cmd, param1, param2); //向下
}
//组件执行自己的action
int32 msi_do_cmd(struct msi *msi, uint32 cmd, uint32 param1, uint32 param2)
{
uint32 flag;
int32 ret = RET_OK;
msi_action action;
if(msi){
flag = disable_irq();
action = msi->action;
enable_irq(flag);
if(action){
ret = action(msi, cmd, param1, param2);
}
}
return ret;
}
//指定从某个组件开始执行cmd
void msi_cmd(const char *name, uint32 cmd, uint32 param1, uint32 param2)
{
struct msi *msi = msi_find(name, 0);
if (msi) {
msi_do_cmd(msi, cmd, param1, param2);
msi_output_cmd(msi, cmd, param1, param2);
msi_put(msi);
}
}
int32 msi_core_init()
{
os_mutex_init(&g_MSI.lock);
return RET_OK;
}

View File

@@ -0,0 +1,51 @@
#include "basic_include.h"
#include "lib/multimedia/msi.h"
static int32 msi_rbuffer_fb_exist(struct rbuffer *rb, struct framebuff *fb, uint32 start, uint32 end)
{
uint32 i = 0;
struct framebuff **q = (struct framebuff **)rb->rbq;
for (i = start; i < end; i++) {
if (q[i] == fb) {
return 1;
} else {
struct framebuff *next = q[i]->next;
while (next) {
if (next == fb) {
return 1;
} else {
next = next;
}
}
}
}
return 0;
}
int32 msi_rbuffer_trace_fb(struct msi *mif, struct rbuffer *rb, struct framebuff *fb)
{
uint32 rpos = rb->rpos;
uint32 wpos = rb->wpos;
if (!RB_EMPTY(rb)) {
if (rpos < wpos) {
if (msi_rbuffer_fb_exist(rb, fb, rpos, wpos)) {
os_printf(KERN_NOTICE"MSI %s: FB %p is here!\r\n", mif->name, fb);
return 1;
}
} else {
if (msi_rbuffer_fb_exist(rb, fb, rpos, rb->qsize)) {
os_printf(KERN_NOTICE"MSI %s: FB %p is here!\r\n", mif->name, fb);
return 1;
}
if (msi_rbuffer_fb_exist(rb, fb, 0, wpos)) {
os_printf(KERN_NOTICE"MSI %s: FB %p is here!\r\n", mif->name, fb);
return 1;
}
}
}
return 0;
}