Revert "Remove FrameBuffer2Proxy"
This reverts commit de0d063767bbaffae7ab9b2c785bb862b387ae5c.
Reason for revert: Perf test regressions that need investigation.
Original change's description:
> Remove FrameBuffer2Proxy
>
> Bug: webrtc:14003
> Change-Id: I461a9159b33ca3693bcb59d94c2035093825588b
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/265866
> Commit-Queue: Evan Shrubsole <eshr@webrtc.org>
> Reviewed-by: Erik Språng <sprang@webrtc.org>
> Cr-Commit-Position: refs/heads/main@{#37253}
Bug: webrtc:14003
Change-Id: Ic7ef05e4021e8568eb8cfff13dc3e6753fbdec18
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/266340
Commit-Queue: Evan Shrubsole <eshr@webrtc.org>
Auto-Submit: Evan Shrubsole <eshr@webrtc.org>
Commit-Queue: Erik Språng <sprang@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37277}
diff --git a/video/BUILD.gn b/video/BUILD.gn
index 6e59619..65f02d8 100644
--- a/video/BUILD.gn
+++ b/video/BUILD.gn
@@ -280,7 +280,6 @@
"../rtc_base:logging",
"../rtc_base:macromagic",
"../rtc_base:rtc_task_queue",
- "../rtc_base/experiments:rtt_mult_experiment",
"../system_wrappers",
"../system_wrappers:field_trial",
]
diff --git a/video/frame_buffer_proxy.cc b/video/frame_buffer_proxy.cc
index 1d28d94..f69d9da 100644
--- a/video/frame_buffer_proxy.cc
+++ b/video/frame_buffer_proxy.cc
@@ -21,11 +21,11 @@
#include "api/video/encoded_frame.h"
#include "api/video/frame_buffer.h"
#include "api/video/video_content_type.h"
+#include "modules/video_coding/frame_buffer2.h"
#include "modules/video_coding/frame_helpers.h"
#include "modules/video_coding/timing/inter_frame_delay.h"
#include "modules/video_coding/timing/jitter_estimator.h"
#include "rtc_base/checks.h"
-#include "rtc_base/experiments/rtt_mult_experiment.h"
#include "rtc_base/logging.h"
#include "rtc_base/thread_annotations.h"
#include "video/frame_decode_timing.h"
@@ -36,6 +36,104 @@
namespace {
+class FrameBuffer2Proxy : public FrameBufferProxy {
+ public:
+ FrameBuffer2Proxy(Clock* clock,
+ VCMTiming* timing,
+ VCMReceiveStatisticsCallback* stats_proxy,
+ rtc::TaskQueue* decode_queue,
+ FrameSchedulingReceiver* receiver,
+ TimeDelta max_wait_for_keyframe,
+ TimeDelta max_wait_for_frame,
+ const FieldTrialsView& field_trials)
+ : max_wait_for_keyframe_(max_wait_for_keyframe),
+ max_wait_for_frame_(max_wait_for_frame),
+ frame_buffer_(clock, timing, stats_proxy, field_trials),
+ decode_queue_(decode_queue),
+ stats_proxy_(stats_proxy),
+ receiver_(receiver) {
+ RTC_DCHECK(decode_queue_);
+ RTC_DCHECK(stats_proxy_);
+ RTC_DCHECK(receiver_);
+ }
+
+ void StopOnWorker() override {
+ RTC_DCHECK_RUN_ON(&worker_sequence_checker_);
+ decode_queue_->PostTask([this] {
+ frame_buffer_.Stop();
+ decode_safety_->SetNotAlive();
+ });
+ }
+
+ void SetProtectionMode(VCMVideoProtection protection_mode) override {
+ RTC_DCHECK_RUN_ON(&worker_sequence_checker_);
+ frame_buffer_.SetProtectionMode(kProtectionNackFEC);
+ }
+
+ void Clear() override {
+ RTC_DCHECK_RUN_ON(&worker_sequence_checker_);
+ frame_buffer_.Clear();
+ }
+
+ absl::optional<int64_t> InsertFrame(
+ std::unique_ptr<EncodedFrame> frame) override {
+ RTC_DCHECK_RUN_ON(&worker_sequence_checker_);
+ int64_t last_continuous_pid = frame_buffer_.InsertFrame(std::move(frame));
+ if (last_continuous_pid != -1)
+ return last_continuous_pid;
+ return absl::nullopt;
+ }
+
+ void UpdateRtt(int64_t max_rtt_ms) override {
+ RTC_DCHECK_RUN_ON(&worker_sequence_checker_);
+ frame_buffer_.UpdateRtt(max_rtt_ms);
+ }
+
+ void StartNextDecode(bool keyframe_required) override {
+ if (!decode_queue_->IsCurrent()) {
+ decode_queue_->PostTask(ToQueuedTask(
+ decode_safety_,
+ [this, keyframe_required] { StartNextDecode(keyframe_required); }));
+ return;
+ }
+ RTC_DCHECK_RUN_ON(decode_queue_);
+
+ frame_buffer_.NextFrame(
+ MaxWait(keyframe_required).ms(), keyframe_required, decode_queue_,
+ /* encoded frame handler */
+ [this, keyframe_required](std::unique_ptr<EncodedFrame> frame) {
+ RTC_DCHECK_RUN_ON(decode_queue_);
+ if (!decode_safety_->alive())
+ return;
+ if (frame) {
+ receiver_->OnEncodedFrame(std::move(frame));
+ } else {
+ receiver_->OnDecodableFrameTimeout(MaxWait(keyframe_required));
+ }
+ });
+ }
+
+ int Size() override {
+ RTC_DCHECK_RUN_ON(&worker_sequence_checker_);
+ return frame_buffer_.Size();
+ }
+
+ private:
+ TimeDelta MaxWait(bool keyframe_required) const {
+ return keyframe_required ? max_wait_for_keyframe_ : max_wait_for_frame_;
+ }
+
+ RTC_NO_UNIQUE_ADDRESS SequenceChecker worker_sequence_checker_;
+ const TimeDelta max_wait_for_keyframe_;
+ const TimeDelta max_wait_for_frame_;
+ video_coding::FrameBuffer frame_buffer_;
+ rtc::TaskQueue* const decode_queue_;
+ VCMReceiveStatisticsCallback* const stats_proxy_;
+ FrameSchedulingReceiver* const receiver_;
+ rtc::scoped_refptr<PendingTaskSafetyFlag> decode_safety_ =
+ PendingTaskSafetyFlag::CreateDetached();
+};
+
// Max number of frames the buffer will hold.
static constexpr size_t kMaxFramesBuffered = 800;
// Max number of decoded frame info that will be saved.
@@ -436,6 +534,7 @@
};
enum class FrameBufferArm {
+ kFrameBuffer2,
kFrameBuffer3,
kSyncDecode,
};
@@ -444,8 +543,9 @@
FrameBufferArm ParseFrameBufferFieldTrial(const FieldTrialsView& field_trials) {
webrtc::FieldTrialEnum<FrameBufferArm> arm(
- "arm", FrameBufferArm::kFrameBuffer3,
+ "arm", FrameBufferArm::kFrameBuffer2,
{
+ {"FrameBuffer2", FrameBufferArm::kFrameBuffer2},
{"FrameBuffer3", FrameBufferArm::kFrameBuffer3},
{"SyncDecoding", FrameBufferArm::kSyncDecode},
});
@@ -467,6 +567,10 @@
DecodeSynchronizer* decode_sync,
const FieldTrialsView& field_trials) {
switch (ParseFrameBufferFieldTrial(field_trials)) {
+ case FrameBufferArm::kFrameBuffer2:
+ return std::make_unique<FrameBuffer2Proxy>(
+ clock, timing, stats_proxy, decode_queue, receiver,
+ max_wait_for_keyframe, max_wait_for_frame, field_trials);
case FrameBufferArm::kSyncDecode: {
std::unique_ptr<FrameDecodeScheduler> scheduler;
if (decode_sync) {
diff --git a/video/frame_buffer_proxy_unittest.cc b/video/frame_buffer_proxy_unittest.cc
index 4d4aae4..6babcda 100644
--- a/video/frame_buffer_proxy_unittest.cc
+++ b/video/frame_buffer_proxy_unittest.cc
@@ -27,6 +27,7 @@
#include "api/video/video_content_type.h"
#include "api/video/video_timing.h"
#include "rtc_base/checks.h"
+#include "rtc_base/event.h"
#include "test/fake_encoded_frame.h"
#include "test/gmock.h"
#include "test/gtest.h"
@@ -103,6 +104,11 @@
(override));
};
+bool IsFrameBuffer2Enabled(const FieldTrialsView& field_trials) {
+ return field_trials.Lookup("WebRTC-FrameBuffer3").find("arm:FrameBuffer2") !=
+ std::string::npos;
+}
+
} // namespace
constexpr auto kMaxWaitForKeyframe = TimeDelta::Millis(500);
@@ -233,7 +239,7 @@
TEST_P(FrameBufferProxyTest, InitialTimeoutAfterKeyframeTimeoutPeriod) {
StartNextDecodeForceKeyframe();
- // No frame inserted. Timeout expected.
+ // No frame insterted. Timeout expected.
EXPECT_THAT(WaitForFrameOrTimeout(kMaxWaitForKeyframe), TimedOut());
// No new timeout set since receiver has not started new decode.
@@ -658,6 +664,8 @@
TEST_P(FrameBufferProxyTest, FrameCompleteCalledOnceForCompleteTemporalUnit) {
// FrameBuffer2 logs the complete frame on the arrival of the last layer.
+ if (IsFrameBuffer2Enabled(field_trials_))
+ return;
StartNextDecodeForceKeyframe();
// `OnCompleteFrame` should not be called for the first two frames since they
@@ -734,13 +742,18 @@
.AsLast()
.Build());
// FrameBuffer2 drops the frame, while FrameBuffer3 will continue the stream.
- EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Frame(test::WithId(2)));
+ if (!IsFrameBuffer2Enabled(field_trials_)) {
+ EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Frame(test::WithId(2)));
+ } else {
+ EXPECT_THAT(WaitForFrameOrTimeout(kMaxWaitForFrame), TimedOut());
+ }
}
INSTANTIATE_TEST_SUITE_P(
FrameBufferProxy,
FrameBufferProxyTest,
- ::testing::Values("WebRTC-FrameBuffer3/arm:FrameBuffer3/",
+ ::testing::Values("WebRTC-FrameBuffer3/arm:FrameBuffer2/",
+ "WebRTC-FrameBuffer3/arm:FrameBuffer3/",
"WebRTC-FrameBuffer3/arm:SyncDecoding/"));
class LowLatencyFrameBufferProxyTest : public ::testing::Test,
@@ -821,6 +834,8 @@
FrameBufferProxy,
LowLatencyFrameBufferProxyTest,
::testing::Values(
+ "WebRTC-FrameBuffer3/arm:FrameBuffer2/"
+ "WebRTC-ZeroPlayoutDelay/min_pacing:16ms,max_decode_queue_size:5/",
"WebRTC-FrameBuffer3/arm:FrameBuffer3/"
"WebRTC-ZeroPlayoutDelay/min_pacing:16ms,max_decode_queue_size:5/",
"WebRTC-FrameBuffer3/arm:SyncDecoding/"