视频文件头解析--wmv-解析流程

来源:互联网 发布:想在淘宝上卖东西 编辑:程序博客网 时间:2024/05/20 17:28

1、第一层,Header Object,这个结构一般不解析。没什么用。跳过这30字节的结构

2、第二层,File Properties Object 、Header ExtensionObject和Stream Properties Object,前两个也没解析,直接跳过了。Header Object是一个容器,它里面必须包含一个File PropertiesObject, 一个Header Extension Object 和至少一个Stream Properties Object。

a)  用while循环从读入的数据中查找每个Stream Properties Object类型的128bit的Object ID,(Stream Properties Object是流属性对象,定义一个媒体流和其属性),如果找到,返回找到的位置pos。ff_asf_stream_header(B7DC0791-A9B7-11CF-8EE6-00C00C205365(guid),16进制guid的顺序是9107DCB7-B7A9-CF11-8EE6-00C00C205365)这个标志代表了Stream Properties Object类型的Object ID。

b)  获取16字节的Stream Type字段,判断当前stream的类型(video、audio)

i.  如果当前stream是ASF_Video_Media型,即Stream Type是BC19EFC0-5B4D-11CF-A8FD-00805F5C442B(guid),16进制guid的顺序是C0EF19BC-4D5B-CF11-A8FD-00805F5C442B,那么进行Video media type类型的Type-Specific Data数据解析。转第三层,BITMAPINFOHEADER 类型结构。

ii.  如果当前stream是ASF_Audio_Media类型,即Stream Type是F8699E40-5B4D-11CF-A8FD-00805F5C442B(guid),16进制guid的顺序是409E69F8-4D5B-CF11-A8FD-00805F5C442B,那么进行Audio media type类型的Type-Specific Data数据解析。转第三层,WAVEFORMATEX类型结构。

iii.当前stream是ASF_Command_Media型,即Stream Type是59DACFC0-59E6-11D0-A3AC-00A0C90348F6(guid),16进制guid的顺序是C0CFDA59-E659-11D0-A3AC-00A0C90348F6。不做其他操作。

iv.  当前stream是ASF_Binary_Media型,即Stream Type是3AFB65E2-47EF-40F2-AC2C-70A90D71D343(guid),16进制guid的顺序是E265FB3A-EF47-F240-AC2C-70A90D71D343,转第三层,ASF_Binary_Media类型。

c)  获取Type-SpecificData Length ,4字节。用来解析第三层的Type-Specific Data数据。

d)  跳过ErrorCorrection Data Length,4字节字段

e)  紧接着的16bit分别为Stream Number(7)\Reserved(8bit,全为0)\Encrypted Content Flag(1bit,一般不设置,一旦设置,这个stream里得date就不解析),这16个bit与上0x7f之后,得到StreamNumber,即以后用到的video或者audio pid。

f)  跳过Reserved(4字节)字段,解析第三层的Type-Specific Data。

3、第三层,Type-Specific Data。

Type-Specific Data的数据类型由Stream Type字段限定。根据不同的类型,各自有不同的Type-Specific Data结构。

a)ASF_Binary_Media类型。

这个类型结构体的参数基本不解析,除了Major media type为31178C9D-03E1-4528-B582-3DF9DB22F503(guid),16进制guid的顺序是9D8C1731-E103-2845-B582-3DF9DB22F503的时候,类型为audio,会去解析这个结构体之后的参数。以ASF_Audio_Media方式解析。

Stream Type是ASF_Binary_Media类型的。那么这个stream包含:Stream Type是ASF_Binary_Media类  型的。那么这个stream包含:

Major mediatype,128bit;

Media subtype,128bit;

Fixed-size samples,32bit;

Temporalcompression,32bit;

Sample size,32bit;

Format type,128bit;

Format datasize,32bit;

 

b) Stream Type是ASF_Audio_Media类型的。那么这个stream使用WAVEFORMATEX 结构:

WAVEFORMATEX 定义音频数据格式

typedef struct

    WORD wFormatTag;//数据格式 如果包含在WAVEFORMATEXTENSIBLE中则必须为WAVE_FORMAT_EXTENSIBLE  

    WORD nChannels;//通道 通常为单通道,stereo data使用双通道 

    DWORD nSamplesPerSec;//采样输入率 hz 

    DWORD nAvgBytesPerSec; 

    WORD nBlockAlign; 

    WORD wBitsPerSample; 

    WORD cbSize;

} WAVEFORMATEX;

