1. 程式人生 > >TS 檔案格式解析

TS 檔案格式解析

https://blog.csdn.net/cabbage2008/article/details/49281729

TS 流都是固定等長的188位元組包



如下圖所示 用UltraEdit開啟的一個TS流,我們發現每隔188個位元組就有一個47(可以看做是包頭)


TS的包頭佔用四個位元組

以第一個包為例:

47 60 00 10 00 00 B0 0D 00 00 C1 00 00 00 01 E0
81 0C 8C BE 32 FF FF ……………………………..
………………………………………………………
………………………………………………………
………………………………….FF

我們將其按照位進行劃分 (0~31位,共4個位元組 32位)

1. 0~7    位: 同步位置   第一個位元組 如 十六進位制 47  (01000111)


2. 8~10  位: 第9位是有效載荷單元起始符:(1表示起始符 0 表示後續資料) 一個TS包是188位元組  而一幀資料遠遠大於188位元組  所以一幀資料被拆分成多個TS包。
                              起始符為1 的表示該幀的第一個TS包 裡面含有當前幀的描述資訊 PTS(Presentation Time
                                       Stamp)表示該幀資料的時間位置以及當前幀含有的資料量(TS包個數,大部分不描述
                                        用0代替)
                              起始符為0的TS包  存放當前幀的剩餘資訊

                          只會出現三個十六進位制數字之一: 0 4 6,其它說明包錯誤    如當前為 6

                         0: 二進位制 0000  (有效載荷單元起始符 為0)   這裡借用了PID一位
                         4: 二進位制 0100  (有效載荷單元起始符 為1)   這裡借用了PID一位
                         6: 二進位制 0110 (有效載荷單元起始符 為1)   這裡借用了PID一位

3. 11~23位:PID(packet ID)  是每個節目的唯一標識    如當前為 0 0 0 (第一個包為 000)(除了pid=000 標識第一個包  其它數字都是隨機可選的  無須按某種序列排序)

4. 24~27位:四位剛好可以用一個16進位制數字標識   這裡表示其負載型別 (其存放有效資料)    當前為1 表示負載中只有有效載荷
                        0:保留值,供未來使用   (碰到丟棄即可)
                        1:負載中只有有效載荷
                        2:負載中只有自適應欄位
                        3:先有自適應欄位,再有有效載荷
                        
                        自適應欄位長度, 佔一個位元組
                        自適應欄位內容,佔得位元組由長度自適應欄位長度決定,多餘的位元組用0xFF填充

5.28~31位:無須考慮  直接跳過  簡單理解為相同PID的順序碼

PES  (Packetized Elementary Stream) 打包的元流 簡單說一個個PES包去掉PES包頭剩下的就是一幀幀的資料

有效載荷單元起始符 為1 的TS包會含有部分PES包頭

一個TS流由一組組188位元組的包組成

所有的事務都是有始有終,如何尋找第一個TS包將是我們本節的主題。


如圖所示,一般來說第一個TS包一般在第一個位置,本例舉出一個特殊情況

在尋找第一個TS包時,不斷讀取TS包,直到找到pid=000的位置,並將讀取過的TS包置入緩衝區

本節將粗略講述在確定好第一個包位置後如何找後續包

一個TS流如下圖所示:


第一個TS包

47 60 00 10 00 00 B0 0D 00 00 C1 00 00 00 01E0
81 0
C 8C BE 32 FF FF ……………………………..
………………………………………………………
………………………………………………………
………………………………….FF

包頭:47 60 00 10 

指標:00

tableid:00

固定值:B

section_length:0 0D(值:13)

transport_stream_id:00 00

version number & current_next_indicator:C1

section_number:00

last_section_number:00

program_number:00 01

program_map_PID:E081  (PMT的pid為081 前三位為保留位)

CRC_32:0C 8C BE 32 

第二個TS包

47 60 81 10   (47 同步位元組  6 說明資料正確  pid = 081  1 負載中只含有有效載荷)

00 02 B0 17 00 01 C1 00 00 E8 10 F0 00 1B E8 10
F0 00 03 E8 14 F0 00 66 74 A4 2D FF FF FF FF FF
...................................................................................
...................................................................................
...................................................................................

.......................................................................FF

包頭:47 60 81 10   (47 同步位元組  6 說明資料正確  pid = 081  1 負載中只含有有效載荷)
指標:00
tableid:02
固定值:B
section_length:0 17(值:23 表示到後面FF總共有23個位元組)program_number:00 01
reserved&version_number&current_next_indicator:C1
section_number:00
last_section_number:00
PCR_PID:E8 10
program_info_length: F0 00 (前四位不算 後12位表示後面節目描述資訊長度 此處無)
此時剩餘23-9=14位元組-4位元組(CRC)  = 10位元組/5 = 2  N=2 此處有兩個流型別
第一流型別:
stream_type: 1B  H264流
elementary_PID:E8 10 前3位為保留位取後13位  則PID=810 表示此PID的都是H264流
ES_info_length:F0 00 前4位為保留位 後12位為描述資訊長度 此處為0
第二流型別:
stream_type: 03  音訊流
elementary_PID:E8 14 前3位為保留位取後13位  則PID=814 表示此PID的都是音訊流
ES_info_length:F0 00 前4位為保留位 後12位為描述資訊長度 此處為0


CRC: 66 74 A4 2D

03 E8 14 : 03 表示流是音訊流 MP3 格式   814  表示  pid=814 的TS包儲存的是MP3格式的音訊流

