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(<sequence_scalable_extension() is present in the bitstream>) {

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

發佈了24 篇原創文章 · 獲贊 5 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章