//WAVEFORMATEX 为波形音频流格式的数据结构,包括

//wFormatTag(16bit)设置波形声音的格式,nChannels(16bit)设置音频文件的通道数量,对于单声道的声音,此此值为1。对于立体声,此值为2.

//nSamplesPerSec(32bit)   设置每个声道播放和记录时的样本频率。

// 如果wFormatTag = WAVE_FORMAT_PCM,那么nSamplesPerSec通常为8.0 kHz, 11.025 kHz, 22.05 kHz和44.1 kHz。例如对于采样率为11.025 kHz的音频,

//nSamplesPerSec 将被设为11025。对于非PCM格式的,请根据厂商的设定计算

//nAvgBytesPerSec(32bit)设置请求的平均数据传输率,单位byte/s。这个值对于创建缓冲大小是很有用的

//nBlockAlign(16bit),以字节为单位设置块对齐。块对齐是指最小数据的原子大小。

//如果wFormatTag = WAVE_FORMAT_PCM,nBlockAlign 为(nChannels*wBitsPerSample)/8。对于非PCM格式请根据厂商的说明计算。

//wBitsPerSample(16bit)根据wFormatTag的类型设置每个样本的位深(即每次采样样本的大小,以bit为单位)。

//如果wFormatTag = WAVE_FORMAT_PCM,此值应该设为8或16,对于非PCM格式,根据厂商的说明设置。

//一些压缩的架构不能设置此值,此时wBitsPerSample应该为零

//cbSize(16bit),额外信息的大小,以字节为单位,额外信息添加在WAVEFORMATEX结构的结尾。

//这个信息可以作为非PCM格式的wFormatTag额外属性,如果wFormatTag不需要额外的信息,

//此值必需为0,对于PCM格式此值被忽略。

根据第二层的Type-Specific Data Length参数,设置每个样本的位深(即每次采样样本的大小,以bit为单位)并且可以判断是否要解析第三层中的cbSize和额外信息,如果Type-Specific Data Length为14,每个样本的位深为8;其他情况下,位深未解析后面16bit的值得到的wBitsPerSample字段。如果Type-Specific DataLength大于等于18,表明后面有额外信息,需要获取cbSize(16bit),额外信息的大小,以字节为单位,额外信息添加在WAVEFORMATEX结构的结尾。额外信息应该叫WAVEFORMATEXTENSIBLE结构。参看第四层的WAVEFORMATEXTENSIBLE结构说明。

4、 第四层

4-1、WAVEFORMATEXTENSIBLE结构,存在于WAVEFORMATEX结构的末尾Codec Specific Data字段。专用于ASF_Audio_Media.WAVEFORMATEXTENSIBLE,为了解决多声道排序和高精度数据的问题,Microsoft 定义了一个新的结构WAVE_FORMAT_EXTENSIBLE。此新结构不仅仅能够解决这些问题,而且还提供了一个自我注册新数据格式的机制。SubFormat字段设置为指定WAVE_FORMAT_EXTENSIBLE结构所描述数据类型的 GUID。WAVEFORMATEXTENSIBLE结构描述了一个多通道波形格式。这个结构是对WAVEFORMATEX的扩展,配置了已经由 WAVEFORMATEX中cbSize成员支持的额外字节。当需要WAVEFORMATEX的地方,WAVEFORMATEXTENSIBLE结构能够被转化为WAVEFORMATEX。

typedef struct

{

    WAVEFORMATEX  Format;

    union

    {

        WORD wValidBitsPerSample;

        WORD wSamplesPerBlock;

        WORD wReserved;

    }Samples;

    DWORD dwChannelMask;

    GUID  SubFormat;

} WAVEFORMATEXTENSIBLE;

通过wValidBitsPerSample和dwChannelMask字段可以获得编码方式码。通过编码方式码,可以确定一帧的数据大小和最终的编码方式。

4-2、BITMAPINFOHEADER 类型结构,专用于ASF_Video_Media.主要用来解析视频每一帧的宽高和每一像素的位深,还有编码方式与video_pid.

原创粉丝点击