1.TS協(xié)議簡(jiǎn)述
使用UE工具打開ts文件,ts協(xié)議都是以0x47作為開頭,代表一個(gè)ts文件開始。0x47也是debug時(shí),經(jīng)常作為是否為ts包的判斷依據(jù)。ts流應(yīng)用場(chǎng)景除了前面HLS,還有廣播電視,衛(wèi)星直播。一般一個(gè)ts流由很多個(gè)頻道組成,每個(gè)頻道由不同pid區(qū)分。
除了使用ue工具,這里還推薦一個(gè)分析ts流的工具,它是EasyICE,對(duì)于分析ts,HLS,非常好用工具,建議下載。
下載地址:https://www.easyice.cn/archives/85
1.1 EasyICE主要功能介紹
主要特性
- TS 文件分析
- UDP,RTP,HLS 實(shí)時(shí)分析,碼流錄制。
- TR 101290 監(jiān)測(cè)。
- PCR 抖動(dòng),精度,間隔分析。
- GOP 統(tǒng)計(jì),碼率變化分析
- Multi language support (Chinese,English)
HLS 分析
唯一一款支持HLS協(xié)議的免費(fèi)分析軟件。通過HLS 緩沖分析模塊,可以一目了然的看到播放器的緩沖狀態(tài)。當(dāng)你的節(jié)目出現(xiàn)卡頓,觀察緩沖狀態(tài)就可以知道是否數(shù)據(jù)到達(dá)太慢。HLS分析支持直播與點(diǎn)播業(yè)務(wù)。
TS切片質(zhì)量報(bào)告,包含了通常人們關(guān)心的,以及Apple要求的切片需符合的技術(shù)參數(shù),不管節(jié)目制作者還是檢驗(yàn)人員,切片質(zhì)量報(bào)告最有用不過了。當(dāng)一個(gè)節(jié)目的播放效果出現(xiàn)問題,對(duì)于節(jié)目本身首先要關(guān)注的就是這些參數(shù)。
UDP/RTP 直播分析
為數(shù)字電視行業(yè)TS OVER IP設(shè)計(jì)的直播分析功能,支持單播,廣播,組播(IGMP_v2,IGMP_v3),可以檢測(cè)TR101290,媒體信息,PID統(tǒng)計(jì),以及PCR的精度,間隔,總抖動(dòng)等內(nèi)容,數(shù)據(jù)接收與檢測(cè)采取異步方式,線程間共享緩沖使用無鎖的設(shè)計(jì),保證了分析結(jié)果的準(zhǔn)確性。
TS 包列表
支持TS包分類,頭部字段解析,以及視頻(MPEG2,H264)幀類型判斷。支持查找,快速定位需要的TS包,便于分析原始數(shù)據(jù)。
TR101290
不同于其他碼流分析產(chǎn)品的TR101290,僅有事件統(tǒng)計(jì),在EasyICE中,你可以根據(jù)某一錯(cuò)誤事件定位到數(shù)據(jù)包視圖的相應(yīng)位置,看看那里出了問題。
圖表
直觀的看到時(shí)間戳變化,時(shí)間戳差值變化(這個(gè)功能就非常好用),GOP幀數(shù),GOP字節(jié)數(shù),以及基于兩PCR包間數(shù)據(jù)量計(jì)算出的碼率變化。同樣,點(diǎn)擊圖表中的每個(gè)采樣點(diǎn),可以定位到數(shù)據(jù)包視圖的相應(yīng)位置。另外,滾動(dòng)鼠標(biāo)可以縮放視圖,甚至可以導(dǎo)出這些采樣值原始數(shù)據(jù)。
其他
比較快的分析速度,支持從cap,pcap格式的抓包文件導(dǎo)出TS流。把cap文件拖進(jìn)去試試看~所有功能免費(fèi)使用
解析音視頻PID
視頻pid與PCR的pid一樣
在ts流中是間隔插入PAT和PMT,PAT和PMT是重復(fù)的,這樣有助于快速搜索節(jié)目。如果不插入,可能在搜索節(jié)目,切換節(jié)目時(shí),可能找不到對(duì)應(yīng)的節(jié)目。
一般0.5s就插入一個(gè)PAT。如下圖:
解析媒體信息
如下圖EasyICE檢測(cè)出的媒體信息。
解析視頻幀
通過這個(gè)工具,還可以解析每組GOP的排布情況。這個(gè)功能也非常好用,瞬間愛上這個(gè)軟件了。
更為直觀的顯示GOP。
碼率波動(dòng)圖
可以實(shí)時(shí)觀察碼率波動(dòng)的情況。
分析數(shù)據(jù)包
可以根據(jù)EasyICE提供的結(jié)果,去分析數(shù)據(jù)包,比如數(shù)據(jù)包是否連續(xù)。
2 .ts?件分層
ts ?件為傳輸流?件,視頻編碼主要格式為 H264/MPEG4,?頻為 AAC/MP3。每一層都是使用header+payload形式打包,類似網(wǎng)絡(luò)5層協(xié)議。
如果把ts文件傳輸比作一個(gè)快遞運(yùn)輸?shù)倪^程,那么es就是真實(shí)的包裹,如一件衣服。pes就是使用打包盒子裝好,并貼好時(shí)間,順序等標(biāo)簽信息。ts就是貼上發(fā)貨地址,寄貨地址等信息,運(yùn)送出去。
ts ?件分為三層:
(1)ts層(Transport Stream),也稱為傳輸流層,在pes 層的基礎(chǔ)上加?數(shù)據(jù)流的識(shí)別(如0x47頭部信息)和傳輸必須的信息。ts header字段,如下表格所示:
重點(diǎn)關(guān)注sync_byte和continuity_counter(循環(huán)計(jì)數(shù)器,音頻,視頻,字幕對(duì)應(yīng)每一個(gè)PID都是獨(dú)立,各自計(jì)數(shù),相互不干擾),在解封裝時(shí),確保該信息正確,才能保證這個(gè)包是有效。
從這個(gè)軟件分析的結(jié)果,也可以得出,音視頻,PAT,PMT的pid都是獨(dú)立。
第一、Ts Header
ts 層的內(nèi)容是通過 PID 值來標(biāo)識(shí)的,主要內(nèi)容包括:PAT 表、PMT 表、?頻流、視頻流。解析 ts 流要先找到 PAT 表,只要找到 PAT 就可以找到 PMT,然后就可以找到?視頻流了。PAT 表和 PMT 表需要定期插? ts 流,因?yàn)?strong>?戶隨時(shí)可能加? ts 流,這個(gè)間隔?較?,通常每隔?個(gè)視頻幀就要加? PAT和 PMT。PAT 和 PMT 表是必須的,還可以加?其它表如 SDT(業(yè)務(wù)描述表)等,不過 hls 流只要有PAT 和 PMT 就可以播放了。
如何區(qū)分哪些是音頻數(shù)據(jù),哪些是視頻數(shù)據(jù)?
先弄清PAT和PMT關(guān)系。
PAT表:主要的作?就是指明了 PMT 表的 PID 值。能找到PAT。PAT的pid默認(rèn)值是0。通過PAT能夠解析出當(dāng)前ts流包含的節(jié)目數(shù)量以及對(duì)應(yīng)節(jié)目的PMT pid。
PMT表:主要作用就是指明了音視頻流的PID值。通過PMT的PID值就可以區(qū)分那個(gè)包是視頻數(shù)據(jù),那個(gè)包是音頻數(shù)據(jù)。
音頻流:編碼好的音頻數(shù)據(jù)。
視頻流:編碼好的視頻數(shù)據(jù)。
根據(jù)上面的流程,舉個(gè)例子,如一個(gè)ts流可能有很多個(gè)節(jié)目,如CCTV-1,CCTV-2,CCTV-3等,如果尋找CCTV-1,先找到ts流的PAT表,然后PAT找CCTV-1的PMT表中的pid=100,解析PMT的pid=100,然后分析出音頻的pid(如為101)、視頻的pid(如為102),字幕pid(如為103)等,這些都是相互獨(dú)立。根據(jù)音頻、視頻、字幕對(duì)應(yīng)的pid,找到對(duì)應(yīng)的pid的ts,并根據(jù)id放入不同的隊(duì)列,然后解析出具體的音頻,視頻數(shù)據(jù)。注意:這里還涉及到ts->pes->es的解封裝過程。
第二、adaptation field
adaptation field所包含的字段如下表格,這里重點(diǎn)關(guān)注PCR和錯(cuò)誤指示符。
?適應(yīng)區(qū)的?度要包含傳輸錯(cuò)誤指示符標(biāo)識(shí)的?個(gè)字節(jié)。PCR是節(jié)目時(shí)鐘參考,也是一種音視頻同步的時(shí)鐘,pcr、dts、pts 都是對(duì)同?個(gè)系統(tǒng)時(shí)鐘的采樣值,pcr 是遞增的,因此可以將其設(shè)置為 dts 值,?頻數(shù)據(jù)不需要 pcr(PCR的pid,一般與視頻的pid是同一個(gè)值)。
在測(cè)試的時(shí)候發(fā)現(xiàn),如果沒有字段,ipad 是可以播放的,但 vlc ?法播放。
打包 ts 流時(shí) PAT 和 PMT 表(屬于文本數(shù)據(jù))是沒有 adaptation field,不夠的?度直接補(bǔ) 0xff 即可。視頻流和?頻流都需要加 adaptation field,即文本數(shù)據(jù)不需要adaptation field,音視頻數(shù)據(jù)需要adaptation field。一般在?個(gè)幀的第?個(gè) ts包和最后?個(gè) ts 包?加adaptation field,中間的 ts 包不加adaptation field。所以adaptation field是靈活改變,如下圖所示:
PAT 格式如下圖所示:
PAT表所對(duì)應(yīng)的字段如下表所示,重點(diǎn)關(guān)注表中紅色框框部分,table_id就是PAT默認(rèn)的pid,默認(rèn)值為0。program_number表示當(dāng)節(jié)目號(hào)為0x0001時(shí),是PMT。PID對(duì)應(yīng)的值就是去尋找PMT表的依據(jù)。CRC32,表示校驗(yàn)碼,用于驗(yàn)證。
PMT表所對(duì)應(yīng)的字段如下表所示:
PMT表的table_id與PAT表的pid,相關(guān)聯(lián)。
PAT表中的PCR_PID表示所在TS分組的PID,一般為視頻ID相關(guān)聯(lián)。stream_type表示當(dāng)前包是音頻,視頻還是字幕或其他數(shù)據(jù)。如h264編碼對(duì)應(yīng)的是0x1b,aac編碼對(duì)應(yīng)的0x0f,mp3編碼對(duì)應(yīng)0x03。elementary_PID表示音頻、視頻、字幕或其它數(shù)據(jù)對(duì)應(yīng)的PID,通過elementary_PID就可以找到真正的數(shù)據(jù),用于解碼。CRC32同樣也是用于數(shù)據(jù)驗(yàn)證。
注意:這里有一段數(shù)據(jù)是循環(huán),從字段stream_type開始到ES_info_length結(jié)束,這是一段循環(huán),一直在解析。
如果需要加密數(shù)據(jù),一般是在ts層的payload部分。
(2)pes 層(Packet Elemental Stream),也稱為打包層,在?視頻數(shù)據(jù)上加了時(shí)間戳等對(duì)數(shù)據(jù)幀的說明信息。也就是說時(shí)間戳pts是存儲(chǔ)在pes header里。在做音視頻同步,就需要去關(guān)聯(lián)這里的時(shí)間戳信息。
pes 層是在每?個(gè)視頻/?頻幀上加?了時(shí)間戳等信息,pes 包內(nèi)容很多,這?只留下最常?的。如果需要更詳細(xì)研究,就需要根據(jù)spec去學(xué)習(xí)。
當(dāng)解析完ts層后,這里繼續(xù)解析PES層,PES層格式如下:
PES Header一般為6Bytes,Option Pes Header為3Bytes-259Bytes,不是固定值,Payload最大值不超過65526Bytes。
PES層字段表如下圖所示:
pes start code表示一個(gè)pes的起始。stream id表示音頻,視頻id,與PMT表的id,相關(guān)聯(lián)。pes packet length表示pes包長(zhǎng)度。第一個(gè)flag表示是否是加密包,真正加密是在ts的payload部分。第二個(gè)flag表示是否包含pts,dts等。pes data length表示pes payload數(shù)據(jù)長(zhǎng)度。這些字段中最關(guān)鍵的就是pts和dts值。
pts 是顯示時(shí)間戳、dts 是解碼時(shí)間戳,視頻數(shù)據(jù)兩種時(shí)間戳都需要,如果音視頻的pts和dts相同,就只需要pts即可。有 pts 和 dts 兩種時(shí)間戳是 B 幀引起的,I 幀 和 P 幀的 pts 等于 dts。如果?個(gè)視頻沒有B 幀,則 pts 永遠(yuǎn)和 dts 相同。
從?件中順序讀取視頻幀,取出的幀順序和 dts 順序相同。dts 算法?較簡(jiǎn)單,初始值 + 增量即可,pts 計(jì)算?較復(fù)雜,需要在 dts 的基礎(chǔ)上加偏移量。
注意:?頻的 pes 中只有 pts(同 dts,這也是為什么能夠常使用audio master的原因之一),而視頻的 I、P 幀兩種時(shí)間戳都要有,視頻 B 幀只要 pts(同 dts)。打包 pts 和 dts 就需要知道視頻幀類型,但是通過容器格式我們是?法判斷幀類型的,必須解析 h.264內(nèi)容才可以獲取幀類型,通過幀類型去加添加pts或dts。
B幀會(huì)增加緩存,解碼一般是先解出P幀,再解出B幀,所以B幀會(huì)增加延時(shí),顯示一般就是B幀先顯示,因?yàn)锽幀的原因,就需要調(diào)整幀順序,需要花時(shí)間。如下圖所示:
計(jì)算點(diǎn)播視頻dts公式:
視頻dts計(jì)算公式為 dts = 初始值 + 90000 / video_frame_rate ,初始值可以隨便指定,但是最好不要取 0,video_frame_rate 就是視頻幀率,?如 20、30。
pts 和 dts 是 以 timestamp(時(shí)間戳) 為單位的,1s = 90000 time scale ,所以一幀的pts就是90000/video_frame_rate 個(gè) timescale。
播放時(shí)長(zhǎng)就是??幀的 timescale 除以采樣頻率,可以轉(zhuǎn)換為?幀的播放時(shí)?。
計(jì)算點(diǎn)播音頻dts公式:
音頻dts計(jì)算公式為dts =初 始 值 + (90000 * audio_samples_per_frame) /audio_sample_rate audio_samples_per_frame 這 個(gè) 值 與 編 解 碼 相 關(guān) ,一般 aac 取 值 1024 , mp3 取 值 1158
audio_sample_rate 是采樣率,?如 24000、41000. AAC ?般解碼出來是每聲道 1024 個(gè) sample,也就是說?幀的時(shí)?為 1024/sample_rate 秒。所以每?幀時(shí)間戳依次 0,1024/sample_rate, ...,1024*n/sample_rate 秒 。
十分注意:如果是直播場(chǎng)景,直播視頻的 dts 和 pts 應(yīng)該直接?直播數(shù)據(jù)流中的時(shí)間,不應(yīng)該按公式計(jì)算。
(3)es 層(Elementary Stream),也稱為原始流層,表示原始的音視頻數(shù)據(jù)。
ts協(xié)議,三層數(shù)據(jù)結(jié)構(gòu)圖,如下:
ts層由ts Header(一般由4Bytes組成,第一個(gè)字節(jié)是固定0x47開頭),adaption field(調(diào)整的字節(jié),靈活改變),payload(是ts層負(fù)載,一般是184Bytes)組成。所以一般ts包是為188個(gè)字節(jié),也有些大于188字節(jié)的。
ts層的payload主要由pes層數(shù)據(jù)組成。PES層主要由pes header(一般是6Bytes),option pes header(調(diào)整的字節(jié),靈活改變),pes payload(不是固定值)組成。
pes層的payload主要是由es層數(shù)據(jù)組成,es層主要由視頻的nal header(一般是4Bytes,一把是會(huì)有start code),nal type(一般是1Bytes),h264 data(不是固定值),音頻的adts header(7Bytes),aac data(不是固定值)組成。
第一,h.264 視頻
關(guān)于h264格式可以參考前面的文章,有助于你更好理解h264。
聊聊H264的 NALU
h264 NALU代碼實(shí)戰(zhàn)(1)
H264解碼器原理之一
H.264詳解之一
打包 h.264 數(shù)據(jù)時(shí)必須給視頻數(shù)據(jù)加上?個(gè) nalu(Network Abstraction Layer Unit),nalu 包括nalu header 和 nalu type,nalu header 固定為 0x00000001(幀開始)或 0x000001(幀中)。h.264 的數(shù)據(jù)是由 slice 組成的,slice 的內(nèi)容包括:視頻、sps、pps 等。nalu type 決定了后?的h.264 數(shù)據(jù)內(nèi)容。其結(jié)構(gòu)的spec表示如下:
F:1bit,forbidden_zero_bit,h.264 規(guī)定必須取 0。
NRI:2bits,nal_ref_idc,取值為 0~3,指示這個(gè) nalu 的重要性,I 幀、sps、pps 通常取3,P 幀常取 2,B 幀通常取 0。
Type:5bits,取值如下表所示:
一般在工程項(xiàng)目中,IDR幀,SEI,SPS,PPS,這些都是常用分析的圖像信息。
注意:打包 es 層數(shù)據(jù)時(shí) pes 頭和 es 數(shù)據(jù)之間要加??個(gè) type=9 的 nalu(分解符號(hào)),關(guān)鍵幀 slice 前必須要加?type=7 (sps)和 type=8 的 nalu(pps),?且是緊鄰的。如下圖所示:
第二,aac?頻
打包aac?頻必須加上?個(gè)adts(Audio Data Transport Stream)頭,共7Byte,adts包括fixed_header和variable_header兩部分,各28bit。spec如下圖所示:
fixed_header如下圖所示,如果需要手動(dòng)添加頭部,則需要參考如下字段。可以參考這2篇文章。
AAC ADTS實(shí)戰(zhàn)(1)
AAC ADTS格式分析(1)
重點(diǎn)關(guān)注紅色框框部分,id表示執(zhí)行是MPEG-4還是MPEG-2標(biāo)準(zhǔn)。profile表示是什么編碼方式,其中1表示aac。sampling_frequency_index表示支持的采樣率。channel_configurati on表示通道配置,如左聲道,右聲道等。
variable_header如下圖所示,
重點(diǎn)關(guān)注打紅色框部分,aac_frame_length表示adts頭在內(nèi)的音視頻數(shù)據(jù)長(zhǎng)度。
3.總結(jié)
關(guān)于這篇文章,主要講解的就是ts主要格式分析和非常好用的工具EasyICE介紹,這樣會(huì)幫助你提高工作效率。
本篇文章就分析到這里,歡迎大家關(guān)注歡迎關(guān)注,點(diǎn)贊,轉(zhuǎn)發(fā),收藏,分享,評(píng)論區(qū)討論。
后面關(guān)于項(xiàng)目知識(shí),后期會(huì)更新。歡迎關(guān)注微信公眾號(hào)"記錄世界 from antonio"。






