JCHub

  • Home
  • Category
    • A/V
    • WebRTC
    • Beauty of Programming
    • Linux
    • Windows
    • Moments of Life
    • Campus Life
  • Reference
    • API Reference
    • Utilities
    • AV Test
    • Doc
  • Message Board
  • About
WebRTC
WebRTC

Continue,2022,加油

自从去年4月后,由于临时接手了离职音频算法工程师的工作,所以一直忙于音频处理的研究工作,同时解决产品上音频相关问题。由于要学的内容很多,很难有空余时间,不知不觉把博客给落下了。进入2022年,经过去年一段时间的潜心修炼,目前对WebRTC整个音频处理有了更深入的认识,当然,空余时间也多了些,所以准备继续更新博客,也把没回复的评论过下,找个时间回复。 这段消失的时间,自己总结起来有三方面收货: 1)加深了音频3A算法的熟悉,尤其是AEC3算法内部处理流程,以及特定场景下回声问题排查以及修复,例如采集丢音,采集播放抖动等场景的回声; 2)学了很多音频信号处理,同时解决了语音激励,共享桌面音频等场景下一系列问题; 3)进一步提升我们产品音频传输的带宽自适应能力。 回头想想,自己也许算半个音频工程师了 。 目前已经进入2022年了,虎年春节也要到来,后面准备保持之前的更新节奏,继续分享WebRTC以及音视频相关知识,加油!

2022年1月26日 4comments 3446hotness 20likes Jeff Read all
WebRTC

WebRTC研究:记一次音频带宽估计引入的异常分析

本篇文章主要从自己前几个月遇到的一个小问题引出。 问题背景 之前使用Web浏览器播放做测试,发现升级Chrome 87后播放视频会卡,排查服务端下行处理日志发现,带宽估计模块异常,如下是部分异常日志: [crayon-69bce1ecacdb9722031876/] 由于下行带宽估计会作用到Pacing模块,带宽估计的异常触发Pacing模块发送异常,从而导致视频卡顿。明明最近没有优化服务端带宽估计处理,哪里出错了呢? 通过异常日志可以很容易发现是反馈的Transport Feecback报文异常,Transport Feecback报文记录的部分RTP包在发送端没有发送时间记录,所以导致“Failed to lookup send time for”错误。进一步分析发现是Chrome 87音频也有带宽估计RTCP反馈,Transport Feedback报文中同时记录着音视频的信息。由于我们服务端目前只支持视频的带宽估计处理,带宽估计模块没有记录音频的发送时间信息,所以导致报错。 源码分析 接收端 在RemoteEstimatorProxy中,如果收到的RTP包有TransportSequenceNumber报头扩展,就会将该RTP包信息记录到Transport Feecback报文中。Transport Feecback报文中记录着音频信息,说明发送端音频注册了TransportSequenceNumber报头扩展。 我们服务端在处理Web浏览器间的音频数据转发时,没做太多处理,毕竟浏览器上优化空间不大,除了重新构建序列号等报头信息,RTP报头扩展维持不动。所以问题出在上行的浏览器发送端。 发送端 M86及以前版本 AudioSendStream::AudioSendStream中: [crayon-69bce1ecacdbf910207846/] 默认没启用音频带宽估计特性。 在AudioSendStream::ConfigureStream中: [crayon-69bce1ecacdc1550217130/] 所以旧版WebRTC中音频默认没有注册TransportSequenceNumber扩展。 M87及以后版本 AudioSendStream::AudioSendStream中: [crayon-69bce1ecacdc3393964008/] allocate_audio_without_feedback_默认为false。 AudioSendStream::ConfigureStream中: [crayon-69bce1ecacdc4247740965/] 可知新版WebRTC中音频默认注册TransportSequenceNumber报头扩展,也就是开启带宽估计特性。 了解了区别后,问题修复就简单了。后面我们服务端增加了对音频带宽估计的兼容处理修复了该问题。 总结 本文在分析相关问题基础上,介绍了新旧WebRTC版本在音频带宽估计处理上的一个小区别。新版WebRTC默认启用音频带宽估计也是为了提高带宽估计准确性。

