在對H264進行編解碼分析時,碰到一個完整視訊幀被切分成多個Slice用于網絡媒體傳輸的情況。而且接收端進行解碼時需要一個完整幀(FFmpeg解碼不需要拼接,内部已實作),是以怎麼拼接多個Slice呢?
對于H264視訊流中關于NAL Unit句法、Slice Header結構等不是本文講述的重點,相關資料可在網上查詢,但需要對H264流媒體協定格式中的AVCC及Annex B格式有一定了解。本文主要以Annex B視訊格式協定講解。
Annnex B格式在接收端接收到視訊幀資料基本以0x000001或0x00000001開始,一般完整I幀包含:SPS、PPS、SEI、I幀資料(也有可能不包含SPS、PPS等資訊),如下圖:

P幀資料如下圖:
若完整的視訊幀未被切分成多個slice時,可直接被解碼成YUV或RGB資料,但是當切分成多個slice,需要根據first_mb_in_slice計算每個幀片所在位置。
比如上圖B幀中資料為0x00 0x00 0x00 0x01 0x41 0xE2,讀取第6位轉成二進制:1110 0010,與上0x80:0xB8&0x80=0x80,即表示為一幀的第一片(可查詢指數哥倫布碼,即第一個位為1)。接下來一包資料為0x00 0x00 0x00 0x01 0x41 0x63,則與上0x80為0x0,則表示不是第一片(不是第一個片時的值在上一包的基礎上會出現遞增)。可歸納規律(假設的資料):
第一包:0x00 0x00 0x00 0x01 0x41 0xE1
第二包:0x00 0x00 0x00 0x01 0x41 0x62
第三包:0x00 0x00 0x00 0x01 0x41 0x63
第四包:0x00 0x00 0x00 0x01 0x41 0xE2
可看出第一包0xE1&0x80=0x80則是第一片,0x62&0x80=0x0則為第二包,直到遇到下一個0x80時為完整的一幀(第一包+第二包+第三包)。
以上就是合并的基本思路,一般情況下I幀不會被切分成多個slice,而是以完整幀進行傳輸,P幀多數情況下存在切分的情況。