您的位置 首页 > 数码极客

【avi播放不了】AVI视频回放——STM32F769I图像处理能力评估4

硬件平台:STM32F769IDISCOVERY

软件开发平台:Keil 5.1

工具:SD卡、容量8G、Class10(10MB/S)

分析AVI文件:

AVI是音频和视频交错的文件,因此视频和音频可以交叉播放。AVI视频中的编码器非常多,包括MPEG4、XVID、H.264、MJPEG等。此处使用的AVI文件的编码器是MJPEG,因此每个视频帧文件都是JPEG照片,因此可以使用硬件解码器解码。AVI文件中的音频编码器也有多种格式,包括MP3、AC3、PCM、AAC等。在这里,我使用未编码的PCM数据格式。这样可以将读取的数据直接发送到音频处理模块,而无需进行复杂的转换。节省时间,使视频回放更加顺畅。

AVI文件基于RIFF文件结构,有两个最常用的数据单位:chunk块和LIST列表。整个RIFF文件的结构如下:

RIFF场数据大小AVI场

- LIST字段数据大小hdrl字段

- avih字段数据大小内容

-列表字段数据大小strl字段

- strh字段数据大小内容

- strf字段数据大小内容

- strd字段数据大小内容(可选)

-列表字段数据大小strl字段

- strh字段数据大小内容

- strf字段数据大小内容

- strd字段数据大小内容(可选)

-列表场数据大小INFO场视频编码器相关信息。

- JUNK现场数据大小无用数据

-列表字段数据大小movi字段音频、视频数据

- idx1字段数据大小每帧音频、视频数据大小和文件内偏移地址(可选)

如上图所示,AVI RIFF文件由RIFF标头、hdrl列表(AVI文件的数据格式)、INFO列表、movi列表(AVI的视频音频序列数据)和可选索引块组成。

我们这次解码的AVI文件,视频是MJPEG编码,音频是PCM编码,现在重点分析这种类型的文件。

RIFF标头:文件开始前12个字节,如下图所示。

前4个字节是RIFF,表示这是RIFF结构中的文件。中间4个字节是RIFF结构数据大小,不包括前8个字节(前8个字节等于AVI文件大小),后4个字节表示这是AVI文件。

Hdrl列表:嵌套一系列块和子列表、avih块以及一个或多个strl子列表。

文件偏移地址0x0c-0x0f: list字符。

文件偏移地址0x10-0x13: hdrl列表数据大小(不包括前8个字节)。

文件偏移地址0x14-0x17: hdrl字符。

AVIh块:记录有关avi文件的全局信息,是hdrl列表的子块。文件偏移起始地址:0x18。数据结构如下:

文件偏移地址0x18-0x1b: avih字符。

文件偏移地址0x1c-0x1f: avih块大小不包括前8个字节。

文件偏移地址0x20 -0x23:显示每帧所需的时间(以美国为单位)

文件偏移地址0x24 -0x27:最大数据速率。

文件偏移地址0x28 -0x2B:数据填充的粒度。

文件偏移地址0x2c -0x2f: AVI文件的全局标记(例如,是否包含索引块等)。

文件偏移地址0x30 -0x33:视频帧总数。

文件偏移地址0x34 -0x37:指定交互式格式的初始帧数(非交互式格式必须指定为0)

文件偏移地址0x38 -0x3b:此文件中包含的流数

文件偏移地址0x3C -0x3F:建议读取此文件的缓存大小

文件偏移地址0x40 -0x43:视频图像的宽度(以像素为单位)

文件偏移地址0x44 -0x47:视频图像的高度(以像素为单位)

文件偏移地址0x48 -0x57:保留

Strl列表:包含一个或多个strh块和一个strf块。文件中的流数对应于几个strl列表。一般AVI文件必须包含视频流和音频流文件,但某些AVI文件必须只有一个流文件(视频流或音频流)。两个流列表的出现顺序不是固定的。第一个可以是视频流或音频流,但两个流数据的结构是相同的。

文件偏移地址0x58-0x5b: list字符。

文件偏移地址0x5c-0x5f: strl列表数据大小(不包括前8个字节)。

文件偏移地址0x60-0x63: strl字符。

/p>

strh块:用于描述流的头信息,是strl列表的子块。数据结构如下图所示:

无论是音频流还是视频流,播放时长 = dwLength /dwRate / dwScale。选择最大值为AVI视频文件播放的总时长。

strf块:该块用于描述流的具体信息,是strl列表的子块。对于视频流,用于描述位图信息,对于采用MJPEG编码的视频,这段信息不重要。对于音频流,描述音频的相关信息,包括声道数,以及采样率等等。对于音频流,数据结构如下所示:

INFO列表:描述编码该AVI文件的程序信息,里面包含一个ISFT块。对我们来说,这段信息不重要。

JUNK块:主要用于内部数据的对齐,都是些无用的信息,可以直接跳过。

movi列表:存放音频、视频数据块,音频、视频数据块在该列表中交错方式存放着。音频数据块的结构为:01wb+音频数据块的大小+音频数据。视频数据块的结构:00db(00dc)+ 视频数据块的大小+视频数据。其中01wb—代表音频数据,00db--未压缩的视频数据,00dc--压缩的视频数据。