2021年4月26日 2comments 3259hotness 5likes Jeff Read all
WebRTC

WebRTC研究:Encoded Transform

前段时间看到腾讯云的分享:《WebRTC Insertable Stream 初探与 WebRTC “管道化”》。想不到国内也开始关注这个新特性了,作为一个经常关注WebRTC最新提交代码的人,去年初就关注到了WebRTC Insertable Streams相关代码提交,不过对我这样一个Native Code开发者来说,用途不大,毕竟自己也可以在源码层面实现,获取或者修改自己需要的任何数据。但是这一特性对Web开发者来说用途就大了,给了Web开发者更多的自由与操作性。 WebRTC Insertable Streams 以前WebRTC Web开发者无法操作WebRTC采集或者编码后的音视频数据,当然也无法使用自定义的音视频编解码器,很多人使用WebRTC可能只是想用到传输这一块功能。当然也有比较黑科技的做法,使用WebAssembly技术把WebRTC库编译成二进制文件给Javascript调用,不过这一做法难度颇大,很多人编译WebRTC都废了九牛二虎之力,更别说使用WebAssembly技术编译,而且自己改的不一定稳定。所以WebRTC Insertable Streams这项新特性就诞生了。 WebRTC Insertable Streams目前包含两项内容: Encoded Transform:操作编码后的数据以及解码前数据(Post-encoding/Pre-decoding) Mediacapture Transform:操作编码前数据以及解码后数据(Pre-encoding /Post-decoding) WebRTC Insertable Streams这项新特性增加了些新API,让Web开发者对媒体数据可以做如下的事: 允许用户不打破WebRTC正常处理pipeline,手动处理数据 允许使用WASM技术进行数据处理 允许使用Web Worker技术处理数据,避免阻塞主线程 允许端到端间进行数据加解密,避免安全以及隐私泄露风险(不信任SFU服务器,避免中间人攻击) 根据[1],这里列举几个应用场景: 视频特效 视频背景移除 语音处理 动态控制编解码器参数 各个媒体Tracks的自定义带宽分配 自定义编解码器(与WebCodecs结合) 是不是很有趣?不过截止今天,WebRTC也只是实现了Encoded Transform特性,只能操作编码后的数据。所以本篇文章就从源码层面分析下目前的Encoded Transform实现。 Encoded Transform 前面说到Encoded Transform处理的是Post-encoding/Pre-decoding的媒体数据。 该特性接口定义位于FrameTransformerInterface中。 FrameTransformerInterface 看下接口定义: [crayon-69bce1ecaf422092868080/] 上面代码中,FrameTransformerInterface注册完TransformedFrame相关回调后,在回调TransformedFrameCallback::OnTransformedFrame获取编码后的Payload数据,调用TransformableFrameInterface接口对Payload数据进行操作: 调用GetData获取Payload数据,调用SetData设置Payload数据,我们可以通过GetData获取原始编码后的媒体数据,处理后再调用SetData达到修改媒体数据目的。当然了,也可以获取音视频的其他信息,例如音频,可以获取音频的RTP报头信息。 接下来我们以音频为例看下目前Encoded Transform相关代码实现。 音频发送端 这里先看下发送端代码流程: [crayon-69bce1ecaf428689447730/] WebRTC对ChannelSend::SendData进行了修改,其中frame_transformer_delegate_(ChannelSendFrameTransformerDelegate)继承自TransformedFrameCallback。 [crayon-69bce1ecaf42a302904859/] 处理完数据后通过ChannelSend::SendRtpAudio将数据返回到原来的的处理Pipeline。所以若初始化了ChannelSendFrameTransformerDelegate,处理流程变为: [crayon-69bce1ecaf42b495957477/] 这里FrameTransformerInterface由我们外部自己实现。所以我们需要修改Payload数据的话需要实现FrameTransformerInterface,在FrameTransformerInterface::Transform中通过TransformableAudioFrameInterface进行获取或者修改Paylod数据,最后通过注册的回调接口返回修改的Payload数据。。 音频接收端 这里先看下接收端代码流程: [crayon-69bce1ecaf42e556852471/] WebRTC对ChannelReceive::ReceivePacket处理流程进行了修改。 [crayon-69bce1ecaf42f630975399/] 同前面发送端代码,其中frame_transformer_delegate_(ChannelReceiveFrameTransformerDelegate)也是继承自TransformedFrameCallback。最后处理完数据后通过ChannelReceive::OnReceivedPayloadData将数据返回到原来的处理Pipeline。具体代码类似发送端,就不再分析了。最后代码处理流程变为: [crayon-69bce1ecaf430947534028/] 在接收端我们也需要在外部实现FrameTransformerInterface,从而进行数据处理。 总结 本文简单介绍了Insertable Streams这个新特性,并从音频角度分析了其中一项内容的源码实现:Encoded Transform。等后续WebRTC官方更新了Mediacapture Transform实现代码,我也将做下分析。 参考 [1] webrtc-encoded-transform.https://github.com/w3c/webrtc-encoded-transform.

