AVI视频封装格式(阅读笔记)
文章目录
最近想了解一下avi视频格式,找了一些文章,在阅读过程做一些笔记,以防忘记。
在github有一个开源的 avilib库(C语言),可以方便地实现读写avi文件: https://github.com/woshinieao/avilib
1.AVI简介(本节为抄录)
AVI(Audio Video Interleaved的缩写) 是一种RIFF文件格式,多用于音视频捕捉、编辑、回放等应用程序中。通常情况下,一个AVI文件可以包含多个不同类型的媒体流(典型的情况下有一个音频流和一个视频流),不过含有单一音频流或单一视频流的AVI文件也是合法的。AVI可以算是Windows操作系统上最基本的、也是最常用的一种媒体文件格式。
RIFF(Resource Interchange File Format资源交互文件格式) ,是由Microsoft提出的一种多媒体文件存储方式,不同编码的视频、音频文件按照RIFF保存,当提取文件时,可以根据RIFF的规则解析文件。常见的RIFF文件有:WAV、AVI等。
RIFF文件使用四字符码FOURCC(four-character code)来表征数据类型,比如‘RIFF’、‘AVI ’、‘LIST’等。注意,Windows操作系统使用的字节顺序是little-endian,因此一个四字符码‘abcd’实际的DWORD值应为0x64636261。另外,四字符码中像‘AVI ’一样含有空格也是合法的。
2.AVI格式示意图(本节为抄录)
AVI格式包含3块内容:
- 信息块——包括文件的通用信息,定义数据格式,所用的压缩算法等参数;
- 数据块——包含实际数据流,即图像和声音序列数据。这是文件的主体,也是决定文件容量的主要部分。视频文件的大小等于该文件的数据率乘以该视频播放的时间长度;
- 索引块——索引块包含数据块列表好它们在文件中的位置,以提供文件内数据随机存取能力。
————抄录结束————
3.示意图 VS 数据结构 VS 具体数据
这里拿一个具体的avi视频文件,参照示意图和部分C语言代码进行对照学习。
3.1 RIFF文件头【最开始12个字节】
注意这里的数据长度是unsigned int(4个字节),小端模式(低位在前,高位在后),例如本文件的长度是0x001D8624.
3.2 hdrl信息【第13-24字节】
3.3 avih信息【第25-88字节】
记录AVI文件的全局信息,使用AVIMAINHEADER数据结构来操作
具体视频中的数据:
width=0x0140=320,height=0xF0=240,对应的AVI文件是320*240像素.
3.4 strl块【】
它包含strh和strf两个子块。
3.4.1 strh块
typedef struct avi_strh_chunk
{
unsigned char id[4]; //块ID,固定为strh
unsigned int size; //块大小,等于struct avi_strh_chunk去掉id和size的大小
unsigned char stream_type[4]; //流的类型,vids表示视频流,auds表示音频流
unsigned char codec[4]; //指定处理这个流需要的解码器,如JPEG
unsigned int flags; //标记,如是否允许这个流输出、调色板是否变化等,一般设为0即可
unsigned short priority; //流的优先级,视频流设为0即可
unsigned short language; //音频语言代号,视频流设为0即可
unsigned int init_frames; //为交互格式指定初始帧数(非交互格式应该指定为0)
unsigned int scale; //
unsigned int rate; //对于视频流,rate / scale = 帧率fps
unsigned int start; //对于视频流,设为0即可
unsigned int length; //对于视频流,length即总帧数
unsigned int suggest_buff_size; //读取这个流数据建议使用的缓冲区大小
unsigned int quality; //流数据的质量指标
unsigned int sample_size; //音频采样大小,视频流设为0即可
RECT rcFrame{
short int left;
short int top;
short int right;
short int bottom;
}; //视频数据图像所占的矩形。即这个流在视频主窗口显示的位置。
}AVI_STRH_CHUNK;
3.4.2 strf块
typedef struct avi_strf_chunk
{
unsigned char id[4]; //块ID,固定为strf
unsigned int size; //块大小,等于struct avi_strf_chunk去掉id和size的大小
unsigned int size1; //size1含义和值同size一样
unsigned int width; //视频主窗口宽度(单位:像素)
unsigned int height; //视频主窗口高度(单位:像素)
unsigned short planes; //始终为1
unsigned short bitcount; //每个像素占的位数,只能是1、4、8、16、24和32中的一个
unsigned char compression[4]; //视频流编码格式,如JPEG、MJPG等
unsigned int image_size; //视频图像大小,等于width * height * bitcount / 8
unsigned int x_pixels_per_meter; //显示设备的水平分辨率,设为0即可
unsigned int y_pixels_per_meter; //显示设备的垂直分辨率,设为0即可
unsigned int num_colors; //含义不清楚,设为0即可
unsigned int imp_colors; //含义不清楚,设为0即可
}AVI_STRF_CHUNK;
4.使用ffmpeg软件将其他格式的视频转为mjpeg编码的AVI文件
下载ffmpeg 的windows版本exe,下载地址:https://ffmpeg.org/download.html;选择windows版本的可执行文件。
ffmpeg -i hc16s.mp4 -s 320x240 -c:v mjpeg hc16s_1.avi
ffmpeg使用参考文章:《01 FFmpeg使用入门》
5.使用《格式工厂》将其他格式的视频转为mjpeg编码的AVI文件
在格式工厂官网下载该软件:http://www.pcgeshi.com/index.html
5.1打开软件,进入视频转换界面
5.2进入输出配置界面
5.3配置重点
- 视频编码一定选 MJPG,这样每帧的图片就是jpg格式;
- 屏幕大小根据实际情况选择;
- 码率越大,精度就越高,但是文件体积也越大。
重点参考文章:
- CSDN博主「houxiaoni01」: [https://blog.csdn.net/houxiaoni01/article/details/84341885];
- 作者:原野追逐 JPEG流封装AVI视频.