rtmp 推送h264 + aac 的數據


相關源碼下載:

 

http://download.csdn.net/detail/keepingstudying/8340431

 

需要libfaac,librtmp 的支持,

1、幀的划分

1.1 H.264幀

對於H.264而言每幀的界定符為00 00 00 01或者00 00 01。

比如下面的h264文件片斷這就包函三幀數據

00 00 00 01 67 42 C0 28 DA 01 E0 08 9F 96 10 00
00 03 00 10 00 00 03 01 48 F1 83 2A 00 00 00 01
68 CE 3C 80 00 00 01 06 05 FF FF 5D DC 45 E9 BD
E6 D9 48 B7 96 2C D8 20 D9 23 EE EF …

第一幀是00 00 00 01 67 42 C0 28 DA 01 E0 08 9F 96 10 00 00 03 00 10 00 00 03 01 48 F1 83 2A
第二幀是00 00 00 01 68 CE 3C 80
第三幀是00 00 01 06 05 FF FF 5D DC 45 E9 BD E6 D9 48 B7 96 2C D8 20 D9 23 EE EF ..

幀類型有:
NAL_SLICE = 1
NAL_SLICE_DPA = 2
NAL_SLICE_DPB = 3
NAL_SLICE_DPC = 4
NAL_SLICE_IDR = 5
NAL_SEI = 6
NAL_SPS = 7
NAL_PPS = 8
NAL_AUD = 9
NAL_FILLER = 12,

我們發送RTMP數據時只需要知道四種幀類型,其它類型我都把它規類成非關鍵幀。
分別是
NAL_SPS(7), sps幀
NAL_PPS(8), pps幀
NAL_SLICE_IDR(5), 關鍵幀
NAL_SLICE(1) 非關鍵幀

幀類型的方式判斷為界面符后首字節的低四位。
第一幀的幀類型為: 0x67 & 0x1F = 7,這是一個SPS幀
第二幀的幀類型為: 0x68 & 0x1F = 8,這是一個PPS幀
第三幀的幀類型為: 0x06 & 0x1F = 6,這是一個SEI幀

以上是我們利用幀界定符划分幀,並可以判斷每一個幀的類型。

注意:如果是壓縮圖像成H264幀,我們就可不必進行幀界定,因為每一次壓縮的輸出都明確了該幀的大小(包括界定符),每一次的壓縮的結果可能包函多幀。一會具體討論。

1.2 AAC幀

對於AAC幀它的界定符是FF F1

這里我就不舉例了,可通過查看AAC的二進制文件可以看到如下的幀結構。
FF F1 50 80 24 9F FD DE 04 00 00 6C 69 62 66 61 61 63 20 31 2E 32 38 00 00 42 15 95 ..

注意:那么對於AAC而言加上界定符每一幀的前7字節是幀的描述信息,也就是說AAC的祼數據是除去前面的7個字節的,在發送RTMP時,我們要去掉這7個字節。同樣,如果我們是一邊壓縮一邊發送RTMP,我們同樣不需要界定幀,因為libfaac每次壓縮完成的輸出就是一個完整的幀數據,我們只需要將該幀打包發送即可。

綜合上面的所述,如果我們只是一邊壓縮一邊將壓縮結果發送到RTMP服務器,那我們就可以不用對幀進行界定,如果我們是發送H264與AAC文件,那我們就要對幀進行界定。

2.視頻與音頻的編碼信息

如果我們只是簡答的將壓縮數據打包發送給RTMP服務器,那么RTMP服務器是不可以對數據進行解碼和播放的,在這之前我們要將音視頻的視頻的編碼信息發送給RTMP服務器。很多人可能苦於尋找下面的三個編碼參數而不得要領。其實要想得到也是很簡單的。

2.1 (H264)SPS

對於H264而言,SPS就是編碼后的第一幀。如果是讀取H264文件,就是第一個幀界定符與第二幀界定符中間的數據長度是4。

2.2 (H264)PPS

對於H264而言,PPS就是編碼后的第二幀。如果是讀取H264文件,就是第二個幀界定符與第三幀界定符中間的數據,長度不固定。

2.3 (AAC)AudioDecoderSpecificInfo

這個長度為2個字節,可以通過計算或者調用函數獲取。
建議通過調用faacEncGetDecoderSpecificInfo(fh,&spec,&len);獲取。
一般情況雙聲道44100采樣下,該值是0x1210

3.librtmp的使用

 

 

 

 

4.包類型

4.1 H.264編碼信息幀

H.264的編碼信息幀是發送給RTMP服務器稱為AVC sequence header,RTMP服務器只有收到AVC sequence header中的sps,pps才能解析后續發送的H264幀。

sps與pps怎么獲取到呢?

在前面已經說過,H264的第1幀是sps幀,pps是第2幀。

我們在編碼時會調用如下接口

我完全可以不用知道sps,pps的具體意義:)

4.2 H.264關鍵幀

4.3 H.264非關鍵幀

 

這里要說明一下:

