Remove WebRTC-FrameBuffer3 field trial
The new frame buffer is already the default. Sync decoding can now be inferred by the presence of a metronome rather than using the field trial. Tests have been updated to use the DecodeSynchronizer rather than the field trial. Bug: webrtc:14003 Change-Id: I33b457feaf4eac1500f3bf828680e445ae4d93cf Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/274163 Auto-Submit: Evan Shrubsole <eshr@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Erik Språng <sprang@webrtc.org> Cr-Commit-Position: refs/heads/main@{#38011}
This commit is contained in:

committed by
WebRTC LUCI CQ

parent
fbfd81f61a
commit
a006ba152f
@ -55,6 +55,7 @@ rtc_library("video") {
|
||||
deps = [
|
||||
":frame_cadence_adapter",
|
||||
":frame_dumping_decoder",
|
||||
":task_queue_frame_decode_scheduler",
|
||||
":unique_timestamp_counter",
|
||||
":video_stream_buffer_controller",
|
||||
":video_stream_encoder_impl",
|
||||
@ -239,6 +240,7 @@ rtc_library("video_stream_buffer_controller") {
|
||||
]
|
||||
deps = [
|
||||
":decode_synchronizer",
|
||||
":frame_decode_scheduler",
|
||||
":frame_decode_timing",
|
||||
":task_queue_frame_decode_scheduler",
|
||||
":video_receive_stream_timeout_tracker",
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include "video/call_stats2.h"
|
||||
#include "video/frame_dumping_decoder.h"
|
||||
#include "video/receive_statistics_proxy2.h"
|
||||
#include "video/task_queue_frame_decode_scheduler.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -227,7 +228,6 @@ VideoReceiveStream2::VideoReceiveStream2(
|
||||
TimeDelta::Millis(config_.rtp.nack.rtp_history_ms),
|
||||
false)),
|
||||
maximum_pre_stream_decoders_("max", kDefaultMaximumPreStreamDecoders),
|
||||
decode_sync_(decode_sync),
|
||||
decode_queue_(task_queue_factory_->CreateTaskQueue(
|
||||
"DecodingQueue",
|
||||
TaskQueueFactory::Priority::HIGH)) {
|
||||
@ -251,9 +251,13 @@ VideoReceiveStream2::VideoReceiveStream2(
|
||||
|
||||
timing_->set_render_delay(TimeDelta::Millis(config_.render_delay_ms));
|
||||
|
||||
buffer_ = VideoStreamBufferController::CreateFromFieldTrial(
|
||||
std::unique_ptr<FrameDecodeScheduler> scheduler =
|
||||
decode_sync ? decode_sync->CreateSynchronizedFrameScheduler()
|
||||
: std::make_unique<TaskQueueFrameDecodeScheduler>(
|
||||
clock, call_->worker_thread());
|
||||
buffer_ = std::make_unique<VideoStreamBufferController>(
|
||||
clock_, call_->worker_thread(), timing_.get(), &stats_proxy_, this,
|
||||
max_wait_for_keyframe_, max_wait_for_frame_, decode_sync_,
|
||||
max_wait_for_keyframe_, max_wait_for_frame_, std::move(scheduler),
|
||||
call_->trials());
|
||||
|
||||
if (rtx_ssrc()) {
|
||||
|
@ -339,8 +339,6 @@ class VideoReceiveStream2
|
||||
// any video frame has been received.
|
||||
FieldTrialParameter<int> maximum_pre_stream_decoders_;
|
||||
|
||||
DecodeSynchronizer* decode_sync_;
|
||||
|
||||
// Defined last so they are destroyed before all other members.
|
||||
rtc::TaskQueue decode_queue_;
|
||||
|
||||
|
@ -203,12 +203,6 @@ class VideoReceiveStream2Test : public ::testing::TestWithParam<bool> {
|
||||
&fake_metronome_,
|
||||
time_controller_.GetMainThread()),
|
||||
h264_decoder_factory_(&mock_decoder_) {
|
||||
if (UseMetronome()) {
|
||||
fake_call_.SetFieldTrial("WebRTC-FrameBuffer3/arm:SyncDecoding/");
|
||||
} else {
|
||||
fake_call_.SetFieldTrial("WebRTC-FrameBuffer3/arm:FrameBuffer3/");
|
||||
}
|
||||
|
||||
// By default, mock decoder factory is backed by VideoDecoderProxyFactory.
|
||||
ON_CALL(mock_h264_decoder_factory_, CreateVideoDecoder)
|
||||
.WillByDefault(
|
||||
@ -270,7 +264,7 @@ class VideoReceiveStream2Test : public ::testing::TestWithParam<bool> {
|
||||
time_controller_.GetTaskQueueFactory(), &fake_call_,
|
||||
kDefaultNumCpuCores, &packet_router_, config_.Copy(), &call_stats_,
|
||||
clock_, absl::WrapUnique(timing_), &nack_periodic_processor_,
|
||||
GetParam() ? &decode_sync_ : nullptr, nullptr);
|
||||
UseMetronome() ? &decode_sync_ : nullptr, nullptr);
|
||||
video_receive_stream_->RegisterWithTransport(
|
||||
&rtp_stream_receiver_controller_);
|
||||
if (state)
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/logging.h"
|
||||
#include "rtc_base/thread_annotations.h"
|
||||
#include "video/frame_decode_scheduler.h"
|
||||
#include "video/frame_decode_timing.h"
|
||||
#include "video/task_queue_frame_decode_scheduler.h"
|
||||
#include "video/video_receive_stream_timeout_tracker.h"
|
||||
@ -70,68 +71,8 @@ Timestamp ReceiveTime(const EncodedFrame& frame) {
|
||||
return *ts;
|
||||
}
|
||||
|
||||
enum class FrameBufferArm {
|
||||
kFrameBuffer3,
|
||||
kSyncDecode,
|
||||
};
|
||||
|
||||
constexpr const char* kFrameBufferFieldTrial = "WebRTC-FrameBuffer3";
|
||||
|
||||
FrameBufferArm ParseFrameBufferFieldTrial(const FieldTrialsView& field_trials) {
|
||||
webrtc::FieldTrialEnum<FrameBufferArm> arm(
|
||||
"arm", FrameBufferArm::kFrameBuffer3,
|
||||
{
|
||||
{"FrameBuffer3", FrameBufferArm::kFrameBuffer3},
|
||||
{"SyncDecoding", FrameBufferArm::kSyncDecode},
|
||||
});
|
||||
ParseFieldTrial({&arm}, field_trials.Lookup(kFrameBufferFieldTrial));
|
||||
return arm.Get();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::unique_ptr<VideoStreamBufferController>
|
||||
VideoStreamBufferController::CreateFromFieldTrial(
|
||||
Clock* clock,
|
||||
TaskQueueBase* worker_queue,
|
||||
VCMTiming* timing,
|
||||
VCMReceiveStatisticsCallback* stats_proxy,
|
||||
FrameSchedulingReceiver* receiver,
|
||||
TimeDelta max_wait_for_keyframe,
|
||||
TimeDelta max_wait_for_frame,
|
||||
DecodeSynchronizer* decode_sync,
|
||||
const FieldTrialsView& field_trials) {
|
||||
switch (ParseFrameBufferFieldTrial(field_trials)) {
|
||||
case FrameBufferArm::kSyncDecode: {
|
||||
std::unique_ptr<FrameDecodeScheduler> scheduler;
|
||||
if (decode_sync) {
|
||||
scheduler = decode_sync->CreateSynchronizedFrameScheduler();
|
||||
} else {
|
||||
RTC_LOG(LS_ERROR) << "In FrameBuffer with sync decode trial, but "
|
||||
"no DecodeSynchronizer was present!";
|
||||
// Crash in debug, but in production use the task queue scheduler.
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
scheduler = std::make_unique<TaskQueueFrameDecodeScheduler>(
|
||||
clock, worker_queue);
|
||||
}
|
||||
return std::make_unique<VideoStreamBufferController>(
|
||||
clock, worker_queue, timing, stats_proxy, receiver,
|
||||
max_wait_for_keyframe, max_wait_for_frame, std::move(scheduler),
|
||||
field_trials);
|
||||
}
|
||||
case FrameBufferArm::kFrameBuffer3:
|
||||
ABSL_FALLTHROUGH_INTENDED;
|
||||
default: {
|
||||
auto scheduler =
|
||||
std::make_unique<TaskQueueFrameDecodeScheduler>(clock, worker_queue);
|
||||
return std::make_unique<VideoStreamBufferController>(
|
||||
clock, worker_queue, timing, stats_proxy, receiver,
|
||||
max_wait_for_keyframe, max_wait_for_frame, std::move(scheduler),
|
||||
field_trials);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VideoStreamBufferController::VideoStreamBufferController(
|
||||
Clock* clock,
|
||||
TaskQueueBase* worker_queue,
|
||||
|
@ -38,17 +38,6 @@ class FrameSchedulingReceiver {
|
||||
|
||||
class VideoStreamBufferController {
|
||||
public:
|
||||
static std::unique_ptr<VideoStreamBufferController> CreateFromFieldTrial(
|
||||
Clock* clock,
|
||||
TaskQueueBase* worker_queue,
|
||||
VCMTiming* timing,
|
||||
VCMReceiveStatisticsCallback* stats_proxy,
|
||||
FrameSchedulingReceiver* receiver,
|
||||
TimeDelta max_wait_for_keyframe,
|
||||
TimeDelta max_wait_for_frame,
|
||||
DecodeSynchronizer* decode_sync,
|
||||
const FieldTrialsView& field_trials);
|
||||
virtual ~VideoStreamBufferController() = default;
|
||||
VideoStreamBufferController(
|
||||
Clock* clock,
|
||||
TaskQueueBase* worker_queue,
|
||||
@ -59,6 +48,7 @@ class VideoStreamBufferController {
|
||||
TimeDelta max_wait_for_frame,
|
||||
std::unique_ptr<FrameDecodeScheduler> frame_decode_scheduler,
|
||||
const FieldTrialsView& field_trials);
|
||||
virtual ~VideoStreamBufferController() = default;
|
||||
|
||||
void Stop();
|
||||
void SetProtectionMode(VCMVideoProtection protection_mode);
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@ -33,6 +34,7 @@
|
||||
#include "test/scoped_key_value_config.h"
|
||||
#include "test/time_controller/simulated_time_controller.h"
|
||||
#include "video/decode_synchronizer.h"
|
||||
#include "video/task_queue_frame_decode_scheduler.h"
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::AllOf;
|
||||
@ -107,11 +109,12 @@ class VCMReceiveStatisticsCallbackMock : public VCMReceiveStatisticsCallback {
|
||||
constexpr auto kMaxWaitForKeyframe = TimeDelta::Millis(500);
|
||||
constexpr auto kMaxWaitForFrame = TimeDelta::Millis(1500);
|
||||
class VideoStreamBufferControllerFixture
|
||||
: public ::testing::WithParamInterface<std::string>,
|
||||
: public ::testing::WithParamInterface<std::tuple<bool, std::string>>,
|
||||
public FrameSchedulingReceiver {
|
||||
public:
|
||||
VideoStreamBufferControllerFixture()
|
||||
: field_trials_(GetParam()),
|
||||
: sync_decoding_(std::get<0>(GetParam())),
|
||||
field_trials_(std::get<1>(GetParam())),
|
||||
time_controller_(kClockStart),
|
||||
clock_(time_controller_.GetClock()),
|
||||
fake_metronome_(time_controller_.GetTaskQueueFactory(),
|
||||
@ -120,7 +123,7 @@ class VideoStreamBufferControllerFixture
|
||||
&fake_metronome_,
|
||||
time_controller_.GetMainThread()),
|
||||
timing_(clock_, field_trials_),
|
||||
buffer_(VideoStreamBufferController::CreateFromFieldTrial(
|
||||
buffer_(std::make_unique<VideoStreamBufferController>(
|
||||
clock_,
|
||||
time_controller_.GetMainThread(),
|
||||
&timing_,
|
||||
@ -128,7 +131,10 @@ class VideoStreamBufferControllerFixture
|
||||
this,
|
||||
kMaxWaitForKeyframe,
|
||||
kMaxWaitForFrame,
|
||||
&decode_sync_,
|
||||
sync_decoding_ ? decode_sync_.CreateSynchronizedFrameScheduler()
|
||||
: std::make_unique<TaskQueueFrameDecodeScheduler>(
|
||||
clock_,
|
||||
time_controller_.GetMainThread()),
|
||||
field_trials_)) {
|
||||
// Avoid starting with negative render times.
|
||||
timing_.set_min_playout_delay(TimeDelta::Millis(10));
|
||||
@ -198,6 +204,7 @@ class VideoStreamBufferControllerFixture
|
||||
int dropped_frames() const { return dropped_frames_; }
|
||||
|
||||
protected:
|
||||
const bool sync_decoding_;
|
||||
test::ScopedKeyValueConfig field_trials_;
|
||||
GlobalSimulatedTimeController time_controller_;
|
||||
Clock* const clock_;
|
||||
@ -732,11 +739,14 @@ TEST_P(VideoStreamBufferControllerTest, NextFrameWithOldTimestamp) {
|
||||
EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Frame(test::WithId(2)));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
VideoStreamBufferController,
|
||||
VideoStreamBufferControllerTest,
|
||||
::testing::Values("WebRTC-FrameBuffer3/arm:FrameBuffer3/",
|
||||
"WebRTC-FrameBuffer3/arm:SyncDecoding/"));
|
||||
INSTANTIATE_TEST_SUITE_P(VideoStreamBufferController,
|
||||
VideoStreamBufferControllerTest,
|
||||
::testing::Combine(::testing::Bool(),
|
||||
::testing::Values("")),
|
||||
[](const auto& info) {
|
||||
return std::get<0>(info.param) ? "SyncDecoding"
|
||||
: "UnsyncedDecoding";
|
||||
});
|
||||
|
||||
class LowLatencyVideoStreamBufferControllerTest
|
||||
: public ::testing::Test,
|
||||
@ -817,10 +827,11 @@ TEST_P(LowLatencyVideoStreamBufferControllerTest,
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
VideoStreamBufferController,
|
||||
LowLatencyVideoStreamBufferControllerTest,
|
||||
::testing::Values(
|
||||
"WebRTC-FrameBuffer3/arm:FrameBuffer3/"
|
||||
"WebRTC-ZeroPlayoutDelay/min_pacing:16ms,max_decode_queue_size:5/",
|
||||
"WebRTC-FrameBuffer3/arm:SyncDecoding/"
|
||||
"WebRTC-ZeroPlayoutDelay/min_pacing:16ms,max_decode_queue_size:5/"));
|
||||
::testing::Combine(
|
||||
::testing::Bool(),
|
||||
::testing::Values(
|
||||
"WebRTC-ZeroPlayoutDelay/min_pacing:16ms,max_decode_queue_size:5/",
|
||||
"WebRTC-ZeroPlayoutDelay/"
|
||||
"min_pacing:16ms,max_decode_queue_size:5/")));
|
||||
|
||||
} // namespace webrtc
|
||||
|
Reference in New Issue
Block a user