Toybrick

标题: MPP+LIVE555推流,遇到码流较大时出现卡死 [打印本页]

作者: appleUncle    时间: 2020-7-29 17:12
标题: MPP+LIVE555推流,遇到码流较大时出现卡死
按照《RK3399Pro入门教程(10)RTSP推流介绍》做的rtsp推流,成功运行,用vlc取流可以看到。
但是当码流较大时(大概4000kpbs以上时),vlc播放就卡死了,等码流变小的时候又正常播放。
经测试,我的摄像头640X480P在户外基本上都会卡死,室内光线暗一点还好。

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

求救

作者: jefferyzhang    时间: 2020-8-4 11:49
这个问题还真没遇到过。。。。vlc可以打开统计数据看下包收到了没有,还是包收丢了。
udp协议只管发,不管你对方收没收到的,你这情况一般是网络丢包了
作者: appleUncle    时间: 2020-8-4 16:53
本帖最后由 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. }
复制代码









欢迎光临 Toybrick (https://t.rock-chips.com/) Powered by Discuz! X3.3