[live555]客户端优化 丢包问题

背景描述:

在流媒体传输的时候,I P P P B B P I P B B I 类似的一帧传输,但是经常会随机出现丢包的情况,如何改善用户体验,就显的特别重要
其中花屏的体验十分差,花屏是因为 I帧中间某一帧丢了包导致的问题,因为每一帧之间的变化和差距不是很大,所以最好的办法就是直接跳到下一个I帧 ,或者通过RTCP 请求丢失的包,重新排序解码

这篇优化,采用第一种,环境在live555中

模拟丢包环境

在live555 中rtspserver 已经默认有一个丢包的 宏开关

MultiFramedRTPSink::sendPacketIfNecessary(){
    // Send the packet:
#ifdef TEST_LOSS
    if ((our_random()%350) != 0) // simulate 10% packet loss #####
#endif
      if (!fRTPInterface.sendPacket(fOutBuf->packet(), fOutBuf->curPacketSize())) {
	// if failure handler has been specified, call it
	if (fOnSendErrorFunc != NULL) (*fOnSendErrorFunc)(fOnSendErrorData);
      }
    ++fPacketCount;
    fTotalOctetCount += fOutBuf->curPacketSize();
    fOctetCount += fOutBuf->curPacketSize()
      - rtpHeaderSize - fSpecialHeaderSize - fTotalFrameSpecificHeaderSizes;

    ++fSeqNo; // for next time
//.........
}

define TEST_LOSS 修改 被取余的数 我改为350 ,改的太小丢包频率太高会导致一直卡顿

客户端优化

因为rtsp server 发包会丢包,那么客户端就需要丢弃已经丢包的帧,直到系一个I帧到来
MultiFramedRTPSource::doGetNextFrame1() 对 获取的每一个包组成一个帧,并且传递给客户端解码播放

while (fNeedDelivery) {

BufferedPacket* nextPacket
      = fReorderingBuffer->getNextCompletedPacket(packetLossPrecededThis);//获取每个包
processSpecialHeader(nextPacket, specialHeaderSize);//处理 FU-A FU-B分包情况

nextPacket->use(fTo, fMaxSize, frameSize, fNumTruncatedBytes,
		    fCurPacketRTPSeqNum, fCurPacketRTPTimestamp,
		    fPresentationTime, fCurPacketHasBeenSynchronizedUsingRTCP,
		    fCurPacketMarkerBit); //将包组成一帧

fReorderingBuffer->releaseUsedPacket(nextPacket); //统计期望的包rtpseqnum

}

主要是这四个方法

fCurrentPacketBeginsFrame 用于分包中,为true 就是FU—A start 分包的开始,false 就不是分包开始
packetLossPrecededThis true表示 丢包开始的那一个帧
fPacketLossInFragmentedFrame true 表示 获取的包 ,还在已经丢包的那个帧中

举例 I P P P B B P I P B B I 中
第一个P帧丢包了,live555 默认会帮我们丢弃包,然后根据fNeedDelivery 继续获取下一包 知道出现下一帧P开始,fPacketLossInFragmentedFrame 为false

    if (fPacketLossInFragmentedFrame) {
      // This packet is unusable; reject it:
      fReorderingBuffer->releaseUsedPacket(nextPacket);
      fNeedDelivery = True;
      continue;
    }

第二个P帧开始,通过nextPacket->use 组成完整一帧,那么就需要判断 当前帧 nal_unit_type 是不是5 即I帧,不然也会被丢弃,所以这个P帧会被抛弃

通过读取RTP header 和 nalu header 方式 获取nal_unit_type

      unsigned char* headerStart = nextPacket->data();
      unsigned char type = (headerStart[0]&0x1F);
      if(28==type||29==type){
          nal_unit_type = (headerStart[1]&0x1F);
      }else{
          nal_unit_type = type;
      }

根据是不是 nal_unit_type = 5 决定是否冻屏直到下一个I帧过来

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值