Webrtc 分辨率自适应调整

自适应,是根据当前设备性能情况来动态的调整视频码率/帧率,为用户提供更好音视频体验感。

开启自适应

webrtc 默认开启自适应, googCpuOveruseDetection 默认为true ,可以通过设置此值为false 关闭自适应。

自适应策略

webrtc 提供了三种策略:

MAINTAIN_FRAMERATE:保帧率,降分辨率,该模式的使用场景为视频模式。

MAINTAIN_RESOLUTION: 保分辨率降帧率,使用场景为屏幕共享或者文档模式,对清晰度要求较高的场景。

BALANCED: 平衡帧率与分辨率。 默认关闭,需要通过 WebRTC-Video-BalancedDegradation 开启。

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,
};

自适应策略的设置

webrtc api 层提供了自适应策略的设置接口,通过设置 videotrack 的 ContentHint 属性就可以了。

 enumclass ContentHint { kNone, kFluid, kDetailed, kText };

kFluid,表示编码器保持帧率,降低分辨率。用于视频模式,对视频流畅度要求较高,默认值kDetailed/kText, 表示编码器保持分辨率,降帧率。用于屏幕共享/文档模式,对清晰度要求较高场景
WebRtcVideoSendStream::GetDegradationPreference 函数中将 ContentHint 转换成 DegradationPreference。

自适应处理流程

Webrtc 分辨率自适应调整

1、视频采集设备,采集视频后交由IvdieoAdapter,根据设置的参数帧率,分辨率,进行预处理;

2、VideoAdapter 预处理后交由编码管理器,进行编码信息设置,设置完成后交由编码器进行编码;

3、在编码过程中,对CPU使用度,QP,像素,带宽进行检测。超过阈值认为过载,小于阈值则认为欠载;

4、将CPU使用度,QP,像素,带宽检测结果,统一转换为过载(kOveruse)/欠载(kUnderUse),根据 检测结果计算新的 分辨率/帧率值,具体由ResourceAdaptationProcess类处理;

5、由VideoStreamAdapter 将新的值,更新到其他模块。

CPU使用度(EncodeUsageResource)

“CPU使用度” 是指编码耗时 / 采集耗时,是一个比值。

  • 当该比值越大时,表示编码跟不上采集,达到了编码器的性能瓶颈,需要对编码进行降级;
  • 当该比值越小时,表示编码能力有富余,还可以进行编码升级,提供更好的视频质量。

由此可见,CPU使用度通过编码相对速率,来衡量当前的运行性能。这样做的好处有几个:

1、不与CPU硬件绑定,与硬件平台解耦

2、兼顾当前软件运行环境的影响,比如其他应用对CPU的消耗、操作系统对各进程资源的调度策略

初始值:

• high_encode_usage_threshold_percent:过载阀值,默认为 85.

• low_encode_usage_threshold_percent 欠载阀值,默认值为 42

• high_threshold_consecutive_count:过载的次数,默认为 2

•当编码器 is_hardware_accelerate,也就是使用硬件编码时,该阈值会进行调整,分别设置成150与200。

cpu使用度计算:

编码耗时 = 本帧编码结束时间 – 本帧编码开始时间;

编码采集间隔时间= 本帧编码开始时间 – 上一帧编码开始时间;

为了防止出现检测结果抖动,影响用户体验,需要对数据进行平滑处理,编码时长与采集间隔,都用了指数加权移动平均法(EWMA);

编码器占用率(usage_percent) = 编码时长/编码采集间隔时间。

Overuse

usage_percent 值大于 85 并且 usage_percent 连续超过两次,当被认定过载,编码降级

bool OveruseFrameDetector::IsOverusing(int usage_percent) {
  RTC_DCHECK_RUN_ON(&task_checker_);

  if (usage_percent >= options_.high_encode_usage_threshold_percent) {
    ++checks_above_threshold_;
  } else {
    checks_above_threshold_ = 0;
  }
  return checks_above_threshold_ >= options_.high_threshold_consecutive_count;
}

Underuse

欠载处理的 case 稍微就有点复杂了,目的是为了避免 Underuse 与 Overuse 频繁切换。

bool OveruseFrameDetector::IsUnderusing(int usage_percent, int64_t time_now) {
  RTC_DCHECK_RUN_ON(&task_checker_);
  int delay = in_quick_rampup_ ? kQuickRampUpDelayMs : current_rampup_delay_ms_;
  if (time_now < last_rampup_time_ms_ + delay)
    return false;

  return usage_percent < options_.low_encode_usage_threshold_percent;
}