2021年3月28日 6comments 4765hotness 11likes Jeff Read all
WebRTC

WebRTC研究:统计参数之往返时延

前面文章介绍了抖动,今天我们来看下chrome://webrtc-internals/页面中的一个重要统计参数:往返时延(RTT)。 什么是RTT 往返时延(round-trip time,RTT) 是网络请求从起点到目的地然后再回到起点所花费的时长(不包括接收端的处理时间)。RTT是分析网络性能的一个重要指标,我们通常使用RTT来诊断网络连接的速度,可靠性以及拥塞程度。 ping命令是最常见的一种估计往返时延的方法。下面是ping Google的示例,底部显示了rtt的不同表示:最小,平均,最大,平均偏差。 [crayon-69bce1ecb08d4496468943/] RTT计算方式 WebRTC中目前有两种方式计算RTT: 基于媒体流发送端的计算(默认开启)。通过Sender Report(SR)与Receiver Report(RR)携带的信息。 基于媒体流接收端的计算。通过RTCP Extended ReportsRTCP(XR)携带的信息。 这两种方式计算RTT的原理都一样。至于为什么需要接收端计算方式,这是因为在一些场景,媒体流传输是单向的,两个端点间一个只发媒体数据,一个只接收,例如客户端与SFU服务器间。假设客户端与SFU服务器上行推流场景,客户端推流,服务端收流,这种场景下作为接收端的服务端并不会发送SR,导致无法计算RTT。于是就有了通过RTCP XR在接收端计算这种方式。 媒体流发送端RTT计算 WebRTC中媒体流发送端RTT的计算是根据SR以及RR中携带的时间信息。这里我们回顾下Sender Report与Receiver Report RTCP两种报文。 Sender Report [crayon-69bce1ecb08d9657265952/] NTP timestamp:64bits。记录着发送该SR的NTP时间戳。 Receiver Report [crayon-69bce1ecb08dc119120310/] last SR timestamp (LSR): 32 bits。64位NTP时间戳中间的32bit(NTP时间戳指绝对时间,相对1900年1月1日00:00:00经历的时间,单位为秒。完整NTP时间戳用64bits表示,左半32bits表示整数,右半32bits表示小数,一般为了紧凑,取中间32bits表示即可,这时整数与小数分别16bits表示)。记录着上次源SSRC_n发送SR的NTP时间,从收到的SR记录的NTP时间戳获取。如果没有收到SR,值为0。 delay since last SR (DLSR): 32 bits。以1/65536(2^16)秒为单位。记录着上次接收到源SSRC_n发送的SR到当前发送RR的间隔时间。如果没有收到SR,值为0。 计算原理 前面简单介绍了RR中记录的时间信息,下面我们看下如何根据这些时间信息计算RTT。 上图中\(T_{0}\)时刻媒体流发送端发送SR,SR中记录着send_time_ntp。媒体流接收端\(t_{0}\)时刻收到SR,\(t_{1}\)时刻回复RR,RR中记录着:1)从收到的SR中获取的send_time_ntp信息;2)接收端回复RR与收到SR的间隔时间delay_since_last_sr。发送端在\(T_{1}\)时刻收到回复的RR。可知: 代码导读 WebRTC中,发送端首先需要调用ModuleRtpRtcpImpl::OnSendingRtpFrame,这样才能触发发送SR。 接着收到反馈的RR后才能进行RTT计算。WebRTC中发送端RTT计算代码位于RTCPReceiver::HandleReportBlock。 主要代码流程如下: [crayon-69bce1ecb08dd798380073/] RTCPReceiver::HandleReportBlock中RTT计算代码如下: [crayon-69bce1ecb08e0113437285/] 结合前面的公式,上面代码应该很好理解。最后得到一个ms表示的RTT,chrome://webrtc-internals/中RTT的单位是秒。 媒体流接收端RTT计算 RTCP XR报文 WebRTC中媒体流接收端RTT的计算是根据XR中携带的时间信息。这里我们看下XR报文格式: [crayon-69bce1ecb08e1114553411/] 时间信息存放在report blocks中。report blocks格式如下: [crayon-69bce1ecb08e3132468409/] 接收端RTT计算主要用到了Receiver Reference Time Report Block与DLRR Report Block这两种report blocks。 Receiver Reference Time Report Block(RRTR) 由媒体流接收端发送。报文格式如下: [crayon-69bce1ecb08e4879335738/] NTP timestamp:64bits。记录着发送该Receiver Reference Time Report Block的NTP时间戳。 DLRR Report Block 由媒体流发送端发送。报文格式如下: [crayon-69bce1ecb08e5426314432/] last RR timestamp (LRR): 32 bits。记录着上次源SSRC_n发送Receiver Reference Time Report Block的NTP时间,从收到的Receiver Reference Time Report Block记录的NTP时间戳获取。如果没有收到,值为0。 delay since last RR (DLRR): 32 bits。以1/65536(2^16)秒为单位。记录着上次接收到源SSRC_n发送的Receiver Reference Time Report Block到当前发送DLRR Report Block的间隔时间。如果没有收到Receiver Reference Time Report Block,值为0。 计算原理 类似发送端RTT计算,只不过SR变为了Receiver Reference Time Report Block,由媒体流接收端发送。RR变为了DLRR Report Block,由媒体流发送端发送,最后在接收端计算。具体原理这里就不再啰嗦一次了。 代码导读 需要配置接收端ModuleRtpRtcpImpl中RtpRtcpInterface::Configuration的non_sender_rtt_measurement开启XR。 这里以视频为例,配置开启方式如下: [crayon-69bce1ecb08e6200327755/] 也就是检查SDP中某编码器"a=rtcp-fb"是否含有"rrtr"。例如: [crayon-69bce1ecb08e7208802962/] 最终这个receiver_reference_time_report配置会传给RtpRtcpInterface::Configuration中的non_sender_rtt_measurement配置项,最后传到RTCPSender中。 媒体流接收端首先发送RRTR,然后收到媒体流发送端反馈的DLRR Report Block进行RTT计算。WebRTC中接收端RTT计算代码位于RTCPReceiver::HandleXrDlrrReportBlock。 主要代码流程如下: [crayon-69bce1ecb08e8733416954/] RTCPReceiver::HandleXrDlrrReportBlock中RTT计算代码如下: [crayon-69bce1ecb08e9837899924/] 代码类似前面发送端RTT计算,就不分析了。 注意事项 WebRTC中RTCP XR总是附在SR或者RR后组成Compound RTCP包发送。 总结 本文简单介绍了RTT以及WebRTC中两种RTT的计算,RTT作为网络性能分析的一个重要指标,在WebRTC中扮演一个很重要的角色,至于具体用途,后面有空结合其它再分析。 参考 [1] RFC3550.https://tools.ietf.org/html/rfc3550. [2] RFC3611.https://tools.ietf.org/html/rfc3611.

