WebRTC 是如何设置视频编码偏好的?

发布于:2022-12-10 ⋅ 阅读:(585) ⋅ 点赞:(0)

目录

前言

正文

一、基于 RTCRtpSendParameters.degradationPreference 设置的值

二、基于 RTCPeerConnection 中设置的 googCpuOveruseDetection 的约束值

三、基于媒体流类型,是否为屏幕共享流

四、基于 webrtc::field_trial 中设置 WebRTC-Video-BalancedDegradation 属性值

五、基于判断推测

六、上层参数是如何作用到视频编码偏好选择的呢?

结尾

前言

WebRTC 作为实时音视频通讯的解决方案,在视频画面编码过程中有非常多的控制机制,有时候,你可能会遇到这样的情况,明明分辨率设置的很高,但是编码出来的视频画面分辨率却非常低。同样,帧率有时候也会面临相同的问题。这其实是 WebRTC 内部的视频编码偏好机制在起作用,刚刚接触 WebRTC 的同学遇到这样的问题,很可能会一头雾水,今天我们就揭秘 WebRTC 在这个过程中的实现逻辑,消除大家在这方面的疑惑。

本文福利, 免费领取C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg webRTC rtmp hls rtsp ffplay srs↓↓↓↓↓↓见下面↓↓文章底部点击免费领取↓↓

正文

了解 WebRTC 编码机制的小伙伴都知道,WebRTC 在处理视频编码偏好总共有四种模式,分别是默认模式、保帧率模式、保分辨率模式、平衡模式。WebRTC 在实际工作过程中,一般设置某种编码偏好后,后续就不再变化了。当然也存在某些特例,比如普通摄像头视频流编码偏好选择的是保帧率模式,启用屏幕分享后,对应的视频流可能会变成保分辨率模式。但是,大多数情况下,对应的视频编码偏好一般都是固定的,这样也便于问题的分析和排查。

其中,默认模式在 WebRTC 中又叫 DISABLED 模式,当处于该模式下时,WebRTC 在视频编码过程中不进行任何控制,不会因为某些过度使用的信令情况而起作用,一般信令频繁的话可以会是因为 CPU 利用率过高,所以当不启用 CPU 过载监测的时候,可以采用这种模式。

保帧率模式在 WebRTC 中又叫做 MAINTAIN_FRAMERATE 模式,根据它的名字我们也能知道在这种模式下,WebRTC 在编码视频画面的时候会优先保证帧率的正常输出,让帧率保持一个稳定的数值,当带宽不足或者 CPU 过高的时候,可能会造成视频流畅度降低,分辨率下降,主观感觉上就是视频画面开始模糊,但是画面还在以固定的频率刷新。

保分辨率模式在 WebRTC 中又叫 MAINTAIN_RESOLUTION 模式,它其实是和 MAINTAIN_FRAMERATE 模式相对应的,视频编码的时候是保证分辨率稳定输出,但这样做的风险就是当带宽不足时,可能导致帧率下降,出现视频卡顿的情况。其实,在现实生活中,我们遇到最多就是这种情况。比如在进行视频会议,或者观看网络直播(比如体育赛事、主播带货、云监控等业务场景)时,如果网络带宽不足或者出现网络抖动时,就会出现明显的画面卡顿,甚至是视频画面静止不动。

最后看平衡模式,也叫 BALANCED 模式,它是 WebRTC 相对智能化的一种视频编码模式,在帧率和分辨率之间寻找最佳的动态平衡。但是,在这个过程中其实策略上更加偏向保分辨率。

下面是 WebRTC 内部定义的四种编码偏好类型枚举值(默认模式、保帧率模式、保分辨率模式、平衡模式),大家可以参考。

enum class DegradationPreference {
  // Don't take any actions based on over-utilization signals. Not part of the
  // web API.
  // 默认模式
  DISABLED,
  // On over-use, request lower resolution, possibly causing down-scaling.
  // 保帧率模式
  MAINTAIN_FRAMERATE,
  // On over-use, request lower frame rate, possibly causing frame drops.
  // 保分辨率模式
  MAINTAIN_RESOLUTION,
  // Try to strike a "pleasing" balance between frame rate or resolution.
  // 平衡模式
  BALANCED,
}

