zoukankan      html  css  js  c++  java
  • 嵌入式流媒体音视频服务器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

  • 相关阅读:
    fastreport 中文汉字换行
    Delphi调用自身onchange事件,如提示缺少声明object时,不能调用,用此方法!
    delphi 截取某个字符之前的字段,,如 1234567-9,要分别得到
    delphi 四舍五入取整函数
    SQLServer2008不允许保存更改错误解决办法_不允许保存更改、不允许修改表解决_百度经验
    关于APP的架构实现!微博和知乎中的 feed 流是如何实现的?
    win2003没有OLE DB Provider for SQLServer驱动,可安装sqlserver2000或者安装MDAC2.6,适用于winxp、win2003
    SQLServer2000安装失败,[ODBC 驱动程序管理器]未发现数据源,详细信息请查看日志文件 sql2000 [Microsoft][ODBC 驱动程序管理器] 未发现数据源,参见sqlstp.org,直接退出
    sql server2008R2 密钥
    CentOS7安装memcached
  • 原文地址:https://www.cnblogs.com/babosa/p/5904610.html
Copyright © 2011-2022 走看看