Files
TAIXIN/sdk/app/video_app/auto_h264_msi.c

186 lines
6.6 KiB
C
Raw Normal View History

#include "basic_include.h"
#include "lib/multimedia/msi.h"
#include "lib/heap/av_heap.h"
#include "lib/heap/av_psram_heap.h"
#include "stream_define.h"
#include "user_work/user_work.h"
struct msi *h264_msi_init_with_mode(uint32_t drv1_from, uint16_t drv1_w, uint16_t drv1_h, uint16_t drv2_from, uint16_t drv2_w, uint16_t drv2_h);
struct msi *h264_msi_init_with_timeLapse(uint32_t drv1_from, uint16_t drv1_w, uint16_t drv1_h, uint32_t timer);
// data申请空间函数
#define STREAM_MALLOC av_psram_malloc
#define STREAM_FREE av_psram_free
#define STREAM_ZALLOC av_psram_zalloc
// 结构体申请空间函数
#define STREAM_LIBC_MALLOC av_malloc
#define STREAM_LIBC_FREE av_free
#define STREAM_LIBC_ZALLOC av_zalloc
struct auto_h264_msi_s
{
struct os_work work;
struct msi *msi;
struct msi *register_h264_msi;
uint32_t timeLapse_timer;
uint16_t w0, w1, h0, h1;
uint8_t src_from0;
uint8_t src_from1;
// mode: 0:默认 1:缩时录影模式,其他:默认模式
uint8_t stop : 1, mode : 1, current_mode : 1;
};
static int32 auto_h264_work(struct os_work *work)
{
uint8_t delay_time = 40;
struct auto_h264_msi_s *auto_h264 = (struct auto_h264_msi_s *) work;
struct msi *auto_h264_msi = auto_h264->msi;
// 这里尝试发送数据?检查一下是否有接收的msi,如果有接收的msi,则启动mjpeg,如果没有,则将硬件停下来?
uint32_t send_count = msi_output_fb(auto_h264->msi, NULL);
if (send_count)
{
// 如果模式不一样,则将stop置位1,重新启动
uint8_t mode = auto_h264->mode;
if (mode != auto_h264->current_mode)
{
auto_h264->current_mode = mode;
auto_h264->stop = 1;
}
if (auto_h264->stop == 1)
{
// 启动h264
if (auto_h264->register_h264_msi)
{
msi_del_output(auto_h264->register_h264_msi, NULL, auto_h264_msi->name);
msi_destroy(auto_h264->register_h264_msi);
auto_h264->register_h264_msi = NULL;
}
// 尝试重新创建,如果创建失败,下一次再继续创建
if (auto_h264->current_mode == 1)
{
auto_h264->register_h264_msi = h264_msi_init_with_timeLapse(auto_h264->src_from0, auto_h264->w0, auto_h264->h0, auto_h264->timeLapse_timer);
}
else
{
auto_h264->register_h264_msi = h264_msi_init_with_mode(auto_h264->src_from0, auto_h264->w0, auto_h264->h0, auto_h264->src_from1, auto_h264->w1, auto_h264->h1);
}
if (auto_h264->register_h264_msi)
{
msi_add_output(auto_h264->register_h264_msi, NULL, auto_h264_msi->name);
auto_h264->stop = 0;
}
}
}
else if (send_count == 0)
{
if (auto_h264->stop == 0)
{
// 停止h264的启动
auto_h264->stop = 1;
if (auto_h264->register_h264_msi)
{
msi_del_output(auto_h264->register_h264_msi, NULL, auto_h264_msi->name);
msi_destroy(auto_h264->register_h264_msi);
auto_h264->register_h264_msi = NULL;
}
}
}
os_run_work_delay(work, delay_time);
return 0;
}
static int32_t auto_h264_msi_action(struct msi *msi, uint32_t cmd_id, uint32_t param1, uint32_t param2)
{
int32_t ret = RET_OK;
struct auto_h264_msi_s *auto_h264 = (struct auto_h264_msi_s *) msi->priv;
switch (cmd_id)
{
case MSI_CMD_POST_DESTROY:
{
os_work_cancle2(&auto_h264->work, 1);
STREAM_LIBC_FREE(auto_h264);
}
break;
case MSI_CMD_PRE_DESTROY:
{
os_work_cancle2(&auto_h264->work, 1);
if (auto_h264->register_h264_msi)
{
msi_destroy(auto_h264->register_h264_msi);
auto_h264->register_h264_msi = NULL;
}
}
break;
case MSI_CMD_TRANS_FB:
{
struct framebuff *fb = (struct framebuff *) param1;
// 如果是mjpeg,帮忙转发到其他数据流
// 如果需要支持264,也要帮忙转发
if (fb->mtype == F_H264)
{
// 类型匹配才可以转发
if ((fb->stype == FSTYPE_H264_VPP_DATA0 + auto_h264->src_from0) || (fb->stype == FSTYPE_H264_VPP_DATA0 + auto_h264->src_from1))
{
_os_printf("+");
struct framebuff *fb = (struct framebuff *) param1;
fb_get(fb);
msi_output_fb(msi, fb);
}
ret = RET_OK + 1;
break;
}
}
break;
case MSI_CMD_AUTO_H264:
{
uint32_t cmd_self = (uint32_t) param1;
switch (cmd_self)
{
case MSI_AUTO_H264_MODE:
auto_h264->mode = param2;
break;
case MSI_AUTO_H264_TIMELAPSE_TIME:
auto_h264->timeLapse_timer = param2;
break;
}
break;
}
default:
break;
}
return ret;
}
// 如果不使能,src_from0设置最大值,其他设置为0
// src_from为VPP_DATA0或者VPP_DATA1,是支持自动设置w和h
struct msi *auto_h264_msi_init(const char *auto_h264_name, uint8_t src_from0, uint16_t w0, uint16_t h0, uint8_t src_from1, uint16_t w1, uint16_t h1)
{
uint8_t isnew;
struct msi *msi = msi_new(auto_h264_name, 0, &isnew);
struct auto_h264_msi_s *auto_h264 = (struct auto_h264_msi_s *) msi->priv;
if (isnew)
{
auto_h264 = (struct auto_h264_msi_s *) STREAM_LIBC_ZALLOC(sizeof(struct auto_h264_msi_s));
msi->priv = (void *) auto_h264;
msi->action = auto_h264_msi_action;
auto_h264->msi = msi;
auto_h264->stop = 1;
auto_h264->src_from0 = src_from0;
auto_h264->src_from1 = src_from1;
auto_h264->w0 = w0;
auto_h264->w1 = w1;
auto_h264->h0 = h0;
auto_h264->h1 = h1;
auto_h264->timeLapse_timer = 1000;
msi->enable = 1;
// 启动workqueue
OS_WORK_INIT(&auto_h264->work, auto_h264_work, 0);
os_run_work(&auto_h264->work);
}
return msi;
}