pure sdk for main
This commit is contained in:
@@ -0,0 +1,431 @@
|
||||
#include "sys_config.h"
|
||||
#include "typesdef.h"
|
||||
#include "dev.h"
|
||||
#include "devid.h"
|
||||
#include "stream_frame.h"
|
||||
#include "utlist.h"
|
||||
#include "osal/work.h"
|
||||
#include "custom_mem/custom_mem.h"
|
||||
#include "osal/string.h"
|
||||
#include "osal/task.h"
|
||||
#include "osal/event.h"
|
||||
#include "stream_define.h"
|
||||
#include "avidemux.h"
|
||||
#include "osal_file.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* AVI2.0
|
||||
*****************************************************************************/
|
||||
|
||||
//data申请空间函数
|
||||
#define STREAM_MALLOC custom_malloc_psram
|
||||
#define STREAM_FREE custom_free_psram
|
||||
#define STREAM_ZALLOC custom_zalloc_psram
|
||||
|
||||
//结构体申请空间函数
|
||||
#define STREAM_LIBC_MALLOC custom_malloc
|
||||
#define STREAM_LIBC_FREE custom_free
|
||||
#define STREAM_LIBC_ZALLOC custom_zalloc
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
PLAYER2_STOP = BIT(0),
|
||||
PLAYER2_EXIT = BIT(1),
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct player2_msg_s
|
||||
{
|
||||
void *task;
|
||||
struct os_event evt;
|
||||
void *fp;
|
||||
struct aviinfo *info;
|
||||
stream *s;
|
||||
uint32_t magic;
|
||||
struct data_structure *video_data_tmp;
|
||||
struct data_structure *audio_data_tmp;
|
||||
int32_t locate_frame_number;
|
||||
uint32_t fps;
|
||||
uint32_t frq;
|
||||
//用于音频视频同步计算的时间
|
||||
uint32_t video_time;
|
||||
uint32_t audio_time;
|
||||
uint8_t thread_stop : 1, rev: 7;
|
||||
};
|
||||
|
||||
|
||||
//暂时不支持快进快退
|
||||
static uint32_t newavi_player2_cmd(stream *s,int opcode,uint32_t arg)
|
||||
{
|
||||
uint32_t res = 0;
|
||||
struct player2_msg_s *msg = (struct player2_msg_s *)s->priv;
|
||||
switch(opcode)
|
||||
{
|
||||
//跳转位置,快进
|
||||
case NEWAVI_PLAYER_LOCATE_FORWARD_INDEX:
|
||||
{
|
||||
res = msg->locate_frame_number*1000/msg->fps;
|
||||
}
|
||||
break;
|
||||
|
||||
//快退
|
||||
case NEWAVI_PLAYER_LOCATE_REWIND_INDEX:
|
||||
{
|
||||
res = msg->locate_frame_number*1000/msg->fps;
|
||||
}
|
||||
break;
|
||||
//修改data的magic,用于过滤某些数据情况
|
||||
case NEWAVI_PLAYER_MAGIC:
|
||||
msg->magic = arg;
|
||||
break;
|
||||
//返回是否正在播放的状态
|
||||
case NEWAVI_PLAYER_STATUS:
|
||||
res = msg->thread_stop;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void newplayer2_thread(void *d)
|
||||
{
|
||||
struct player2_msg_s *msg = (struct player2_msg_s *)d;
|
||||
stream *s = msg->s;
|
||||
uint32_t base = 0,size;
|
||||
uint32_t audio_base;
|
||||
uint32_t base_tmp = 0;
|
||||
int res = 0;
|
||||
int read_len;
|
||||
uint8_t *data = NULL;
|
||||
struct aviinfo *info = msg->info;
|
||||
uint32_t audio_read_len = 0;
|
||||
|
||||
while(!msg->thread_stop)
|
||||
{
|
||||
if(!s->enable)
|
||||
{
|
||||
goto newplayer2_thread_wait;
|
||||
}
|
||||
|
||||
if(!msg->video_data_tmp)
|
||||
{
|
||||
msg->video_data_tmp = get_src_data_f(msg->s);
|
||||
}
|
||||
|
||||
if(msg->frq && !msg->audio_data_tmp)
|
||||
{
|
||||
msg->audio_data_tmp = get_src_data_f(msg->s);
|
||||
}
|
||||
|
||||
if(!msg->video_data_tmp && !msg->audio_data_tmp)
|
||||
{
|
||||
goto newplayer2_thread_wait;
|
||||
}
|
||||
|
||||
if(msg->video_data_tmp)
|
||||
{
|
||||
//这里应该要去计算一下音频视频是否同步,以音频为主(因为音频比较敏感)
|
||||
//播放的时间小,就需要播放下一帧视频
|
||||
//os_printf("video_time:%d\taudio_time:%d\n",msg->video_time,msg->audio_time);
|
||||
if(msg->video_time > msg->audio_time)
|
||||
{
|
||||
goto newplayer2_thread_video_end;
|
||||
}
|
||||
//代表已经发送了,可以尝试读取下一帧
|
||||
if(base == base_tmp)
|
||||
{
|
||||
res = read_avi_offset(&info->str[0],&base,&size);
|
||||
}
|
||||
|
||||
if(base == 0 || res)
|
||||
{
|
||||
force_del_data(msg->video_data_tmp);
|
||||
msg->video_data_tmp = NULL;
|
||||
|
||||
//需要退出
|
||||
os_printf("@@@@@@@@@@@@@@@@@@@@@@%s:%d\n",__FUNCTION__,__LINE__);
|
||||
goto newplayer2_thread_exit;
|
||||
}
|
||||
|
||||
if(base_tmp != base)
|
||||
{
|
||||
|
||||
//读取data数据发送出去
|
||||
data = (uint8_t*)STREAM_MALLOC(size);
|
||||
if(!data)
|
||||
{
|
||||
goto newplayer2_thread_wait;
|
||||
}
|
||||
read_len = read_avi_data(&info->str[0],(char*)data,size);
|
||||
if(read_len <= 0)
|
||||
{
|
||||
//要退出,结束或者读取异常了
|
||||
os_printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%s:%d\n",__FUNCTION__,__LINE__);
|
||||
goto newplayer2_thread_exit;
|
||||
}
|
||||
|
||||
msg->video_data_tmp->data = data;
|
||||
msg->video_data_tmp->ref = 0;
|
||||
msg->video_data_tmp->type = SET_DATA_TYPE(JPEG,JPEG_FULL);
|
||||
//暂时使用msg->fps帧去播放
|
||||
msg->video_data_tmp->magic = msg->magic;
|
||||
set_stream_real_data_len(msg->video_data_tmp,read_len);
|
||||
msg->locate_frame_number = get_avi_cur(&info->str[0])-1;
|
||||
msg->video_time = get_avi_cur(&info->str[0])*1000/msg->fps;
|
||||
set_stream_data_time(msg->video_data_tmp,(get_avi_cur(&info->str[0])-1)*1000/msg->fps);
|
||||
//_os_printf("(V:%X\ttype:%X\tread_len:%d)\r\n",msg->video_data_tmp,msg->video_data_tmp->type,read_len);
|
||||
send_data_to_stream(msg->video_data_tmp);
|
||||
msg->video_data_tmp = NULL;
|
||||
data = NULL;
|
||||
|
||||
base_tmp = base;
|
||||
_os_printf("(V)");
|
||||
}
|
||||
else
|
||||
{
|
||||
msg->locate_frame_number = get_avi_cur(&info->str[0])-1;
|
||||
msg->video_time = get_avi_cur(&info->str[0])*1000/msg->fps;
|
||||
}
|
||||
}
|
||||
|
||||
newplayer2_thread_video_end:
|
||||
if(msg->frq && msg->audio_data_tmp)
|
||||
{
|
||||
if(msg->video_time < msg->audio_time)
|
||||
{
|
||||
goto newplayer2_thread_wait;
|
||||
}
|
||||
|
||||
res = read_avi_offset(&info->str[1],&audio_base,&size);
|
||||
if(audio_base == 0 || res)
|
||||
{
|
||||
force_del_data(msg->audio_data_tmp);
|
||||
msg->audio_data_tmp = NULL;
|
||||
goto newplayer2_thread_exit;
|
||||
}
|
||||
|
||||
|
||||
data = (uint8_t*)STREAM_MALLOC(size);
|
||||
if(!data)
|
||||
{
|
||||
goto newplayer2_thread_wait;
|
||||
}
|
||||
read_len = read_avi_data(&info->str[1],(char*)data,size);
|
||||
if(read_len <= 0)
|
||||
{
|
||||
//要退出,结束或者读取异常了
|
||||
os_printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%s:%d\n",__FUNCTION__,__LINE__);
|
||||
goto newplayer2_thread_exit;
|
||||
}
|
||||
msg->audio_data_tmp->data = data;
|
||||
msg->audio_data_tmp->ref = 0;
|
||||
msg->audio_data_tmp->type = SET_DATA_TYPE(SOUND,SOUND_FILE);
|
||||
//暂时使用msg->fps帧去播放
|
||||
msg->audio_data_tmp->magic = msg->magic;
|
||||
set_stream_real_data_len(msg->audio_data_tmp,read_len);
|
||||
audio_read_len += read_len;
|
||||
set_stream_data_time(msg->audio_data_tmp,msg->audio_time);
|
||||
msg->audio_time = audio_read_len*1000/msg->frq;
|
||||
//_os_printf("(A:%X\ttype:%X\tread_len:%d)\r\n",msg->audio_data_tmp,msg->audio_data_tmp->type,read_len);
|
||||
send_data_to_stream(msg->audio_data_tmp);
|
||||
|
||||
msg->audio_data_tmp = NULL;
|
||||
data = NULL;
|
||||
_os_printf("(A)");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
newplayer2_thread_wait:
|
||||
os_sleep_ms(1);
|
||||
}
|
||||
newplayer2_thread_exit:
|
||||
os_printf("%s:%d exit\n",__FUNCTION__,__LINE__);
|
||||
if(data)
|
||||
{
|
||||
STREAM_FREE(data);
|
||||
data = NULL;
|
||||
}
|
||||
if(msg->video_data_tmp)
|
||||
{
|
||||
force_del_data(msg->video_data_tmp);
|
||||
msg->video_data_tmp = NULL;
|
||||
}
|
||||
|
||||
if(msg->audio_data_tmp)
|
||||
{
|
||||
force_del_data(msg->audio_data_tmp);
|
||||
msg->audio_data_tmp = NULL;
|
||||
}
|
||||
|
||||
msg->thread_stop = 1;
|
||||
os_event_wait(&msg->evt,PLAYER2_STOP,NULL,OS_EVENT_WMODE_OR,-1);
|
||||
os_event_set(&msg->evt,PLAYER2_EXIT,NULL);
|
||||
}
|
||||
|
||||
|
||||
static int opcode_func(stream *s,void *priv,int opcode)
|
||||
{
|
||||
int res = 0;
|
||||
switch(opcode)
|
||||
{
|
||||
case STREAM_OPEN_ENTER:
|
||||
break;
|
||||
case STREAM_OPEN_EXIT:
|
||||
{
|
||||
|
||||
struct player2_msg_s *msg = (struct player2_msg_s*)priv;
|
||||
s->priv = (void*)priv;
|
||||
msg->s = s;
|
||||
msg->magic = 0;
|
||||
msg->thread_stop = 0;
|
||||
msg->fps = msg->info->str[0].dwRate;
|
||||
if(msg->info->strmsk&BIT(1))
|
||||
{
|
||||
msg->frq = msg->info->str[1].dwRate;
|
||||
}
|
||||
else
|
||||
{
|
||||
msg->audio_time = ~0; //没有音频,不需要考虑音频同步
|
||||
}
|
||||
os_printf("fps:%d\tfrq:%d\n",msg->fps,msg->frq);
|
||||
os_event_init(&msg->evt);
|
||||
register_stream_self_cmd_func(s,newavi_player2_cmd);
|
||||
msg->task = os_task_create(s->name,newplayer2_thread,(void*)msg,OS_TASK_PRIORITY_NORMAL,0,NULL,1024);
|
||||
if(!msg->task)
|
||||
{
|
||||
os_event_set(&msg->evt,PLAYER2_EXIT,NULL);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case STREAM_OPEN_FAIL:
|
||||
break;
|
||||
case STREAM_DATA_DIS:
|
||||
{
|
||||
}
|
||||
break;
|
||||
|
||||
case STREAM_DATA_FREE:
|
||||
{
|
||||
struct data_structure *data = (struct data_structure *)priv;
|
||||
if(data->data)
|
||||
{
|
||||
STREAM_FREE(data->data);
|
||||
data->data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case STREAM_FILTER_DATA:
|
||||
{
|
||||
}
|
||||
break;
|
||||
|
||||
case STREAM_DATA_FREE_END:
|
||||
break;
|
||||
|
||||
|
||||
//数据发送完成,可以选择唤醒对应的任务
|
||||
case STREAM_SEND_DATA_FINISH:
|
||||
break;
|
||||
|
||||
|
||||
case STREAM_SEND_DATA_START:
|
||||
{
|
||||
}
|
||||
break;
|
||||
|
||||
case STREAM_DATA_DESTORY:
|
||||
{
|
||||
}
|
||||
break;
|
||||
|
||||
case STREAM_CLOSE_ENTER:
|
||||
{
|
||||
struct player2_msg_s *msg = (struct player2_msg_s*)s->priv;
|
||||
msg->thread_stop = 1;
|
||||
os_event_set(&msg->evt,PLAYER2_STOP,NULL);
|
||||
os_event_wait(&msg->evt,PLAYER2_EXIT,NULL,OS_EVENT_WMODE_OR,-1);
|
||||
os_printf("newavi2_player close\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case STREAM_CLOSE_EXIT:
|
||||
{
|
||||
struct player2_msg_s *msg = (struct player2_msg_s*)s->priv;
|
||||
if(msg->info)
|
||||
{
|
||||
free_aviinfo_point(msg->info);
|
||||
STREAM_LIBC_FREE(msg->info);
|
||||
}
|
||||
|
||||
if(msg->fp)
|
||||
{
|
||||
osal_fclose(msg->fp);
|
||||
}
|
||||
STREAM_LIBC_FREE(msg);
|
||||
os_printf("newavi2_player success\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case STREAM_MARK_GC_END:
|
||||
{
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
//默认都返回成功
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static struct player2_msg_s *avi2_read_init(const char *filename)
|
||||
{
|
||||
struct player2_msg_s *msg = NULL;
|
||||
struct aviinfo *info = NULL;
|
||||
struct aviinfo *info_tmp = NULL;
|
||||
void *fp = NULL;
|
||||
|
||||
fp = osal_fopen(filename,"rb");
|
||||
info = (struct aviinfo *)STREAM_LIBC_ZALLOC(sizeof(struct aviinfo));
|
||||
if(fp && info)
|
||||
{
|
||||
info_tmp = avidemux_parse(fp,info);
|
||||
}
|
||||
|
||||
if(fp && info_tmp)
|
||||
{
|
||||
msg = (struct player2_msg_s *)STREAM_LIBC_ZALLOC(sizeof(struct player2_msg_s));
|
||||
msg->fp = fp;
|
||||
msg->info = info_tmp;
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
stream *newavi_player2_init(const char *stream_name,const char *filename)
|
||||
{
|
||||
|
||||
struct player2_msg_s *msg = NULL;
|
||||
stream *s = NULL;
|
||||
msg = avi2_read_init(filename);
|
||||
//创建workqueue去不停读取视频数据,然后发送出去
|
||||
if(msg)
|
||||
{
|
||||
s = open_stream_available(stream_name,8,0,opcode_func,(void*)msg);
|
||||
}
|
||||
|
||||
|
||||
return s;
|
||||
}
|
||||
Reference in New Issue
Block a user