pure sdk for main
This commit is contained in:
@@ -0,0 +1,674 @@
|
||||
#include "avi.h"
|
||||
#include "osal/string.h"
|
||||
#include "osal_file.h"
|
||||
#include "utlist.h"
|
||||
#include "custom_mem/custom_mem.h"
|
||||
//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
|
||||
|
||||
//目前没有做兼容性,所以只是识别strh和strl,也不考虑顺序,读取完这两个段就退出
|
||||
void read_strh_strf(void *fp,struct avi_msg_s *avi_msg)
|
||||
{
|
||||
struct chunk_s str;
|
||||
AVIStreamHeader stream;
|
||||
WAVEFORMATEX wav;
|
||||
uint32_t offset;
|
||||
uint8_t video_or_audio = 0;
|
||||
while(1)
|
||||
{
|
||||
osal_fread(&str,1,sizeof(str),fp);
|
||||
offset = osal_ftell(fp);
|
||||
if(strncasecmp((void*)&(str.dwFourCC) ,"strh",4) == 0)
|
||||
{
|
||||
//分析流AVIStreamHeader
|
||||
osal_fread(&stream,1,sizeof(stream),fp);
|
||||
if(strncasecmp((void*)&(stream.fccType) ,"vids",4) == 0)
|
||||
{
|
||||
video_or_audio = 0;
|
||||
avi_msg->fps = stream.dwRate;
|
||||
}
|
||||
else if(strncasecmp((void*)&(stream.fccType) ,"auds",4) == 0)
|
||||
{
|
||||
video_or_audio = 1;
|
||||
|
||||
}
|
||||
//偏移
|
||||
osal_fseek(fp,offset + str.size);
|
||||
}
|
||||
else if(strncasecmp((void*)&(str.dwFourCC) ,"strf",4) == 0)
|
||||
{
|
||||
//视频就不要读取了
|
||||
if(video_or_audio == 0)
|
||||
{
|
||||
|
||||
}
|
||||
//音频就读取看看采样率
|
||||
else if(video_or_audio == 1)
|
||||
{
|
||||
osal_fread(&wav,1,sizeof(wav),fp);
|
||||
//仅仅支持pcm
|
||||
if(wav.wFormatTag == 1)
|
||||
{
|
||||
avi_msg->sample = wav.nSamplesPerSec;
|
||||
}
|
||||
else
|
||||
{
|
||||
avi_msg->sample = 0;
|
||||
}
|
||||
|
||||
}
|
||||
//分析流
|
||||
osal_fseek(fp,offset + str.size);
|
||||
//默认读取到strf就退出,所以遇到strf在前面,就会有异常咯
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void *avi_read_init(const char *filename)
|
||||
{
|
||||
struct avi_msg_s *avi_msg = NULL;
|
||||
int err = 1;
|
||||
char data[32];
|
||||
char chunk_name[5] = {0};
|
||||
uint32_t readlen;
|
||||
uint32_t chunk_size;
|
||||
uint32_t seek_offset = 0;
|
||||
uint32_t hdrl_offset = 0;
|
||||
uint32_t offset;
|
||||
void *fp = osal_fopen(filename,"rb");
|
||||
if(!fp)
|
||||
{
|
||||
goto avi_read_init_end;
|
||||
}
|
||||
readlen = osal_fread(data,1,12,fp);
|
||||
if(readlen < 12)
|
||||
{
|
||||
|
||||
goto avi_read_init_end;
|
||||
}
|
||||
if( strncasecmp(data ,"RIFF",4) !=0 ||strncasecmp(data+8,"AVI ",4) !=0 )
|
||||
{
|
||||
printf("avi file err\n");
|
||||
goto avi_read_init_end;
|
||||
}
|
||||
avi_msg = (struct avi_msg_s*)STREAM_LIBC_ZALLOC(sizeof(struct avi_msg_s));
|
||||
if(!avi_msg)
|
||||
{
|
||||
err = 2;
|
||||
goto avi_read_init_end;
|
||||
}
|
||||
|
||||
avi_msg->fp = fp;
|
||||
|
||||
while(1)
|
||||
{
|
||||
readlen = osal_fread(data,1,8,fp);
|
||||
if(readlen<8)
|
||||
{
|
||||
if(readlen)
|
||||
{
|
||||
printf("%s:%d err!!!!!!!!!!!!!\t%d\tosal_ftell:%d\n",__FUNCTION__,__LINE__,readlen,osal_ftell(fp));
|
||||
goto avi_read_init_end;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
err = 0;
|
||||
goto avi_read_init_continue;
|
||||
}
|
||||
|
||||
}
|
||||
memcpy(&chunk_size,data+4,4);
|
||||
|
||||
chunk_size = (chunk_size+1)&(~1);
|
||||
printf("chunk_size:%X\t%d\ttell:%X\n",chunk_size,chunk_size,osal_ftell(fp));
|
||||
memcpy(chunk_name,data,4);
|
||||
if(strncasecmp(data ,"LIST",4) == 0)
|
||||
{
|
||||
readlen = osal_fread(data,1,4,fp);
|
||||
chunk_size -= 4;
|
||||
memcpy(chunk_name,data,4);
|
||||
//printf("chunk_name[%d]:%s\n",__LINE__,chunk_name);
|
||||
if(strncasecmp(data ,"hdrl",4) == 0)
|
||||
{
|
||||
seek_offset = chunk_size + osal_ftell(fp);
|
||||
hdrl_offset = osal_ftell(fp);
|
||||
//readlen = osal_fread(&avi_msg->avi,1,sizeof(AVIMainHeader),fp);
|
||||
//printf("width:%d\theight:%d\n",avi_msg->avi.dwWidth,avi_msg->avi.dwHeight);
|
||||
//printf("seek_offset:%X\n",seek_offset);
|
||||
osal_fseek(fp,seek_offset);
|
||||
|
||||
}
|
||||
else if(strncasecmp(data ,"INFO",4) == 0)
|
||||
{
|
||||
seek_offset = chunk_size + osal_ftell(fp);
|
||||
osal_fseek(fp,seek_offset);
|
||||
}
|
||||
else if(strncasecmp(data ,"movi",4) == 0)
|
||||
{
|
||||
avi_msg->movi_addr = osal_ftell(fp) - 4;
|
||||
//printf("movi_addr:%X\n",avi_msg->movi_addr);
|
||||
seek_offset = chunk_size + osal_ftell(fp);
|
||||
osal_fseek(fp,seek_offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s:%d err!!!!!!!!!!!!!\n",__FUNCTION__,__LINE__);
|
||||
goto avi_read_init_end;
|
||||
}
|
||||
}
|
||||
else if(strncasecmp(data ,"JUNK",4) == 0)
|
||||
{
|
||||
seek_offset = chunk_size + osal_ftell(fp);
|
||||
osal_fseek(fp,seek_offset);
|
||||
}
|
||||
else if(strncasecmp(data ,"idx1",4) == 0)
|
||||
{
|
||||
avi_msg->idx1_addr = osal_ftell(fp);
|
||||
avi_msg->idx1_size = chunk_size;
|
||||
//printf("idx1_addr:%X\tidx1_size:%d\n",avi_msg->idx1_addr,avi_msg->idx1_size);
|
||||
seek_offset = chunk_size + osal_ftell(fp);
|
||||
osal_fseek(fp,seek_offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s:%d err!!!!!!!!!!!!!\n",__FUNCTION__,__LINE__);
|
||||
goto avi_read_init_end;
|
||||
}
|
||||
}
|
||||
avi_read_init_continue:
|
||||
if(hdrl_offset)
|
||||
{
|
||||
printf("hdrl_offset:%d\n",hdrl_offset);
|
||||
osal_fseek(fp,hdrl_offset);
|
||||
readlen = osal_fread(&avi_msg->avi,1,sizeof(AVIMainHeader),fp);
|
||||
|
||||
//开始解析是否有音频、视频.
|
||||
struct chunk_s List_msg;
|
||||
avi_read_init_List_again:
|
||||
readlen = osal_fread(&List_msg,1,sizeof(List_msg),fp);
|
||||
offset = osal_ftell(fp);
|
||||
//有流,去分析一下有哪些流
|
||||
if(strncasecmp((void*)&(List_msg.dwFourCC) ,"LIST",4) == 0)
|
||||
{
|
||||
//尝试读取strl
|
||||
readlen = osal_fread(data,1,4,fp);
|
||||
memcpy(chunk_name,data,4);
|
||||
printf("chunk_name[%d]:%s\n",__LINE__,chunk_name);
|
||||
//如果有strl,代表有流
|
||||
if(strncasecmp(data ,"strl",4) == 0)
|
||||
{
|
||||
//读取一下流,读取完毕后要seek到后面的块,然后重复读取是否有下一个流
|
||||
read_strh_strf(fp,avi_msg);
|
||||
|
||||
//跳过List,重复读取
|
||||
osal_fseek(fp,offset+List_msg.size);
|
||||
goto avi_read_init_List_again;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
avi_read_init_end:
|
||||
|
||||
if(err)
|
||||
{
|
||||
if(avi_msg)
|
||||
{
|
||||
STREAM_LIBC_FREE(avi_msg);
|
||||
avi_msg = NULL;
|
||||
}
|
||||
if(fp)
|
||||
{
|
||||
osal_fclose(fp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
read_msg_init(avi_msg);
|
||||
avi_msg->video_frame_num = 0;
|
||||
avi_msg->audio_frame_num = 0;
|
||||
avi_msg->video_file_addr = avi_msg->idx1_addr;
|
||||
avi_msg->video_not_read_size = avi_msg->idx1_size;
|
||||
avi_msg->video_cache_remain = 0;
|
||||
|
||||
avi_msg->audio_file_addr = avi_msg->idx1_addr;
|
||||
avi_msg->audio_not_read_size = avi_msg->idx1_size;
|
||||
avi_msg->audio_cache_remain = 0;
|
||||
}
|
||||
|
||||
printf("err:%d\n",err);
|
||||
return avi_msg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct fast_index_list *save_fast_index_list(struct fast_index_list *fast_index,uint32_t avi_index,uint32_t audio_index,uint32_t offset)
|
||||
{
|
||||
struct fast_index_list *list = (struct fast_index_list*)STREAM_LIBC_MALLOC(sizeof(struct fast_index_list));
|
||||
if(!list)
|
||||
{
|
||||
return fast_index;
|
||||
}
|
||||
list->next = NULL;
|
||||
list->prev = NULL;
|
||||
list->avi_index = avi_index;
|
||||
list->audio_index = audio_index;
|
||||
list->offset = offset;
|
||||
DL_APPEND(fast_index, list);
|
||||
return fast_index;
|
||||
}
|
||||
|
||||
static struct fast_index_list * parse_idx1_continue(struct fast_index_list *fast_index,struct avi_read_msg_s *avi_msg,char *buf,uint32_t size)
|
||||
{
|
||||
if(size%16 != 0)
|
||||
{
|
||||
return fast_index;
|
||||
}
|
||||
struct idx1_s *idx1 = (struct idx1_s*)buf;
|
||||
uint32_t offset = avi_msg->addr_offset;
|
||||
|
||||
for(int i=0;i<size/16;i++)
|
||||
{
|
||||
|
||||
//idx1->dwFlags = 0;
|
||||
//音频
|
||||
if(idx1->dwChunkId == 0x62773130 && idx1->dwFlags)
|
||||
{
|
||||
avi_msg->audio_index += idx1->dwSize;
|
||||
}
|
||||
//视频
|
||||
else if(idx1->dwChunkId == 0x63643030)
|
||||
{
|
||||
if(avi_msg->avi_index%512 == 0 && avi_msg->avi_index>0)
|
||||
{
|
||||
fast_index = save_fast_index_list(fast_index,avi_msg->avi_index,avi_msg->audio_index,offset);
|
||||
}
|
||||
avi_msg->avi_index++;
|
||||
}
|
||||
idx1++;
|
||||
offset+=16;
|
||||
}
|
||||
|
||||
return fast_index;
|
||||
}
|
||||
|
||||
//实现快进快退功能(跳转帧)
|
||||
void avi_jmp_index(struct avi_msg_s *avi_msg,uint32_t index)
|
||||
{
|
||||
//索引快速索引表,看看最接近的帧,如果是0,则从头开始,如果非0,就索引
|
||||
}
|
||||
|
||||
|
||||
//往下读取到下一帧到对应的视频帧
|
||||
void avi_read_next_index(struct avi_msg_s *avi_msg,uint32_t *offset,uint32_t *size,uint32_t *frame_num)
|
||||
{
|
||||
uint32_t read_size;
|
||||
avi_read_next_index_again:
|
||||
if(avi_msg->video_cache_remain > 0)
|
||||
{
|
||||
//不符合视频,就继续去读取,知道读取到视频帧
|
||||
if(!(avi_msg->video_idx1->dwChunkId == 0x63643030 && avi_msg->video_idx1->dwFlags))
|
||||
{
|
||||
avi_msg->video_idx1++;
|
||||
avi_msg->video_cache_remain -= sizeof(struct idx1_s);
|
||||
goto avi_read_next_index_again;
|
||||
}
|
||||
//继续读取索引
|
||||
*offset = avi_msg->video_idx1->dwOffset + avi_msg->movi_addr+8;
|
||||
*size = avi_msg->video_idx1->dwSize;
|
||||
|
||||
//进行偏移
|
||||
avi_msg->video_frame_num++;
|
||||
avi_msg->video_idx1++;
|
||||
avi_msg->video_cache_remain -= sizeof(struct idx1_s);
|
||||
//还没有读取到对应的帧,就要继续读取
|
||||
if(*frame_num >= avi_msg->video_frame_num)
|
||||
{
|
||||
goto avi_read_next_index_again;
|
||||
}
|
||||
*frame_num = avi_msg->video_frame_num;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(avi_msg->video_not_read_size >= 512)
|
||||
{
|
||||
read_size = 512;
|
||||
}
|
||||
else
|
||||
{
|
||||
read_size = avi_msg->video_not_read_size;
|
||||
}
|
||||
if(read_size)
|
||||
{
|
||||
osal_fseek(avi_msg->fp,avi_msg->video_file_addr);
|
||||
osal_fread(avi_msg->video_buf,1,read_size,avi_msg->fp);
|
||||
|
||||
avi_msg->video_not_read_size -= read_size;
|
||||
avi_msg->video_file_addr += read_size;
|
||||
avi_msg->video_cache_remain = read_size;
|
||||
avi_msg->video_idx1 = (struct idx1_s *)avi_msg->video_buf;
|
||||
goto avi_read_next_index_again;
|
||||
}
|
||||
//读取结束
|
||||
else
|
||||
{
|
||||
*offset = 0;
|
||||
*size = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void avi_read_next_audio_index(struct avi_msg_s *avi_msg,uint32_t *offset,uint32_t *size,uint32_t *frame_num)
|
||||
{
|
||||
uint32_t read_size;
|
||||
avi_read_next_audio_index_again:
|
||||
if(avi_msg->audio_cache_remain > 0)
|
||||
{
|
||||
//不符合视频,就继续去读取,知道读取到视频帧
|
||||
//os_printf("avi_msg->audio_idx1->dwChunkId:%08X\n",avi_msg->audio_idx1->dwChunkId);
|
||||
if(!(avi_msg->audio_idx1->dwChunkId == 0x62773130 && avi_msg->audio_idx1->dwFlags))
|
||||
{
|
||||
avi_msg->audio_idx1++;
|
||||
avi_msg->audio_cache_remain -= sizeof(struct idx1_s);
|
||||
goto avi_read_next_audio_index_again;
|
||||
}
|
||||
//继续读取索引
|
||||
*offset = avi_msg->audio_idx1->dwOffset + avi_msg->movi_addr+8;
|
||||
*size = avi_msg->audio_idx1->dwSize;
|
||||
|
||||
//os_printf("offset:%X\tsize:%X\n",*offset,*size);
|
||||
|
||||
//进行偏移
|
||||
avi_msg->audio_frame_num += (*size);
|
||||
avi_msg->audio_idx1++;
|
||||
avi_msg->audio_cache_remain -= sizeof(struct idx1_s);
|
||||
//还没有读取到对应的帧,就要继续读取
|
||||
if(*frame_num >= avi_msg->audio_frame_num)
|
||||
{
|
||||
goto avi_read_next_audio_index_again;
|
||||
}
|
||||
*frame_num = avi_msg->audio_frame_num;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(avi_msg->audio_not_read_size >= 512)
|
||||
{
|
||||
read_size = 512;
|
||||
}
|
||||
else
|
||||
{
|
||||
read_size = avi_msg->audio_not_read_size;
|
||||
}
|
||||
if(read_size)
|
||||
{
|
||||
osal_fseek(avi_msg->fp,avi_msg->audio_file_addr);
|
||||
osal_fread(avi_msg->audio_buf,1,read_size,avi_msg->fp);
|
||||
|
||||
avi_msg->audio_not_read_size -= read_size;
|
||||
avi_msg->audio_file_addr += read_size;
|
||||
avi_msg->audio_cache_remain = read_size;
|
||||
avi_msg->audio_idx1 = (struct idx1_s *)avi_msg->audio_buf;
|
||||
goto avi_read_next_audio_index_again;
|
||||
}
|
||||
//读取结束
|
||||
else
|
||||
{
|
||||
*offset = 0;
|
||||
*size = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void gen_fast_index_list(struct avi_msg_s *avi_msg)
|
||||
{
|
||||
uint32_t read_size = 0;
|
||||
struct avi_read_msg_s *read_msg = avi_msg->avi_read_msg;
|
||||
|
||||
//读取完毕后,需要释放空间,保留快速索引表
|
||||
if(read_msg && read_msg->remain_read_size)
|
||||
{
|
||||
osal_fseek(avi_msg->fp,read_msg->addr_offset);
|
||||
if(read_msg->remain_read_size >= 512)
|
||||
{
|
||||
read_size = 512;
|
||||
}
|
||||
else
|
||||
{
|
||||
read_size = read_msg->remain_read_size;
|
||||
}
|
||||
osal_fread((void*)read_msg->buf,1,read_size,avi_msg->fp);
|
||||
avi_msg->fast_index = parse_idx1_continue(avi_msg->fast_index,avi_msg->avi_read_msg,(char*)read_msg->buf,read_size);
|
||||
|
||||
read_msg->addr_offset += read_size;
|
||||
read_msg->remain_read_size -= read_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(read_msg)
|
||||
{
|
||||
read_msg_deinit(avi_msg);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//定位索引点,重新计算
|
||||
void locate_avi_index(struct avi_msg_s *avi_msg,uint32_t index)
|
||||
{
|
||||
|
||||
if(index == 0)
|
||||
{
|
||||
avi_msg->video_frame_num = 0;
|
||||
avi_msg->video_cache_remain = 0;
|
||||
avi_msg->video_not_read_size = avi_msg->idx1_size;
|
||||
avi_msg->video_file_addr = avi_msg->idx1_addr;
|
||||
|
||||
avi_msg->audio_frame_num = 0;
|
||||
avi_msg->audio_cache_remain = 0;
|
||||
avi_msg->audio_file_addr = avi_msg->idx1_addr;
|
||||
avi_msg->audio_not_read_size = avi_msg->idx1_size;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
struct fast_index_list *fast_index = avi_msg->fast_index;
|
||||
struct fast_index_list *list,*tmp;
|
||||
struct fast_index_list *last_index = NULL;
|
||||
|
||||
DL_FOREACH_SAFE(fast_index,list,tmp)
|
||||
{
|
||||
if(list->avi_index > index)
|
||||
{
|
||||
break;
|
||||
}
|
||||
//完全匹配,保存last_index;
|
||||
else if(list->avi_index == index)
|
||||
{
|
||||
last_index = list;
|
||||
break;
|
||||
}
|
||||
last_index = list;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//如果存在,则就从这里开始索引,一直索引到对应的index
|
||||
if(last_index)
|
||||
{
|
||||
avi_msg->video_frame_num = last_index->avi_index;
|
||||
avi_msg->video_cache_remain = 0;
|
||||
//通过偏移,计算还有多少数据没有被读取
|
||||
avi_msg->video_not_read_size = (avi_msg->idx1_size-(last_index->offset-avi_msg->idx1_addr));
|
||||
avi_msg->video_file_addr = last_index->offset;
|
||||
}
|
||||
//从0开始索引
|
||||
else
|
||||
{
|
||||
avi_msg->video_frame_num = 0;
|
||||
avi_msg->video_cache_remain = 0;
|
||||
avi_msg->video_not_read_size = avi_msg->idx1_size;
|
||||
avi_msg->video_file_addr = avi_msg->idx1_addr;
|
||||
|
||||
avi_msg->audio_frame_num = 0;
|
||||
avi_msg->audio_cache_remain = 0;
|
||||
avi_msg->audio_file_addr = avi_msg->idx1_addr;
|
||||
avi_msg->audio_not_read_size = avi_msg->idx1_size;
|
||||
}
|
||||
|
||||
//os_printf("last_index:%X\tsample:%X\n",last_index,avi_msg->sample);
|
||||
//索引到了视频,那么就要开始索引音频了,不过需要先计算当前视频的时间,然后计算出音频位置,最后定位
|
||||
if(avi_msg->sample)
|
||||
{
|
||||
//index是要快进或者快退到的视频点
|
||||
uint32_t video_time = index*1000/avi_msg->fps;
|
||||
uint32_t audio_offset = video_time*avi_msg->sample*2/1000;
|
||||
//os_printf("audio want to offset time:%d\toffset:%d\n",video_time,audio_offset);
|
||||
last_index = NULL;
|
||||
//查找最近的快速索引位置
|
||||
DL_FOREACH_SAFE(fast_index,list,tmp)
|
||||
{
|
||||
//os_printf("list->audio_index:%d\n",list->audio_index);
|
||||
if(list->audio_index > audio_offset)
|
||||
{
|
||||
break;
|
||||
}
|
||||
//完全匹配,保存last_index;
|
||||
else if(list->audio_index == index)
|
||||
{
|
||||
last_index = list;
|
||||
break;
|
||||
}
|
||||
last_index = list;
|
||||
}
|
||||
|
||||
|
||||
//索引到了音频位置
|
||||
if(last_index)
|
||||
{
|
||||
//计算当前索引的音频位置
|
||||
//("index audio_offset:%d\n",list->audio_index);
|
||||
//这个代表当前缓冲区的索引位置
|
||||
avi_msg->audio_frame_num = list->audio_index;
|
||||
avi_msg->audio_cache_remain = 0;
|
||||
//通过偏移,计算还有多少数据没有被读取
|
||||
avi_msg->audio_not_read_size = (avi_msg->idx1_size-(last_index->offset-avi_msg->idx1_addr));
|
||||
avi_msg->audio_file_addr = last_index->offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
avi_msg->audio_frame_num = 0;
|
||||
avi_msg->audio_cache_remain = 0;
|
||||
avi_msg->audio_not_read_size = avi_msg->idx1_size;
|
||||
avi_msg->audio_file_addr = avi_msg->idx1_addr;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void free_fast_index_list(struct fast_index_list *fast_index)
|
||||
{
|
||||
struct fast_index_list *list,*tmp;
|
||||
DL_FOREACH_SAFE(fast_index,list,tmp)
|
||||
{
|
||||
//从已有链表释放
|
||||
DL_DELETE(fast_index,list);
|
||||
STREAM_LIBC_FREE(list);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void avi_deinit(struct avi_msg_s *avi_msg)
|
||||
{
|
||||
if(avi_msg)
|
||||
{
|
||||
osal_fclose(avi_msg->fp);
|
||||
//如果没有释放,就会释放(快速索引在索引完后,会自动释放,但是如果在没有索引完毕又要关闭视频,就需要在这里释放)
|
||||
read_msg_deinit(avi_msg);
|
||||
if(avi_msg->fast_index)
|
||||
{
|
||||
free_fast_index_list(avi_msg->fast_index);
|
||||
}
|
||||
STREAM_LIBC_FREE(avi_msg);
|
||||
}
|
||||
}
|
||||
|
||||
void parse_idx1(char *buf,uint32_t size)
|
||||
{
|
||||
if(size%16 != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
struct idx1_s *idx1 = (struct idx1_s*)buf;
|
||||
for(int i=0;i<size/16;i++)
|
||||
{
|
||||
idx1->dwFlags = 0;
|
||||
printf("id:%s\tflags:00000010\toffset:%08X\tsize:%08X\n",(char*)&idx1->dwChunkId,idx1->dwOffset,idx1->dwSize);
|
||||
idx1+=1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct avi_read_msg_s *read_msg_init(struct avi_msg_s *avi_msg)
|
||||
{
|
||||
struct avi_read_msg_s *read_msg = STREAM_LIBC_MALLOC(sizeof(struct avi_read_msg_s));
|
||||
if(read_msg)
|
||||
{
|
||||
read_msg->addr_offset = avi_msg->idx1_addr;
|
||||
read_msg->avi_index = 0;
|
||||
read_msg->audio_index = 0;
|
||||
read_msg->remain_read_size = avi_msg->idx1_size;
|
||||
}
|
||||
avi_msg->avi_read_msg = read_msg;
|
||||
return read_msg;
|
||||
}
|
||||
|
||||
void read_msg_deinit(struct avi_msg_s *avi_msg)
|
||||
{
|
||||
if(avi_msg->avi_read_msg)
|
||||
{
|
||||
STREAM_LIBC_FREE(avi_msg->avi_read_msg);
|
||||
avi_msg->avi_read_msg = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
#ifndef __AVI_H
|
||||
#define __AVI_H
|
||||
#include "typesdef.h"
|
||||
#include "stream_frame.h"
|
||||
typedef struct {
|
||||
uint32_t dwFourCC; // 必须为'avih'
|
||||
uint32_t dwSize; // 本数据结构的大小,不包括最初的8个字节(dwFourCC和dwSize两个字段)
|
||||
uint32_t dwMicroSecPerFrame; // 每帧的持续时间(以毫秒ms为单位),定义avi的显示速率
|
||||
uint32_t dwMaxBytesPerSec; // 最大的数据传输率
|
||||
uint32_t dwPaddingGranularity; // 数据填充的粒度
|
||||
uint32_t dwFlages; // AVI文件的特殊属性,如是否包含索引块,音视频数据是否交叉存储
|
||||
uint32_t dwTotalFrame; // 文件中的总帧数
|
||||
uint32_t dwInitialFrames; // 说明在开始播放前需要多少桢
|
||||
uint32_t dwStreams; // 文件中包含的数据流个数
|
||||
uint32_t dwSuggestedBufferSize; // 建议使用的缓冲区的大小,
|
||||
// 通常为存储一桢图像以及同步声音所需要的数据之和
|
||||
uint32_t dwWidth; // 图像宽
|
||||
uint32_t dwHeight; // 图像高
|
||||
uint32_t dwReserved[4]; // 保留值
|
||||
} AVIMainHeader;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32_t fccType; // 4字节,表示数据流的种类,vids表示视频数据流,auds表示音频数据流
|
||||
uint32_t fccHandler; // 4字节 ,表示数据流解压缩的驱动程序代号
|
||||
uint32_t dwFlags; // 数据流属性
|
||||
uint16_t wPriority; // 此数据流的播放优先级
|
||||
uint16_t wLanguage; // 音频的语言代号
|
||||
uint32_t dwInitalFrames; // 说明在开始播放前需要多少桢
|
||||
uint32_t dwScale; // 数据量,视频每桢的大小或者音频的采样大小
|
||||
uint32_t dwRate; // dwScale/dwRate = 每秒的采样数
|
||||
uint32_t dwStart; // 数据流开始播放的位置,以dwScale为单位
|
||||
uint32_t dwLength; // 数据流的数据量,以dwScale为单位
|
||||
uint32_t dwSuggestedBufferSize; // 建议缓冲区的大小
|
||||
uint32_t dwQuality; // 解压缩质量参数,值越大,质量越好
|
||||
uint32_t dwSampleSize; // 音频的采样大小
|
||||
uint16_t rcFrame[4]; // 视频图像所占的矩形
|
||||
}AVIStreamHeader;
|
||||
|
||||
//实际标准后面可能还有信息,这里就不解析了
|
||||
typedef struct tWAVEFORMATEX {
|
||||
uint16_t wFormatTag;
|
||||
uint16_t nChannels;
|
||||
uint32_t nSamplesPerSec;
|
||||
uint32_t nAvgBytesPerSec;
|
||||
uint16_t nBlockAlign;
|
||||
uint16_t wBitsPerSample;
|
||||
uint16_t cbSize;
|
||||
} WAVEFORMATEX;
|
||||
|
||||
struct avi_list
|
||||
{
|
||||
uint32_t offset;
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
typedef struct avi_list avi_list_audio_s;
|
||||
typedef struct avi_list avi_list_photo_s;
|
||||
|
||||
struct idx1_s
|
||||
{
|
||||
uint32_t dwChunkId;
|
||||
uint32_t dwFlags;
|
||||
uint32_t dwOffset;
|
||||
uint32_t dwSize;
|
||||
};
|
||||
|
||||
|
||||
//快速索引表
|
||||
struct fast_index_list
|
||||
{
|
||||
struct fast_index_list *next;
|
||||
struct fast_index_list *prev;
|
||||
uint32_t avi_index; //当前视频index的值,这个记录的是视频的帧数
|
||||
uint32_t audio_index; //当前音频index,这个记录的是音频的长度
|
||||
uint32_t offset; //当前的偏移值,读取的第一个index就是对应avi或者index
|
||||
};
|
||||
struct avi_msg_s
|
||||
{
|
||||
AVIMainHeader avi;
|
||||
void *fp;
|
||||
uint32_t fps;
|
||||
uint32_t sample;
|
||||
uint32_t movi_addr;
|
||||
uint32_t idx1_addr;
|
||||
uint32_t idx1_size;
|
||||
struct avi_read_msg_s *avi_read_msg;
|
||||
struct fast_index_list *fast_index;
|
||||
|
||||
//当前读取视频帧的buf
|
||||
uint32_t video_buf[512/4]; //当前读取视频帧的索引的缓冲区
|
||||
uint32_t video_file_addr; //当前读取视频帧的地址
|
||||
int32_t video_frame_num; //视频帧数
|
||||
uint32_t video_not_read_size; //剩余长度
|
||||
int32_t video_cache_remain; //缓存剩余长度
|
||||
struct idx1_s *video_idx1;
|
||||
|
||||
//当前读取音频帧的buf
|
||||
uint32_t audio_buf[512/4]; //当前读取音频帧的索引的缓冲区
|
||||
uint32_t audio_file_addr; //当前读取音频帧的地址
|
||||
int32_t audio_frame_num; //音频的读取偏移长度
|
||||
uint32_t audio_not_read_size; //剩余长度
|
||||
int32_t audio_cache_remain; //缓存剩余长度
|
||||
struct idx1_s *audio_idx1;
|
||||
};
|
||||
|
||||
struct chunk_s
|
||||
{
|
||||
uint32_t dwFourCC;
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct avi_read_msg_s
|
||||
{
|
||||
uint32_t addr_offset;
|
||||
uint32_t avi_index;
|
||||
uint32_t audio_index;
|
||||
uint32_t remain_read_size;
|
||||
uint32_t buf[512/4];
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
void *avi_read_init(const char *filename);
|
||||
void parse_idx1(char *buf,uint32_t size);
|
||||
void avi_deinit(struct avi_msg_s *avi_msg);
|
||||
struct avi_read_msg_s *read_msg_init(struct avi_msg_s *avi_msg);
|
||||
void gen_fast_index_list(struct avi_msg_s *avi_msg);
|
||||
void read_msg_deinit(struct avi_msg_s *avi_msg);
|
||||
void locate_avi_index(struct avi_msg_s *avi_msg,uint32_t index);
|
||||
void avi_read_next_index(struct avi_msg_s *avi_msg,uint32_t *offset,uint32_t *size,uint32_t *frame_num);
|
||||
void avi_read_next_audio_index(struct avi_msg_s *avi_msg,uint32_t *offset,uint32_t *size,uint32_t *frame_num);
|
||||
#endif
|
||||
@@ -0,0 +1,427 @@
|
||||
#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 "avi.h"
|
||||
#include "stream_define.h"
|
||||
#include "newavi_player.h"
|
||||
#include "osal_file.h"
|
||||
/*****************************************************************************
|
||||
* AVI1.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
|
||||
|
||||
#define AUDIO_TMP_BUF_SIZE (1024)
|
||||
|
||||
|
||||
|
||||
struct player_msg_s
|
||||
{
|
||||
void *task;
|
||||
stream *s;
|
||||
uint32_t magic;
|
||||
struct avi_msg_s *avi_msg;
|
||||
struct fast_index_list *g_fast_index_list;
|
||||
|
||||
uint32_t audio_frame_number; //读取索引的长度
|
||||
uint32_t audio_frame_number_send; //已经播放的长度
|
||||
uint32_t frame_number; //当前读取的帧
|
||||
uint32_t not_read_size; //剩余未读取的空间长度
|
||||
uint32_t cache_addr; //读取下一次的偏移地址
|
||||
|
||||
struct data_structure *data_tmp;
|
||||
struct data_structure *audio_data_tmp;
|
||||
|
||||
int32_t locate_frame_number; //跳转视频的偏移
|
||||
uint8_t running: 1, thread_stop : 1, speed_flag:1, rev: 5;
|
||||
};
|
||||
|
||||
|
||||
|
||||
static uint32_t newavi_player_cmd(stream *s,int opcode,uint32_t arg)
|
||||
{
|
||||
uint32_t res = 0;
|
||||
struct player_msg_s *msg = (struct player_msg_s *)s->priv;
|
||||
switch(opcode)
|
||||
{
|
||||
//跳转位置,快进
|
||||
case NEWAVI_PLAYER_LOCATE_FORWARD_INDEX:
|
||||
{
|
||||
//快进3s的时间
|
||||
uint32_t play_time = arg+3000;
|
||||
msg->locate_frame_number = play_time*msg->avi_msg->fps/1000;
|
||||
//要判断是否已经到最后
|
||||
if(msg->locate_frame_number > msg->avi_msg->avi.dwTotalFrame )
|
||||
{
|
||||
msg->locate_frame_number = msg->avi_msg->avi.dwTotalFrame;
|
||||
}
|
||||
//os_printf("msg->locate_frame_number:%d\targ:%d\n",msg->locate_frame_number,arg);
|
||||
res = msg->locate_frame_number*1000/msg->avi_msg->fps;
|
||||
}
|
||||
break;
|
||||
|
||||
//快退
|
||||
case NEWAVI_PLAYER_LOCATE_REWIND_INDEX:
|
||||
{
|
||||
uint32_t play_time = 0;
|
||||
if(arg>3000)
|
||||
{
|
||||
play_time = arg-3000;
|
||||
}
|
||||
|
||||
msg->locate_frame_number = play_time*msg->avi_msg->fps/1000;
|
||||
|
||||
//os_printf("msg->locate_frame_number:%d\targ:%d\n",msg->locate_frame_number,arg);
|
||||
res = msg->locate_frame_number*1000/msg->avi_msg->fps;
|
||||
}
|
||||
break;
|
||||
//修改data的magic,用于过滤某些数据情况
|
||||
case NEWAVI_PLAYER_MAGIC:
|
||||
msg->magic = arg;
|
||||
msg->speed_flag = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
|
||||
}
|
||||
static void newplayer_thread(void *d)
|
||||
{
|
||||
struct player_msg_s *msg = (struct player_msg_s *)d;
|
||||
stream *s = msg->s;
|
||||
struct avi_msg_s *avi_msg = msg->avi_msg;
|
||||
uint32_t magic = 0;
|
||||
uint8_t *audio_tmp_buf = (uint8_t *)STREAM_LIBC_MALLOC(AUDIO_TMP_BUF_SIZE);
|
||||
uint32_t now_audio_offset = 0;
|
||||
uint32_t video_time = 0;
|
||||
uint32_t audio_time = 0;
|
||||
if(!avi_msg->sample)
|
||||
{
|
||||
audio_time = ~0; //没有音频
|
||||
}
|
||||
while(!msg->thread_stop)
|
||||
{
|
||||
if(!s->enable)
|
||||
{
|
||||
//这里是否可以考虑先去建立部分快速索引?
|
||||
goto newplayer_thread_end;
|
||||
}
|
||||
//正常这里去建立快速索引
|
||||
gen_fast_index_list(avi_msg);
|
||||
|
||||
//判断一下是否要快进或者快退?
|
||||
//所以先设置locate_frame_number,再配置speed_flag
|
||||
if(msg->speed_flag)
|
||||
{
|
||||
msg->speed_flag = 0;
|
||||
locate_avi_index(avi_msg,msg->locate_frame_number);
|
||||
msg->frame_number = msg->locate_frame_number;
|
||||
magic = msg->magic;
|
||||
video_time = msg->frame_number*1000/avi_msg->fps;
|
||||
|
||||
//os_printf("msg->frame_number:%d\n",msg->frame_number);
|
||||
|
||||
if(avi_msg->sample)
|
||||
{
|
||||
//重置音频,音频是跟着视频走的,表示音频和video同步
|
||||
msg->audio_frame_number_send = video_time*avi_msg->sample*2/1000;;
|
||||
audio_time = msg->audio_frame_number_send*500/avi_msg->sample;
|
||||
now_audio_offset = 0;
|
||||
|
||||
//实际音频索引的位置应该在前面,意思是快速索引在前面,实际播放时间可能在后面,后面需要慢慢去轮询读取到对应的音频
|
||||
msg->audio_frame_number = avi_msg->audio_frame_num;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//如果视频比音频播放前,就需要去读取音频了
|
||||
if(video_time > audio_time)
|
||||
{
|
||||
goto newplayer_audio_thread_start;
|
||||
}
|
||||
|
||||
|
||||
if(!msg->data_tmp)
|
||||
{
|
||||
msg->data_tmp = get_src_data_f(msg->s);
|
||||
if(!msg->data_tmp)
|
||||
{
|
||||
goto newplayer_audio_thread_start;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//理论要判断当前播放的视频帧是否已经最大,最大就直接退出
|
||||
uint32_t offset;
|
||||
uint32_t size = 0;
|
||||
avi_read_next_index(avi_msg,&offset,&size,&msg->frame_number);
|
||||
if(!size)
|
||||
{
|
||||
goto newplayer_audio_thread_start;
|
||||
}
|
||||
uint8_t *buf = (uint8_t *)STREAM_MALLOC(size);
|
||||
if(buf)
|
||||
{
|
||||
osal_fseek(avi_msg->fp,offset);
|
||||
osal_fread(buf,1,size,avi_msg->fp);
|
||||
sys_dcache_clean_range((uint32_t*)buf,size);
|
||||
msg->data_tmp->data = (uint8_t *)buf;
|
||||
msg->data_tmp->type = SET_DATA_TYPE(JPEG,JPEG_FULL);
|
||||
//转换成ms
|
||||
//os_printf("msg->avi_msg->fps:%d\t%d\n",msg->avi_msg->fps,msg->frame_number*1000/msg->avi_msg->fps);
|
||||
set_stream_data_time(msg->data_tmp,msg->frame_number*1000/msg->avi_msg->fps);
|
||||
set_stream_real_data_len(msg->data_tmp,size);
|
||||
video_time = msg->frame_number*1000/msg->avi_msg->fps;
|
||||
|
||||
msg->data_tmp->magic = magic;
|
||||
send_data_to_stream(msg->data_tmp);
|
||||
msg->data_tmp = NULL;
|
||||
//_os_printf("(V:%d)",size);
|
||||
|
||||
}
|
||||
|
||||
newplayer_audio_thread_start:
|
||||
|
||||
if(!avi_msg->sample)
|
||||
{
|
||||
goto newplayer_thread_end;
|
||||
}
|
||||
if(video_time < audio_time)
|
||||
{
|
||||
//os_printf("audio_time:%d\tvideo_time:%d\n",audio_time,video_time);
|
||||
goto newplayer_thread_end;
|
||||
}
|
||||
|
||||
|
||||
if(!msg->audio_data_tmp)
|
||||
{
|
||||
msg->audio_data_tmp = get_src_data_f(msg->s);
|
||||
if(!msg->audio_data_tmp)
|
||||
{
|
||||
goto newplayer_thread_end;
|
||||
}
|
||||
}
|
||||
//先去获取一个音频节点
|
||||
if(msg->audio_data_tmp)
|
||||
{
|
||||
|
||||
//os_printf("audio_time:%d\tvideo_time:%d\n",audio_time,video_time);
|
||||
//为stream申请音频的空间,然后读取音频发送
|
||||
uint8_t *audio_data_buf = (uint8_t *)STREAM_LIBC_MALLOC(AUDIO_TMP_BUF_SIZE);
|
||||
//申请到空间,就将音频先读取到缓冲区,没有空间,则下次重新尝试
|
||||
if(audio_data_buf)
|
||||
{
|
||||
uint32_t max_read_len;
|
||||
uint32_t read_len = 0;
|
||||
max_read_len = AUDIO_TMP_BUF_SIZE - now_audio_offset;
|
||||
while(max_read_len)
|
||||
{
|
||||
|
||||
//读取够音频数据长度,然后通过流发送,然后再将剩下的拷贝到缓冲区,由于
|
||||
avi_read_next_audio_index(avi_msg,&offset,&size,&msg->audio_frame_number);
|
||||
//音频已经读取完毕了
|
||||
if(!size)
|
||||
{
|
||||
break;
|
||||
}
|
||||
osal_fseek(avi_msg->fp,offset);
|
||||
read_len = max_read_len>size?size:max_read_len;
|
||||
osal_fread(audio_tmp_buf+now_audio_offset,1,read_len,avi_msg->fp);
|
||||
now_audio_offset += read_len;
|
||||
max_read_len -= read_len;
|
||||
}
|
||||
|
||||
//流发送,先拷贝数据
|
||||
hw_memcpy(audio_data_buf,audio_tmp_buf,now_audio_offset);
|
||||
msg->audio_data_tmp->data = (uint8_t *)audio_data_buf;
|
||||
msg->audio_data_tmp->type = SET_DATA_TYPE(SOUND,SOUND_FILE);
|
||||
//转换成ms
|
||||
//os_printf("msg->avi_msg->fps:%d\t%d\n",msg->avi_msg->fps,msg->frame_number*1000/msg->avi_msg->fps);
|
||||
//设置音频的时间
|
||||
set_stream_data_time(msg->audio_data_tmp,msg->audio_frame_number_send*500/avi_msg->sample);//msg->audio_frame_number_send*1000/(avi_msg->sample*2)
|
||||
set_stream_real_data_len(msg->audio_data_tmp,now_audio_offset);
|
||||
msg->audio_data_tmp->magic = magic;
|
||||
//_os_printf("(A:%d\t%d)",now_audio_offset,avi_msg->sample);
|
||||
send_data_to_stream(msg->audio_data_tmp);
|
||||
msg->audio_data_tmp = NULL;
|
||||
msg->audio_frame_number_send += now_audio_offset;
|
||||
audio_time = msg->audio_frame_number_send*500/avi_msg->sample;
|
||||
|
||||
//将剩余的数据拷贝
|
||||
now_audio_offset = size-read_len;
|
||||
//os_printf("remain:%d\n",now_audio_offset);
|
||||
//如果有剩余,紧接着读取数据就可以了
|
||||
if(now_audio_offset)
|
||||
{
|
||||
osal_fread(audio_tmp_buf,1,now_audio_offset,avi_msg->fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
newplayer_thread_end:
|
||||
os_sleep_ms(1);
|
||||
}
|
||||
msg->running = 0;
|
||||
|
||||
if(audio_tmp_buf)
|
||||
{
|
||||
STREAM_LIBC_FREE(audio_tmp_buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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 player_msg_s *msg = (struct player_msg_s*)STREAM_LIBC_ZALLOC(sizeof(struct player_msg_s));
|
||||
if(msg)
|
||||
{
|
||||
s->priv = (void*)msg;
|
||||
msg->s = s;
|
||||
msg->avi_msg = (struct avi_msg_s*)priv;
|
||||
msg->magic = 0;
|
||||
//初始化快速索引
|
||||
|
||||
msg->not_read_size = msg->avi_msg->idx1_size;
|
||||
msg->cache_addr = msg->avi_msg->idx1_addr;
|
||||
register_stream_self_cmd_func(s,newavi_player_cmd);
|
||||
//enable_stream(s,1);
|
||||
//OS_WORK_INIT(&msg->work, newplayer_work, 0);
|
||||
msg->running = 1;
|
||||
msg->task = os_task_create(s->name,newplayer_thread,(void*)msg,OS_TASK_PRIORITY_NORMAL,0,NULL,1024);
|
||||
//os_task_init(s->name,&msg->task,newplayer_thread,(uint32_t)msg);
|
||||
//os_run_work_delay(&msg->work, 1);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
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)
|
||||
{
|
||||
if(GET_DATA_TYPE1(data->type) == SOUND)
|
||||
{
|
||||
STREAM_LIBC_FREE(data->data);
|
||||
|
||||
}
|
||||
else if(GET_DATA_TYPE1(data->type) == JPEG)
|
||||
{
|
||||
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_EXIT:
|
||||
{
|
||||
os_printf("newavi player close\n");
|
||||
struct player_msg_s *msg = (struct player_msg_s *)s->priv;
|
||||
//os_work_cancle2(&msg->work, 1);
|
||||
msg->thread_stop = 1;
|
||||
while(msg->running)
|
||||
{
|
||||
os_sleep_ms(1);
|
||||
}
|
||||
if(msg->data_tmp)
|
||||
{
|
||||
force_del_data(msg->data_tmp);
|
||||
}
|
||||
|
||||
if(msg->audio_data_tmp)
|
||||
{
|
||||
force_del_data(msg->audio_data_tmp);
|
||||
}
|
||||
|
||||
if(msg->avi_msg)
|
||||
{
|
||||
avi_deinit(msg->avi_msg);
|
||||
}
|
||||
|
||||
STREAM_LIBC_FREE(msg);
|
||||
}
|
||||
break;
|
||||
|
||||
case STREAM_MARK_GC_END:
|
||||
{
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
//默认都返回成功
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
stream *newavi_player_init(const char *stream_name,const char *filename)
|
||||
{
|
||||
struct avi_msg_s *avi_msg = NULL;
|
||||
stream *s = NULL;
|
||||
avi_msg = avi_read_init(filename);
|
||||
os_printf("avi_msg:%X\n",avi_msg);
|
||||
//创建workqueue去不停读取视频数据,然后发送出去
|
||||
s = open_stream_available(stream_name,8,0,opcode_func,avi_msg);
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#ifndef __NEWAVI_PLAYER_H
|
||||
#define __NEWAVI_PLAYER_H
|
||||
#include "stream_define.h"
|
||||
#if 0
|
||||
enum
|
||||
{
|
||||
NEWAVI_PLAYER_LOCATE_FORWARD_INDEX = CUSTOM_STREAM_CMD+1,
|
||||
NEWAVI_PLAYER_LOCATE_REWIND_INDEX,
|
||||
NEWAVI_PLAYER_MAGIC,
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
Reference in New Issue
Block a user