idx1索引块:描述音视频数据的索引块信息,该内容是可选的。数据结构为:idx1+索引块数据大小+索引块数据。索引块数据有两种格式,一种为视频数据索引:00dc+4字节描述是否为重要帧(重要帧:0x00000010,无关帧:0x00000000)+4字节偏移地址(相对于movi列表的偏移地址)+视频数据大小;一种为音频数据索引:01wb+4字节描述是否为重要帧(重要帧:0x00000010,无关帧:0x00000000)+4字节偏移地址(相对于movi列表的偏移地址)+音频数据大小。

利用索引块可以方便的定位视频数据和音频数据,现在随便打开一个AVI文件,找到索引块位置如下图所示:

可以看到索引块的内容第一个位视频索引块信息,它在movi列表的偏移地址为

4个字节。接下来找到movi列表,如下图所示:

由图上所知,movi列表开始的第一个数据块为视频数据,跟索引块刚好一一对应。视频数据开始的地址为:0x26f6,movi列表中movi字段的地址为:0x26f2,二者地址相减当好差4个字节,与视频索引块的偏移地址相对应。但这并不是真实数据的起始位置,需要在移动8个字节。最后总结下:真实数据的偏移地址 = movi字段的起始地址+视频索引块中偏移地址+8。对于音频索引块也是一样的。

视频解码:

对于我们来说,需要知道的AVI文件参数如下所示:

1.AVI文件的大小。

2.视频画面的宽度和高度。

3.视频帧率和音频采样率

4.视频帧总数及其每帧数据的偏移地址

5.音频帧总数及其每帧数据的偏移地址

6.音频的通道数

7.文件播放总时长

上面的几个参数可以从AVI文件中直接读取或者计算出来,有了以上的参数,我们就可以进行视频解码了。

我这里使用SD卡(class10)存放AVI文件,为了让AVI视频播放更加流畅,我们要对SD卡的读数据进行测试,下面是测试结果:

数据大小时间
16K2ms
32K4ms
64K6ms
128K10ms

读取时间越短,那么AVI视频文件解码也就越快。

视频解码流程大致如下:

1.初始化系统时钟相关外设,配置系统时钟为200MHZ。

2.初始SDRAM相关外设。

3.初始化液晶屏相关外设。

4.初始化SD卡相关外设,配置时钟为25MHZ,并安装FATFS文件系统。

5.初始化音频相关外设。

5.初始化JPEG硬件解码器相关外设。

6.在SDRAM中开辟两个视频帧输入缓存器,每个大小为256KB,用于存放AVI文件的视频帧数据。开辟一个视频帧索引区,大小为512KB,结构为:视频帧数据偏移地址(4字节)+视频帧数据(4字节),用于存放所有的视频帧信息。开辟一个音频帧索引区大小为512KB,结构为:音频帧数据偏移地址(4字节),用于存放所有的音频帧信息。

7.打开AVI文件,使能FATFS快速查找功能,获取解码的相关参数,并把索引块的信息分类填充到音频帧索引区和视频索引区,方便音频数据和视频数据的定位。

8.开始解码前,将第一帧和第二帧视频数据分别填充到视频帧输入缓存器。同时将第一帧和第二帧视频数据分别填充到音频输入缓存器。

9.开始解码,将视频帧输入缓存器1的内容传送到JPEG硬件解码器,等待解码完成。在等待的过程中,判断视频帧输入缓存器是否为空,如果是空的话,马上填充下一帧视频数据到视频帧输入缓存器。将音频帧输入缓存器1的内容传送到音频解码器,等待解码完成。在等待的过程中,判断视频帧输入缓存器是否为空,如果是空的话,马上填充下一帧视频数据到音频帧输入缓存器。

10.音频和视频解码同步进行,视频解码完成后,显示图像。

11.等待视频帧间隔时间到达,进行下一帧数据处理。如此循环往复,就可以播放AVI视频了。具体程序编写,可以参照我的程序。

下面是解码720X480的视频,帧率12:

视频请点击下方阅读原文观看

下面是解码480X270的视频,帧率20:

视频请点击下方阅读原文观看

下面是官方DEMO,800X480的视频,视频标称帧率25,实测最大到20(受限SD卡读写速度)

视频请点击下方阅读原文观看

如果想获取更快的解码速度,建议使用U盘存放视频文件。对于高质量的影片,解码较为吃力,有时候CPU会出现硬件出错而死掉,也有可能出现音频和视频不同步的现象,所以不建议播放高质量的影片,对于中等质量的影片,播放挺流畅的。。这里说明一下,只支持采用MJPEG视频编码器和PCM音频编码器的视频文件。如果手头没有这种类型的AVI文件,可以通过狸窝AVI视频转换器来转换,个人感觉蛮好用的,不过里面没有800X480格式,这是比较遗憾的。

欢迎点击阅读原文与作者交流、沟通。


以上图文内容均是EEWORLD论坛网友:ilovefengshulin 原创,在此感谢。

欢迎微博@EEWORLD

如果你也写过此类原创干货请关注微信公众号:EEWORLD(电子工程世界)回复“投稿”,也可将你的原创发至:bbs_service@eeworld.com.cn,一经入选,我们将帮你登上头条!

与更多行业内网友进行交流请登陆EEWORLD论坛。

关于作者: luda

无忧经验小编鲁达,内容侵删请Email至wohenlihai#qq.com(#改为@)

热门推荐