Live555 RTP 打包以及发送
H264 H265 为例
-
在收到客户端播放请求后,由
OnDemandServerMediaSubsession
调用MediaSink::startPlaying
方法:Boolean MediaSink::startPlaying(MediaSource& source, afterPlayingFunc* afterFunc, void* afterClientData) { ... // 赋值 fSource,一般为 H264or5VideoStreamDiscreteFramer fSource = (FramedSource*)&source; fAfterFunc = afterFunc; fAfterClientData = afterClientData; // 虚函数 return continuePlaying(); }
-
调用
H264or5VideoRTPSink::continuePlaying
方法:Boolean H264or5VideoRTPSink::continuePlaying() { // 创建 H264or5Fragmenter 对象,fSource 在上一步被赋值 if (fOurFragmenter == NULL) { fOurFragmenter = new H264or5Fragmenter(fHNumber, envir(), fSource, OutPacketBuffer::maxSize, ourMaxPacketSize() - 12/*RTP hdr size*/); } else { fOurFragmenter->reassignInputSource(fSource); } // 为 fSource 重赋值 fSource = fOurFragmenter; // 调用父类方法 return MultiFramedRTPSink::continuePlaying(); }
-
调用
MultiFramedRTPSink::continuePlaying -> MultiFramedRTPSink::buildAndSendPacket -> MultiFramedRTPSink::packFrame
方法:void MultiFramedRTPSink::packFrame() { // 填充 rtp 头 ... if (fOutBuf->haveOverflowData()) { ... } else { // 从 fSouce 获取新帧 if (fSource == NULL) return; fSource->getNextFrame(fOutBuf->curPtr(), fOutBuf->totalBytesAvailable(), afterGettingFrame, this, ourHandleClosure, this); } }
-
调用
FramedSource::getNextFrame
方法:void FramedSource::getNextFrame(...) { ... // 虚函数 doGetNextFrame(); }
-
调用
H264or5Fragmenter::doGetNextFrame
方法:void H264or5Fragmenter::doGetNextFrame() { if (fNumValidDataBytes == 1) { // 从 fInputSource 获取新帧,此处的 fInoutSoure 即第一步中被赋值的 fSource, // 即 H264or5VideoStreamDiscreteFramer // 获取到新帧后,调用 H264or5Fragmenter::afterGettingFrame,其又会调用 // H264or5Fragmenter::doGetNextFrame 方法,进入 else 分支 fInputSource->getNextFrame(&fInputBuffer[1], fInputBufferSize - 1, afterGettingFrame, this, FramedSource::handleClosure, this); } else { // 按需对获取到的帧数据进行分片,填充 rtp 包相关数据 ... // 调用 MultiFramedRTPSink::afterGettingFrame FramedSource::afterGetting(this); } }
-
调用
MultiFramedRTPSink::afterGettingFrame -> MultiFramedRTPSink::afterGettingFrame1
方法:void MultiFramedRTPSink::afterGettingFrame1(...) { if (numFrameBytesToUse == 0 && frameSize > 0) { } else { if (...) { // 发送包 sendPacketIfNecessary(); } else { } } }
-
调用
MultiFramedRTPSink::sendPacketIfNecessary
方法:void MultiFramedRTPSink::sendPacketIfNecessary() { ... // 发送 rtp 包 fRTPInterface.sendPacket(fOutBuf->packet(), fOutBuf->curPacketSize()) ... if (fNoFramesLeft) { } else { // 调度下一个发送任务 nextTask() = envir().taskScheduler().scheduleDelayedTask(uSecondsToGo, (TaskFunc*)sendNext, this); } }
-
调用
MultiFramedRTPSink::sendNext
方法:void MultiFramedRTPSink::sendNext(void* firstArg) { MultiFramedRTPSink* sink = (MultiFramedRTPSink*)firstArg; // 跳转到第三步 sink->buildAndSendPacket(False); }