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