• 嵌入式流媒体音视频服务器EasyIPCamera中live555发送性能优化点


    EasyIPCamera流媒体服务器

    今年EasyDarwin团队在给国内某最大的金融安防公司做技术咨询的时候,开发了一款适用于嵌入式IPCamera、NVR的RTSP流媒体服务器:EasyIPCamera,EasyIPCamera的核心是基于live555进行封装的,外围增加对live555 RTSPServer的调用接口,更加方便海思等安防芯片进行RTSPServer服务的建立,EasyIPCamera在海思3156A芯片上的性能经过我们半年多的调试,目前已经可以稳定在4路1080P并发:

    • TCP/UDP 方式分别连接3路下,1080P 4M 定码率,音频格式G711(64K)G726(16K 24K 32K 40K)AAC(64K 96K 128K)都没问题;
    • TCP/UDP 方式分别连接4路下,1080P 4M 定码率,音频格式G711(64K)G726(16K 24K 32K 40K)AAC(64K 96K 128K)都没问题;

      EasyIPCamera嵌入式流媒体服务器

    live555网络发送优化

    在live555的RTP发送类MultiFramedRTPSink中的sendPacketIfNecessary()函数中,我们改造原有的live555发送过程,增加了live555在嵌入式arm中网络发送的速度,提升了嵌入式RTSPServer流媒体服务器的发送性能,具体代码:

    void MultiFramedRTPSink::sendPacketIfNecessary() {
      if (fNumFramesUsedSoFar > 0) {
        // Send the packet:
    #ifdef TEST_LOSS
        if ((our_random()%10) != 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
      }
    
      if (fOutBuf->haveOverflowData()
          && fOutBuf->totalBytesAvailable() > fOutBuf->totalBufferSize()/2) {
        // Efficiency hack: Reset the packet start pointer to just in front of
        // the overflow data (allowing for the RTP header and special headers),
        // so that we probably don't have to "memmove()" the overflow data
        // into place when building the next packet:
        unsigned newPacketStart = fOutBuf->curPacketSize()
          - (rtpHeaderSize + fSpecialHeaderSize + frameSpecificHeaderSize());
        fOutBuf->adjustPacketStart(newPacketStart);
      } else {
        // Normal case: Reset the packet start pointer back to the start:
        fOutBuf->resetPacketStart();
      }
      fOutBuf->resetOffset();
      fNumFramesUsedSoFar = 0;
    
      if (fNoFramesLeft) {
        // We're done:
        onSourceClosure();
      } else {
    #if 0   //原有方法是重新计算一个Task时间,让live555下一次循环再将未发送完的包继续发送完成
        // We have more frames left to send.  Figure out when the next frame
        // is due to start playing, then make sure that we wait this long before
        // sending the next packet.
        struct timeval timeNow;
        gettimeofday(&timeNow, NULL);
        int secsDiff = fNextSendTime.tv_sec - timeNow.tv_sec;
        int64_t uSecondsToGo = secsDiff*1000000 + (fNextSendTime.tv_usec - timeNow.tv_usec);
        if (uSecondsToGo < 0 || secsDiff < 0) { // sanity check: Make sure that the time-to-delay is non-negative:
          uSecondsToGo = 0;
        }
    
        // Delay this amount of time:
        //nextTask() = envir().taskScheduler().scheduleDelayedTask(uSecondsToGo, (TaskFunc*)sendNext, this);
    #else   //现有方法是不经过循环,直接将未发送的包全部发完再进行live555的eventLoop循环
        sendNext(this);
    #endif
      }
    }

    获取更多信息

    邮件:support@easydarwin.org

    WEB:www.EasyDarwin.org

    Copyright © EasyDarwin.org 2012-2016

    EasyDarwin

  • 相关阅读:
    linux 下高精度时间
    pstack
    linux 调试常用命令
    定位 UNIX 上常见问题的经验总结
    在 POSIX 线程编程中避免内存泄漏
    ulimit
    设计模式之迭代器模式(PHP实现)
    设计模式之责任链模式(php实现)
    设计模式之代理模式(php实现)
    设计模式之享元模式(PHP实现)
  • 原文地址:https://www.cnblogs.com/babosa/p/5904610.html
Copyright © 2020-2023  润新知