开发者社区> jerry.yin> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

视频文件格式分析(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格式并不适合应用在流视频传输和播放的场合。


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

相关文章
如何将mp3文件转pcma格式或PCM格式的wav文件
如何将mp3文件转pcma格式或PCM格式的wav文件
0 0
文件格式的小说明
.com 和 .exe 和 .bat 这三种称为可执行文件。   也就是说:在一套软件里,只要执行以上扩展的文件(如鼠标双击此类型文件),软件就可以正常运行了。   编写一套软件,涉及内容很多。   如编写一套学校管理软件,需要学校的一些数据,那么我们可以把数据文件归类。
552 0
mpeg文件格式分析
<table border="0" cellspacing="3" cellpadding="0" width="100%"><tbody> <tr> <td> <p align="left"><span style="font-size:16px"><br> MPEG-1流比特层次结构分析总结<br> 1.简要介绍Mpeg<br> 2.Mpeg-1数据流分析<br> 2.1视频
1105 0
MP4文件格式的解析
<h2 style="text-align:center">MP4文件格式的解析,以及MP4文件的分割算法</h2> <p><span style="font-family:幼圆; font-size:15px">  mp4应该算是一种比较复杂的媒体格式了,起源于QuickTime。以前研究的时候就花了一番的功夫,尤其是如何把它完美的融入到<span style="color:#0000
1773 0
wav文件格式分析详解
wav文件格式分析详解 文章转载自:http://blog.csdn.net/BlueSoal/article/details/932395 一、综述    WAVE文件作为多媒体中使用的声波文件格式之一,它是以RIFF格式为标准的。
791 0
avi文件格式详解
AVI是音频视频交错(Audio Video Interleaved)的英文缩写,它是Microsoft公司开发的一种符合RIFF文件规范的数字音频与视频文件格式,原先用于Microsoft Video for Windows (简称VFW)环境,现在已被Windows 95/98、OS/2等多数操作系统直接支持。
731 0
+关注
jerry.yin
毕业于上海大学通信与信息工程学院,从事流媒体和视频编解码的研究与开发工作; 研究领域包括视频编解码标准、视频处理和流媒体技术、移动互联网技术等。
文章
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载