kQuickRampUpDelayMs: 默认为 10s。

in_quick_rampup_: 标识是否需要快速上升,当上次是 Underuse 时,in_quick_rampup_才为 true。

current_rampup_delay_ms_:假设上次是 Underuse ,当前是 Overuse 状态,为了避免下次很快切换成 Underuse 状态,引入了这个变量。

T1: 上次 Underuse –> Overuse 的间隔

T2: 下次 Overuse –> Underuse 的间隔

当 T1 >= 40, T2 也就是 current_rampup_delayms 直接取 40,

当 T1 < 40 或者 Overuse 的总次数大于 4, T2 的范围在[80,240].

delay:用于计算当前时间与上次状态为 Underuse 时间间隔,防止状态切换过于频繁(不仅是 Underuse 与 Overuse,还要考虑 Underuse 与 Underuse)。

1、上次是 Underuse,此时 in_quick_rampup_为 true,需要快速上升,仅需当前时间与上次切换时间间隔大于 10s 就行了。

2、上次是 Overuse 或者其它,这时候 delay 就是 current_rampup_delay_ms_,current_rampup_delay_ms_的计算原理见上面的注解.

3、usage_percent值小于42 时,认为欠载,编码升级

QP检测(QualityScalerResource)

QP (QuantizationParameter 量化参数),相当于图像的复杂度。反应了视频的质量。QP过大,图像失真, 质量下降。QP过小,导致质量上升,码率上升。

QP检测目的是,让视频质量维持在可接受范围的前提下,调节整体视频表现,如分辨率、帧率,让视频达到最佳播放效果。

QP检测机制,只是利用QP分析结果对分辨率、帧率进行调节,并不对编码QP做直接调整。

当一系列图像的平均QP超过阈值时会调整分辨率(H264的合法范围是24~37),平均最高QP超过37要降分辨率,平均最小QP低于24要提高分辨率

•WebRTC-Video-QualityScalerSettings

•WebRTC-Video-QualityScaling 使用指数过滤,否则使用滑动窗口

默认每2秒检测一次

  1. 每帧编码结束后,都会上报QP
  2. 获取每帧的QP后,分别被添加到三个数据集 average_qp_、qp_smoother_high_、qp_smoother_low_ 中,在样本数据添加后立即完成滤波计算。
  • average_qp_使用滑窗滤波rtc::MovingAverage,
  • qp_smoother_high_和qp_smoother_low_ 使用指数滤波rtc::ExpFilter,均起到平滑数据的作用。

3.进行检测判断

  • 采样点小于60, 认为采样点不足, kInsufficientSamples
  • 当drop_rate大于 60%,认为视频质量不佳, kHighQp
  • 当*avg_qp_high > 37,qp 过高 kHighQp
  • 当*avg_qp_low <= 24,qp 过低 kLowQp
  • 其他情况返回 kNormalQp

•为了方便后期处理 kHighQp 会转化成 kOveruse,kLowQp 转化成 kUnderuse。

像素检测(PixelLimitResource)

需要设置在 field_trial 才能开启,
WebRTC-PixelLimitResource/Enabled-518400(960*540)

  1. 启用一个5s 的定时器
  2. 获取最后一帧编码前视频帧的frame_size(宽*高)
  3. max_pixels_ 是从field_trial 读取而来
  4. current_pixels与max_pixels_ 进行比较
  • 若current_pixels> max_pixels_ 则认为过载 kOveruse
  • 若current_pixels<0.6*max_pixels_ 则认为欠载 kUnderuse

带宽变化检测(BandwidthQualityScalerReource)

•触发条件

1、保帧率,调整分辨率并且 编码配置允许质量调整(
is_quality_scaling_allowed=true)

2、属于QP提升,和QP互斥 !
encoder_info.is_qp_trusted.value_or(true)

3.每5秒检测一次

4.码率检测

•根据当前像素(最后一次更新的像素),从配置表中查询,获取最高,最低码率

  • 当前码率(最后一次的码率)大于最高码码率95% 过载
  • 当前码率(最后一次的码率)小于最低编码码率80% 欠载
Webrtc 分辨率自适应调整

执行欠载/过载过程

检测器处理生成了 kOveruse 和 kUnderuse 两种信号,再结合 DegradationPreference 值对像素或帧率进行调整

Webrtc 分辨率自适应调整

源码实现

Webrtc 分辨率自适应调整

作者:马龙飞鸽

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(2)

相关推荐

发表回复

登录后才能评论