在libx264中每一次調用x264_encoder_encode輸出了n個幀,我們要從這n個幀里找出sps和pps,剩下的分次全部發送nal,sps與pps的幀界定符都是00 00 00 01,而普通幀可能是00 00 00 01也有可能00 00 01。
比如說x264_encoder_encode輸出了6幀。
分別是 sps幀,pps幀,關鍵幀,非關鍵幀,非關鍵幀,非關鍵幀。
發送結果應該是,sps,pps合成為一幀調用發送函數,剩下4幀,除去每個nal的界定符,分別發送每一個nal。

如果x264_encoder_encode里沒有sps幀與pps幀,則結果除去第一幀的界定符所以幀做為一個整體調用發送函數,它們的類型是由第一幀類型決定。

另外,H264的流的第1幀一定是sps幀(包含幀界定符為8個字節),第2幀一定是pps幀。

4.4 AAC編碼信息

 

對於音頻解碼參數AAC sequence header是通過

下面是獲得AAC sequence header的方法

另外如果你是打開aac文件進行發送,那么你可以嘗試自己計算這個值,其實也很簡單,打開faac源代碼看一下faacEncGetDecoderSpecificInfo的實現,也就是幾個移位的事:)。
對於一般情況44100Hz雙聲道,這個值是0x1210,偷懶就是直接用這個值吧。

4.5 AAC普通數據

如前面所述,發送AAC的普通數據要改造一下,因為AAC的前7個字節(包括幀界定符)對於RTMP服務器來說是無用的。

至此所有流程均結束了。
要注意的幾件事:
libRTMP多線程發送有時候可能會出現問題,不知道是什么問題,最好改成隊列發送。
將填充好的packet通過消息或者其它方式發送給其它線程,發送線程統一發送即可

以下信息作為aac 編碼的參考內容;

AAC的幀頭一般7個字節,或者包含CRC校驗的話9個字節,這里面包括了聲音的相關參數。

結構如下:

Structure

AAAAAAAA AAAABCCD EEFFFFGH HHIJKLMM MMMMMMMM MMMOOOOO OOOOOOPP (QQQQQQQQ QQQQQQQQ)

Header consists of 7 or 9 bytes (without or with CRC).

RTMP直播到FMS中的AAC音頻頭 AAC Frame Header (轉) - niulei20012001 - niulei20012001的博客

 

 

 

Letter Length (bits) Description
A 12 syncword 0xFFF, all bits must be 1
B 1 MPEG Version: 0 for MPEG-4, 1 for MPEG-2
C 2 Layer: always 0
D 1 protection absent, Warning, set to 1 if there is no CRC and 0 if there is CRC
E 2 profile, the MPEG-4 Audio Object Type minus 1
F 4 MPEG-4 Sampling Frequency Index (15 is forbidden)
G 1 private stream, set to 0 when encoding, ignore when decoding
H 3 MPEG-4 Channel Configuration (in the case of 0, the channel configuration is sent via an inband PCE)
I 1 originality, set to 0 when encoding, ignore when decoding
J 1 home, set to 0 when encoding, ignore when decoding
K 1 copyrighted stream, set to 0 when encoding, ignore when decoding
L 1 copyright start, set to 0 when encoding, ignore when decoding
M 13 frame length, this value must include 7 or 9 bytes of header length: FrameLength = (ProtectionAbsent == 1 ? 7 : 9) + size(AACFrame)
O 11 Buffer fullness
P 2 Number of AAC frames (RDBs) in ADTS frame minus 1, for maximum compatibility always use 1 AAC frame per ADTS frame
Q 16 CRC if protection absent is 0

 

http://wiki.multimedia.cx/index.php?title=ADTS

其中最重要的就是E,F,H。

E就是類型了

1: AAC Main
2: AAC LC (Low Complexity)
3: AAC SSR (Scalable Sample Rate)
4: AAC LTP (Long Term Prediction)

F就是采樣頻率