2021年3月21日 12comments 8124hotness 20likes Jeff Read all
WebRTC

WebRTC研究:统计参数之抖动

当我们调试WebRTC web客户端时,经常会打开chrome://webrtc-internals/这个页面,在这里我们可以看到音视频流的各种统计。今天我们就来看下其中的一个统计参数:抖动(jitter)。 什么是抖动 在网络传输中,每个包从发送端到接收端的时延都是不相同的,而jitter就是用来衡量这种不同。一般在发送端,数据包发送时间间隔是相同的,也就是均匀发送数据,但是传输过程中由于各种情况,例如拥塞,丢包,网络错误等,接收端收到的数据包间隔就会不一样,可能一会大,一会小,导致时延发生变化,这个时延的变化程度就是所谓的抖动,接收端如果不做任何处理,就会影响用户体验。例如对于视频来说,会导致帧率变化,视频播放就不平滑,有卡顿感。如下图片是抖动的一个形象描述。 WebRTC内部通过NetEQ与JitterBuffer进行音视频的抖动处理,消除抖动造成的影响,这些会在我的后续文章介绍。 抖动计算 根据RFC3550,假设RTP包i,RTP报头记录的时间戳为Si(单位为采样率),到达接收端的时间为Ri(单位同样为采样率),对于包i,j,我们定义一个变量\(D\),描述两个包时间的差异,由接收时间差减去发送时间差: 抖动\(J\)按如下公式定义: 上述公式中i-1指的是前一个收到的包,不是按RTP序列号计数的。增益参数1/16是为了消除噪声影响,使抖动收敛在较合理范围内,避免突发数据的影响。 由公式可知,如果接受端收到的包间隔跟发送端发送间隔一样,那么抖动为0。 代码导读 WebRTC统计参数中的抖动计算代码位于StreamStatisticianImpl::UpdateJitter中,看下如何计算。 1)计算接收时间差,也就是\(Ri - R_{i-1}\): [crayon-69bce1ecb1efd127984664/] 2)计算\(|D(i-1,i)|\),其中发送时间为RTP报头记录的时间戳: [crayon-69bce1ecb1f03729239673/] 3)由公式(2),使用jitter_diff表示\(|D(i-1,i)|-J(i-1)\): 所以相关代码如下: [crayon-69bce1ecb1f05420604096/] 至此我们得到了jitter_diff_q4,单位为采样率,如果需要转换为毫秒时间单位,需要如下计算: 1)由于jitter_diff_q4放大了16倍,首先需要还原回去: [crayon-69bce1ecb1f06600478255/] 2)转换为毫秒单位: [crayon-69bce1ecb1f07937921611/] 这样我们就得到了以毫秒表示的抖动统计参数,chrome://webrtc-internals/中抖动的单位是秒。 参考 [1] Jitter.https://en.wikipedia.org/wiki/Jitter. [2] RFC3550.https://tools.ietf.org/html/rfc3550.

