自己这几天完成了ffmpeg发送与接收处理的模块,写下一篇说明性的文档,供大家借阅和批评。
网络视频流的解码
开发环境:CentOS6.1,ffmpeg0.10.3
1.发送端
1.1主要功能描述
在发送端,可以自定义要发送视频的帧数,或者整个视频文件;发送时的速率大小;对于视频的编码格式,只要ffmpeg支持的,且接收端安装了相应的解码器的,都可以进行发送,接收端收到一视频帧后便进行解码,再保存成ppm格式图片。
1.2关键技术概要
发送端在发送实际视频帧之前,首先对于接收端解码视频需要的关键信息给予了发送,接收端解码需要的关键信息有:相应视频的解码器ID,视频帧的长、宽度。因为接收端在不知道发送过来的视频帧的相关信息之前,无法正常解码,要获得这些信息可以有两种方法:一是发送端与接收端对于视频的编码格式、视频帧的长、宽协定好,双方只能对特定格式的视频进行操作;二是双方不协定,通过发送端把关键信息发送给接收端,接收端接收后,用该信息以正确初始化解码前的相关处理,以此达到双方的协同。很明显,第二种方法灵活多变,本设计采用第二种。关键信息结构体如下所示:
structCtx_decoder
{
uint16_t decoder_ID;//解码器ID,在ffmpeg中唯一标识某一解码器
uint16_t width; //视频帧的长,单位px
uint16_t height; //视频帧的宽,单位px
}My_Ctxdecoder;
实际发送数据时,发送端针对视频帧超过1350B的情况,进行了拆帧,加头,最后分组分送;视频帧小于等于1350B的就直接加头发送。传输层协议采用UDP,以满足视频传输的实时性为主要目的,忽略少量的丢包现象。分组头部信息为:
structVideo_Packet //分组头部结构体
{
intpacket_cnt; //该帧拆分为分组的数量
intvideo_total_size; //该帧的总大小
intvideo_size; //该帧拆分为分组后,分组携带的视频数据量
intpacket_idx; //拆分后的分组的序列号,在同一帧内有效
intFrame_seq; //该帧的序列号