Enable post-encode frame drop in libaom AV1 encoder
Bug: webrtc:351644568 Change-Id: Ic761fbaf21f1c55b8839a21cc54e450f71606b8d Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/376060 Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Sergey Silkin <ssilkin@webrtc.org> Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org> Cr-Commit-Position: refs/heads/main@{#43884}
This commit is contained in:
parent
578b12bb03
commit
0b48e61230
@ -104,6 +104,9 @@ ACTIVE_FIELD_TRIALS: FrozenSet[FieldTrial] = frozenset([
|
|||||||
FieldTrial('WebRTC-LibaomAv1Encoder-AdaptiveMaxConsecDrops',
|
FieldTrial('WebRTC-LibaomAv1Encoder-AdaptiveMaxConsecDrops',
|
||||||
351644568,
|
351644568,
|
||||||
date(2025, 7, 1)),
|
date(2025, 7, 1)),
|
||||||
|
FieldTrial('WebRTC-LibaomAv1Encoder-PostEncodeFrameDrop',
|
||||||
|
351644568,
|
||||||
|
date(2026, 1, 30)),
|
||||||
FieldTrial('WebRTC-LibvpxVp8Encoder-AndroidSpecificThreadingSettings',
|
FieldTrial('WebRTC-LibvpxVp8Encoder-AndroidSpecificThreadingSettings',
|
||||||
42226191,
|
42226191,
|
||||||
date(2024, 9, 1)),
|
date(2024, 9, 1)),
|
||||||
|
|||||||
@ -163,6 +163,7 @@ if (rtc_include_tests && !build_with_chromium) {
|
|||||||
"../resources/near88_stereo.pcm",
|
"../resources/near88_stereo.pcm",
|
||||||
"../resources/near8_stereo.pcm",
|
"../resources/near8_stereo.pcm",
|
||||||
"../resources/near96_stereo.pcm",
|
"../resources/near96_stereo.pcm",
|
||||||
|
"../resources/photo_1850_1110.yuv",
|
||||||
"../resources/ref03.aecdump",
|
"../resources/ref03.aecdump",
|
||||||
"../resources/remote_bitrate_estimator/VideoSendersTest_BweTest_IncreasingChoke1_0_AST.bin",
|
"../resources/remote_bitrate_estimator/VideoSendersTest_BweTest_IncreasingChoke1_0_AST.bin",
|
||||||
"../resources/remote_bitrate_estimator/VideoSendersTest_BweTest_IncreasingChoke1_0_TOF.bin",
|
"../resources/remote_bitrate_estimator/VideoSendersTest_BweTest_IncreasingChoke1_0_TOF.bin",
|
||||||
@ -199,7 +200,7 @@ if (rtc_include_tests && !build_with_chromium) {
|
|||||||
bundle_data("modules_unittests_bundle_data") {
|
bundle_data("modules_unittests_bundle_data") {
|
||||||
testonly = true
|
testonly = true
|
||||||
sources = modules_unittests_resources
|
sources = modules_unittests_resources
|
||||||
outputs = [ "{{bundle_resources_dir}}/{{source_file_part}}" ]
|
outputs = [ "{{bundle_resources_dir}}/{{source_root_relative_dir}}/{{source_file_part}}" ]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -105,7 +105,9 @@ if (rtc_include_tests) {
|
|||||||
"../../../../api/units:time_delta",
|
"../../../../api/units:time_delta",
|
||||||
"../../../../api/video:video_frame",
|
"../../../../api/video:video_frame",
|
||||||
"../../../../modules/rtp_rtcp:rtp_rtcp_format",
|
"../../../../modules/rtp_rtcp:rtp_rtcp_format",
|
||||||
|
"../../../../test:fileutils",
|
||||||
"../../../../test:scoped_key_value_config",
|
"../../../../test:scoped_key_value_config",
|
||||||
|
"../../../../test:video_test_support",
|
||||||
"../../svc:scalability_mode_util",
|
"../../svc:scalability_mode_util",
|
||||||
"../../svc:scalability_structures",
|
"../../svc:scalability_structures",
|
||||||
"../../svc:scalable_video_controller",
|
"../../svc:scalable_video_controller",
|
||||||
|
|||||||
@ -135,7 +135,10 @@ class LibaomAv1Encoder final : public VideoEncoder {
|
|||||||
const LibaomAv1EncoderInfoSettings encoder_info_override_;
|
const LibaomAv1EncoderInfoSettings encoder_info_override_;
|
||||||
// TODO(webrtc:351644568): Remove this kill-switch after the feature is fully
|
// TODO(webrtc:351644568): Remove this kill-switch after the feature is fully
|
||||||
// deployed.
|
// deployed.
|
||||||
bool adaptive_max_consec_drops_;
|
const bool adaptive_max_consec_drops_;
|
||||||
|
// TODO(webrtc:351644568): Remove this kill-switch after the feature is fully
|
||||||
|
// deployed.
|
||||||
|
const bool post_encode_frame_drop_;
|
||||||
};
|
};
|
||||||
|
|
||||||
int32_t VerifyCodecSettings(const VideoCodec& codec_settings) {
|
int32_t VerifyCodecSettings(const VideoCodec& codec_settings) {
|
||||||
@ -177,7 +180,9 @@ LibaomAv1Encoder::LibaomAv1Encoder(const Environment& env,
|
|||||||
timestamp_(0),
|
timestamp_(0),
|
||||||
encoder_info_override_(env.field_trials()),
|
encoder_info_override_(env.field_trials()),
|
||||||
adaptive_max_consec_drops_(!env.field_trials().IsDisabled(
|
adaptive_max_consec_drops_(!env.field_trials().IsDisabled(
|
||||||
"WebRTC-LibaomAv1Encoder-AdaptiveMaxConsecDrops")) {}
|
"WebRTC-LibaomAv1Encoder-AdaptiveMaxConsecDrops")),
|
||||||
|
post_encode_frame_drop_(!env.field_trials().IsDisabled(
|
||||||
|
"WebRTC-LibaomAv1Encoder-PostEncodeFrameDrop")) {}
|
||||||
|
|
||||||
LibaomAv1Encoder::~LibaomAv1Encoder() {
|
LibaomAv1Encoder::~LibaomAv1Encoder() {
|
||||||
Release();
|
Release();
|
||||||
@ -336,6 +341,10 @@ int LibaomAv1Encoder::InitEncode(const VideoCodec* codec_settings,
|
|||||||
250);
|
250);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (post_encode_frame_drop_) {
|
||||||
|
SET_ENCODER_PARAM_OR_RETURN_ERROR(AV1E_SET_POSTENCODE_DROP_RTC, 1);
|
||||||
|
}
|
||||||
|
|
||||||
return WEBRTC_VIDEO_CODEC_OK;
|
return WEBRTC_VIDEO_CODEC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
#include "api/environment/environment_factory.h"
|
#include "api/environment/environment_factory.h"
|
||||||
#include "api/test/create_frame_generator.h"
|
#include "api/test/create_frame_generator.h"
|
||||||
#include "api/test/frame_generator_interface.h"
|
#include "api/test/frame_generator_interface.h"
|
||||||
|
#include "api/video/i420_buffer.h"
|
||||||
#include "api/video_codecs/video_codec.h"
|
#include "api/video_codecs/video_codec.h"
|
||||||
#include "api/video_codecs/video_encoder.h"
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||||
@ -29,6 +30,8 @@
|
|||||||
#include "test/gmock.h"
|
#include "test/gmock.h"
|
||||||
#include "test/gtest.h"
|
#include "test/gtest.h"
|
||||||
#include "test/scoped_key_value_config.h"
|
#include "test/scoped_key_value_config.h"
|
||||||
|
#include "test/testsupport/file_utils.h"
|
||||||
|
#include "test/testsupport/frame_reader.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace {
|
namespace {
|
||||||
@ -237,7 +240,7 @@ class LibaomAv1EncoderMaxConsecDropTest
|
|||||||
TEST_P(LibaomAv1EncoderMaxConsecDropTest, MaxConsecDrops) {
|
TEST_P(LibaomAv1EncoderMaxConsecDropTest, MaxConsecDrops) {
|
||||||
VideoBitrateAllocation allocation;
|
VideoBitrateAllocation allocation;
|
||||||
allocation.SetBitrate(0, 0,
|
allocation.SetBitrate(0, 0,
|
||||||
1000); // Very low bitrate to provoke frame drops.
|
2000); // A low bitrate to provoke frame drops.
|
||||||
std::unique_ptr<VideoEncoder> encoder =
|
std::unique_ptr<VideoEncoder> encoder =
|
||||||
CreateLibaomAv1Encoder(CreateEnvironment());
|
CreateLibaomAv1Encoder(CreateEnvironment());
|
||||||
VideoCodec codec_settings = DefaultCodecSettings();
|
VideoCodec codec_settings = DefaultCodecSettings();
|
||||||
@ -509,5 +512,72 @@ TEST(LibaomAv1EncoderTest, DisableAutomaticResize) {
|
|||||||
std::nullopt);
|
std::nullopt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(LibaomAv1EncoderTest, PostEncodeFrameDrop) {
|
||||||
|
// To trigger post-encode frame drop, encode a frame of a high complexity
|
||||||
|
// using a medium bitrate, then reduce the bitrate and encode the same frame
|
||||||
|
// again.
|
||||||
|
// Using a medium bitrate for the first frame prevents quality and QP
|
||||||
|
// saturation. Encoding the same content twice prevents scene change
|
||||||
|
// detection. The second frame overshoots RC buffer and provokes post-encode
|
||||||
|
// drop.
|
||||||
|
VideoFrame input_frame =
|
||||||
|
VideoFrame::Builder()
|
||||||
|
.set_video_frame_buffer(
|
||||||
|
test::CreateYuvFrameReader(
|
||||||
|
test::ResourcePath("photo_1850_1110", "yuv"),
|
||||||
|
{.width = 1850, .height = 1110})
|
||||||
|
->PullFrame())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
VideoBitrateAllocation allocation;
|
||||||
|
allocation.SetBitrate(/*spatial_index=*/0, /*temporal_index=*/0,
|
||||||
|
/*bitrate_bps=*/10000000);
|
||||||
|
std::unique_ptr<VideoEncoder> encoder =
|
||||||
|
CreateLibaomAv1Encoder(CreateEnvironment());
|
||||||
|
VideoCodec codec_settings = DefaultCodecSettings();
|
||||||
|
codec_settings.width = input_frame.width();
|
||||||
|
codec_settings.height = input_frame.height();
|
||||||
|
codec_settings.startBitrate = allocation.get_sum_kbps();
|
||||||
|
codec_settings.SetFrameDropEnabled(true);
|
||||||
|
codec_settings.SetScalabilityMode(ScalabilityMode::kL1T1);
|
||||||
|
ASSERT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()),
|
||||||
|
WEBRTC_VIDEO_CODEC_OK);
|
||||||
|
encoder->SetRates(VideoEncoder::RateControlParameters(
|
||||||
|
allocation, codec_settings.maxFramerate));
|
||||||
|
|
||||||
|
class EncoderCallback : public EncodedImageCallback {
|
||||||
|
public:
|
||||||
|
EncoderCallback() = default;
|
||||||
|
int frames_encoded() const { return frames_encoded_; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Result OnEncodedImage(
|
||||||
|
const EncodedImage& encoded_image,
|
||||||
|
const CodecSpecificInfo* /* codec_specific_info */) override {
|
||||||
|
frames_encoded_++;
|
||||||
|
return Result(Result::Error::OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
int frames_encoded_ = 0;
|
||||||
|
} callback;
|
||||||
|
encoder->RegisterEncodeCompleteCallback(&callback);
|
||||||
|
|
||||||
|
input_frame.set_rtp_timestamp(1 * kVideoPayloadTypeFrequency /
|
||||||
|
codec_settings.maxFramerate);
|
||||||
|
RTC_CHECK_EQ(encoder->Encode(input_frame, /*frame_types=*/nullptr),
|
||||||
|
WEBRTC_VIDEO_CODEC_OK);
|
||||||
|
|
||||||
|
allocation.SetBitrate(/*spatial_index=*/0, /*temporal_index=*/0,
|
||||||
|
/*bitrate_bps=*/1000);
|
||||||
|
encoder->SetRates(VideoEncoder::RateControlParameters(
|
||||||
|
allocation, codec_settings.maxFramerate));
|
||||||
|
|
||||||
|
input_frame.set_rtp_timestamp(2 * kVideoPayloadTypeFrequency /
|
||||||
|
codec_settings.maxFramerate);
|
||||||
|
RTC_CHECK_EQ(encoder->Encode(input_frame, /*frame_types=*/nullptr),
|
||||||
|
WEBRTC_VIDEO_CODEC_OK);
|
||||||
|
RTC_CHECK_EQ(callback.frames_encoded(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user