2021年3月14日 8comments 5169hotness 17likes Jeff Read all
WebRTC

WebRTC研究:WebRTC M89关键更新

最近更新了M89代码,看了下Release Notes,有几个需要关心的地方。 Plan B SDP语法后续处理计划 WebRTC 1.0已经正式成为W3C标准,推荐使用标准SDP格式:Unified Plan,主流浏览器基本都支持Unified Plan SDP。Plan B SDP后续将会不赞成使用,直到移除掉。官方后续时间计划如下: M89 (2021.02):在开发者控制台增加不赞成使用警告 M93 (2021.08): Plan B被移除掉, 但是增加了选项,可以延长移除的截止日期 M96 (2022.01): 不再允许延长截止日期,Plan B将彻底移除 rtp payload类型增加新范围 M89中RTP payload类型增加了新的值范围:35-65。 首先根据RFC3551,回顾下目前用于标准音视频编码器的RTP payload类型。 音频编码器的payload类型 [crayon-69bce1ecb3392689383656/] 视频编码器的payload类型 [crayon-69bce1ecb3397478892044/] 原有动态RTP payload类型范围局限性 RFC 3551中定义的动态RTP payload类型范围[96,127]只能表示32种payload类型。由于Chrome支持的音视频编解码器越来越多,而且像DTMF,FEC,RTX机制,冗余编码,H264不同profile/打包模式等都需要占用一个RTP payload类型。原先的范围已经不够使用了。 这里我们看下某个默认生成的Offer SDP中的内容(有点长),a=rtpmap后面跟着就是某种RTP payload类型。 [crayon-69bce1ecb339a861392565/] 根据m-line,可知,音频用到的RTP payload类型有:111 103 104 9 0 8 106 105 13 110 112 113 126。视频用到的RTP payload类型有:96 97 98 99 100 101 102 121 127 120 125 107 108 109 124 119 123 118 114 115 116。 在动态RTP payload类型[96,127]范围内,用到了31个取值,如果稍微再复杂些,[96,127]确实不够用了。 新增RTP payload类型范围 RFC3551中,section-3中提到,当需要定义的动态payload类型超过32个时,推荐优先使用unassigned payload类型这个范围的值。 为了兼容旧版Chrome,所以M89中增加了新的RTP payload类型范围:35-65。由前面视频编码器的payload类型可知[35,65]位于[35,71]这个Unassigned payload类型范围内。 在webrtc_video_engine.cc中相关说明代码如下: [crayon-69bce1ecb339b333263973/] 总结 针对前面提到的两点重要更新,我觉得后续我们WebRTC服务器开发的得注意下,需要完全支持Unified Plan,同时需要能正确识别[35,65]这个范围表示的RTP payload类型。 参考 [1] WebRTC M89 Release Notes.https://groups.google.com/g/discuss-webrtc/c/Zrsn2hi8FV0/m/7Y4RLluHAQAJ. [2] RFC3551.https://tools.ietf.org/html/rfc3551. 本文已收录到大话WebRTC专栏,更多精彩请访问《大话WebRTC》。