0: 96000 Hz

    • 1: 88200 Hz
    • 2: 64000 Hz
    • 3: 48000 Hz
    • 4: 44100 Hz
    • 5: 32000 Hz
    • 6: 24000 Hz
    • 7: 22050 Hz
    • 8: 16000 Hz
    • 9: 12000 Hz
    • 10: 11025 Hz
    • 11: 8000 Hz
    • 12: 7350 Hz

      H就是聲道

      1: 1 channel: front-center

    • 2: 2 channels: front-left, front-right
    • 3: 3 channels: front-center, front-left, front-right
    • 4: 4 channels: front-center, front-left, front-right, back-center
    • 5: 5 channels: front-center, front-left, front-right, back-left, back-right
    • 6: 6 channels: front-center, front-left, front-right, back-left, back-right, LFE-channel
    • 7: 8 channels: front-center, front-left, front-right, side-left, side-right, back-left, back-right, LFE-channel

      有了這三個參數,就可以發送音頻的第一幀了,然后后面的幀,把包頭的7個字節去掉?,打包到RTMP協議發送就可以了。

      http://wiki.multimedia.cx/index.php?title=MPEG-4_Audio#Audio_Object_Types

      當然發送的時候要打上RTMP的包頭,數據部分用 AF 00 代替AAC的包頭。長度再計算一下。時間戳用采樣的時間也可以,自己另算也可以。

      //--------------------------------------------------------------------------------------------------------------//

      第一個音頻包那就是AAC header.

      如:af 00 13 90。包長4個字節,解釋如下,

      1)第一個字節af,a就是10代表的意思是AAC,

      Format of SoundData. The following values are defined:
      0 = Linear PCM, platform endian
      1 = ADPCM
      2 = MP3
      3 = Linear PCM, little endian
      4 = Nellymoser 16 kHz mono
      5 = Nellymoser 8 kHz mono
      6 = Nellymoser
      7 = G.711 A-law logarithmic PCM
      8 = G.711 mu-law logarithmic PCM
      9 = reserved
      10 = AAC
      11 = Speex
      14 = MP3 8 kHz
      15 = Device-specific sound
      Formats 7, 8, 14, and 15 are reserved.
      AAC is supported in Flash Player 9,0,115,0 and higher.
      Speex is supported in Flash Player 10 and higher.

      2)第一個字節中的后四位f代表如下

      前2個bit的含義 抽樣頻率,這里是二進制11,代表44kHZ

      Sampling rate. The following values are defined:
      0 = 5.5 kHz
      1 = 11 kHz
      2 = 22 kHz
      3 = 44 kHz

      第3個bit,代表 音頻用16位的

      Size of each audio sample. This parameter only pertains to
      uncompressed formats. Compressed formats always decode
      to 16 bits internally.
      0 = 8-bit samples
      1 = 16-bit samples

      第4個bit代表聲道

      Mono or stereo sound
      0 = Mono sound
      1 = Stereo sound

      3)第2個字節

      AACPacketType,這個字段來表示AACAUDIODATA的類型:0 = AAC sequence header,1 = AAC raw。第一個音頻包用0,后面的都用1

      4)第3,4個字節內容AudioSpecificConfig如下

      AAC sequence header存放的是AudioSpecificConfig結構,該結構則在“ISO-14496-3 Audio”中描述。AudioSpecificConfig結構的描述非常復雜,這里我做一下簡化,事先設定要將要編碼的音頻格式,其中,選擇"AAC-LC"為音頻編碼,音頻采樣率為44100,於是AudioSpecificConfig簡化為下表:

      0x13 0x90(1001110010000) 表示 ObjectProfile=2, AAC-LC,SamplingFrequencyIndex=7,ChannelConfiguration=聲道2

    • RTMP直播到FMS中的AAC音頻頭 AAC Frame Header (轉) - niulei20012001 - niulei20012001的博客

       

      AudioSpecificConfig,即為ObjectProfile,SamplingFrequencyIndex,ChannelConfiguration,TFSpecificConfig。

      其中,ObjectProfile (AAC main ~1, AAC lc ~2, AAC ssr ~3);

      SamplingFrequencyIndex (0 ~ 96000, 1~88200, 2~64000, 3~48000, 4~44100, 5~32000, 6~24000, 7~ 22050, 8~16000...),通常aac固定選中44100,即應該對應為4,但是試驗結果表明,當音頻采樣率小於等於44100時,應該選擇3,而當音頻采樣率為48000時,應該選擇2;

      ChannelConfiguration對應的是音頻的頻道數目。單聲道對應1,雙聲道對應2,依次類推。

      TFSpecificConfig的說明見標准14496-3中(1.2 T/F Audio Specific Configuration)的講解,這里恆定的設置為0;

      索引值如下含義:

      There are 13 supported frequencies:

      • 0: 96000 Hz
      • 1: 88200 Hz
      • 2: 64000 Hz
      • 3: 48000 Hz
      • 4: 44100 Hz
      • 5: 32000 Hz
      • 6: 24000 Hz
      • 7: 22050 Hz
      • 8: 16000 Hz
      • 9: 12000 Hz
      • 10: 11025 Hz
      • 11: 8000 Hz
      • 12: 7350 Hz
      • 13: Reserved
      • 14: Reserved
      • 15: frequency is written explictly

      channel_configuration: 表示聲道數

      • 0: Defined in AOT Specifc Config
      • 1: 1 channel: front-center
      • 2: 2 channels: front-left, front-right
      • 3: 3 channels: front-center, front-left, front-right
      • 4: 4 channels: front-center, front-left, front-right, back-center
      • 5: 5 channels: front-center, front-left, front-right, back-left, back-right
      • 6: 6 channels: front-center, front-left, front-right, back-left, back-right, LFE-channel
      • 7: 8 channels: front-center, front-left, front-right, side-left, side-right, back-left, back-right, LFE-channel
      • 8-15: Reserved

       

      后面的視頻包都是AF 01 + 去除7個字節頭的音頻AAC數據


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM