live555對於實時音視訊的支援
為了使live555能夠支援實時流的播放,需要進行改造。
有兩種方式:
1,一個比較簡單,可以使用管道檔案的方式。缺點是當碼流較大時,
會明顯的卡頓、馬賽克。(測試超過80K時會卡得非常厲害)
2,再一個,需要自己過載source,submission類。在其中實現資料的對接。
下面分別介紹一下這兩種方式
一、管道方式:
1,開啟live/testProgs/testOnDemandRTSPServer.cpp,修改reuseFirstSource的值為True,並編譯之
2,參考該程式的引數,即可實現檔案的播放。而我們將其指向管道檔案
2,mkfifo live/testProgs/test.264
3,寫自己的程式,將H264編碼的資料write到test.264管道中。就普通的open,write即可
注意,在寫入端,注意攔截SIGPIPE訊號。signal(SIGPIPE, _sighandle). 原因是,當rtsp端關閉流時,
會導致SIGPIPE發生,並退出程式。但其實我們可能不想退出。
二、重寫source
1,編寫類:LiveServerMediaSubsession: public OnDemandServerMediaSubsession
2,對於H264編碼而言,我們可以把H264VideoFileServerMediaSubsession原樣抄過來,在其基礎上修改
3,去掉無用的引數,重寫createNewStreamSource。裡面換成一個新類:FrameLiveSource做輸入Source
4,編寫類:FramedLiveSource: public FramedSource
5,有幾個函式需要完成:
1)maxFrameSize,最大幀的大小。
2)doGetNextFrame(); 關鍵函式,負責獲取資料。核心程式碼如下:
memcpy(fTo, buffer, len);
gettimeofday(&fPresentationTime, NULL);
fFrameSize = len;
nextTask() = envir().taskScheduler().scheduleDelayedTask(0,
(TaskFunc*)FramedSource::afterGetting, this);
3)isH264VideoStreamFramer。當資料準備好時,該函式返回True
6,後面就簡單了,只要把doGetNextFrame和正常的實時視訊資料聯絡起來,一切就解決了。
三、live555的下載、編譯方式
1,網站上下載live555,網址:http://www.live555.com/liveMedia/
2,./genMakefile linux
3,make
其中,./genMakefile linux,是對應config.linux來的。
我們可以參考config.armlinux修改成自己所需的版本
五、音訊SERVER的實現 使用G726-40
共需要兩個類:
1,class FramedAudioSource : public FramedSource
1)只要實現一個:doGetNextFrame即可,關鍵程式碼如下:
int len = Get_Data(fTo, fMaxSize);
if (len <= 0)
{//獲取不到資料時,一定要起個檢查定時器。否則程式就停止了
//nextTask() = envir().taskScheduler().scheduleDelayedTask(...
}
fFrameSize = len;
FramedSource::afterGetting(this);
2,建立OnDemandServerMediaSubsession的子類,AudioServerMediaSubssion
1)實現兩個介面:createNewRTPSink和createNewStreamSource
2)createNewStreamSource使用FramedAudioSource建立
3)createNewRTPSink
RTPSink* AudioServerMediaSubsession::createNewRTPSink(Groupsock* rtpGroupsock,
unsigned char rtpPayloadTypeIfDynamic, FramedSource* inputSource) {
return SimpleRTPSink::createNew(envir(), rtpGroupsock, rtpPayloadTypeIfDynamic,
m_timeStampFrequency, "audio", m_audioType, 1, False, False);
}
這個函式中,關鍵的有:
m_timeStampFrequency,根據實際情況填寫16000或者8000等取樣率
m_audioType,編碼方式,例如:"G726-40"。這個準確的定義,請參照MediaSession::createSourceObjects中的內容
六、音訊與視訊同時提供
這個就簡單了,只要sms->addSubsession多來幾次,新增多個Subsession即可。
最後、其它遇到的問題:
1,當連線斷開時,FrameLiveSource會被釋放。再連線時重新建立。所以要做好資料的釋放與分配的處理
同時也要注意資料釋放的瞬間,多執行緒非同步問題導致的問題
2,StreamParser.cpp中,BANK_SIZE的大小,需要做對應的修改,以便容納足夠大的資料
3,env(),這個東西一定要關心。繼承一個類,實現setResultMsg可用於輸出live555本身的一些資訊。