Revert "Frame rate controller per spatial layer."
This reverts commit ae9e188e67a489db597224e3cfcfdee04edf0cba. Reason for revert: Verify if this causes chromium:882358. Original change's description: > Frame rate controller per spatial layer. > > This allows VP9 encoder wrapper to control frame rate of each spatial > layer. The wrapper configures encoder to skip encoding spatial layer > when actual frame rate exceeds the target frame rate of that layer. > Target frame rate of high spatial layer is expected to be equal or > higher then that of low spatial layer. For now frame rate controller > is only enabled in screen sharing mode. > > Added unit test which configures encoder to produce 3 spatial layers > with frame rates 10, 20 and 30fps and verifies that absolute delta of > final and target rate doesn't exceed 10%. > > Bug: webrtc:9682 > Change-Id: I7a7833f63927dd475e7b42d43e4d29061613e64e > Reviewed-on: https://webrtc-review.googlesource.com/96640 > Commit-Queue: Sergey Silkin <ssilkin@webrtc.org> > Reviewed-by: Erik Språng <sprang@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#24593} TBR=sprang@webrtc.org,ssilkin@webrtc.org # Not skipping CQ checks because original CL landed > 1 day ago. Bug: webrtc:9682, chromium:882358 Change-Id: Idc4051eef72104823038ed9139bb9c75018f7d86 Reviewed-on: https://webrtc-review.googlesource.com/99082 Commit-Queue: Sergey Silkin <ssilkin@webrtc.org> Reviewed-by: Sergey Silkin <ssilkin@webrtc.org> Cr-Commit-Position: refs/heads/master@{#24646}
This commit is contained in:

committed by
Commit Bot

