原文地址:https://blog.csdn.net/mediapro/article/details/105790057,感谢大神;
SRT传输库评估报告(V1.0.0)
www.mediapro.cc
SRT是Haivision开源的一套集FEC前向纠错、ACK、NAK选择性重传、JitterBuff、拥塞控制、传输安全保障等技术于一体的实时传输解决方案。方案基于UDP协议进行扩展,目前SRT在广电领域获得了不错的应用,因其弱网抵抗以及较好的实时性,必将取代基于TCP的RTMP伪直播方案。SRT方案使用C++开发,提供C风格接口,依赖OpenSSL\Pthreads库,官方编译脚本支持Windows、Linux、Mac\IOS系统,可自行参考移植到Android。
本文对SRT封装库SD-SRT进行测试,该封装库主要针对音视频领域需求,进行了帧码流拆分合并、丢包冻结、自动重连、EPoll收发、状态回调等功能的扩展,并对外提供简洁易用的接口,可用于内网点对点或者公网CS架构,其接口说明见附录。
希望通过本测试,加深对于SRT的传输特征、参数配置、适用场合的认识。
从官方声明可见,SRT具有以下特点:
SRT利用Full ACK完成RTT的计算、反馈接收端的接收缓存情况等。
SRT基于UDP,在UDP基础上增加16字节头部,其包结构如下:
默认情况,SRT按MTU 1500字节进行配置,去除20字节IP头、8字节UDP头、16字节SRT头后,支持负载可达到1456字节,又因其保持对TS容器的友好性,默认限定负载长度为188*7=1316字节。(Windows平台为了网络性能达到最优,建议用户设置UDP负载小于1024,此时用户可设置SRT最大长度不超过1024 - 16)。
SRT版本说明
本次测试使用SRT版本:1.4.1-152-a4ff6ab
网络环境说明
为了保证测试环境一致性和可重现性,我们将在较好的网络环境下借助第三方弱网模拟工具Clumsy,模拟各类网络情况。
Clumsy是一款小巧而功能强大的开源弱网模拟工具,支持windows平台,可用于模拟:丢包(Drop)、延时(Lag)、重复(Duplicate)、乱序(Out of order)、篡改(Tamper)、抖动(Throttle)等。其项目地址:http://jagt.github.io/clumsy/cn/index.html
图3 Clumsy对所有发送的包按10%进行丢包处理示意
如果要对发往指定某IP的UDP包进行丢包,可将Filtering条件设置为:
udp and (ip.DstAddr == 192.168.31.33)
本次测试我们使用两台PC机器,二者接入到同一个WIFI网络,信号强度充足,其中一台作为发送端并在其上执行Clumsy,另一台作为接收端。
测试DEMO说明
本次测试使用windows平台下的桌面投屏DEMO,DEMO分为发送端和接收端,发送端采集自身桌面和扬声器音频,压缩后通过SD-SRT 点对点SDK发往接收端,后者解码并渲染输出,从而实现屏幕共享功能。在此场景下,DEMO接收端将充SRT服务端,DEMO发送端充当SRT客户端。
A、接收端
该组DEMO的功能与投屏类应用类似,我们首先启动接收端DEMO。进入UDP-AVClient-ScreenPlay文件夹,双击启动AVClient.exe即可。
图4 接收端DEMO启动界面
接收端启动后,将显示其投屏码(IP:PORT),发送端可以使用该投屏码进行投屏。
当发送端码流到来时,接收端将使用一个新的窗口“Remote Video”显示远端画面,如下图所示:
图5 接收端独立的窗口展示远端画面
注意:“Remote Video”窗口是一个全屏窗口,用户可以自行在底部任务栏切换。当远端停止音视频传输时,该窗口内容无更新。该窗口不会响应鼠标事件,只能底部切换。
接收端文件夹下的AVClient.ini文件为其配置文件,对配置文件的修改需要重启客户端方能生效。配置文件包括如下几项:
图6 接收端配置文件
UseFreezeFrameWhenLost 表示当出现视频丢包无法恢复时,为了不展现出花屏而将画面冻结,直至完整的关键帧到来再继续送显。该值一般设置为1开启。
BufferTime表示接收端Jitter buff缓存毫秒数,对应SRT的SRTO_RCVLATENCY参数。为了抵抗网络传输、丢包重传等行为带来的抖动,SRT需要设置接收端缓存以保障输出的流畅性(可以在发送端和接收端中任意一方或双方设置,实际缓存时间取二者中的较大值),SRT的默认缓存时间为120ms,官方建议设置为RTT*4,最小值不低于120ms。因为流畅性和实时性(时延)是一对矛盾的指标,Jitter buff必然将引入一定延时。在后面的测试过程中,将会对BuffTime进行调整,查看调整前后的效果对比。
B、发送端
发送端为UDP-AVClient-ScreenCap目录下的AVClient.exe,在启动前我们需要先对其进行配置,配置文件为AVClient.ini
图7 发送端配置文件
VideoBitrate表示发送端使用的视频编码码率,单位kbps,设置为2000即表示2Mbps
VideoTransWidth表示发送端使用的视频编码宽度,VideoTransHeight表示视频编码高度,ViceFrameRate表示视频编码帧率(本程序使用Direct桌面采集,在性能较低的机器上可能采集帧率无法达到30fps,编码帧率仍然会按30fps配置编码器)
EncodeQualityLevel0to7表示当采用X264软编码时,使用的preset级别,0表示ultrafast,1表示superfast,2表示veryfast,3表示faster,4表示fast,5表示medium,6表示slow,7表示slower。等级越高同等码率下的图像质量越好,但CPU占用也越高,请根据自身机器配置而定,建议设置为1。当使用X264软编码时,使用5秒一个IDR帧。当使用硬编码时,使用3秒一个IDR帧。
HWEnable表示是否启用硬编码,程序支持Intel QSV硬编码和Nvidia硬编码,相比X264能获得更低的CPU占用。不过硬编码的缺点是灵活性不足,无法支持传输层IDR帧请求机制。
SrtMaxBitrateFactor表示设置SRT最大码率MAXBW为编码码率VideoBitrate的几倍,我们称之为峰值码率容忍度。比如该值为2.0,VideoBitrate为2000时,则将设置SRT的SRTO_MAXBW为2.0*2000 kbps(实际内部会转换为SRT所要求的BytePerSecond)。当设置为0.0时,SRT将不限码率。
SRT的 MAXBW对于传输性能影响较大,主要体现在两个方面,发送端将依据MAXBW调整发送数据间隔,实现Smooth发送平滑处理。另一方面,允许的MAXBW越大,短时间内允许的重传次数更多,越能提高弱网重传成功率,但也会给网络带来更大的码率波动压力。实际过程中应该根据自身编码器码率及其波动范围、信道带宽来综合权衡,设置合理的MAXBW。
启动发送端后进入如下界面,输入接收端展示的投屏码(IP:PORT)即可开始SRT连接。
图8 发送端启动界面
连接后,客户端将进入下图所示的待共享屏幕状态。可以点击主界面启动按钮或者使用悬浮球来启动桌面共享。启动后,接收端就能看到发送端的桌面并能听到发送端扬声器播放的音乐了。
图9 发送端开始共享桌面
说明:同市面上各大实时视频服务商一样,DEMO也提供丢帧冻结机制,这样用户无法察觉到丢帧带来的花屏,从而获得更好的用户体验。因此本次测试中,丢包最终将体现为画面卡顿。
评测项:流畅度
关于流畅度,我们将分为以下几个级别:
评测项:延时
延时计算方式:在发送端打开毫秒精度秒表,接收端将看到秒表值,使用手机对二者屏幕拍照,计算二者差值得到总延时。整个系统中,延时主要有非传输层延时和传输层延时两部分组成。非传输层延时包括:采集、编码、解码、渲染引入的延时,本DEMO实际采集帧率无法达到恒定30fps,对整体延时稍有影响。
传输层延时主要由接收端JitterBuff引入,后者用于消除网络因丢包重传、网络本身带来的抖动。JitterBuff越大,播发端缓存的数据越多。
需要说明的是延时指标和流畅性指标往往是一对矛盾,播发端缓存的数据越多,流畅性越好,延时也越大,反之若缓存的数据较少或者不缓存,则延时更低,但与此同时它的弱网抵抗力越差,重传恢复成功率越低进而影响流畅性。
上图是SRT的Too-Late Packet Drop机制描述,虽然为3号包的丢失发起了NAK请求,但发送端在收到NAK请求后判断3号包即便发出也已经超出了其接收端的dead line,已经错过了它的输出时间,而放弃重传。同样即便3号包被重传,接收端也会因其错过输出时间而直接丢弃之。
评测项:清晰度
DEMO图像质量与传输层无紧密关系,主要由用户指定的编码分辨率、码率、桌面画面内容决定。注:帧率降低时,帧间相关性降低,运动估计残差更大,同等码率下编码质量会稍弱。
为了研究接收端缓存时间、发送端峰值码率容忍度对于丢包抵抗力的影响,我们设计以下测试(发送端编码码率为2Mbps,720P分辨率,X264软编码,30fps,发送端全屏播放影片《美女与野兽》,画面中等复杂度)。
A、丢包率5%,发送端峰值码率容忍度设置为2.0,接收端缓存时间依次设置为200ms、300ms、400ms、500ms,观察卡顿频率、峰值码率、延时三个指标。
接收缓存时间 |
卡顿频率 |
实际峰值/平均码率 |
实际延时 |
120ms(SRT默认值) |
约20秒卡顿一次 |
2.7Mbps/2.1Mbps |
300ms |
200ms |
约30秒卡顿一次 |
2.7Mbps/2.1Mbps |
420ms |
300ms |
约40秒卡顿一次 |
2.9Mbps/2.1Mbps |
530ms |
400ms |
约40秒卡顿一次 |
2.9Mbps/2.1Mbps |
630ms |
500ms |
约40秒卡顿一次 |
2.9Mbps/2.1Mbps |
720ms |
通过本项实验,我们发现接收端缓存时间对丢包抵抗有一定正向作用,缓存时间过短,容易在发送端放弃重传(预判超出接收端包输出时间)或者接收端收到后因超时而主动丢弃。当缓存时间达到要求后,继续增大缓存时间对丢包抵抗力无明显作用。
峰值码率容忍度 |
卡顿频率 |
实际峰值/平均码率 |
实际延时 |
3.0 |
约220秒卡顿一次 |
3.2Mbps/2.2Mbps |
720ms |
4.0 |
约240秒卡顿一次 |
3.5Mbps/2.3Mbps |
720ms |
无限制(SRT默认值) |
长时间无卡顿 |
3.6Mbps/2.3Mbps |
720ms |
通过本项实验,我们确定发送端码率峰值放得越宽,丢包抵抗力越强,这是因为短时间内可以更高频率的进行丢包重传,增加了重传次数也就提升了成功率。当我们的网络允许较大的码率波动时,非受限的MAXBW设置可以获得显著的质量提升。
丢包率 |
卡顿频率 |
实际峰值/平均码率 |
10% |
长时间无卡顿 |
3.5Mbps/2.4Mbps |
20% |
约300秒卡顿一次 |
3.5Mbps/2.5Mbps |
30% |
约30秒卡顿一次 |
4.5Mbps/2.9Mbps |
50% |
约10秒卡顿一次 |
8Mbps/4Mbps |
随着丢包率的继续上升,即便不限制码率峰值,由于缓存时间的限制,在有限的时间内重传仍然存在失败的可能,导致最终丢包卡顿。此时需要增大接收缓存时间来进一步提高丢包抵抗力。
发送端使用Clumsy 设置Duplicate发送重复率5%、12%、20%、30%,每次重复1包(Count设置为2)。发送端使用峰值码率容忍度设置为0.0(无限制),接收端使用缓存时间120ms。
5%重复包时,连续观察20分钟,画面流畅,延时稳定在300ms左右。
12%重复包时,连续观察20分钟,画面流畅,延时稳定在300ms左右。
20%重复包时,连续观察20分钟,画面流畅,延时稳定在300ms左右。
30%重复包时,连续观察20分钟,画面流畅,延时稳定在300ms左右。
可见单纯的重复包对SRT影响很小。
发送端使用Clumsy 设置Out of order发送乱序率30%。发送端使用峰值码率容忍度设置为0.0(无限制),接收端使用缓存时间依次为120ms、300ms、500ms。
缓存时间 |
卡顿频率 |
实际峰值/平均码率 |
120ms |
约100秒卡顿一次 |
3.5Mbps/2.5Mbps |
300ms |
约120秒卡顿一次 |
3.5Mbps/2.5Mbps |
500ms |
约155秒卡顿一次 |
3.5Mbps/2.5Mbps |
可见乱序包对系统影响很大,接近丢包的影响,可能系统内部的乱序容忍窗口上限较小,很多乱序当做丢包处理(SRT会根据超时迟到包的偏离间隔来更新乱序容忍窗口)。但缓存时间增大时,对乱序的恢复能力明显增加,这可能是乱序容忍窗口扩大以及重传成功率提升两方面因素导致。
发送端使用Clumsy 设置Lag发送延时50、100、200、400、600ms。
经过测试,线路延时最终会叠加到总体延时之上,测试结果符合预期。
发送端峰值码率容忍度设置为0.0(无限制),接收端使用缓存时间为120ms,进行如下实验:
发送端使用Clumsy 设置Throttle分别5%、12%、20%、30%概率抖动30ms。
测试结果:5%~30%概率30ms抖动对流畅性、延时无可感知的影响。
发送端使用Clumsy 设置Throttle 30%概率抖动100ms。
测试结果:小概率卡顿,延时增长到500ms,关闭抖动后延时仍为500ms未回归。说明SRT根据抖动情况自动增大缓存时间,避免因缓存不足而持续卡顿。
发送端峰值码率容忍度设置为0.0(无限制),接收端使用缓存时间为5ms,不开启丢包等其他弱网测试,视频卡顿频繁。也证实了官网的说法,即便网络RTT非常小,也不要修改接收端缓存时间小于默认值120ms。
本DEMO基于SD-SRT库,内部实现了自动重连机制,当物理网络断开或者丢包率过高导致SRT断开后,SD-SRT将不断尝试重连,网络恢复后将快速重连上并恢复业务。实际验证网线插拔,突发丢包率达到80%以上等场景,业务均可恢复。
SRT采用滤镜的方式引入FEC并且默认情况下关闭了FEC功能,可通过SRTO_PACKETFILTER选项设置FEC描述字符串来启用。描述字符串格式为:
"fec,cols:%d,rows:%d,layout:%s,arq:%s"
其中col用于描述2D 异或FEC的列数,rows描述行数,layout描述FEC的布局(even、staircase),arq描述FEC与NAK的结合方式。下图是一种3行6列even布局的FEC示意图,图中1~18号灰色包为媒体包,R1~R9号橙色包为冗余包,它们共同组成一个FEC Group。其中1号冗余包由1~6号媒体包异或得到,4号冗余包由1、7、13号媒体包异或得到。
2D FEC rows=3, cols=6
以上布局,冗余率为9/18=50%。
假设丢包1、2、3、4、5、6、R1、7共8个,可以由8~12 + R2恢复7号媒体包,7、13、R4恢复1号媒体包,8、14、R5恢复2号媒体包并按此规则依次恢复3、4、5、6。
假设丢包13、14、15、16、17、18、R3、R4,将无法恢复。
假设超出8个丢包,比如丢包1、2、3、4、5、6、R1、7、8,只能恢复3、4、5、6号媒体包。这种两头丢失、中间恢复的情况对于视频流用途不太大,因为视频流往往采用丢包冻结机制,一帧中任意丢包均丢弃整帧码流避免花屏。对于音频包,任何包的恢复都是有利的。两头丢失、中间恢复对于重传来说可以减少部分包的重传,但相比全部重传是否一定产生优势比较难说。(对比2D异或FEC,若采用RS FEC 50%的冗余(18 + 9),可以抵抗任意9个丢包)
以上为even布局,包的发送顺序为:1、2、3、4、5、6、R1、7、8、9、10、11、12、R2、13、R4、14、R5、15、R6、16、R7、17、R8、18、R9、R3,可见在Group的尾部形成了较为密集的数据发送(带宽增长了一倍),对网络并不友好。Staircase阶梯布局正是为了解决这一问题,通过阶梯排列可以将冗余包的发送错开,避免集中发送带来的码率波动。
值得注意的是2D FEC的冗余度是由行和列决定的,列越大抵抗连续丢包的能力越强。如果上图改成6行3列,其最多抵抗连续5个丢包。
开启FEC时,若发生丢包,FEC恢复处理将引入抖动,比如收到的媒体包和冗余包:1、3、4、5、6、7、8、R1、R2、R3,其中2号媒体包的丢失需要暂停输出,并等到R1号冗余包到来才能恢复并输出。对于2D异或FEC,为消除FEC带来的抖动,至少需要准备的延时LatencyFec为N个包的发送时长:
N = (R + (C - 1)) + 2
其中R为row行大小,C为cols列大小,N个包的发送时长与码率、帧率强相关。极端情况下假设码率比较低,1帧视频仅1个包,帧率30fps,N为30时,最小需要准备的缓存时间为1秒。
当FEC的ARQ选项配置为ALWAYS时,即只要发现丢包即刻发起NAK重传请求,则推荐的延时为max(RTT*4, LatencyFec)。当FEC的ARQ选项配置为ONREQ时,推荐的延时为RTT*4 + LatencyFec即二者之和,这是因为ONREQ模式下,需要等到确认FEC失败才发起NAK重传,确认失败的条件是当前FEC GROUP已经接收完成了仍旧无法恢复GROUP内丢失的包。
QOS-FEC-NACK方案的重传机制与SRT有所不同,QOS-FEC-NACK会根据GROUP内已检测到的丢包数目、包类型结合GROUP的冗余包数量提前预判是否需要发起重传,不需要等到下一个GROUP到来才发起重传请求,这样做的目的是尽量减少重传等待时间进而减小延时,对于已经具备媒体包恢复条件或者媒体包未丢失的情况,FEC冗余包的丢失不会触发重传,因为它们已经没有意义。
|
SRT |
QOS-FEC-NACK |
机制 |
ARQ(ACK+NACK)+ FEC |
NACK + FEC |
模式 |
Live /File/Message |
Live |
主要技术 |
发端Smooth JitterBuff 2D XOR FEC,固定冗余度 FEC作为NACK重传参考 超时时间内反复重传 NACK信令冗余防丢失 NACK主动放弃机制 带宽估计 内部传输模式(内部维护socket) OpenSSL安全 |
发端Smooth JitterBuff 1D RS FEC 自适应冗余度 FEC 视频帧边界形成大GROUP抗连续丢包抵抗力强 FEC作为NACK重传参考 仅单次重传机会 NACK预判提前发起 NACK信令冗余防丢失 NACK主动放弃机制 内部传输模式 外部传输模式 码率自适应参考信息提供 |
推荐场景 |
推荐单链路上4*RTT延时(服务器转发模式下总延时8*RTT)。适合实时性要求1秒左右的单向抗弱网直播或者RTT较小、带宽不受限但需要抵抗突发丢包的内网场合。 有望成为一些领域的标准协议。 |
推荐在实时性要求较高的互动场合使用,允许一定的丢包(体现为画面卡顿)。适合要求带宽波动比较稳定可控的场合。 对外无依赖性、轻量级、跨平台性能佳。 |
缺点 |
默认未开启FEC的情况下,弱网抵抗力重点依赖ARQ机制,总体延时偏大。 FEC为新增功能稳定性还有所欠缺,FEC未与视频帧信息结合,同样冗余度的情况下抗丢包能力弱。 |
即便放宽延时指标,也无法保证100%的接收成功率。(FEC+单次NACK重传,若重传仍然丢失或者重传超时,都将体现为最终丢包)。 为私有协议,收发双方均需集成才能互通。 |
我们测试了SRT在默认关闭FEC的场景下的弱网抵抗力,对其传输性能影响较大的两个参数(接收缓存时间、最大码率)进行了重点评估。当前SRT版本的推荐应用场景为:实时性要求1秒左右的单向抗弱网直播或者RTT较小、带宽不受限但需要抵抗突发丢包的内网场合。另外SRT提供的可靠传输文件模式和消息模式可用于改进现有TCP传输方案,提高弱网下的吞吐率。我们将进一步跟踪SRT项目的进展,待其FEC功能稳定性提升后另行评估。
https://blog.wmspanel.com/2019/06/srt-latency-maxbw-efficient-usage.html
https://blog.wmspanel.com/2020/04/srt-fec-forward-error-correction.html
http://kth.diva-portal.org/smash/get/diva2:1335907/FULLTEXT01.pdf
附录
SD-SRT封装库接口
/***
* 环境初始化,系统只需调用一次,主要用于SRT环境以及日志模块的初始化
* @param: outputPath 表示日志存放路径,支持相对路径和绝对路径,若目录不存在将自动创建
* @param: outputLevel表示日志输出的级别,只有等于或者高于该级别的日志输出到文件,取值范围参考LOG_OUTPUT_LEVEL
* @return:
*/
void SDSrtAvCom_Enviroment_Init(const char* outputPath, int outputLevel);
void SDSrtAvCom_Enviroment_Free();
/***
* 创建SrtAvCom
* @param unLogId: 日志ID,仅用于日志输出时的对象标识。
* @return: 返回模块指针,为NULL则失败
*/
void* SDSrtAvCom_Create(UINT unLogId);
/***
* 销毁SrtAvCom,使用者应该做好与其他API之间的互斥保护
* @param pRtp_avcom: 模块指针
* @return:
*/
void SDSrtAvCom_Delete(void* pRtp_avcom);
/***
* 开始工作
* @param strLocalIP: 本地IP地址,允许为NULL,为非NULL时将绑定到该IP(网卡)。
* @param shLocalPort: 本地通信端口(该端口用于音频,视频端口号将在此基础上加1),对于客户端模式时,允许设置本地端口号为0,此时将由系统自动选择可用的端口。
* @param strRemoteIP: 对方IP地址,当为服务端模式时设置为NULL
* @param shRemotePort: 对方收发端口(该端口用于音频,视频端口号将在此基础上加1),当为服务端模式时设置为0
* @param pfVideoRecvCallBack: 接收到视频数据后的对外输出回调函数
* @param pfAudioRecvCallBack: 接收到音频数据后的对外输出回调函数
* @param pObject: 调用上述两个回调函数时的附带透传形参,模块内部不会解析本参数仅做透传处理
* @return: TRUE FALSE
*/
BOOL SDSrtAvCom_Start(
void* pRtp_avcom,
const char *strLocalIP,
USHORT shLocalPort,
const char *strRemoteIP,
USHORT shRemotePort,
CallBackFuncRecvVideoData pfVideoRecvCallBack,
CallBackFuncRecvAudioData pfAudioRecvCallBack,
void *pObject);
/***
* 停止SrtAvCom工作
* @param pRtp_avcom: 模块指针
* @return:
*/
void SDSrtAvCom_Stop(void* pRtp_avcom);
/***
* 发送视频数据
* @param pRtp_avcom: 模块指针
* @param byBuf: 传入一帧带起始码的裸码流,内部自行拆分拼接。
* @param nLen: 数据长度
* @return:
*/
BOOL SDSrtAvCom_SendVideoData(void* pRtp_avcom, unsigned char *byBuf, int nLen);
/***
* 发送音频数据
* @param pRtp_avcom: 模块指针
* @param byBuf: 传入一帧音频裸码流,可以是ADTS,内部无拆包透传
* @param nLen: 数据长度
* @return:
*/
BOOL SDSrtAvCom_SendAudioData(void* pRtp_avcom, unsigned char *byBuf, int nLen);
/***
* 设置基础传输参数,请在Start接口之前调用
* @param pRtp_avcom: 模块指针
* @param nRecvDelayMs: 接收缓存时间,建议4*RTT,单位ms。可在发送端或接收端设置,将取其中较大的值
* @param nMaxBitrateKbps:最大传输码率,建议3*VideoEncBitrate,单位kbps。需要在发送端设置,当设置为0时表示不受限。若码率本身比较平稳,可设置为2*VideoEncBitrate。
* @return:
*/
BOOL SDSrtAvCom_SetBaseTransParams(void* pRtp_avcom, int nRecvDelayMs, int nMaxBitrateKbps);
/***
* 设置视频通道FEC传输参数,请在Start接口之前调用
* @param pRtp_avcom: 模块指针
* @param bEnable: 是否启用FEC,收发双方需保持一致
* @param nCols: FEC Group列数
* @param nRows: FEC Group行数
* @param eLayoutMode:2D FEC布局模式
* @param eArqMode:FEC-ARQ配合模式
* @return:
*/
BOOL SDSrtAvCom_SetVideoFecParams(void* pRtp_avcom, BOOL bEnable, int nCols, int nRows, E_SRT_FEC_LAYOUT eLayoutMode, E_SRT_FEC_ARQ eArqMode);
/***
* 设置音频通道FEC传输参数,请在Start接口之前调用
* @param pRtp_avcom: 模块指针
* @param bEnable: 是否启用FEC,收发双方需保持一致
* @param nCols: FEC Group列数
* @param nRows: FEC Group行数
* @param eLayoutMode:2D FEC布局模式
* @param eArqMode:FEC-ARQ配合模式
* @return:
*/
BOOL SDSrtAvCom_SetAudioFecParams(void* pRtp_avcom, BOOL bEnable, int nCols, int nRows, E_SRT_FEC_LAYOUT eLayoutMode, E_SRT_FEC_ARQ eArqMode);
/***
* 获取视频通道统计信息
* @param pRtp_avcom: 模块指针
* @param pfRttMs: RTT,单位毫秒
* @param pfUpLossRate: 上行丢包率.内部已经乘100
* @param pfDownLossRate: 下行丢包率.内部已经乘100
* @param pfEstimatedUpBitrate:上行带宽估算.Kbps
* @param pfUpBitrate:上行码率.Kbps
* @param pfDownBitrate:下行码率.Kbps
* @return:
*/
BOOL SDSrtAvCom_GetVideoTransStatis(void* pRtp_avcom, double *pfRttMs, double *pfUpLossRate, double *pfDownLossRate, double *pfEstimatedUpBitrate, double *pfUpBitrate, double *pfDownBitrate);
/***
* 获取音频通道统计信息
* @param pRtp_avcom: 模块指针
* @param pfRttMs: RTT,单位毫秒
* @param pfUpLossRate: 上行丢包率.内部已经乘100
* @param pfDownLossRate: 下行丢包率.内部已经乘100
* @param pfEstimatedUpBitrate:上行带宽估算.Kbps
* @param pfUpBitrate:上行码率.Kbps
* @param pfDownBitrate:下行码率.Kbps
* @return:
*/
BOOL SDSrtAvCom_GetAudioTransStatis(void* pRtp_avcom, double *pfRttMs, double *pfUpLossRate, double *pfDownLossRate, double *pfEstimatedUpBitrate, double *pfUpBitrate, double *pfDownBitrate);
附录:结构体说明
//2D FEC布局模式
Typedef enum E_SRT_FEC_LAYOUT
{
//普通连续模式
e_SRT_FEC_LAYOUT_EVEN = 0,
//阶梯模式,可以降低一定码率波动(冗余包分散发送)
e_SRT_FEC_LAYOUT_STAIR
} E_SRT_FEC_LAYOUT;
//FEC-ARQ配合模式
typedef enum E_SRT_FEC_ARQ
{
//只要丢包均会发起NAK,不管FEC能否恢复
e_SRT_FEC_ARQ_ALWAYS = 0,
//仅在FEC失败时发起NAK
e_SRT_FEC_ARQ_ONREQ,
//关闭NAK
e_SRT_FEC_ARQ_NEVER,
} E_SRT_FEC_ARQ;
/*输出接收到的视频数据 回调函数
* @param bComplete用来表示当前帧数据是否完整(无局部丢包)
* @param bPrevTotalFrameLost用来表示当前帧与上一次输出帧之间无整帧丢失的情况,即本帧序号与上一帧序号是否连续。
* 通过以上两个标志,结合关键帧判定标志,外层可以很方便的实现丢帧冻结机制
*/
typedef void (*CallBackFuncRecvVideoData)(void* pObj, int nLen, unsigned char *byBuf, unsigned int unPTS, BOOL bComplete, BOOL bPrevTotalFrameLost);
/*输出接收到的视频数据 回调函数*/
typedef void (*CallBackFuncRecvAudioData)(void* pObj, int nLen, unsigned char *byBuf, unsigned int unPTS);