1B E8 10: 1B表示流是視訊流h264格式    810  表示  pid=810 的TS包儲存的是h264格式的視訊流

第一個TS包 一般叫做 PAT (Program Association Table,節目相關表)

第二個TS包 一般叫做PMT  (Program Map Table,節目對映表)

第三個TS包

00000170h: 47 48 14 10 00 00 01 C0 (PTD 為814 前面 4 說明含有有效載荷起始符為1 含有PES包頭)
00000180h: 01 88 80 80 05 21 00 01 96 07 FF FD 85 00 33 22
00000190h: 22 11 22 11 11 11 11 11 11 24 82 41 00 90 40 00
000001a0h: 00 00 00 00 40 00 .................................................
...............................................................................
................................................................................
00000220h: 70 34 5B CE 64 B7 D2 F5 4E 07 50 8E 11 1E 60 61
00000230h: 21 32 11 59

第四個TS包
00000230h: 47 08 14 11 68 4D 8C CB A7 24 92 45   (PTD 為814 前面為 0 說明有效載荷起始符為0 不含有PES包頭)
00000240h: B8 EE A7 1C C4 ……………………………….
…………………………………………………………………….
…………………………………………………………………….
000002e0h:C8 31 B5 59 8C B7 3A 7B 53 9D AB 73 54 E6 D8 0D
47(同步位元組)0(0 說明有效載荷起始符為0 不含有PES包頭)
814PID  1 (負載中只有有效載荷,沒有自適應欄位,後面的都是一幀資料 本例為MP3(由第二個TS包知道))

第五個TS包
000002f0h:47 08 14 32 99 00 FF FF FF FF FF FF FF FF FF FF
00000300h:FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
…………………………………………………………………….
…………………………………………………………………….
…………………………………………………………………….
00000380h:FF FF FF FF FF FF FF FF FF FF FF FF FF FF 52 DE
00000390h:E6 B5 D0 76 CD CB B2 24 B3 92 AD 4E CD 19 D2 CC
000003a0h:82 D4 78 10 80 6C 0E 99 49 A4 59 C0
47(同步位元組)0(0 說明有效載荷起始符為0 不含有PES包頭)
814PID  3 (先有自適應欄位,再有有效載荷)
自適應欄位長度: 0x 99   表示佔用 153個位元組
00: 各個指示器都為0 表示不含其它資訊
跳到第153個位元組 到52 開始時真正的幀資料

第六個TS包
000003a0h: 47 48 14 13
000003b0h:00 00 01 C0 01 88 80 80 05 21 00 01 A6 E7 FF FD
000003c0h:85 00 54 44 22 22 34 21 12 11 22 22 21 48 90 00
....................................................................................................
....................................................................................................
....................................................................................................
00000460h:B4 12 54 02 48 19 F3 D8
47(同步位元組)4(4 說明含有有效載荷起始符為1 含有PES包頭)
814PID  1 (負載中只有有效載荷,沒有自適應欄位,後面的都是一幀資料 本例為MP3(由第二個TS包知道))

注意: 本TS包 又包含PES頭資訊 說明開始下一幀

第七個TS包
00000460h: 47 48 10 30 07 10 00 00
00000470h:01 0F 7E 88 00 00 01 E0 00 00 80 C0 0A 31 00 01
00000480h:96 07 11 00 01 7E 91 00 00 00 01 67 4D 40 1E 96
…………………………………………………………………
…………………………………………………………………
…………………………………………………………………
00000520h:D2 99 71 F3
47(同步位元組)4(4 說明含有有效載荷起始符為1 含有PES包頭)
810PID  3 (先有自適應欄位,再有有效載荷,後面的都是一幀資料 本例為h264(由第二個TS包知道) 流ID E0
自適應欄位長度, 0x07  說明後面7個位元組後為PES包頭或者h264資料

第八個TS包
00000520h: 47 08 10 11 64 C9 FC 5A 40 40 BD 8C
……………………………………………………………………
……………………………………………………………………
…………………………………………………………………….
000005d0h:18 91 2F 18 98 2D B2 AF EE 0E 3D 53 FB B2 91 FE
47(同步位元組)0(0 說明有效載荷起始符為0 不含有PES包頭)
810PID  1 (負載中只有有效載荷,沒有自適應欄位,後面的都是一幀資料 本例為h264(由第二個TS包知道))

1. 首先找到PID為0x00的TS包,找到裡面的節目對映表(PMT)PID,因為可能有幾個節目資訊。所以可能有幾個PMT_PID,以一個為例

2.接著查詢該PMT_PID的TS包,通常就緊接著。在該PMT包中找音訊和視訊的PID。以視訊為例。

3.開始提取一幀ES資料“

   3.1  查詢視訊PID的TS包

   3.2  找PES包頭,方法:TS包頭第2個位元組的高6位(有效載荷單元起始指示符)為1的TS包,跳過自適應欄位,找到PES包頭,提取時間戳,再跳至ES資料,這就是一幀ES資料的開始部分。

  3.3  查詢有效載荷單元起始指示符為0的TS包。跳過TS包頭,跳過自適應欄位,提取後面的ES資料

  3.4  同3.3接著查詢

  3.5  當碰到有效載荷單元起始指示符又變為1的視訊TS包,就知道這是下一幀的開始了,將前面的所有ES資料組合成一幀資料。開始下一輪組幀。