parent
fb2a66a58a
commit
042661b404
@ -36,6 +36,8 @@
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
const float kMaxScreenSharingFramerateFps = 5.0f;
|
||||
|
||||
// Only positive speeds, range for real-time coding currently is: 5 - 8.
|
||||
// Lower means slower/better quality, higher means fastest/lower quality.
|
||||
int GetCpuSpeed(int width, int height) {
|
||||
@ -155,6 +157,7 @@ VP9EncoderImpl::VP9EncoderImpl(const cricket::VideoCodec& codec)
|
||||
num_spatial_layers_(0),
|
||||
is_svc_(false),
|
||||
inter_layer_pred_(InterLayerPredMode::kOn),
|
||||
framerate_controller_(kMaxScreenSharingFramerateFps),
|
||||
is_flexible_mode_(false) {
|
||||
memset(&codec_, 0, sizeof(codec_));
|
||||
memset(&svc_params_, 0, sizeof(vpx_svc_extra_cfg_t));
|
||||
@ -221,14 +224,6 @@ bool VP9EncoderImpl::SetSvcRates(
|
||||
force_key_frame_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!was_layer_enabled) {
|
||||
// Reset frame rate controller if layer is resumed after pause.
|
||||
framerate_controller_[sl_idx].Reset();
|
||||
}
|
||||
|
||||
framerate_controller_[sl_idx].SetTargetRate(
|
||||
codec_.spatialLayers[sl_idx].maxFramerate);
|
||||
}
|
||||
} else {
|
||||
float rate_ratio[VPX_MAX_LAYERS] = {0};
|
||||
@ -268,8 +263,6 @@ bool VP9EncoderImpl::SetSvcRates(
|
||||
<< num_temporal_layers_;
|
||||
return false;
|
||||
}
|
||||
|
||||
framerate_controller_[i].SetTargetRate(codec_.maxFramerate);
|
||||
}
|
||||
}
|
||||
|
||||
@ -360,12 +353,14 @@ int VP9EncoderImpl::InitEncode(const VideoCodec* inst,
|
||||
num_spatial_layers_ = inst->VP9().numberOfSpatialLayers;
|
||||
RTC_DCHECK_GT(num_spatial_layers_, 0);
|
||||
num_temporal_layers_ = inst->VP9().numberOfTemporalLayers;
|
||||
if (num_temporal_layers_ == 0) {
|
||||
if (num_temporal_layers_ == 0)
|
||||
num_temporal_layers_ = 1;
|
||||
}
|
||||
|
||||
framerate_controller_ = std::vector<FramerateController>(
|
||||
num_spatial_layers_, FramerateController(codec_.maxFramerate));
|
||||
// Init framerate controller.
|
||||
if (codec_.mode == VideoCodecMode::kScreensharing) {
|
||||
framerate_controller_.Reset();
|
||||
framerate_controller_.SetTargetRate(kMaxScreenSharingFramerateFps);
|
||||
}
|
||||
|
||||
is_svc_ = (num_spatial_layers_ > 1 || num_temporal_layers_ > 1);
|
||||
|
||||
@ -542,15 +537,6 @@ int VP9EncoderImpl::InitAndSetControlSettings(const VideoCodec* inst) {
|
||||
|
||||
svc_params_.scaling_factor_num[i] = 1;
|
||||
svc_params_.scaling_factor_den[i] = scale_factor;
|
||||
|
||||
RTC_DCHECK_GT(codec_.spatialLayers[i].maxFramerate, 0);
|
||||
RTC_DCHECK_LE(codec_.spatialLayers[i].maxFramerate, codec_.maxFramerate);
|
||||
if (i > 0) {
|
||||
// Frame rate of high spatial layer is supposed to be equal or higher
|
||||
// than frame rate of low spatial layer.
|
||||
RTC_DCHECK_GE(codec_.spatialLayers[i].maxFramerate,
|
||||
codec_.spatialLayers[i - 1].maxFramerate);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int scaling_factor_num = 256;
|
||||
@ -683,30 +669,10 @@ int VP9EncoderImpl::Encode(const VideoFrame& input_image,
|
||||
}
|
||||
|
||||
if (VideoCodecMode::kScreensharing == codec_.mode && !force_key_frame_) {
|
||||
// Skip encoding spatial layer frames if their target frame rate is lower
|
||||
// than actual input frame rate.
|
||||
vpx_svc_layer_id_t layer_id = {0};
|
||||
const size_t gof_idx = (pics_since_key_ + 1) % gof_.num_frames_in_gof;
|
||||
layer_id.temporal_layer_id = gof_.temporal_idx[gof_idx];
|
||||
|
||||
const uint32_t frame_timestamp_ms =
|
||||
1000 * input_image.timestamp() / kVideoPayloadTypeFrequency;
|
||||
|
||||
for (uint8_t sl_idx = 0; sl_idx < num_active_spatial_layers_; ++sl_idx) {
|
||||
if (framerate_controller_[sl_idx].DropFrame(frame_timestamp_ms)) {
|
||||
++layer_id.spatial_layer_id;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RTC_DCHECK_LE(layer_id.spatial_layer_id, num_active_spatial_layers_);
|
||||
if (layer_id.spatial_layer_id >= num_active_spatial_layers_) {
|
||||
// Drop entire picture.
|
||||
if (framerate_controller_.DropFrame(1000 * input_image.timestamp() /
|
||||
kVideoPayloadTypeFrequency)) {
|
||||
return WEBRTC_VIDEO_CODEC_OK;
|
||||
}
|
||||
|
||||
vpx_codec_control(encoder_, VP9E_SET_SVC_LAYER_ID, &layer_id);
|
||||
}
|
||||
|
||||
RTC_DCHECK_EQ(input_image.width(), raw_->d_w);
|
||||
@ -765,17 +731,11 @@ int VP9EncoderImpl::Encode(const VideoFrame& input_image,
|
||||
flags = VPX_EFLAG_FORCE_KF;
|
||||
}
|
||||
|
||||
// TODO(ssilkin): Frame duration should be specified per spatial layer
|
||||
// since their frame rate can be different. For now calculate frame duration
|
||||
// based on target frame rate of the highest spatial layer, which frame rate
|
||||
// is supposed to be equal or higher than frame rate of low spatial layers.
|
||||
// Also, timestamp should represent actual time passed since previous frame
|
||||
// (not 'expected' time). Then rate controller can drain buffer more
|
||||
// accurately.
|
||||
RTC_DCHECK_GE(framerate_controller_.size(), num_active_spatial_layers_);
|
||||
uint32_t duration = static_cast<uint32_t>(
|
||||
90000 /
|
||||
framerate_controller_[num_active_spatial_layers_ - 1].GetTargetRate());
|
||||
RTC_CHECK_GT(codec_.maxFramerate, 0);
|
||||
uint32_t target_framerate_fps = codec_.mode == VideoCodecMode::kScreensharing
|
||||
? kMaxScreenSharingFramerateFps
|
||||
: codec_.maxFramerate;
|
||||
uint32_t duration = 90000 / target_framerate_fps;
|
||||
const vpx_codec_err_t rv = vpx_codec_encode(encoder_, raw_, timestamp_,
|
||||
duration, flags, VPX_DL_REALTIME);
|
||||
if (rv != VPX_CODEC_OK) {
|
||||
@ -1107,11 +1067,10 @@ void VP9EncoderImpl::DeliverBufferedFrame(bool end_of_picture) {
|
||||
&frag_info);
|
||||
encoded_image_._length = 0;
|
||||
|
||||
if (codec_.mode == VideoCodecMode::kScreensharing) {
|
||||
const uint8_t spatial_idx = encoded_image_.SpatialIndex().value_or(0);
|
||||
const uint32_t frame_timestamp_ms =
|
||||
if (end_of_picture && codec_.mode == VideoCodecMode::kScreensharing) {
|
||||
const uint32_t timestamp_ms =
|
||||
1000 * encoded_image_.Timestamp() / kVideoPayloadTypeFrequency;
|
||||
framerate_controller_[spatial_idx].AddFrame(frame_timestamp_ms);
|
||||
framerate_controller_.AddFrame(timestamp_ms);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user