【音視頻技術】H264流媒體封裝FLV文件

    最近再封裝H264文件,本來想想用ffmpeg,可惜設備端沒有足夠的空間放ffmpeg的庫了,無奈只好開始擼協議自己封裝了~

首先至少得了解以下知識點:

【音視頻技術】AVC H264的一些基本概念和知識點

【音視頻技術】FLV封裝格式

【音視頻技術】AMF實用協議解析說明

好了,開擼。

FLV的封裝格式就不說了,這篇博客着重說一下 H264中的NALU如何封裝成 FLV中的video tag ,關於FLVheader 及FLV其他結構有不清楚的可以上網查其他資料或者看我寫的這篇【音視頻技術】FLV封裝格式博客。

-------------------------------------------------------------------------------------------------------------

H264 的NALU 封裝成FLV有三種不同的形式: 

(H264 NALU 不清楚的【音視頻技術】AVC H264的一些基本概念和知識點

(1)H264 NALU type SPS +PPS;

(2)H264 NALU type SEI;

(3)H264 NALU type Slice 也就是 type值爲(1-5);

--------------------------------------------------------------------------------------------------------------

(1)H264 NALU type SPS +PPS 封裝成 FLV video tag:

    在H264的碼流中 SPS 和 PPS是成對出現的,先是SPS然後是PPS,SPS對於H264來說就是編碼後的第一幀、PPS是編碼後的第二幀這兩針攜帶的數據主要是編碼器的一些屬性,比如寬高 profile level deblock濾波器等等。

    在封裝FLV中這兩幀數據被合併到一個video TAG中:


FLV tag header                Bytes                    value

1)Tag type                     // 0                        0x09

2)Data Size                    // 1-3                     0x00 0x00 0x24

3)TimeStamp                 // 4-6                     0x00 0x00 0x00     (First frame)

4)TimeStampExtend       // 7                        0x00

5)StreamID                    // 8-10                  0x00 0x00 0x00   (always zero)


AVC Video tag header         

1)FrameType | CodecID       //11                             0x17

2)AVCPacketType                //12                             0x00

3)Composition Time              //13-15                       0x00 0x00 0x00


                                 


AVCDecoderConfigurationRecord

1)Configuration VerSion                 //16                  0x01      

2)AVC Profile SPS[1]                     //17                   0x42       

3)profile_compatibility SPS[2]       //18                   0x00      

4)AVC Level SPS[3]                       //19                   0x2A      

5)lengthSizeMinusOne                    //20                   0xFF

6)numOfSequenceParameterSets //21                  0xE1      

SPS

1)SPS0 Length                                //22-23            0x0010

2)SPS0 Data

3)SPS(n) length /btyes 如果存在多個循環存放最多31個SPS

4)SPS(n) Data

                                     

PPS

PPS  count                                         //1byte             0x01

PPS0 Length                                     //2bytes           0x00 0x04

PPS0 Data

PPS(n) Length

PPS(n) Data

+PreviousTag Size


--------------------------------------------------------------------------------------------------------

(2)H264 NALU type Sei 封裝成 FLV video tag:

    SEI NALU 是沒有圖像數據的,它的主要作用是對圖像數據或者視頻流的補充,有些內容可能對解碼有幫助。在封裝FLV文件中含義SEI的videoTAG其中包含色SEI數據還有SEI幀後緊跟着的一個IDR數據,其編碼結構如下;


FLV tag header                Bytes                    value

1)Tag type                     // 0                          0x09

2)Data Size                    // 1-3                     0x00 0x00 0x24

3)TimeStamp                 // 4-6                     0x00 0x00 0x00     (First frame)

4)TimeStampExtend       // 7                       0x00

5)StreamID                    // 8-10                   0x00 0x00 0x00   (always zero)


AVC Video tag header         

1)FrameType | CodecID       //11                             0x27

2)AVCPacketType                //12                             0x01

3)Composition Time              //13-15                       0x00 0x00 0x00

SEI

1)SEI length                   //16-19                        0x00  0x00 0x00 0x05

2)SEI Data                       // 20-N                       0x06 E5 01 81 80

3)IDR NALU Length    //4Bytes               0x00 0x00 0x1F 0xF4

4)IDR NALU Data

+PreviousTag Size


----------------------------------------------------------------------------------------------------

(3)H264 NALU type Slice 封裝成 FLV video tag:

    Slice Type NALU (1-5) 就是H264 中一片一片的數據了,在FLV video tag中封裝 如下:


FLV tag header                Bytes                    value

1)Tag type                     // 0                          0x09

2)Data Size                    // 1-3                     0x00 0x95 0xF6

3)TimeStamp                 // 4-6                     0x00 0x00 0x00     (First frame)

4)TimeStampExtend       // 7                       0x00

5)StreamID                    // 8-10                   0x00 0x00 0x00   (always zero)


AVC Video tag header         

1)FrameType | CodecID       //11                             0x27 or 0x17

2)AVCPacketType                //12                             0x01

3)Composition Time              //13-15                       0x00 0x00 0x00


NALU

NALU Length                        //   4bytes                     0x00 0x00 0x95 0xED

NALU data

+PreviousTag Size

    OK,上述就是H264在封裝成FLV文件時的3中video tag。再說點調試時的經驗吧。封裝FLV我總共花了3天,第一天瞭解FLV協議,AMF協議,結合着flv的媒體文件來對照協議,理解各個字段的意思。大家可以使用UEdit這個工具來看二進制文件,也可以使用這個flv解析工具來直接解析flv文件 (還算挺好用的吧)。封裝過程中有些大端小端的一定要注意,還有擴展時間戳位(不知道搞協議的人怎麼想的搞出這個東西來)。第二天,再網上搞了一套代碼,看懂後改了改 ,可以封裝H264了 但是 生產出來的flv文件播放有馬賽克。後來用ffmpeg封裝對比前後的文件慢慢找出的端倪。錯在SEI type的nalu 我處理的不對又改了改,大功告成。源代碼的話我就不放了,如果按照我這個按部就班的做應該沒問題的,我就是這麼搞出來的。

整個工作過程這篇博客給我的幫助是最大的,內容也是最正確的,其他看了好多感覺都有寫的不對的地方(感謝感謝):

打包H264碼流到FLV文件







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章