1. 程式人生 > >RTP打包G711音訊資料傳送

RTP打包G711音訊資料傳送

前面部落格講過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