视频文件格式分析(1):avi格式-阿里云开发者社区

开发者社区> jerry.yin> 正文

视频文件格式分析(1):avi格式

简介: 近日某网盘对用户保存其中的部分私人视频进行篡改,使得这部分视频无论是在线或者下载后均无法播放。我们借着研究对应方法,修复被非法篡改的视频数据,恢复正常使用的机会,研究一下avi的数据格式。
+关注继续查看

近日某网盘对用户保存其中的部分私人视频进行篡改,使得这部分视频无论是在线或者下载后均无法播放。我们借着研究对应方法,修复被非法篡改的视频数据,恢复正常使用的机会,研究一下avi的数据格式。

avi视频的格式分析

avi是“音视频交错(Audio-Video Interlance)"的缩写,是非常常见的视频文件封装格式。avi是一种适用于采集、编辑、播放的RIFF格式,对不同的编码标准和播放工具具有很强的适应性。

1、文件主体结构

RIFF文件的组成方式由多个chuck组成,组成方式为:

  1. FOURCC字符:表示当前chuck的名称;
  2. chuck大小:一个uint32类型整数,使用little-endian保存;该值仅表示下一部分“文件内容”的字节数大小;
  3. chuck数据:表示当前chuck中实际包含的信息内容;

每一个文件有且仅有一个RIFF chuck,它可以包含多个子chuck,其中的list可以再包含下一级子chuck。相比普通chuck,在RIFF和LIST的chuck大小和数据之间多了一个表示“Form Type/List Type”4个FOURCC字符,如“AVI[ ]”或“WAVE”等,即组成为:

  1. FOURCC字符:表示当前chuck的名称,对于最上层的chuck,固定为“RIFF”;
  2. chuck大小:一个uint32类型整数,使用little-endian保存;该值仅表示下一部分“文件内容”的字节数大小,不包含riff字符和文件大小本身;
  3. 4字节的形式类型或者列表类型:在此为“AVI[ ]”;
  4. chuck数据:表示当前chuck中实际包含的信息内容;

下一部分数据是AVI的LIST子块。AVI数据块一般包含3个LIST,分别是hdrl、movi和idxl三个,分别表示头信息、音视频数据和索引信息。

每一个list的结构如下:

  1. FOURCC字符:“LIST”
  2. LIST数据块的大小;
  3. LIST类型;
  4. LIST数据;

首先研究第一个LIST,即hdrl list。首先包括了一个数据结构表示当前数据的AVI Main Header结构,用AVIMAINHEADER表示。这个数据结构包含了当前AVI文件的整体信息,包括视频分辨率、视频中的流数目等。AVIMAINHEADER实现方式如下:

typedef struct _avimainheader {
    FOURCC fcc;<span style="white-space:pre">			</span>//fourcc字符“avih”
    DWORD  cb;<span style="white-space:pre">			</span>//当前结构占据多少个字节
    DWORD  dwMicroSecPerFrame;<span style="white-space:pre">	</span>//显示相邻两帧的间隔,以毫秒为单位
    DWORD  dwMaxBytesPerSec;<span style="white-space:pre">	</span>//每秒钟传输的最大数据量的估计值
    DWORD  dwPaddingGranularity;//字节对齐单位,数据块长度必须是该值的倍数
    DWORD  dwFlags;<span style="white-space:pre">		</span>//一些标志位
    DWORD  dwTotalFrames;<span style="white-space:pre">	</span>//数据帧的总数
    DWORD  dwInitialFrames;<span style="white-space:pre">	</span>//第一个视频帧开始播放之前需预先准备的帧数
    DWORD  dwStreams;<span style="white-space:pre">		</span>//文件中流的个数(如一个视频流+一个音频流=2个流)
    DWORD  dwSuggestedBufferSize;//读取数据的缓存区的建议大小
    DWORD  dwWidth;<span style="white-space:pre">		</span>//视频像素宽度
    DWORD  dwHeight;<span style="white-space:pre">		</span>//视频像素高度
    DWORD  dwReserved[4];<span style="white-space:pre">	</span>//保留位
} AVIMAINHEADER;

在AVIMAINHEADER之后是hdrl的子list——strl,包括strh和strf,分别表示stream header和stream format信息。另外,还可能包括strd和strn等部分分别表示header data和stream name等数据。

以下为strh包含的 AVISTREAMHEADER结构:

typedef struct _avistreamheader {
     FOURCC fcc;//“strh”四字符
     DWORD  cb;//当前结构大小
     FOURCC fccType;//表示当前stream所包含的数据类型
     FOURCC fccHandler;//对于音频、视频数据,该部分表示所采用的解码器
     DWORD  dwFlags;
     WORD   wPriority;//表示当前流的优先级
     WORD   wLanguage;//语言
     DWORD  dwInitialFrames;
     DWORD  dwScale;//与下一个元素一起表示sample的频率,如视频帧率等。
     DWORD  dwRate;
     DWORD  dwStart;//表示当前流的起始时间
     DWORD  dwLength;//该stream的长度
     DWORD  dwSuggestedBufferSize;//建议缓存区大小
     DWORD  dwQuality;//表示数据质量;在视频流中表示编码的QP
     DWORD  dwSampleSize;//sample的大小
     struct {
         short int left;
         short int top;
         short int right;
         short int bottom;
     }  rcFrame;//数据显示的目标区域
} AVISTREAMHEADER;

