视频文件头解析--mpeg-个人对mpg文件结构的理解

1、一个mpg文件可以只包含视频内容,那么文件开头以0x000001B3作为起始码

2、以0x000001BA 开头,就意味着同时包含音频数据和视频数据,如果没有音频数据,则以0x000001B3开头

3、一个mpg文件可以包含多个pack,每个pack的起始码都是0x000001BA ,pack没有结束码,一般遇到下一个0x000001BA 开头,就意味着此pack结束。

4、Pack头一般应该是14字节,4字节的开始码或者叫起始标志位,以0x000001BA或者0x000001B3作为起始码.然后紧跟着10字节的pack header,即pack头信息,这个头信息一般没有太多有用的内容,不解析。(Pack的具体组成件附件1,pack具体格式)

5、Pack由3部分组成pack_header、system_header(具体长度为head_length+4(起始码4B)+2(head_length 2B))、PES_packets(多个)。其中system_header当且仅当pack是第一个数据包是才存在。

6、PES_packets的结构:

a)   4字节的起始码,一般是3字节包头起始码前缀的0x000001+1字节的数据流识别stream_id。

b)   2字节的pes包长

c)   紧接着是不定长的基本流特有信息,其中包含:1)2字节的pes包头识别标志,或者叫控制标志位,主要内容是pes加扰控制、优先级、版权以及PTS\DTS标志等(有否PTS/DTS标志,是解决视音频同步显示、防止解码器输入缓存器上溢或下溢的关键所在)。2)1字节的PES扩展数据长度,即pes包头长。3)0-46B的信息区。4)最多256字节的填充字节。

d)   最大长度为65526(2^16-1-6-3)字节的包数据。

7、根据PES_packets结构中的前4字节的起始码,可以判断当前pes包里面的数据的具体内容是什么。比如:

a)   0x000001E0   -  0x000001EF:   Video   PES  start   code();

b)   0x000001C0   -  0x000001DF:   Audio   PES  start   code(ISO/IEC   13818-3  or   11172-3);

c)   0x000001BD:   Private  Stream(AC3)

8、关于video_pid、音、视频编码方式和文件类型:

a)如果起始码是0x000001B3,那么那么后面的pes数据是视频且为原始流,video_pid=0x01;video_codec=0x02;file_type=ES( Elementary Streams (原始流),对视频、音频信号及其他数据进行编码压缩后的数据流称为原始流).参看mpeg2标准13818-2视频部分文档。

b)如果起始码是0x000001E0-0x000001EF,即(stream_id>=0xe0)&&(stream_id<=0xef),那么后面的pes数据是视频,video_pid=stream_id;video_codec=0x02;file_type=mpg。

c)如果起始码是0x000001C0-0x000001DF,即((stream_id>=0xc0)&&(stream_id<=0xdf)),那么后面的pes数据为音频数据,audio_pid =stream_id;audio_codec= 0x04;file_type=MPG;参看mpeg2标准13818-3音频部分文档。

d)如果起始码是0x000001BD,即stream_id == 0xbd,那么后面的pes数据为AC3音频数据。解析AC3的数据的时候有些特别,主要步骤如下:

(1)跳过了2字节的pes封包长度,也叫pespacket长度,直接到达2字节的控制标志位,获取stream_flag,然后判断pes加扰控制位是否存在((stream_flag & 0xC0) !=0X80),因为pes加扰控制位总是设置为10,所以如果与出来的结果不为0x80,则表明此段流为不标准的,不解析。

(2)如果是标准流,再增加1字节,到达pes扩展数据长度,解析出标志pts_flag(pts_flag = psBuf[pos] & 0xC0),获取pes_packet包里面的PTS和DTS标志位,这两个位不可以为01,所以与上0xc0的结果只可能为0x00/0x80/0xc0.

(3)如果pts_flag为0x00/0x80/0xc0其中之一,那么可以获取之后数据(pes扩展数据)的长度。如果不是,跳出,继续解析下一个packet的数据。

if((pts_flag == 0x00) ||(pts_flag == 0x80) || (pts_flag == 0xc0))

{

pos++;//指针后移一字节,获取pes头数据长度,也就是pts的长度

pts_length = psBuf[pos];

pos++;//指针后移1字节,然后再后移pts数据长度,解析音频信息

pos +=pts_length;

stream_id = psBuf[pos];

pos++;//pos加1字节,准备做下一个packet的解析

}

