Medium
live555幾乎所有的處理單元都繼承自Medium類;該類抽象了基本的接口,包括環境,task和媒體名和媒體查找函數(lookupByName)以及一些輔助函數。也包括返回當前的環境類UsageEnvironment,以及環境指向下一個TaskToken的指針nextTask等。
ServerMediaSession
對象的創建函數在文件DynamicRTSPServer.cpp中。DynamicRTSPServer的繼承關系是
DynamicRTSPServer::RTSPServerSupportingHTTPStreaming::RTSPServer::Medium
DynamicRTSPServer從RTSPServer繼承過來,僅僅添加了構造器和查找函數,沒有添加其他成員。構造器是創建socket然后傳給 RTSPServer,查找是如果沒有已經打開的流服務,那么根據參數創建流服務。RTSPServer的屬性有socket,端口號,Session點號,認證機制和ServerMediaSession表。
當接收到帶有URI的請求后,會首先創建SMS,調用 ServerMediaSession的構造函數,除了創建時間戳,拷貝文件名外都是使用的缺省值,并且將初始化子會話鏈表。當處理describe命令時,ServerMediaSession通過調用generateSDPDescription函數生成。 在NEW_SMS()中創建ServerMediaSession對象,然后創建相應的ServerMediaSubsession并將這個子會話對象添加到添加到會話對象中。
如子回話是MPEG4,創建MPEG4VideoFileServerMediaSubsession對象,對象的繼承關系:
MPEG4VideoFileServerMediaSubsession::FileServerMediaSubsession ::OnDemandServerMediaSubsession::ServerMediaSubsession ::Medium
ServerMediaSession::Medium
相關類介紹:
ServerMediaSession:添加了子會話鏈表,SDP描述以及一些媒體相關處理函數。
ServerMediaSubsession:定義了指向ServerMediaSession的父指針,指向下個一個對象的指針。該媒體的SDP信息,該媒體的讀取定位函數等。 ServerMediaSubsession類和具體的流播放相關,是個純虛類。其中startStream和getStreamParameter是純虛函數。
OnDemandServerMediaSubsession:添加了流source處理和RTPSink處理函數以及經典命名屬性等。封裝seek,pause等處理,把這些接口中clientSessionid號到這里轉換成了FramedSource。 該類的成員函數大部分和ServerMediaSubsession相似,在流媒體完成定位等處理。createNewStreamSource和createNewRTPSink是兩個純虛函數,在子類中必須實現。類中getStreamParameters方法會創建streamState。這個方法在處理RTP的Setup命令時被調用。
FileServerMediaSubsession:增加了文件名和文件大小屬性。
MPEG4VideoFileServerMediaSubsession:添加了RTPSink屬性,并且實現了OnDemandServerMediaSubsession中定義的兩個純虛函數,即創建了source和sink對象。這個source是MPEG4VideoStreamFramer。該類中還定義了StreamState的內部類。
StreamState:包含了指向OnDemandServerMediaSubsession的引用,RTPSink指針,BasicUDPSink指針,RTCPInstance指針FramedSource指針,fRTPgs和fRTCPgs(groupsock).
StreamState類可以用OnDemandServerMediaSubsession的fLastStreamToken屬性指向。
類streamState的屬性:
OnDemandServerMediaSubsession& fMaster; Boolean fAreCurrentlyPlaying;
unsigned fReferenceCount; Port fServerRTPPort, fServerRTCPPort;
RTPSink* fRTPSink; BasicUDPSink* fUDPSink;
float fStreamDuration; unsigned fTotalBW; RTCPInstance* fRTCPInstance;
FramedSource* fMediaSource; Groupsock* fRTPgs; Groupsock* fRTCPgs;
Sink
Sink類提供了總的媒體播放接口。sink有兩種,一個是BasicUDPSink,一個是RTPSink,如果協商時沒有RTP信息,那么創建BasicUDPSink。Source和 Sink通過函數createNewRTPSink和createNewStreamSource。這兩個函數在類 OnDemandServerMeidaSubsession中定義為純虛函數,如果媒體類型是mpeg4videofileserver,那么對應的函數定義在類MPEG4VideoFileServerMediaSubsession中。
MPEG4ESVideoRTPSink::VideoRTPSink::MultiFramedRTPSink::RTPSink::MediaSink::Medium
MediaSink定義中有一個媒體源指針,主要處理函數有startplaying(),stopplaying()和 afterPlayingFunc函數指針。
RTPSink類定義了RTP相關的處理和屬性。包含Socket組對象,時間處理系列,統計計數處理等相關屬性。
MultiFramedRTPSink是RTPSink的子類,處理buffer中的多個RTP包。類中添加了輔助SDP處理和VOPIsPresent屬性和一個判斷性處理函數。
MultiFramedRTPSink類完成多幀組包處理主要函數有buildAndSendPacket,packFrame,
sendNext, afterGettingFrame,這幾個函數之間有相互調用。內部有OutPacketBuffer屬性,在創建時設定為(1000(希望),1448(最大))大小,其他是統計或者標識屬性。這個發送數據包是通過 fRTPInterface.sendPacket(fOutBuf->packet(), fOutBuf->curPacketSize());實現。這個fRTPInterface是父類RTPSink的屬性。
VideoRTPSink僅僅添加了sdpMediaType處理函數, 返回SDP類型是“video”
MPEG4ESVideoRTPSink中的處理函數doSpecialFrameHandling:首先檢測開頭的四個字節看是否是 VOP_START_CODE,該函數處理RTP的起始/中止標識和添加時間戳。其他處理包括是否允許分片,是否是起始包判斷以及輔助SDP處理。
Source
createNewStreamSource調用的是MPEG4VideoFileServerMediaSubsession中的定義。在類 OnDemandServerMediaSubsession中的createNewStreamSource定義是一個純虛函數。
創建的source是:
MPEG4VideoStreamFramer:MPEGVideoStreamFramer:FramedFilter:FramedSource:MediaSource:Medium
MediaSource在Medium類的基礎上添加了更多媒體類型判斷,比如是H264,mpeg還是jpeg。此外還有一個MIME類型。
FramedSource類處理成幀類型的媒體,比如 mpeg,mjpeg,h264,amr等音頻類型的媒體。函數分幀處理媒體流,主要處理是getNextFrame,afterGetting以及關閉等媒體處理,此外定義了doGetNextFrame純虛函數,這個函數由getNextFrame調用,處理具體的媒體流。該類還定義了兩個函數指針,afterGettingFunc* fAfterGettingFunc; onCloseFunc* fOnCloseFunc;處理。 該類的屬性包括數據拷貝的指針,幀的大小,展示時間,和播放間隔,是否當前等待播放標志。
FramedFilter是FramedSource的子類,這是個中間類,主要在類中添加了指向輸入源的指針 FramedSource* fInputSource;
MPEGVideoStreamFramer:是FramedFilter的子類,因為mpeg是時間相關的媒體流,所以在父類的基礎上添加了時間處理函數,此外還有 continueReadProcessing函數。主要的屬性有:幀率,結束標志,圖片計數,展示時間,GOP時間相關內容,圖片時間相關屬性。此外還有一個重要的類屬性: MPEGVideoStreamParser用來分析媒體流。
MPEG4VideoStreamFramer:在父類的基礎上添加了config信息,類如profile等級信息。在該類的定義文件中還實現了MPEG4文件分析類,繼承自MPEGVideoStreamParser。處理mepg4相關信息。
ByteStreamFileSource::FramedFileSource::FramedSource
source里面有一個非常重要的StreamParser(流分析)對象,用來分析,讀取流數據。其中afterGettingBytes和不同媒體流處理相關,內部有一個函數fClientContinueFunc為不同媒體注冊的函數。而getNextFrame會調用afterGettingBytes。
MPEG4ESVideoRTPSource:MultiFramedRTPSource:RTPSource:FramedSource:MediaSource:Medium
RTPSource:添加RTP相關處理,主要屬性有RTPInterface,時間標簽,處理數據幀拆分packetMarkerbit時間戳頻率和統計信息。RTP統計信息:收到的總包數,從reset以后收到的總包數,收到的字節數,初始化序列標識,前面一個RTP包的時間戳,接受到的發送者報告的NTP時間,接受到的發送者報告時間。RTPSource僅僅處理RTP協議相關的問題。MultiFramedRTPsource中的 networkHandler中會調用到這些處理。
playing
在服務端的操作中是圍繞著StreamState展開的,OnDemandServerMediaSubsession類中的StartStream通過調用StreamState的startplaying開始進行,并且初始化rtpSeqNum和rtpTimestamp (= rtpSink()->presetNextTimestamp()) 兩個變量。在MediaSink定義了startPlaying,這里通過調用BasicUDPSink類中的continuePlaying最終調用到了 buildAndSendPacket,函數buildAndSendPacket根據傳入的參數是否第一幀分別進行處理。如果是第一幀,那么取當前時間標簽,作為發送時間,
在函數packFrame中,首先調用afterGettingFrame1,然后調用
fSource->getNextFrame(fOutBuf->curPtr(), fOutBuf->totalBytesAvailable(),afterGettingFrame, this, ourHandleClosure, this);處理。
在播放過程中,通過nextTask() = envir().taskScheduler().scheduleDelayedTask
(uSecondsToGo,(TaskFunc*)sendNext, this);每次都會計算一個下次發送時間和包添加到調度中進行。
讀取媒體數據在MPEG4VideoStreamParser類定義中處理。成員函數parse分析出讀取數據的大小。然后讀取一幀數據,交給打包代碼處理。