紧跟着strh之后是一个strf数据块,该数据块表示当前流中的数据格式。对于视频,以BITMAPINFO表示;对于音频,以WAVEFORMATEX表示。数据结构如下:

typedef struct tagBITMAPINFO { 
  BITMAPINFOHEADER bmiHeader; 
  RGBQUAD bmiColors[1]; 
} BITMAPINFO; 
typedef struct tagBITMAPINFOHEADER { 
  DWORD biSize; 
  LONG biWidth; 
  LONG biHeight; 
  WORD biPlanes; 
  WORD biBitCount 
  DWORD biCompression; 
  DWORD biSizeImage; 
  LONG biXPelsPerMeter; 
  LONG biYPelsPerMeter; 
  DWORD biClrUsed; 
  DWORD biClrImportant; 
} BITMAPINFOHEADER;
typedef struct tagRGBQUAD { 
  BYTE rgbBlue;
  BYTE rgbGreen;
  BYTE rgbRed;
  BYTE rgbReserved;
} RGBQUAD;
在实验中,BITMAPINFOHEADER中的biCompression成员为一个fourCC字符“avc1”,且不包含后面的RGBQUAD部分。

对于音频部分,WAVEFORMATEX的实现如下:

typedef struct { 
  WORD  wFormatTag; 
  WORD  nChannels; 
  DWORD nSamplesPerSec; 
  DWORD nAvgBytesPerSec; 
  WORD  nBlockAlign; 
  WORD  wBitsPerSample; 
  WORD  cbSize; 
} WAVEFORMATEX; 

这部分的后面还存在一个odml的list,包含一个dmlh的部分,用来表示avi扩展头部序列块。

以上部分即avi文件的文件信息hdrl部分,紧接着便是保存实际音视频数据的movi list。一个fourcc字符“movi”之后的fourcc字符可能含有一下双字符组合中的一个,表示chuck中包含的数据的种类:

字符组合 含义
db 未压缩视频帧
dc 压缩的视频数据
pc 调色信息
wd 音频信息

在文件的最后,包含一个可选的chuck——索引数据“idx1”。索引chuck包含了各个数据chuck在文件中的位置,其实现方式如下:

typedef struct _avioldindex {
   FOURCC  fcc;
   DWORD   cb;
   struct _avioldindex_entry {
      DWORD   dwChunkId;
      DWORD   dwFlags;
      DWORD   dwOffset;
      DWORD   dwSize;
  } aIndex[];
} AVIOLDINDEX;

由此可以看出,avi格式在文件末尾包含了索引信息,所以播放需要获得从开始到结束的完整文件数据。由于这种特性,avi格式并不适合应用在流视频传输和播放的场合。


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
PNG文件结构分析 ---Png解析
PNG文件结构分析 ---Png解析     为了实现更高级的应用,我们必须充分挖掘PNG的潜力。 PNG的文件结构   根据PNG文件的定义来说,其文件头位置总是由位固定的字节来描述的:   十进制数 137 80 78 71 13 10 26 10 十六进制数 89 50 4E 47 0D 0A 1A 0A   其中第一个字节0x89超出了ASCII字符的范围,这是为了避免某些软件将PNG文件当做文本文件来处理。
1057 0
视频的文件格式、压缩格式、码率、分辨率
首先,我们明确几个基本概念:视频的文件格式、压缩格式、码率、分辨率, 视频的文件格式有:mkv,mp4,flv,wmv,rmvb等; 视频的压缩格式有:h.263,h.264,mpeg-2,rmvb等; 视频的码率:码率也叫比特率,表示经过压缩编码后的视音频数据每秒需要用多少个比特来表示,即把每秒显示的 图像进行压缩后的数据量,一般采用的单位是kbps即千位每秒。
1299 0
js判断文件格式及大小
//上传文件大小以及格式验证 function getPhotoSize(obj){ photoExt=obj.
675 0
郑州商品交易所与阿里云达成合作 推进核心数据分析平台建设
5月20日,郑州商品交易所(以下简称“郑商所”)日前与阿里云达成技术合作,通过引入阿里云AnalyticDB云原生数据仓库,进一步提升郑商所数据平台数据分析效率和用户体验。
184 0
Eclipse 分屏显示同一个代码文件
描述:         今天在使用Eclipse开发的时候不知按错哪个键,出现编辑框分屏显示同一个代码,由于之前没有使用过这一功能,所以就去查了一下,原来是Eclipse的分屏功能。   快捷键:        方式一:Window -> Editor -> Toggle Split Editor ...
1417 0
+关注
jerry.yin
毕业于上海大学通信与信息工程学院,从事流媒体和视频编解码的研究与开发工作; 研究领域包括视频编解码标准、视频处理和流媒体技术、移动互联网技术等。
182
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载