(4)关于audio_pid和音频编码方式何有文件类型:

a)   如果(stream_id >= 0x80&& stream_id <= 0x87),表明后面的音频流是AC3,那么audio_pid=(stream_id<<8)|0xbd; audio_codec=0x81 /* DolbyDigital AC3 audio */;file_type=mpg;

b)   如果(stream_id >= 0x88&& stream_id <= 0x8F),表明后面的音频流是DTS,那么audio_pid=(stream_id<<8)|0xbd; audio_codec=0x82 /* DigitalDigital Surround sound. */;file_type=mpg;

C)  如果(stream_id>= 0xA0 && stream_id <= 0xA7),表明后面的音频流是DTS,那么audio_pid=(stream_id<<8)|0xbd; audio_codec=0x88/* LPCM, DVDmode */;file_type=vob /*用于DVD,audio为lpcm格式*/;

 

Mpg包结构(pes基本包)

        将MPEG-2压缩编码的视频基本流(ES-Elementary Stream)数据分组为包长度可变的数据包,称为打包基本流(PES-Packetized Elementary Stream)。广而言之,PES为打包了的专用视频、音频、数据、同步、识别信息数据通道。所谓ES,是指只包含1个信源编码器的数据流即ES是编码的视频数据流,或编码的音频数据流,或其它编码数据流的统称。每个ES都由若干个存取单元(AU-Access Unit)组成,每个视频AU或音频AU都是由头部和编码数据两部分组成的。将帧顺序为I1P4B2B3P7B5B6 的编码ES,通过打包,就将ES变成仅含有1种性质ES的PES包,如仅含视频ES的PES包,仅含音频ES的PES包,仅含其它ES的PES包.

PES包的组成见图2。

 
  

       由图2可见,1个PES包是由包头、ES特有信息和包数据3个部分组成。由于包头和ES特有信息二者可合成1个数据头,所以可认为1个PES包是由数据头和包数据(有效载荷)两个部分组成的

       包头由起始码前缀、数据流识别及PES包长信息3部分构成。包起始码前缀是用23个连续“0”和1个“1”构成的用于表示有用信息种类的数据流识别,是1个8 bit的整数。由二者合成1个专用的包起始码可用于识别数据包所属数据流(视频,音频,或其它)的性质及序号.

       PES包长用于包长识别,表明在此字段后的字节数如,PES包长识别为2 B ,即2×8 = 16 bit字宽,包总长为2^16-1=65535 B,分给数据头9 B(包头6 B + ES特有信息3B ),可变长度的包数据最大容量为65526 B。尽管PES包最大长度可达(2^16 -1)=65535 B(Byte),但在通常的情况下是组成ES的若干个AU中的由头部和编码数据两部分组成的1个AU长度1个AU相当于编码的1幅视频图像或1个音频帧,参见图2右上角从ES到PES的示意图。也可以说,每个AU实际上是编码数据流的显示单元,即相当于解码的1幅视频图像或1个音频帧的取样。

       ES特有信息是由PES包头识别标志、PES包头长信息、信息区和用于调整信息区可变包长的填充字节4部分组成的PES包控制信息。其中,PES包头识别标志由12个部分组成:PES加扰控制信息、PES优先级别指示、数据适配定位指示符、有否版权指示、原版或拷贝指示、有否显示时间标记(PTS-PresentationTime Stamp)/解码时间标记(DTS-DecodeTime Stamp)标志、PES包头有否基本流时钟基准(ESCR-ElementaryStream Clock Reference)信息标志、PES包头有否基本流速率信息标志、有否数字存储媒体(DSM)特技方式信息标志、有否附加的拷贝信息标志、PES包头有否循环冗余校验(CRC-Cyclic Redundancy Check)信息标志、有否PES扩展标志。有扩展标志,表明还存在其它信息。如,在有传输误码时,通过数据包计数器,使接收端能以准确的数据恢复数据流,或借助计数器状态,识别出传输时是否有数据包丢失。

       其中,有否PTS/DTS标志,是解决视音频同步显示、防止解码器输入缓存器上溢或下溢的关键所在因为,PTS表明显示单元出现在系统目标解码器(STD-System TargetDecoder)的时间, DTS表明将存取单元全部字节从STD的ES解码缓存器移走的时刻视频编码图像帧次序为I1P4B2B3P7B5B6I10B8B9的ES,加入PTS/DTS后,打包成一个个视频PES包。每个PES包都有一个包头,用于定义PES内的数据内容,提供定时资料。每个I、P、B帧的包头都有一个PTS和DTS,但PTS与DTS对B帧都是一样的,无须标出B帧的DTS。对I帧和P帧,显示前一定要存储于视频解码器的重新排序缓存器中,经过延迟(重新排序)后再显示,一定要分别标明PTS和DTS。例如,解码器输入的图像帧次序为I1P4B2B3P7B5B6I10B8B9,依解码器输出的帧次序,应该P4比B2、B3在先,但显示时P4一定要比B2、B3在后,即P4要在提前插入数据流中的时间标志指引下,经过缓存器重新排序,以重建编码前视频帧次序I1B2B3P4B5B6P7B8B9I10。显然,PTS/DTS标志表明对确定事件或确定信息解码的专用时标的存在,依靠专用时标解码器,可知道该确定事件或确定信息开始解码或显示的时刻。例如,PTS/DTS标志可用于确定编码、多路复用、解码、重建的时间。