2021年2月27日 4comments 4509hotness 12likes Jeff Read all
WebRTC

Linux平台WebRTC编译

系统要求 系统:Ubuntu 16.04及以上(本文Ubuntu 18.04) 磁盘空间:至少6.4 GB磁盘空间 安装工具 [crayon-69bce1ecb4768922998521/] 安装depot tools [crayon-69bce1ecb476d399040494/] 获取代码 [crayon-69bce1ecb476e338973275/] 安装依赖 [crayon-69bce1ecb476f957280239/] 生成Ninja工程文件 WebRTC默认使用Ninja作为编译系统,Ninja工程文件通过GN生成。 使用如下命令生成默认配置工程(Debug编译,工程文件位于out\Default目录下): [crayon-69bce1ecb4770290826246/] 如果需要Release编译,通过如下命令生成工程文件: [crayon-69bce1ecb4771608374225/] 编译 [crayon-69bce1ecb4772380303000/] 最后在src/out/Default/obj可以看到生成的静态库文件:libwebrtc.a。 代码更新 后续如需要更新代码,按照如下步骤: [crayon-69bce1ecb4773642593443/] 然后参考前面步骤重新生成工程文件,编译即可。 参考 [1] WebRTC Native code Development.https://webrtc.github.io/webrtc-org/native-code/development/. 本文已收录到大话WebRTC专栏,更多精彩请访问《大话WebRTC》。

2021年1月28日 3comments 4207hotness 13likes Jeff Read all
WebRTC

WebRTC研究:Simulcast层数变化

