Live555 RTP 打包以及发送

本文详细描述了如何在Live555框架中,通过OnDemandServerMediaSubsession调用一系列方法,如H264or5VideoRTPSink的continuePlaying,实现H264和H265视频流的RTP打包并发送给客户端的过程。
摘要由CSDN通过智能技术生成

Live555 RTP 打包以及发送

H264 H265 为例

  1. 在收到客户端播放请求后,由 OnDemandServerMediaSubsession 调用 MediaSink::startPlaying 方法:

    Boolean MediaSink::startPlaying(MediaSource& source, afterPlayingFunc* afterFunc,
                                    void* afterClientData)
    {
        ...
    
        // 赋值 fSource,一般为 H264or5VideoStreamDiscreteFramer
        fSource = (FramedSource*)&source;
    
        fAfterFunc = afterFunc;
        fAfterClientData = afterClientData;
        // 虚函数
        return continuePlaying();
    }
    
  2. 调用 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();
    }
    
  3. 调用 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);
        }
    }
    
  4. 调用 FramedSource::getNextFrame 方法:

    void FramedSource::getNextFrame(...)
    {
        ...
        // 虚函数
        doGetNextFrame();
    }
    
  5. 调用 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);
        }
    }
    
  6. 调用 MultiFramedRTPSink::afterGettingFrame -> MultiFramedRTPSink::afterGettingFrame1 方法:

    void MultiFramedRTPSink::afterGettingFrame1(...)
    {
        if (numFrameBytesToUse == 0 && frameSize > 0) {
        } else {
            if (...) {
                // 发送包
                sendPacketIfNecessary();
            } else {
            }
        }
    }
    
  7. 调用 MultiFramedRTPSink::sendPacketIfNecessary 方法:

    void MultiFramedRTPSink::sendPacketIfNecessary()
    {
        ...
        // 发送 rtp 包
        fRTPInterface.sendPacket(fOutBuf->packet(), fOutBuf->curPacketSize())
        ...
    
        if (fNoFramesLeft) {
        } else {
            // 调度下一个发送任务
            nextTask() = envir().taskScheduler().scheduleDelayedTask(uSecondsToGo, (TaskFunc*)sendNext, this);
        }
    }
    
  8. 调用 MultiFramedRTPSink::sendNext 方法:

    void MultiFramedRTPSink::sendNext(void* firstArg)
    {
        MultiFramedRTPSink* sink = (MultiFramedRTPSink*)firstArg;
        // 跳转到第三步
        sink->buildAndSendPacket(False);
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

专注的罗哈哈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值