7、图

6、对照文件内容,各字段值如下:

pack_header: 起始地址:0x0000 0000

Packet_start_code(4B):0x0000 01BA

'01'

SCR_base[32...30](3b):000

marker:1

SCR_base[29...15](15b):00 0000 0000 0010 1

marker:1

SCR_base[14...0](15b):00 0100 1000 0101 1

marker:1

SCR_externsion(9b):00 1111 101

marker:1

mutiplex_rate(22b):0000 0000 0101 0101 0001 01

marker:1

marker:1

reserved(5b):1111 1

stuffing_length(3b):000

 

system_header: 起始地址:0x0000 000e

system_head_start_code(4B):0x0000 01BB

head_length(2B):0x000C

marker:1

rate_bound(22b):000 0000 0010 1010 1000 101

marker:1

audio_bound(6b):0000 01

fixed_flag(1b):0

CSPS_flag(1b):0

system_audio_local_flag(1b):0

system_video_local_flag(1b):0

marker:1

video_bound(5b):0 0001

packet_rate_restriction_flag(1b):0

reserved(7b):111 1111

stream_id(1B):0xE0(E0~EF为视频ID)

'11'

P-STD_buffer_bound_scale(1b):1

P-STD_buffer_size_bound(13b):0 0000 0000 0001

stream_id(1B):0xC0(C0~DF为音频ID)

'11'

P-STD_buffer_bound_scale(1b):0

P-STD_buffer_size_bound(13b):0 0000 0100 1000

 

PES packet:起始地址:0x0000 0020

packet_start_code_prefix(3B):0x 00 00 01

stream_id(1B):0xBE(BE为Padding stream)

PES_packet_length(2B):0x07 DA,跳过该长度的填充字节,刚好为下一个pack的起始标志:

0x000001BA

从0x0800地址开始为第二个pack包,该包的构造格式为pack_header+PES,分析如下:

pack_header: 起始地址:0x0000 0800

Packet_start_code(4B):0x0000 01BA

'01'

program_clock_reference_base(3b):000

marker:1

SCR_base(15b):00 0000 0000 0000 0

marker:1

SCR_base(15b):00 0001 1001 1001 1

marker:1

SCR_externsion(9b):00 0111 100

marker:1

mutiplex_rate(22b):0000 0000 0100 0110 0101 00

marker:1

marker:1

reserved(5b):1111 1

stuffing_length(3b):000

PES packet:起始地址:0x0000 080e

packet_start_code_prefix(3B):0x 00 00 01

stream_id(1B):0xE0(视频)

PES_packet_length(2B):0x07 EC,跳过该长度,到达0x1000地址单元,为下一个pack的起始标志:

0x000001BA

'10'

scrambling_control(2b):00

priority(1b):0

alignment(1b):0

copyright(1b):0

original(1b):0

PTS_DTS_flag(2b):11,该标志不能为01

ESCR_flag(1b):0

ES_rate_flag(1b):0

