Revert "Follow codec preference order for sending codec fallback."

This reverts commit 1ad3e14e9981772554a848c5034c7c555680aef7.

Reason for revert: Breaks downstream project. We are investigating into a potential problem when running on mobile platforms. We will get back with info or reland.

Original change's description:
> Follow codec preference order for sending codec fallback.
>
> When encoder selector is not enabled, currently we always fallback to
> VP8 no matter how the codec preference is setup. Update to follow codec
> preference order for the fallback.
>
> Bug: chromium:378566918
> Change-Id: Ia3fbfc9d407683ef7b3d6246af7e9ec58535dc89
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/370707
> Reviewed-by: Erik Språng <sprang@webrtc.org>
> Reviewed-by: Henrik Boström <hbos@webrtc.org>
> Commit-Queue: Jianlin Qiu <jianlin.qiu@intel.com>
> Reviewed-by: Harald Alvestrand <hta@webrtc.org>
> Reviewed-by: Sergey Silkin <ssilkin@webrtc.org>
> Cr-Commit-Position: refs/heads/main@{#43566}

Bug: chromium:378566918
Change-Id: I09086b5ad100a8f66e87df167e903d0b5fe5b589
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/372080
Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com>
Reviewed-by: Sergey Silkin <ssilkin@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#43600}
This commit is contained in:
Mirko Bonadei 2024-12-18 07:41:08 -08:00 committed by WebRTC LUCI CQ
parent 29af9f0c87
commit 7976b77345
6 changed files with 12 additions and 169 deletions

View File

@ -152,9 +152,6 @@ ACTIVE_FIELD_TRIALS: FrozenSet[FieldTrial] = frozenset([
FieldTrial('WebRTC-SrtpRemoveReceiveStream',
42225949,
date(2024, 10, 1)),
FieldTrial('WebRTC-SwitchEncoderFollowCodecPreferenceOrder',
378566918,
date(2025, 5, 1)),
FieldTrial('WebRTC-TaskQueue-ReplaceLibeventWithStdlib',
42224654,
date(2024, 4, 1)),

View File

@ -1233,10 +1233,6 @@ void WebRtcVideoSendChannel::RequestEncoderFallback() {
RTC_DCHECK_RUN_ON(&thread_checker_);
if (negotiated_codecs_.size() <= 1) {
RTC_LOG(LS_WARNING) << "Encoder failed but no fallback codec is available";
// Remove all the send streams since we cannot encode any more.
while (!send_streams_.empty()) {
RemoveSendStream(send_streams_.begin()->first);
}
return;
}

View File

@ -2547,31 +2547,6 @@ TEST_F(WebRtcVideoChannelBaseTest, TwoStreamsSendAndReceive) {
TwoStreamsSendAndReceive(codec);
}
TEST_F(WebRtcVideoChannelBaseTest,
RequestEncoderFallbackNextCodecFollowNegotiatedOrder) {
cricket::VideoSenderParameters parameters;
parameters.codecs.push_back(GetEngineCodec("VP9"));
parameters.codecs.push_back(GetEngineCodec("AV1"));
parameters.codecs.push_back(GetEngineCodec("VP8"));
EXPECT_TRUE(send_channel_->SetSenderParameters(parameters));
std::optional<Codec> codec = send_channel_->GetSendCodec();
ASSERT_TRUE(codec);
EXPECT_EQ("VP9", codec->name);
SendImpl()->RequestEncoderFallback();
time_controller_.AdvanceTime(kFrameDuration);
codec = send_channel_->GetSendCodec();
ASSERT_TRUE(codec);
EXPECT_EQ("AV1", codec->name);
SendImpl()->RequestEncoderFallback();
time_controller_.AdvanceTime(kFrameDuration);
codec = send_channel_->GetSendCodec();
ASSERT_TRUE(codec);
EXPECT_EQ("VP8", codec->name);
}
#if defined(RTC_ENABLE_VP9)
TEST_F(WebRtcVideoChannelBaseTest, RequestEncoderFallback) {

View File

@ -80,10 +80,6 @@ constexpr char kFrameDropperFieldTrial[] = "WebRTC-FrameDropper";
constexpr char kSwitchEncoderOnInitializationFailuresFieldTrial[] =
"WebRTC-SwitchEncoderOnInitializationFailures";
// TODO(crbugs.com/378566918): Remove this kill switch after rollout.
constexpr char kSwitchEncoderFollowCodecPreferenceOrderFieldTrial[] =
"WebRTC-SwitchEncoderFollowCodecPreferenceOrder";
const size_t kDefaultPayloadSize = 1440;
const int64_t kParameterUpdateIntervalMs = 1000;
@ -1485,21 +1481,15 @@ void VideoStreamEncoder::RequestEncoderSwitch() {
}
// If encoder selector is available, switch to the encoder it prefers.
// Otherwise try switching to VP8 (default WebRTC codec).
std::optional<SdpVideoFormat> preferred_fallback_encoder;
if (is_encoder_selector_available) {
preferred_fallback_encoder = encoder_selector_->OnEncoderBroken();
}
if (!preferred_fallback_encoder) {
if (!env_.field_trials().IsDisabled(
kSwitchEncoderFollowCodecPreferenceOrderFieldTrial)) {
encoder_fallback_requested_ = true;
settings_.encoder_switch_request_callback->RequestEncoderFallback();
return;
} else {
preferred_fallback_encoder =
SdpVideoFormat(CodecTypeToPayloadString(kVideoCodecVP8));
}
preferred_fallback_encoder =
SdpVideoFormat(CodecTypeToPayloadString(kVideoCodecVP8));
}
settings_.encoder_switch_request_callback->RequestEncoderSwitch(
@ -1902,15 +1892,11 @@ void VideoStreamEncoder::EncodeVideoFrame(const VideoFrame& video_frame,
RTC_LOG(LS_VERBOSE) << __func__ << " posted " << time_when_posted_us
<< " ntp time " << video_frame.ntp_time_ms();
// If encoder fallback is requested, but WebRtcVideoEngine cannot switch codec
// due to negotatied codec list is already exhausted, we don't continue to
// encode frames, and WebRtcVideoEngine will destroy the VideoSendStreams
// along with current VideoStreamEncoder. If the encoder fallback is requested
// and WebRtcVideoEngine responds to the fallback request, the VideoSendStream
// is recreated and current VideoStreamEncoder will no longer be used.
if (encoder_fallback_requested_ || !encoder_initialized_) {
// If the encoder fail we can't continue to encode frames. When this happens
// the WebrtcVideoSender is notified and the whole VideoSendStream is
// recreated.
if (encoder_failed_ || !encoder_initialized_)
return;
}
// It's possible that EncodeVideoFrame can be called after we've completed
// a Stop() operation. Check if the encoder_ is set before continuing.

View File

@ -325,6 +325,8 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
bool was_encode_called_since_last_initialization_
RTC_GUARDED_BY(encoder_queue_) = false;
bool encoder_failed_ RTC_GUARDED_BY(encoder_queue_) = false;
// Used to make sure incoming time stamp is increasing for every frame.
int64_t last_captured_timestamp_ RTC_GUARDED_BY(encoder_queue_) = 0;
// Delta used for translating between NTP and internal timestamps.
@ -380,8 +382,6 @@ class VideoStreamEncoder : public VideoStreamEncoderInterface,
// Provides video stream input states: current resolution and frame rate.
VideoStreamInputStateProvider input_state_provider_;
bool encoder_fallback_requested_ RTC_GUARDED_BY(encoder_queue_) = false;
const std::unique_ptr<VideoStreamAdapter> video_stream_adapter_
RTC_GUARDED_BY(encoder_queue_);
// Responsible for adapting input resolution or frame rate to ensure resources

View File

@ -1237,11 +1237,6 @@ class VideoStreamEncoderTest : public ::testing::Test {
return num_set_rates_;
}
int GetNumEncodes() const {
MutexLock lock(&local_mutex_);
return num_encodes_;
}
void SetPreferredPixelFormats(
absl::InlinedVector<VideoFrameBuffer::Type, kMaxPreferredPixelFormats>
pixel_formats) {
@ -1264,7 +1259,6 @@ class VideoStreamEncoderTest : public ::testing::Test {
const std::vector<VideoFrameType>* frame_types) override {
{
MutexLock lock(&local_mutex_);
num_encodes_++;
if (expect_null_frame_) {
EXPECT_EQ(input_image.rtp_timestamp(), 0u);
EXPECT_EQ(input_image.width(), 1);
@ -1396,7 +1390,6 @@ class VideoStreamEncoderTest : public ::testing::Test {
std::vector<ResolutionBitrateLimits> resolution_bitrate_limits_
RTC_GUARDED_BY(local_mutex_);
int num_set_rates_ RTC_GUARDED_BY(local_mutex_) = 0;
int num_encodes_ RTC_GUARDED_BY(local_mutex_) = 0;
std::optional<VideoFrameBuffer::Type> last_input_pixel_format_
RTC_GUARDED_BY(local_mutex_);
absl::InlinedVector<VideoFrameBuffer::Type, kMaxPreferredPixelFormats>
@ -8203,7 +8196,9 @@ TEST_F(VideoStreamEncoderTest,
.WillByDefault(Return(WEBRTC_VIDEO_CODEC_ENCODER_FAILURE));
rtc::Event encode_attempted;
EXPECT_CALL(switch_callback, RequestEncoderFallback())
EXPECT_CALL(switch_callback,
RequestEncoderSwitch(Field(&SdpVideoFormat::name, "VP8"),
/*allow_default_fallback=*/true))
.WillOnce([&encode_attempted]() { encode_attempted.Set(); });
video_source_.IncomingCapturedFrame(CreateFrame(1, nullptr));
@ -8271,112 +8266,6 @@ TEST_F(VideoStreamEncoderTest, NullEncoderReturnSwitch) {
video_stream_encoder_.reset();
}
TEST_F(VideoStreamEncoderTest, NoPreferenceDefaultFallbackToVP8Disabled) {
constexpr int kSufficientBitrateToNotDrop = 1000;
constexpr int kDontCare = 100;
constexpr int kNumFrames = 8;
NiceMock<MockVideoEncoder> video_encoder;
StrictMock<MockEncoderSwitchRequestCallback> switch_callback;
video_send_config_.encoder_settings.encoder_switch_request_callback =
&switch_callback;
auto encoder_factory = std::make_unique<test::VideoEncoderProxyFactory>(
&video_encoder, /*encoder_selector=*/nullptr);
video_send_config_.encoder_settings.encoder_factory = encoder_factory.get();
// Reset encoder for new configuration to take effect.
ConfigureEncoder(video_encoder_config_.Copy());
// The VideoStreamEncoder needs some bitrate before it can start encoding,
// setting some bitrate so that subsequent calls to WaitForEncodedFrame does
// not fail.
video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
/*target_bitrate=*/DataRate::KilobitsPerSec(kSufficientBitrateToNotDrop),
/*stable_target_bitrate=*/
DataRate::KilobitsPerSec(kSufficientBitrateToNotDrop),
/*link_allocation=*/DataRate::KilobitsPerSec(kSufficientBitrateToNotDrop),
/*fraction_lost=*/0,
/*round_trip_time_ms=*/0,
/*cwnd_reduce_ratio=*/0);
EXPECT_CALL(video_encoder, Encode)
.WillOnce(Return(WEBRTC_VIDEO_CODEC_ENCODER_FAILURE));
EXPECT_CALL(switch_callback, RequestEncoderFallback());
VideoFrame frame = CreateFrame(1, kDontCare, kDontCare);
for (int i = 0; i < kNumFrames; ++i) {
int64_t timestamp_ms = CurrentTimeMs();
frame.set_ntp_time_ms(timestamp_ms);
frame.set_timestamp_us(timestamp_ms * 1000);
video_source_.IncomingCapturedFrame(frame);
time_controller_.AdvanceTime(TimeDelta::Millis(33));
}
EXPECT_TRUE_WAIT(fake_encoder_.GetNumEncodes() == 0, 5000);
// After requesting fallback failure, the encoder will be released.
EXPECT_CALL(video_encoder, Release()).Times(1);
AdvanceTime(TimeDelta::Zero());
video_stream_encoder_->Stop();
// The encoders produced by the VideoEncoderProxyFactory have a pointer back
// to it's factory, so in order for the encoder instance in the
// `video_stream_encoder_` to be destroyed before the `encoder_factory` we
// reset the `video_stream_encoder_` here.
video_stream_encoder_.reset();
}
TEST_F(VideoStreamEncoderTest, NoPreferenceDefaultFallbackToVP8Enabled) {
constexpr int kSufficientBitrateToNotDrop = 1000;
constexpr int kDontCare = 100;
webrtc::test::ScopedKeyValueConfig field_trials(
field_trials_,
"WebRTC-SwitchEncoderFollowCodecPreferenceOrder/Disabled/");
NiceMock<MockVideoEncoder> video_encoder;
StrictMock<MockEncoderSwitchRequestCallback> switch_callback;
video_send_config_.encoder_settings.encoder_switch_request_callback =
&switch_callback;
auto encoder_factory = std::make_unique<test::VideoEncoderProxyFactory>(
&video_encoder, /*encoder_selector=*/nullptr);
video_send_config_.encoder_settings.encoder_factory = encoder_factory.get();
video_encoder_config_.codec_type = kVideoCodecVP9;
// Reset encoder for new configuration to take effect.
ConfigureEncoder(video_encoder_config_.Copy());
// The VideoStreamEncoder needs some bitrate before it can start encoding,
// setting some bitrate so that subsequent calls to WaitForEncodedFrame does
// not fail.
video_stream_encoder_->OnBitrateUpdatedAndWaitForManagedResources(
/*target_bitrate=*/DataRate::KilobitsPerSec(kSufficientBitrateToNotDrop),
/*stable_target_bitrate=*/
DataRate::KilobitsPerSec(kSufficientBitrateToNotDrop),
/*link_allocation=*/DataRate::KilobitsPerSec(kSufficientBitrateToNotDrop),
/*fraction_lost=*/0,
/*round_trip_time_ms=*/0,
/*cwnd_reduce_ratio=*/0);
EXPECT_CALL(video_encoder, Encode)
.WillOnce(Return(WEBRTC_VIDEO_CODEC_ENCODER_FAILURE));
// Fallback request will be asking for switching to VP8.
EXPECT_CALL(switch_callback,
RequestEncoderSwitch(Field(&SdpVideoFormat::name, "VP8"),
/*allow_default_fallback=*/true));
VideoFrame frame = CreateFrame(1, kDontCare, kDontCare);
video_source_.IncomingCapturedFrame(frame);
video_stream_encoder_->Stop();
// The encoders produced by the VideoEncoderProxyFactory have a pointer back
// to it's factory, so in order for the encoder instance in the
// `video_stream_encoder_` to be destroyed before the `encoder_factory` we
// reset the `video_stream_encoder_` here.
video_stream_encoder_.reset();
}
TEST_F(VideoStreamEncoderTest,
AllocationPropagatedToEncoderWhenTargetRateChanged) {
const int kFrameWidth = 320;