RTP打包G711音訊資料傳送
阿新 • • 發佈:2018-12-01
前面部落格講過G711編碼,有兩種G711A/G711U,主要在安防中應用,是一幀波形編碼的音訊資料,只是將PCM壓縮一半資料量。一般G711,取樣率8000,通道數1。所以G711中1B就是一個樣本資料。G711打包RTP非常簡單,只要在G711資料前加上RTP頭即可。G711沒有想AAC那樣,按照幀一幀一幀傳送,而是設定一個打包頻率,打包頻率有10ms,20ms,30ms,40ms 等。如40ms的打包頻率,1S打包25幀,1S需要傳送8000個樣本,所以一幀需要8000/25=320個樣本,RTP時間戳增量絕對值是320/8000S,協議要求以取樣率作為時鐘頻率,所以RTP時間戳為 (320/8000)*8000。
負載型別定義如下:
enum RTP_PAYLOAD_TYPE { RTP_PAYLOAD_TYPE_PCMU = 0, RTP_PAYLOAD_TYPE_PCMA = 8, RTP_PAYLOAD_TYPE_JPEG = 26, RTP_PAYLOAD_TYPE_H264 = 96, RTP_PAYLOAD_TYPE_H265 = 97, RTP_PAYLOAD_TYPE_OPUS = 98, RTP_PAYLOAD_TYPE_AAC = 99, RTP_PAYLOAD_TYPE_G726 = 100, RTP_PAYLOAD_TYPE_G726_16 = 101, RTP_PAYLOAD_TYPE_G726_24 = 102, RTP_PAYLOAD_TYPE_G726_32 = 103, RTP_PAYLOAD_TYPE_G726_40 = 104, RTP_PAYLOAD_TYPE_SPEEX = 105, };
RTP打包格式
12BRTP頭 |
G711 負載 |
DEMO程式採用JRTPLIB實現 ,把G711音訊資料打包成RTP傳送到指定埠。
#include <rtpsession.h> #include <rtpudpv4transmitter.h> #include <rtpipv4address.h> #include <rtpsessionparams.h> #include <rtperrors.h> #include <rtplibraryversion.h> #include <iostream> #include <stdlib.h> #include <stdio.h> #include <string.h> using namespace jrtplib; uint16_t iLocalPort = 6666; uint16_t iDestPort = 12000; uint8_t szDestAddr[]={192, 168, 1, 108}; FILE *pG711File = NULL; void checkerror(int rtperr) { if (rtperr < 0) { std::cout << "ERROR: " << RTPGetErrorString(rtperr) << std::endl; exit(-1); } } void rtpPrintf(uint8_t *buf, uint16_t len) { uint16_t i=0; printf("RTP len=%d : \n", len); for(i=0; i<len; i++) { printf(" %02X", buf[i]); if(i%32 == 31) printf("\n"); } printf("\n"); } int main(void) { int status; RTPSession sess; RTPUDPv4TransmissionParams transparams; RTPSessionParams sessparams; /* set g711a param */ sessparams.SetUsePredefinedSSRC(true); sessparams.SetOwnTimestampUnit(1.0/8000.0); sessparams.SetAcceptOwnPackets(true); transparams.SetPortbase(iLocalPort); status = sess.Create(sessparams,&transparams); checkerror(status); RTPIPv4Address addr(szDestAddr,iDestPort); status = sess.AddDestination(addr); checkerror(status); //時間戳 sess.SetDefaultTimestampIncrement(320); //PCMA sess.SetDefaultPayloadType(8); sess.SetDefaultMark(true); pG711File = fopen("./test.g711", "rb"); if(!pG711File) { printf("error: can not open file !\n"); return 0; } uint16_t iReadLen = 0; uint8_t szBuf[1024] = {0}; while( !feof(pG711File) ) { iReadLen = fread(szBuf, 1, 320, pG711File); //rtpPrintf(buf, read_len); status = sess.SendPacket(szBuf, iReadLen, 8, true, 320); checkerror(status); RTPTime::Wait(0.03); } fclose(pG711File); return 0; }
編譯環境 CentOs6.5,Debug目錄執行“make clean;make”重新編譯,”./run.sh“執行即可。
測試執行 RTP傳送的目標機器上執行VLC,開啟test.sdp即可播放G711音訊資料。
播放器播放首先播放器要知道採用的接受協議,從哪個埠接受,是什麼編碼的資料,這些資料資訊是通過SDP檔案傳遞給VLC的。如果採用其他協議RTSP/SIP等,在播放之前會進行信令互動,這種情況是通過信令傳遞SDP資訊的。SDP說明如下:
G711檔案開啟
G711檔案不知道怎麼播放,可以用audacity.exe開啟,開啟方式如下圖即可播放。
CSDN下載地址:https://download.csdn.net/download/hiwubihe/10811502