1、 视频信息处理与传输题目:AVI、MPG、WMV、ASF 、RM 等视频文件格式和相应的结构体函数文件(C 语言格式)摘要:视频是利用人的视觉暂留特性产生的动感可视媒体。根据视觉暂留原理,当静止图像以每秒 2530 帧的速度按一定顺序播放时,人眼是无法辨别单独的静态画面的,看上去是平滑连续的视觉效果。专门包含影像及同步声音信息等视频内容的文件叫视频文件,它一般分为影像文件(Video Forma)。随着计算机技术的迅猛发展和互联网的普及,多媒体信息的传播日益显示其重要的地位。大量的音频、视频、动画等多媒体文件的编码及播放成为人们研究的热点。虽然视频文件的格式有许多种,但从上面的简单说明里我们可
2、以知道,这些格式文件的应用都有着两大使用环境,即本地播放和网络播放,因此根据这两大使用环境我们可以将视频格式分为影像文件格式(Video Format)和流式视频文件格式(Stream Video Format)这么两大类。本文介绍常用的视频文件格式,包括 AVI、MPG、WMV、ASF 、RM 等视频文件格式及其 C 语言格式的结构体函数文件。关键字:视频文件格式、AVI、MPG 、WMV、ASF 、 RM、结构体函数前言:从早期的幕布电影,发展到现在的高清晰数字影片 ,从媒体格式以前的WMV、WMA 等也发展到如今 RMVB、RM 、AVI 等主流媒体格式在 IT 领域,我们常说的“格式”
3、通常指文件的格式、数据的输入输出格式、数据的传送格式等。科学技术的发展使得这些视频信息处理的应用日益广泛且向多元化发展。正文:一、AVI 格式(Audio Video Interleaved,即音频视频交错格式): 所谓“音频视频交错” ,就是可以将视频和音频交织在一起进行同步播放,在 AVI 文件中,其便是将运动图像和伴音数据以交织的方式来进行存储地,并且这种存储完全独立于硬件设备,这就保证了它在不同平台下均可以获得较好的支持。AVI 文件包含三部分: 文件头、数据块和索引块。数据块: 包含实际数据流, 即图像和声音序列数据。这是文件的主体, 也是决定文件容量的主要部分。视频文件的容量等于该
4、文件的数据率乘以该视频播放的时间长度。索引块: 包括数据块列表和他们在文件中的位置, 以提供文件内数据随机存取能力。 文件头: 包括文件的通用信息, 定义数据格式, 所用的压缩算法等参数。只要遵循这个标准,任何视频编码方案都可以使用在 A V I 文件中。这意味着 AV I 有着非常好的扩充性。AVI 文件是一种 RIFF( Resource Interchange File Format, 资源交换文件格式) 格式文件。1、信息块,一个 ID 为“hdrl“的 LIST 块,定义 AVI 文件的数据格式。2、数据块,一个 ID 为 “movi“的 LIST 块,包含 AVI 的音视频序列数据
5、。3、索引块,ID 为 “idxl“的子块,定义 “movi“LIST 块的索引数据,是可选块。“avih“子块的内容可由如下的结构定义:typedef struct DWORD dwMicroSecPerFrame ; /显示每桢所需的时间 ns,定义 avi 的显示速率DWORD dwMaxBytesPerSec; / 最大的数据传输率DWORD dwPaddingGranularity; /记录块的长度需为此值的倍数,通常是 2048DWORD dwFlages; /AVI 文件的特殊属性,如是否包含索引块,音视频数据是否交叉存储DWORD dwTotalFrame; /文件中的总桢数D
6、WORD dwInitialFrames; /说明在开始播放前需要多少桢DWORD dwStreams; /文件中包含的数据流种类DWORD dwSuggestedBufferSize; /建议使用的缓冲区的大小,/通常为存储一桢图像以及同步声音所需要的数据之和DWORD dwWidth; /图像宽DWORD dwHeight; /图像高DWORD dwReserved4; /保留值MainAVIHeader;“strl“ LIST 块用于记录 AVI 数据流,每一种数据流都在该 LIST 块中占有 3 个子块,他们的 ID 分别是“strh“,“strf“, “strd“;“strh“子块由
7、如下结构定义。typedef struct FOURCC fccType; /4 字节,表示数据流的种类 vids 表示视频数据流/auds 音频数据流FOURCC fccHandler;/4 字节 ,表示数据流解压缩的驱动程序代号DWORD dwFlags; /数据流属性WORD wPriority; /此数据流的播放优先级WORD wLanguage; /音频的语言代号DWORD dwInitalFrames;/说明在开始播放前需要多少桢DWORD dwScale; /数据量,视频每桢的大小或者音频的采样大小DWORD dwRate; /dwScale /dwRate = 每秒的采样数DW
8、ORD dwStart; /数据流开始播放的位置,以 dwScale 为单位DWORD dwLength; /数据流的数据量,以 dwScale 为单位DWORD dwSuggestedBufferSize; /建议缓冲区的大小DWORD dwQuality; /解压缩质量参数,值越大,质量越好DWORD dwSampleSize; /音频的采样大小RECT rcFrame; /视频图像所占的矩形AVIStreamHeader;“strf“子块紧跟在“strh“子块之后,其结构视“strh“子块的类型而定,如下所述;如果 strh 子块是视频数据流,则 strf 子块的内容是一个与 windo
9、ws 设备无关位图的 BIMAPINFO 结构,如下:typedef struct tagBITMAPINFOBITMAPINFOHEADER bmiHeader;RGBQUAD bmiColors1; /颜色表BITMAPINFO;typedef struct tagBITMAPINFOHEADERDWORD biSize;LONG biWidth;LONG biHeight;WORD biPlanes;WORD biBitCount;DWORD biCompression;DWORD biSizeImage;LONG biXPelsPerMeter;LONG biYPelsPerMeter
10、;DWORD biClrUsed;DWORD biClrImportant;BITMAPINFOHEADER;如果 strh 子块是音频数据流,则 strf 子块的内容是一个 WAVEFORMAT 结构,如下:typedef struct WORD wFormatTag; WORD nChannels; /声道数DWORD nSamplesPerSec; /采样率DWORD nAvgBytesPerSec; /WAVE 声音中每秒的数据量WORD nBlockAlign; /数据块的对齐标志WORD biSize; /此结构的大小WAVEFORMAT“strd“子块紧跟在 strf 子块后,存
11、储供压缩驱动程序使用的参数,不一定存在,也没有固定的结构。“strl“ LIST 块定义的 AVI 数据流依次将 “hdrl “ LIST 块中的数据流头结构与“movi“ LIST 块中的数据联系在一起,第一个数据流头结构用于数据流 0,第二个用于数据流 1,依次类推。数据块中存储视频和音频数据流,数据可直接存于 “movi“ LIST 块中。数据块中音视频数据按不同的字块存放,其结构如下所述,音频字块“#wb“Wave 数据流视频子块中存储 DIB 数据,又分为压缩或者未压缩 DIB,“#db“RGB 数据流“#dc“压缩的图像数据流(如果第一个流是音频,则 4 字符码为00wb ;第二个
12、流是视频,则 4 字符码为00db或00dc ) . (网上原话,可能是 01db 或 01dc)看到了吧,avi 文件的图像数据可以是压缩的,和非压缩格式的。对于压缩格式来说,也可采用不同的编码,也许你曾经遇到有些 avi 没法识别,就是因为编 码方式不一样,如果没有相应的解码,你就没法识别视频数据。AVI 的编码方式有很多种,比较常见的有 mpeg2,mpeg4 , divx 等。索引块,索引快包含数据块在文件中的位置索引,能提高 avi 文件的读写速度,其中存放着一组 AVIINDEXENTRY 结构数据。如下,这个块并不是必需的,也许不存在。typedef struct DWORD c
13、kid; /记录数据块中子块的标记DWORD dwFlags; /表示 chid 所指子块的属性DWORD dwChunkOffset; /子块的相对位置DWORD dwChunkLength; /子块长度;二、MPG 又称 MPEG(Moving Pictures Experts Group)即动态图像专家组,由国际标准化组织 ISO(International Standards Organization)与 IEC(International Electronic Committee)于 1988 年联合成立,专门致力于运动图像(MPEG 视频)及其伴音编码(MPEG 音频)标准化工作。
14、2.0Mpeg-1 数据流分析2.1 视频序列层(VideoStream):Video_Streamunsigned int h_size; /* Horiz. size in pixels. */unsigned int v_size; /* Vert. size in pixels. */unsigned int mb_height; /* Vert. size in mblocks. */unsigned int mb_width; /* Horiz. size in mblocks. */unsigned char aspect_ratio; /* Code for aspect ra
15、tio. */unsigned char picture_rate; /* Code for picture rate. */unsigned int bit_rate; /* Bit rate. */unsigned int vbv_buffer_size; /* Minimum buffer size. */BOOLEAN const_param_flag; /* Contrained parameter flag. */unsigned char intra_quant_matrix88; /* Quantization matrix forintracoded frames. */un
16、signed char non_intra_quant_matrix88; /* Quanitization matrix for non intracoded frames. */char *ext_data; /* Extension data. */char *user_data; /* User data. */GoP group; /* Current group of pict. */Pict picture; /* Current picture. */Slice slice; /* Current slice. */Macroblock mblock; /* Current m
17、acroblock. */Block block; /* Current block. */int state; /* State of decoding. */int bit_offset; /* Bit offset in stream. */unsigned int *buffer; /* Pointer to next byte in buffer. */int buf_length; /* Length of remaining buffer.*/unsigned int *buf_start; /* Pointer to buffer start. */int max_buf_le
18、ngth; /* Max lenght of buffer. */PictImage *past; /* Past predictive frame. */PictImage *future; /* Future predictive frame. */PictImage *current; /* Current frame. */PictImage *ringRING_BUF_SIZE; /* Ring buffer of frames. */ Video_Stream; 具体的序列标题的结构的部分是这样的:序列sequence_headerSEQ_START_CODE 0x000001b3
19、; /* 常量 ,作用使用来定位视频序列的序列头 */ unsigned int h_size; /* Horiz. size in pixels. */unsigned int v_size; /* Vert. size in pixels. */unsigned int mb_height; /* Vert. size in mblocks. */unsigned int mb_width; /* Horiz. size in mblocks. */unsigned char aspect_ratio; /* Code for aspect ratio. */unsigned char p
20、icture_rate; /* Code for picture rate. */unsigned int bit_rate; /* Bit rate. */unsigned int vbv_buffer_size; /* Minimum buffer size. */BOOLEAN const_param_flag; /* Contrained parameter flag. */unsigned char load_intra_quantizer_matrix;unsigned char intra_quant_matrix88; /* Quantization matrix for in
21、tracoded frames. 这个结构是可选的,要看 load_intra_quantizer_matrix 的值,为真则有这个部分,否则没有,因为intra_quant_matrix 是量化表的值,而 Sequence_header 结构在视频序列中是可重复的,即在每个画面组之前都有可能再次给出一个 sequence_header,并且可以在新的 sequence_header 中重新定义量化表*/unsigned char load_non_intra_quantizer_matrix;unsigned char non_intra_quant_matrix88; /* Quaniti
22、zation matrix for non intracoded frames. 也是可选。愿意于 intra_quant_matrix 可选的原因相同。当load_non_intra_quant_matrix 的值为真的时候需要定义。 */char *ext_data; /* Extension data. */char *user_data; /* User data. */由上面的分析,可以看出来的是:video_sequence()next_start_code()dosequence_header();dogroup_of_pictures() ; /画面组while (nextbi
23、ts()=GROUP_START_CODE)while(nextbits()=SEQUENCE_HEADER_CODE)SEQUENCE_END_CODE;2.2 画面组层(GOP ):typedef struct GoP BOOLEAN drop_flag; /* Flag indicating dropped frame. */unsigned int tc_hours; /* Hour component of time code. */unsigned int tc_minutes; /* Minute component of time code. */unsigned int tc
24、_seconds; /* Second component of time code. */unsigned int tc_pictures; /* Picture counter of time code. */BOOLEAN closed_gop; /* Indicates no pred. vectors to previous group of pictures. */BOOLEAN broken_link; /* B frame unable to be decoded. */char *ext_data; /* Extension data. */char *user_data;
25、/* User data. */ GoP;当然每个画面组层都是开始与标志码:GOP_START_CODE该层次语法上的定义是group_of_picturesGOP_START_CODETime_code; tc_hours,tc_minutes,tc_seconds,tc_picturesClosed_gop;Broken_link;Next_start_code;If(nextbits=extension_start_code) Extension_start_code;While(nextbits()=”0000 0000 0000 0000 0000 0001”) Group_exte
26、nsion_data;next_start_code()if(nextbits=user_data_start_code)user_data_start_codewhile(nextbits()!=0000 0000 0000 0000 0000 0001)user_data;next_start_code()dopicture()while(nextbits=picture_start_code)2.3 画面层(Pictures):picture()picture_start_codetemprol_reference /*时序编号,通常一组画面的编号都在 1024 以内,如果超过那么在 1
27、025 幅画面出复位为 0,重新计数。 */ picture_coding_type vbv_delay/*对于固定比特率的视频流, vbv_delay 用与解码过程开始和随机存取之后,以保证在第一幅画面被显示之前,解码器 已经读到正确数目的比特数。*/if(picture_coding_type=2) | picture_coding_type=3)full_pel_foward_vector /*全象素前向矢量,给定前向矢量的精度,在 P 和 B 画面的标题中出现*/forward_f_codeif(picture_coding_type=3)full_pel_backward_vecto
28、rback_f_codewhile(nextbits()=1)extra_bit_pictureextra_information_pictureextra_bit_picturenext_start_codeif(nextbits()=extension_start_code)extension_start_codewhile(nextbits()!=0000 0000 0000 0000 0000 0001)picture_extension_datanext_start_code()if(nextbits()=user_data_start_code)user_data_start_co
29、dewhile(nextbits()!=0000 0000 0000 0000 0000 0001)user_datanext_start_code()do slice()while(nextbits()=slice_start_code)整个画面单元结构是这样的:typedef struct pict unsigned int temp_ref; /* Temporal reference. */unsigned int code_type; /* Frame type: P, B, I */unsigned int vbv_delay; /* Buffer delay. */BOOLEAN
30、 full_pel_forw_vector; /* Forw. vectors specified in fullpixel values flag. */unsigned int forw_r_size; /* Used for vector decoding. */unsigned int forw_f; /* Used for vector decoding. */BOOLEAN full_pel_back_vector; /* Back vectors specified in full pixel values flag. */unsigned int back_r_size; /*
31、 Used in decoding. */unsigned int back_f; /* Used in decoding. */char *extra_info; /* Extra bit picture info. */char *ext_data; /* Extension data. */char *user_data; /* User data. */ Pict;2.4 片层(Slice):首先给出识别出 Slice 层数据的头标 slice_start_code#define SLICE_MIN_START_CODE 0x00000101#define SLICE_MAX_STAR
32、T_CODE 0x000001afsliceslice_start_code /*从中可以计算出 slice_vertical_position 片中第一个宏块,以宏块为单位的垂直位置*/quantizer_scale /*设置量化步长尺寸。 131*/while(nextbits()=1)extra_bit_slice 1extra_information_sliceextra_bit_scale 0domacroblock()while(nextbits()!=0000 0000 0000 0000 0000 0000)next_start_code()typedef struct sli
33、ce unsigned int vert_pos; /* Vertical position of slice. */unsigned int quant_scale; /* Quantization scale. */char *extra_info; /* Extra bit slice info. */ Slice;2.5 宏块层(Macroblock):macroblock()while(nextbits()=0000 0001 111)macroblock_stuffing /*宏块填料,为了防止下溢出,由编码器填入的数据,有它固定的 11 位 bit 格式就是0000 0001 1
34、11,当然 解决下溢出的方法还有很多,编码器可以在标题之前就加入填料位,或者可以减小quant_scale 获得更多的编码系数等等*/while(nextbits()=0000 0001 000)macroblock_escape /*固定模式的 bit 串,当 macroblock_address 与previous_macroblock_address 的差大于 33 时将用到该码。 使得后继的macroblock_increment 所表示的值加 33。macroblock_address_increment /*用于表示 macroblock_address 和previous_mac
35、orblock_ address 之间的差值。 最大值为 33,当前两者差大于 33时用 macroblock_escape 补充。 Macroblock_address 表示的是宏块在画面中的绝对位置,最左上角的宏块的 macroblock_address 为0,previous_macroblock_address 指示片中最后一个非跳空宏块的位置。*/macroblock_type if(macroblock_motion_forward)motion_horizontal_forward_codeif(forward_f!=1) i6;i+)block(i)if(picture_cod
36、ing_type=4)end_of_marcoblock片被分为 16pixels*16lines 的象素宏块。每个宏块都有它的标题。包含了宏块的地址、类型、量化器标尺信息等等。标题之后是该宏块的 6 个块的数据。在 Xmplay 代码中给出的 macrblock 的定义:typedef struct macroblock int mb_address; /* Macroblock address. */int past_mb_addr; /* Previous mblock address. */int motion_h_forw_code; /* Forw. horiz. motion v
37、ector code. */unsigned int motion_h_forw_r; /* Used in decoding vectors. */int motion_v_forw_code; /* Forw. vert. motion vector code. */unsigned int motion_v_forw_r; /* Used in decdoinge vectors. */int motion_h_back_code; /* Back horiz. motion vector code. */unsigned int motion_h_back_r; /* Used in
38、decoding vectors. */int motion_v_back_code; /* Back vert. motion vector code. */unsigned int motion_v_back_r; /* Used in decoding vectors. */unsigned int cbp; /* Coded block pattern. */BOOLEAN mb_intra; /* Intracoded mblock flag. */BOOLEAN bpict_past_forw; /* Past B frame forw. vector flag. */BOOLEA
39、N bpict_past_back; /* Past B frame back vector flag. */int past_intra_addr; /* Addr of last intracoded mblock. */int recon_right_for_prev; /* Past right forw. vector. */int recon_down_for_prev; /* Past down forw. vector. */int recon_right_back_prev; /* Past right back vector. */int recon_down_back_p
40、rev; /* Past down back vector. */ Macroblock;2.6 块层(Block):typedef struct blockshort int dct_recon88; /* Reconstructed dct coeff matrix. */short int dct_dc_y_past; /* Past lum. dc dct coefficient. */short int dct_dc_cr_past; /* Past cr dc dct coefficient. */short int dct_dc_cb_past; /* Past cb dc dc
41、t coefficient. */ Block;解析块的语法结构是:block(i)if(pattern_codei)if(macroblock_intra)if(i4)dct_dc_size_luminanceif(dc_size_luminance!=0)dct_dc_differentialelsedct_dc_size_chrominanceif(dc_size_chrominance!=0)dct_dc_differentialelsedct_coeff_firstif(picture_coding_type!=4)while(nextbits()!=10)dct_coeff_nex
42、tend_of_block2.7 加密位置的思考。三、WMV(Windows Media Video): 采用独立编码方式并且可以直接在网上实时观看视频节目的文件压缩格式。WM V 格式的主要优点包括: 相比 MPEG 、VOB 格式同等画质时文件相对较小、本地或网络回放、可扩充的媒体类型、部件下载、 可伸缩的媒体类型、流的优先级化、多语言支持、环境独立性、丰富的流间关系以及扩展性。它是由 A SF( A dva n c ed S tr e a m For m at ) 格式升级延伸来的。在同等视频质量下, WM V 格式的体积非常小 ( RM 格式也特小, 不同的技术相同的应用 ), 因此也
43、很适合在网上播放和传输。头 16 个字节是固定的;接下来的 8 个字节为一个整数,表示整个 WMA 文件头部的大小;头部后面的是音频信息;从文件开始偏移量为 31 开始,里面存放了很多帧,有我们需要的标准 Tag 信息,扩展 Tag 信息,WMA 文件控制信息等等。每个帧不是等长的,但是帧头是固定的 24 个字节,其中前 16 字节是用来标识这个帧的名字,后 8 个字节是用来表示这个帧(包括帧头)的大小。四、ASF(Advanced Streaming format):ASF 是一种数据格式,音频,视频,图像以及控制命令脚本等多媒体信息通过这种格式,以网络数据包的形式传输,实现流式多媒体内容发
44、布。ASF 头对象:文件属性对象(File Properties Object)-全局文件属性。流属性对象(Stream Properties Object)-定义一个媒体流和其属性。内容描述对象(Content Description Object)-包含所有目录信息。部件下载对象(Component Download Object)-提供播放部件信息。流组织对象(Stream Groups Object)- 逻辑上把多个媒体流组织在一起。可伸缩对象(Scalable Object)-定义媒体流之间的可伸缩的关系。优先级对象(Prioritization Object)-定义相关流的优先级。
45、相互排斥对象(Mutual Exclusion Object)-定义排斥关系如语言选择。媒体相互依赖对象(Inter-Media Dependency Object)-定义混合媒体流之间的相互依赖关系。级别对象(Rating Object)- 根据 W3C PICS 定义文件的级别。索引参数对象(Index Parameters Object)- 提供必要的信息以重建 ASF 文件的索引。数据类型:typedef struct tagBITMAPINFOHEADERDWORD biSize;LONG biWidth;LONG biHeight;WORD biPlanes;WORD biBitCount;DWORD biCompression;DWORD biSizeImage;LONG biXPelsPerMeter;LONG biYPelsPerMeter;DWORD biClrUsed;DWORD biClrImportant; BITMAPINFOHEADER;typedef structWORD wFormatTag; /编码格式