当我们上行推Simulcast流的时候,会发现Simulcast层数会时不时变化,本来是大小流(大小两个分辨率)两层,但是变为只有一层小流了,后面又恢复为两层了,如果我们服务端支持Simulcast的话,这就成为一个棘手问题。 例如我们团队的WebRTC产品,客户端默认会启用Simulcast,上行推送多个不同分辨率的流到服务端,服务端下行会依据带宽估计值,自动选择某个分辨率的流给订阅客户端。假设此时下行带宽足够,服务端会推送大流。但是对于上行客户端来说,因为某种原因,Simulcast层数减少为一层,只剩一路小流了,如果没有相应处理,此时订阅客户端就接收不到视频流了。 Simulcast层数为何变化 WebRTC中如果送到编码器的采集视频帧分辨率发生变化,会触发ReconfigureEncoder也就是重置编码器操作,然后Simulcast层数也会重新计算。在WebRTC中,Simulcast层数与采集视频帧分辨率的关系由一张表决定: [crayon-69bce1ecb5bb3474543582/] 对于1920x1080的采集分辨率,允许的最大Simulcast层数为3层,对于640x360的采集分辨率,允许的最大层数为2层。所以当采集视频分辨率从1920x1080变为640x360时,Simulcast层数就会发生变化。 下面简单说下几种造成采集视频帧分辨率变化的几种情况: 1)带宽估计值不够; 2)编码视频的QP值在设定的阈值范围外; 3)通过编码延时计算得到的CPU负载发生变化。 发生如上情况时,WebRTC会调整采集的原始视频帧分辨率或者帧率,至于是调整采集分辨率还是帧率,依据我们采取的策略,WebRTC中目前存在四种策略: 1)BALANCED,平衡模式; 2)MAINTAIN_RESOLUTION,保分辨率模式,也就是清晰模式; 3)MAINTAIN_FRAMERATE,保帧率模式,也就是流畅模式; 4)DISABLED,禁用模式。 例如对于摄像头视频流,默认是流畅模式,我们举两个例子说明下。 1)如果分配的带宽估计值满足不了当前编码器分辨率的码率设置时,就会触发降低采集视频帧分辨率的操作; 2)如果检测到CPU负载较高,也会触发降低采集视频帧分辨率的操作。这种现象在移动端设备较为明显,会看到视频刚开始很清晰,后面就模糊了(假设带宽足够情况下)。 当然了,对于屏幕共享流,默认是清晰模式,只会触发降低帧率的操作,看起来视频会变卡。 如何防止Simulcast层数变化 这里我们先看下启用Simulcast时,采集分辨率改变后,重置编码器的相关代码流程: [crayon-69bce1ecb5bba626044655/] 在LimitSimulcastLayerCount中会根据前面提到的表内容,改变Simulcast层数: [crayon-69bce1ecb5bbd325728568/] 可知,通过在webrtc::field_trial设置禁用kUseLegacySimulcastLayerLimitFieldTrial即可保持当前Simulcast层数,避免了大流消失的麻烦。 总结 本文分析了Simulcast层数变化的原因,以及如何防止变化。其中介绍了WebRTC的清晰模式,流畅模式等概念,后续文章会对这些进行详细分析。

2020年12月27日 20comments 9122hotness 12likes Jeff Read all
12345
Copyright Statement

Unauthorized reproduction or plagiarism in any form is strictly prohibited. For reprint requests, please contact via email.

Recent Comments
Mirzoemele Published at 2 months ago(01 01202613104 06 06pm26) Double blind randomised controlled trial of two to...
PedarPhago Published at 7 months ago(08 08202583109 12 12pm25) Association between selective serotonin reuptake i...
EsielTooft Published at 8 months ago(07 07202573112 29 29am25) International scientific apply guidelines for the ...
dongxuh Published at 8 months ago(07 07202573103 27 27pm25) 真心不错的博客,有机会能一起分享
南南 Published at 8 months ago(07 07202573103 15 15pm25) 写的超棒!

COPYRIGHT © 2026 jianchihu.net. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang