186 lines
6.6 KiB
C
186 lines
6.6 KiB
C
#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;
|
|
} |