Don't count frames passed to VP8 BWE disabled streams as being encoded
This excludes these frames from being counted as dropped by encoder.
Also fix bitrate projected distribution for vp9 svc for outliers
detection.
Bug: webrtc:8497
Change-Id: Id37487456170c61e2323a660668f0c319ea5831d
Reviewed-on: https://webrtc-review.googlesource.com/21223
Commit-Queue: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20632}
diff --git a/modules/video_coding/generic_encoder.cc b/modules/video_coding/generic_encoder.cc
index ec47952..fd642fd 100644
--- a/modules/video_coding/generic_encoder.cc
+++ b/modules/video_coding/generic_encoder.cc
@@ -49,6 +49,7 @@
RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
TRACE_EVENT0("webrtc", "VCMGenericEncoder::InitEncode");
streams_or_svc_num_ = settings->numberOfSimulcastStreams;
+ codec_type_ = settings->codecType;
if (settings->codecType == kVideoCodecVP9) {
streams_or_svc_num_ = settings->VP9().numberOfSpatialLayers;
}
@@ -122,9 +123,16 @@
size_t layer_bitrate_bytes_per_sec =
params.target_bitrate.GetSpatialLayerSum(i) / 8;
// VP9 rate control is not yet moved out of VP9Impl. Due to that rates
- // are not split among spatial layers.
- if (layer_bitrate_bytes_per_sec == 0)
- layer_bitrate_bytes_per_sec = params.target_bitrate.get_sum_bps() / 8;
+ // are not split among spatial layers. Use default 1:2:4 bitrate
+ // distribution.
+ // TODO(ilnik): move bitrate per spatial layer calculations out of
+ // vp9_impl.cc and drop the check below.
+ if (codec_type_ == kVideoCodecVP9) {
+ int scaling_factor_num = 1 << i; // 1, 2 or 4
+ int scaling_factor_den = (1 << streams_or_svc_num_) - 1; // 1 + 2 + 4
+ layer_bitrate_bytes_per_sec = params.target_bitrate.get_sum_bps() / 8 *
+ scaling_factor_num / scaling_factor_den;
+ }
vcm_encoded_frame_callback_->OnTargetBitrateChanged(
layer_bitrate_bytes_per_sec, i);
}
@@ -223,6 +231,10 @@
rtc::TimeDiff(capture_time_ms, timing_frames_info_[simulcast_svc_idx]
.encode_start_list.back()
.capture_time_ms) >= 0);
+ // If stream is disabled due to low bandwidth OnEncodeStarted still will be
+ // called and have to be ignored.
+ if (timing_frames_info_[simulcast_svc_idx].target_bitrate_bytes_per_sec == 0)
+ return;
if (timing_frames_info_[simulcast_svc_idx].encode_start_list.size() ==
kMaxEncodeStartTimeListSize) {
RTC_LOG(LS_WARNING) << "Too many frames in the encode_start_list."
@@ -279,6 +291,9 @@
encode_start_ms.emplace(
encode_start_list->front().encode_start_time_ms);
encode_start_list->pop_front();
+ } else {
+ LOG(LS_WARNING) << "Frame with no encode started time recordings. "
+ "Encoder may be reordering frames.";
}
size_t target_bitrate =
diff --git a/modules/video_coding/generic_encoder.h b/modules/video_coding/generic_encoder.h
index 878588d..dc94e4a 100644
--- a/modules/video_coding/generic_encoder.h
+++ b/modules/video_coding/generic_encoder.h
@@ -135,7 +135,8 @@
const bool internal_source_;
rtc::CriticalSection params_lock_;
EncoderParameters encoder_params_ RTC_GUARDED_BY(params_lock_);
- size_t streams_or_svc_num_;
+ size_t streams_or_svc_num_ RTC_GUARDED_BY(race_checker_);
+ VideoCodecType codec_type_ RTC_GUARDED_BY(race_checker_);
};
} // namespace webrtc
diff --git a/modules/video_coding/generic_encoder_unittest.cc b/modules/video_coding/generic_encoder_unittest.cc
index caada6e..48c152f 100644
--- a/modules/video_coding/generic_encoder_unittest.cc
+++ b/modules/video_coding/generic_encoder_unittest.cc
@@ -185,6 +185,7 @@
VideoCodec::TimingFrameTriggerThresholds thresholds;
thresholds.delay_ms = 1; // Make all frames timing frames.
callback.SetTimingFramesThresholds(thresholds);
+ callback.OnTargetBitrateChanged(500, 0);
// Verify a single frame works with encode start time set.
callback.OnEncodeStarted(timestamp, 0);
@@ -208,6 +209,8 @@
codec_specific.codecSpecific.generic.simulcast_idx = 0;
FakeEncodedImageCallback sink;
VCMEncodedFrameCallback callback(&sink, nullptr);
+ // Any non-zero bitrate needed to be set before the first frame.
+ callback.OnTargetBitrateChanged(500, 0);
callback.OnEncodeStarted(timestamp1, 0);
EXPECT_EQ(0u, sink.GetNumFramesDropped());
image.capture_time_ms_ = timestamp1;