视频编码偏好类型大家已经了解了,那么具体的决定因素又有哪些呢?接下来,我分别介绍。

一、基于 RTCRtpSendParameters.degradationPreference 设置的值

前面我们提到,WebRTC 内部处理视频编码偏好时有四种模式,分别是默认模式、保帧率模式、保分辨率模式、平衡模式。其中,默认模式的开启和关闭控制没有开放对应的 Web API,剩下的保帧率模式、保分辨率模式、平衡模式三种都是可以通过 Web API 进行控制的。

当我们通过 API 设置 WebRTC 视频编码偏好时,如果不是平衡模式,设置成保帧率模式或者保分辨率模式都是立即生效的,此时会忽略 webrtc::field_trial 和底层默认的一些设置。

本文福利, 免费领取C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg webRTC rtmp hls rtsp ffplay srs↓↓↓↓↓↓见下面↓↓文章底部点击免费领取↓↓

二、基于 RTCPeerConnection 中设置的 googCpuOveruseDetection 的约束值

当媒体流参数中设置的视频编码偏好不是平衡模式,同时又没有启用 CPU 检测机制的话,WebRTC 的视频编码偏好将会退化为默认模式,即 DISABLED 模式。

三、基于媒体流类型,是否为屏幕共享流

当媒体流参数中设置的视频编码偏好不是平衡模式,同时启用了 CPU 检测机制,如果媒体流是屏幕共享流的话,那么设置的编码偏好将是保分辨率模式。

四、基于 webrtc::field_trial 中设置 WebRTC-Video-BalancedDegradation 属性值

当媒体流参数中设置的视频编码偏好不是平衡模式,同时启用了 CPU 检测机制,媒体流又不是屏幕共享流,此时,webrtc::field_trial 约束簇中,如果设置了 WebRTC-Video-BalancedDegradation 参数,那么 WebRTC 中设置的编码偏好将是平衡模式。

五、基于判断推测

当上述所有设置都不生效时,那么系统最有可能的行为是保分辨率模式,这也是一种推测,也可以作为系统的默认行为。

设置编码偏好生效后,会通过 SetSource() 方法与相应的视频流进行关联,然后进行后续帧率和分辨率的平衡策略调整。其中,SetSource() 方法的声明形式如下:

void SetSource(rtc::VideoSourceInterface<VideoFrame>* source,
               const DegradationPreference& degradation_preference) 

六、上层参数是如何作用到视频编码偏好选择的呢?

那么这个时候问题来了,上层参数是如何作用到视频编码偏好选择的呢?如果你存在这个疑问,你可以直接看关键函数,它就是 bool WebRtcVideoChannel::AddSendStream(const StreamParams& sp) ,这是一个非常关键的函数方法,因为 StreamParams 对象中已经包含了相关的媒体流参数,包含了 SSRC、RIDS、流 ID 等信息,最重要的是在这个方法体内,完成相关媒体流参数的转换处理逻辑。调用 AddSendStream()方法时,WebRTC 首先会检验 StreamParams 参数是否有效,然后判断 SSRC 是否可用。创建 WebRtcVideoSendStream 实例的时候,将参数传递给 WebRtcVideoSendStream 对象。参数 sp 经过 CreateRtpParametersWithEncodings 处理后,赋值给 rtp_parameters_。最后,参数 rtp_parameters_将作用到控制视频编码偏好的地方。

结尾

本文介绍了 WebRTC 关于视频编码偏好的四种模式,分别是默认模式、保帧率模式、保分辨率模式、平衡模式,设置过程会根据一定的策略进行编码模式的选择。但是,之后也有具体的处理逻辑,会在后续的文章中继续分享更新,欢迎关注,非常感谢。

本文福利, 免费领取C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg webRTC rtmp hls rtsp ffplay srs↓↓↓↓↓↓见下面↓↓文章底部点击免费领取↓↓

本文含有隐藏内容,请 开通VIP 后查看