Toybrick

MPP+LIVE555推流,遇到码流较大时出现卡死

appleUncle

中级会员

积分
440
楼主
发表于 2020-7-29 17:12:39    查看: 10301|回复: 2 | [复制链接]    打印 | 只看该作者
按照《RK3399Pro入门教程(10)RTSP推流介绍》做的rtsp推流,成功运行,用vlc取流可以看到。
但是当码流较大时(大概4000kpbs以上时),vlc播放就卡死了,等码流变小的时候又正常播放。
经测试,我的摄像头640X480P在户外基本上都会卡死,室内光线暗一点还好。

一开始我感觉是live555缓冲不够的问题,
我按照live5555调优博客,对live555源码做了各种增加buffer容量,都没有效果。
现在不知道是mpp的问题还是RK3399Pro入门教程(10)RTSP推流介绍博文里面推流代码有问题。

求救
回复

使用道具 举报

jefferyzhang

版主

积分
13580
沙发
发表于 2020-8-4 11:49:51 | 只看该作者
这个问题还真没遇到过。。。。vlc可以打开统计数据看下包收到了没有,还是包收丢了。
udp协议只管发,不管你对方收没收到的,你这情况一般是网络丢包了
回复

使用道具 举报

appleUncle

中级会员

积分
440
板凳
 楼主| 发表于 2020-8-4 16:53:27 | 只看该作者
本帖最后由 appleUncle 于 2020-8-5 09:13 编辑

自己解决了,给后人参考下:
看了好久的live555源码,最后发现live555只需要改下bank_size就差不多完美了,没啥问题
bug在于RK3399Pro入门教程(10)RTSP推流介绍给的例子StreamEncoder.cpp里面有坑啊。
  1. unsigned StreamEncoder::maxFrameSize() const {
  2.           return 80 * 1024;
  3. }
复制代码
这段代码限制了单帧最大为80k,往fOutBuffer里面填充帧的时候进来的帧大于80K且fOutBufferSize又大于80k但是小余进来的帧size的时候神奇的一幕出现了,码流大到一定值时客户端卡死,直到码流变小。
  1. void StreamEncoder::copy_to_outputbuffer(void)
  2. {
  3.               memmove(fOutputBuffer, dstbuf, dstsize);
  4.               fNumValidDataBytes += dstsize;
  5.               fOutputBuffer += dstsize;
  6.               fTotOfFrameToSend++;
  7.         if(dstbuf != NULL)
  8.                 free(dstbuf);
  9. }

  10. void StreamEncoder::continueReadProcessing1(unsigned frameSize,unsigned numTruncatedBytes,
  11.                                           struct timeval presentationTime,
  12.                                           unsigned durationInMicroseconds){

  13.           fNumTruncatedBytes = numTruncatedBytes;
  14.           fPresentationTime = presentationTime;
  15.           fDurationInMicroseconds = durationInMicroseconds;
  16.           encoder_to_h264();
  17.               if(fNumValidDataBytes+dstsize<fOutputBufferSize && fTotOfFrameToSend<fMaxOfFrameToSend)
  18.               {
  19.                 copy_to_outputbuffer();               
  20.               }
  21.             
  22.         fFrameSize = fNumValidDataBytes;
  23.         gettimeofday(&fPresentationTime, NULL);
  24.         reset();
  25.               FramedSource::afterGetting(this);         
  26. }
复制代码

上面的代码可以看到,这种情况出现的时候fOutBuffer一直不会更新,live555那边一直没有读到新的帧,vlc播放器就一直卡住!!直到进来了一帧小余80k的,并且fOutBufferSize也小余了80k,才会恢复播放!!
我就震惊了。
live555源码有些看不懂,但是我猜它里面是设置了2个buffer做pingpong的,要把其中一个buffer里面塞帧直到塞不下为止才会叫sink把这个buffer里的帧全部发送出去,然后去填另一个buffer。
而码流是不均匀的,live555判断啥时候是塞不下了,就是靠判断fOutBufferSize是否小余maxFrameSize()


解决方法是把最大帧size改大点
  1. unsigned StreamEncoder::maxFrameSize() const {
  2.           return 180 * 1024;
  3. }
复制代码




回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

产品中心 购买渠道 开源社区 Wiki教程 资料下载 关于Toybrick


快速回复 返回顶部 返回列表