基于LIVE555的RTSP QoS实现

如何从OnDemandServerMediaSubsession类以及继承类对象中获取RTCP信息(句柄)

OnDemandServerMediaSubsession.cpp void StreamState::startPlaying函数中添加:

fRTCPInstance->setRRHandler(fMaster.fRRHandlerTask, fMaster.fRRHandlerClientData);

OnDemandServerMediaSubsession.hh 中OnDemandServerMediaSubsession添加两个成员:

 TaskFunc* fRRHandlerTask;
 void* fRRHandlerClientData;

以及成员函数

setRTCPRRPacketHandler(TaskFunc* handler, void* clientData) {
  fRRHandlerTask = handler;
  fRRHandlerClientData = clientData;
}

创建CamServerMediaSubsession 对象时,设置回调。(CamServerMediaSubsession 是继承于 OnDemandServerMediaSubsession,重写createNewStreamSource和createNewRTPSink即可)

CamServerMediaSubsession   *sub = CamServerMediaSubsession::createNew(*env, inputDevice, &device);
...
sub->setRTCPRRPacketHandler(RTCPRRHandler, (void *)sub);
...

函调函数中获取RTCP RR信息

void RTCPRRHandler(void* clientData)
{
    using namespace CamStream;
    CamServerMediaSubsession *sub = (CamServerMediaSubsession *)clientData;
    RTPSink *sink = sub->get_rtp_sink();
    if (!sink) {
        std::cout<<"unable to get sink obj, not ready"<<std::endl;
        return;
    }
    bool ignore_firstRR = true;

    RTPTransmissionStatsDB& transmissionStats = sink->transmissionStatsDB();
    RTPTransmissionStatsDB::Iterator iter(transmissionStats);
    RTPTransmissionStats* substat;

    while ((substat = iter.next()) != NULL) {
        auto cam = sub->get_cam_instance();
        auto jitter = substat->jitter();
        auto loss_ratio = ((float)substat->packetLossRatio()/256)*100;   // %
        auto rtt = (int)(((float)substat->roundTripDelay()/65536)*1000);  //ms
        auto last_bitrate = cam->get_bitrate();

        std::cout<<"SSRC "<<substat->SSRC()
            <<" RTT "<<rtt<<" ms"
            <<" jitter "<<jitter
            <<" loss "<<(int)loss_ratio<<"%"<<std::endl;
  } }

最后,根据丢帧率以及RTTD等信息,我们可以调整视频源的码率,实现QoS。

关于CamServerMediaSubsession的实现(实现下面两个函数,就可以蒋H264视频流转为RTP传输流,从而实现RTSP服务器) 

  /*source */
  FramedSource* CamServerMediaSubsession::createNewStreamSource(unsigned clientSessionId, unsigned& estBitrate) { estBitrate = static_cast<unsigned int>(this->bit_rate_); FramedSource *source = replicator_->createStreamReplica(); //H264VideoStreamDiscreteFramer的输入是离散的NALU //H264VideoStreamFramer的输入是stream bit流 FramedSource *h264_source = H264VideoStreamDiscreteFramer::createNew(envir(), source); return h264_source; } /*sink */ RTPSink* CamServerMediaSubsession::createNewRTPSink(Groupsock* rtpGroupsock, unsigned char rtpPayloadTypeIfDynamic, FramedSource* inputSource) { auto sink = H264VideoRTPSink::createNew(envir(), rtpGroupsock, rtpPayloadTypeIfDynamic, sps_nal_, sps_nal_size_, pps_nal_, pps_nal_size_); return sink; }

总结,上面的实现修改了live555源码,官方推荐的方式是通过继承现有类重写方法来实现,不过代码看了半天没头绪,有知道怎么弄的告诉我声(vslinux@qq.com)

原文地址:https://www.cnblogs.com/rayfloyd/p/11720642.html