使用live555庫推流h264,一般從testOnDemandRTSPServer.cpp 修改而來,不過其中都是通過從本地文件,或作類似文件描述符“fd”源中讀數據,這類數據源,需要對數據源進行分析處理,拿h264裸文件來說,就需要根據NAL 00 00 00 01 來切分出一幀幀的數據,這是一個消耗資源的操作,如果我們是已經就緒的h264幀數據在內存裏,就不需要這一部分,否則造成明顯的推流延遲。
testOnDemandRTSPServer.cpp中測試 h264推流的代碼。
// A H.264 video elementary stream:
{
char const* streamName = "h264ESVideoTest";
char const* inputFileName = "test.264";
ServerMediaSession* sms
= ServerMediaSession::createNew(*env, streamName, streamName,
descriptionString);
sms->addSubsession(H264VideoFileServerMediaSubsession
::createNew(*env, inputFileName, reuseFirstSource));
rtspServer->addServerMediaSession(sms);
announceStream(rtspServer, sms, streamName, inputFileName);
}
被添加到 ServerMediaSession的 ServerMediaSubsession ——H264VideoFileServerMediaSubsession,是繼承自FileServerMediaSubsession。 要實現從內存buffer中讀264數據的 ServerMediaSubsession, 需要實現自己的 ServerMediaSubsession. 之前有寫過一篇:https://blog.csdn.net/u012459903/article/details/86676702
實現了兩個自己的類:
class H264LiveVideoServerMediaSubssion : public OnDemandServerMediaSubsession
class H264FramedLiveSource : public FramedSource
在H264LiveVideoServerMediaSubssion 中實現兩個關鍵的函數:createNewStreamSource() ,用來創建source
createNewRTPSink() 創建sink。 對於FileServerMeidiaSubsession, 創建的輸入源。但是之前的這篇blog在創建 StreamSource的時候依然用了 return H264VideoStreamFramer::createNew(envir(), liveSource); 把得到的流再用 H264VideoStreamFramer進行了一遍”過濾“,這個H264VideoStramFramer內部會重新從流數據中遍歷,找出 NAL, 分離出h264幀,這個過程是多餘的並且消耗資源,導致實際推流有明顯延遲。這裏更正:
#if 0
// Create a framer for the Video Elementary Stream:
//return H264VideoStreamFramer::createNew(envir(), liveSource);
#else
//不需要parse, 直接就是完整的一幀
return H264VideoStreamDiscreteFramer::createNew(envir(), liveSource);
#endif
使用 H264VideoStreamDiscreteFramer來代替H264VideoStreamFramer。 注意這個H264VideoStreamDiscreteFramer 要求輸入的數據不帶 NAL頭。不然一直在抱怨。