Source和Sink:可以把source理解為發送端的流,sink理解為接受端。MediaSink是各種類型的Sink的基類,MediaSource是各種類型Source的基類,各種類型的流媒體格式和編碼的支持即是通過對這兩個類的派生實現的。Source和Sink通過RTP子會話(MediaSubSession)聯系在一起。
FramedSource 派生自MediaSource, 一幀碼流的實現。私有unsigned char* fTo; // in 是指向發送的碼流的指針。
重要的函數有 getNextFrame
void FramedSource::getNextFrame(unsigned char* to, unsigned maxSize, afterGettingFunc* afterGettingFunc, void* afterGettingClientData, onCloseFunc* onCloseFunc, void* onCloseClientData) { // Make sure we're not already being read: if (fIsCurrentlyAwaitingData) { envir() << "FramedSource[" << this << "]::getNextFrame(): attempting to read more than once at the same time!\n"; envir().internalError(); } fTo = to; fMaxSize = maxSize; fNumTruncatedBytes = 0; // by default; could be changed by doGetNextFrame() fDurationInMicroseconds = 0; // by default; could be changed by doGetNextFrame() fAfterGettingFunc = afterGettingFunc; fAfterGettingClientData = afterGettingClientData; fOnCloseFunc = onCloseFunc; fOnCloseClientData = onCloseClientData; fIsCurrentlyAwaitingData = True; doGetNextFrame(); }
doGetNextFrame(); 是一個虛函數,具體各種編碼模式,我們可以根據自己的碼流類型定義一個派生自FramedSource的類, 重新再定義doGetNextFrame如何獲得下一幀的碼流。在自己重定義的doGetNextFrame() 中將fTo指向要發送的緩存。
我們可以通過doGetNextFrame() 是fTo重定向我們要發送的流,而不是從文件中讀取。(搞定了source)之后就是要如何讓fTo與發送會話連接起來,OnDemandServerMediaSubsession由 ServerMediaSubsession 派生而來,其有一個新的私有函數 virtual FramedSource* createNewStreamSource,我們又可以重新定義一個派生自OnDemandServerMediaSubsession 的類,重新定義createNewStreamSource 將fTo 與 ServerMedia聯系起來。
如下live555中的例子
FramedSource* H264VideoFileServerMediaSubsession::createNewStreamSource(unsigned /*clientSessionId*/, unsigned& estBitrate) { estBitrate = 500; // kbps, estimate // Create the video source: ByteStreamFileSource* fileSource = ByteStreamFileSource::createNew(envir(), fFileName); if (fileSource == NULL) return NULL; fFileSize = fileSource->fileSize(); // Create a framer for the Video Elementary Stream: return H264VideoStreamFramer::createNew(envir(), fileSource); }
ByteStreamFileSource說到底還是繼承自FramedSource,定義了從文件獲取source的方法,而這個函數又將ServerMedia 與source聯系了起來,
ServerMedia 就知道該發送什么東東了。 return H264VideoStreamFramer::createNew(envir(), fileSource); 給 ServerMedia 返回了一個 FramedSource 。
不過,如果自己定義的ServerMedia直接從 OnDemandServerMediaSubsession 繼承的話,有很多純虛函數需要自己去實現,比較麻煩,所以可以直接從
H264VideoFileServerMediaSubsession 繼承,它實現了這些純虛函數,我們只需重定義createNewStreamSource 就ok了。