LibRTMP优化之调整输出块大小
1. 为什么要调整输出块大小
首先在RTMP_Connect0函数中LibRTMP是关闭了Nagle算法这个TCP选项的,为了实时性这样做是好的,但是要注意到LibRTMP的结构体RTMP的成员是有m_outChunkSize,并且在RTMP_Init函数中被初始化了默认值128,然后整个LibRTMP代码没有改变m_outChunkSize的接口函数,内部也没有改变m_outChunkSize的实现逻辑,也没有发送改变块大小的消息给流媒体服务器的代码逻辑,关闭Nagle加如此小的块大小会导致很多小包,而以太网的MTU是1500,这样如果用在播放客户端由于主要是接收媒体流到也没有什么,但是如果用在发布媒体流的推流客户端网络效率就太低了,并且IP小包太多还会引起流媒体的服务器软中断升高,导致内核占用的CPU过高。m_outChunkSize在发送给流媒体服务器消息会用于分块,所以从这个方面来说LibRTMP还是部分支持改变块大小的,这部分逻辑实现不需要任何改变。
2. 调整输出块大小的函数
static int
ChangeChunkSize(RTMP *r,int outChunkSize)
{
RTMPPacket packet;
char pbuf[RTMP_MAX_HEADER_SIZE + 4];
packet.m_nBytesRead = 0;
packet.m_body = pbuf + RTMP_MAX_HEADER_SIZE;
packet.m_packetType = RTMP_PACKET_TYPE_CHUNK_SIZE;
packet.m_nChannel = 0x04;
packet.m_headerType = RTMP_PACKET_SIZE_LARGE;
packet.m_nTimeStamp = 0;
packet.m_nInfoField2 = 0;
packet.m_hasAbsTimestamp = 0;
packet.m_nBodySize = 4;
r->m_outChunkSize = outChunkSize;
r->m_outChunkSize = htonl(r->m_outChunkSize);
memcpy(packet.m_body, &r->m_outChunkSize, 4);
r->m_outChunkSize = ntohl(r->m_outChunkSize);
return RTMP_SendPacket(r, &packet, TRUE);
}
注1:RTMP协议的消息类型01(RTMP_PACKET_TYPE_CHUNK_SIZE宏的值)就是用于改变输出块大小的消息类型,结合MTU
注2:outChunkSize大小可以选择1500-20(IP头)-20(TCP头)=1460,考虑到IP头、TCP头有扩展选项,加之PPPoE,为保证起见可选为1360,也可以设为大于MTU的其它值,不过这样的话就会出现IP分片了,也不是好习惯。
注3:每当调用本函数后就顺便修改了RTMP的成员变量m_outChunkSize,以保持与服务器收到的一致。
3. 调用调整输出块大小的函数的时机
随时可以调整,只不过在调用ChangeChunkSize函数后,要注意到这个函数内部已经改变了RTMP的成员变量m_outChunkSize,这样在调用这个函数之后的所有发给流媒体服务器的消息要以这个块大小来分块,由于TCP的有序性,服务器在收到该改变块大小的消息后也会以此块大小来解析后序的所有消息,由于播放客户端主要是拉流,播放端需要传给服务器的数据不多,可以不修改,基于此可以在收到connect的响应后的处理逻辑中调用ChangeChunkSize函数,具体如下(HandleInvoke函数中部分代码):
if (r->Link.protocol & RTMP_FEATURE_WRITE)
{
ChangeChunkSize(r, 1360);//若不改拉流时的输出块大小在这里调用ChangeChunkSize
SendReleaseStream(r);
SendFCPublish(r);
}
else
{
RTMP_SendServerBW(r);
RTMP_SendCtrl(r, 3, 0, 300);
}
//ChangeChunkSize(r,1360);//若推、拉流时的输出块大小都改变在这里调用ChangeChunkSize
4. 调整输出块大小带来的变化
- 主要用于发布媒体的源流媒体服务器CPU下降10%
- 通过调整流媒体服务器的输出块大小与媒体流发布客户端一致,流媒体不再需要分块了,而是可以直接转发,这样也会节省一定CPU
- 每一路媒体流流量下降15%
5 音频小包如何处理
对于44.1KHZ双声音,对于采集周期为2048个样本的音频数据通过AAC+SBR音频编码后大小在100到300字节之间结合实时性,有两个处理策略,1 小包就小了,为了实时也就这样了,必竟音频数据量不大 2 RTMP本身是基于RTMP块流协议的,可以在应用层将音频块与视频块合包,当接近MTU时才通过socket 发送给流媒体服务器。
LibRTMP优化之调整输出块大小的更多相关文章
- 调整ESX的VMFS磁盘格式的块大小,让单个虚拟磁盘支持更大容量
调整ESX的VMFS磁盘格式的块大小,让单个虚拟磁盘支持更大容量 前因:客户搭建了VMware ESX企业版的测试平台:有一天接到一个需求,是测试数据库的,需要一个300G的磁盘. 解决过程: 1.按 ...
- hive优化之调整mapreduce数目
一.调整hive作业中的map数 1.通常情况下,作业会通过input的目录产生一个或者多个map任务.主要的决定因素有: input的文件总个数,input的文件大小,集群设置的文件块大小(目前为1 ...
- SQLSERVER复制优化之一《改变包大小》
SQLSERVER复制优化之一<改变包大小> 自从搭了复制之后以为可以安枕无忧了,谁不知问题接踵而来 这次遇到的问题是丢包,不知道情况的读者可以先看一下我之前写的一篇<SQLSERV ...
- SQLSERVER复制优化之一《减少包大小》
原文:SQLSERVER复制优化之一<减少包大小> SQLSERVER复制优化之一<减少包大小> 自从搭了复制之后以为可以安枕无忧了,谁不知问题接踵而来 这次遇到的问题是丢包, ...
- HDFS概述(2)————Block块大小设置
以下内容转自:http://blog.csdn.net/samhacker/article/details/23089157?utm_source=tuicool&utm_medium=ref ...
- Kafka集群优化篇-调整broker的堆内存(heap)案例实操
Kafka集群优化篇-调整broker的堆内存(heap)案例实操 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.查看kafka集群的broker的堆内存使用情况 1>. ...
- Linux下调整ext3分区大小【转】
本文转载自:https://blog.csdn.net/cruise_h/article/details/22403529 本文讨论如何再不丢失数据的情况下调整已有ext3分区的大小,包括: 压缩已有 ...
- Linux系统之更改默认块大小
查看操作系统块大小:#tune2fs -l /dev/sda1 |grep 'Block size' ( tune2fs -l /dev/sda1可以查看更多相关文件 ...
- 调整swap分区大小-Linux下安装Oracle时报swap不够解决方法
调整swap分区大小 方法一:如果磁盘有剩余的空间,用分区工具新建一个swap分区.并写到/etc/fstab里面.再 #swapon -a方法二:可以用一个文件做交换分区. su root cd / ...
随机推荐
- FormsCookieName保存登录用户名的使用
一,写一个类来实现 using System; using System.Collections.Generic; using System.Linq; using System.Web; using ...
- laravel5 MAC is invalid
如果本机的环境更换过,项目中用来加密Crypt组件中的参数会变更. 如果出现这个问题,得更换数据库中加密后的变量 stackoverflow上找到的解决方法都是 composer dump-autol ...
- cocos2d-x中的init,onEnter,onExit......
CCNode的init()方法和onEnter()方法: 一.调用顺序显示FirstScene时: FirstLayer::initFirstLayer::onEnterFirstLayer::onE ...
- Java资源大全中文版
awesome-java-cn 是 Java 资源大全的中文版,包括开发库.开发工具.网站.博客等,将由伯乐在线持续更新. https://github.com/jobbole/awesome-jav ...
- MVC网站后台分离
1.新建一个项目TestAdmin项目类型随便选一个,待会删掉,因为这里我只需要解决方案名称 [项目存放于F盘 F:\TestAdmin] 2.新建一个 ZGJ.Web 的前台MVC项目,将开 ...
- github本地库及clone常用命令
新建本地库 1. cd d: 2. mkdir git 3. cd git 4. git init 5. git remote add origin git@github.com:swportal/ ...
- python 学习 异常处理
异常处理实例 while True: num1 = input('num1:') num2 = input('num2:') try: num1 = int(num1) num2 = int(num2 ...
- angular中的jsonp记录
angular的正常机制采用引入$http服务的形式进行 get post等的访问.但是在跨域访问的时候就需要采用jsonp了. 不废话,直接上示例和引用原文地址: 比如访问地址为 http://ur ...
- Android Studio Gradle更新的解决办法
环境: Win7_64旗舰版.Android Studio2.1.1 问题描述: 在打开Android Studio项目的时候,会下载项目对应版本的gradle,由于是国外网站导致更新较慢,该版本是在 ...
- Restaurant & Cooking Starter Kit v1.2.1
项目: using UnityEngine; using System.Collections; namespace VoidGame { public class Constant : MonoBe ...