DSM_trick_mode_flag(1b):0

additional_copy_info_flag(1b):0

CRC_flag(1b):0

extension_flag(1b):0

PES_header_data_length(1B):0x0A

'0011'

PTS[32...30](3b):000,PTS全称为presentationtime stamp

marker:1

PTS[29...15](15b):0000 0000 0000 000

marker:1

PTS[14...0](15b):1010 1001 1111 001

marker:1

'0001'

DTS[32...30](3b):000,DTS全称为dedodingtime stamp

marker:1

DTS[29...15](15b):0000 0000 0000 000

marker:1

DTS[14...0](15b):1000 1100 1010 000

marker:1

因为除了PTS_DTS_flag为11外,其余6个标志都为0,所以直接进入视频序列:Video Sequence,其结构定义如下:

对各字段分析如下:

sequence header:起始地址:0x0000 0821

sequence_header_code(4B):0x 0000 01B3

horizontal_size(12b):0010 0100 0000

vertical_size(12b):0001 1110 0000

aspect_ratio_info(4b):0010

frame_rate(4b):0001

bit_rate(18b):0001 0110 1111 0011 00

marker:1

VBV_buffer_size(10b):0 0011 1000 0

constrained(1b):0

load_intra_Q_matrix(1b):0

sequence extension:起始地址:0x0000 082d;如果有这一项说明是MPEG-2文件,否则为MPEG-1文

extension_start_code(4B):0x0000 01B5

start_code_identifer(4b):0001

profile_level_escape(1b):0

profile_level(7b):100 1000

progressive(1b):1

chroma(2b):01

horiz_extension(2b):00

vertical_extension(2b):00

接下来的数据是0x0000 01B8,说明该序列中没有extension&user data[i](extension data的开始符为0x0000

01B5,user data的开始符为0x0000 01B2),接下来的内容为Group of pictures header。

link(1b):0

extension & user data[1]:无

picture header: 起始地址:0x0000 083F

picture_start_code(4B):0x0000 0100

temporal_reference(10b):0000 0000 0000 00

picture_coding_type(3b):00 1

vbv_delay(16b):111 1111 1111 1111 1

extra_bit_picture(1b):0

picture coding extension:起始地址:0x0000 0847

extension_start_code(4B):0x0000 01B5

extension_start_code_identifier(4b):1000

f_code[0][0](4b):1111,forward horizontal

f_code[0][1](4b):1111,forward vertical

f_code[1][0](4b):1111,backward horizontal

f_code[1][1](4b):1111,backward vertical

intra_dc_presison(2b):00

picture_structure(2b):11

top_field_first(1b):0

frame_pred_frame_dct(1b):1

concealment_motion_vectors(1b):0

q_scale_type(1b):0

intra_vlc_format(1b):0

alternate_scan(1b):0

repeat_first_field(1b):0

chroma_420_type(1b):1

progressive_frame(1b):1

composite_display_flag(1b):0

extension & user data[2]:无

picture data: 起始地址:0x0000 0850,picture data分为多个slice片,而每个slice又分为多个

Microblock,Microblock继续分为Block块。

13818-2中定义的picture_data()如下:

picture_data(){

do {

slice()

} while (nextbits() == slice_start_code )

next_start_code()

}

Slice

slice() {

slice_start_code32

if (vertical_size> 2800)

slice_vertical_position_extension3

if() {

if(scalable_mode == “data partitioning” )

priority_breakpoint7

}

quantiser_scale_code5

if (nextbits() == ‘1’ ) {

intra_slice_flag 1

intra_slice 1

reserved_bits7

while (nextbits() == ‘1’ ) {

extra_bit_slice/* with the value ‘1*/ 1

extra_information_slice8

}

}

extra_bit_slice/* with the value ‘0’ */ 1

do {

macroblock()

} while (nextbits() != ‘000 0000 0000 0000 0000 0000’ )

next_start_code()

}

       从文件内容分析,从0x0000 0850单元为第一个slice(0000 0101),共有7个slice,第7个slice的起始单元为0x0000 fe04,紧接着开始下一个packe,直到0x0000 3000才开始第一个音频pack包,后面的数据视频pack和音频数据成交叉状态。文件结尾标志为0x0000 01B9

你可能感兴趣的:(音视频编解码)