Pass Environment to VideoDecoders through VideoCodecTester

Bug: webrtc:15791
Change-Id: I002734a17ece1d11b77a261aa8160c4afa1702b5
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/336241
Reviewed-by: Jeremy Leconte <jleconte@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Philip Eliasson <philipel@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41617}
This commit is contained in:
Danil Chapovalov 2024-01-25 15:48:24 +01:00 committed by WebRTC LUCI CQ
parent 523eff622e
commit d213dd5517
6 changed files with 58 additions and 43 deletions

View File

@ -999,6 +999,8 @@ if (rtc_include_tests) {
deps = [
":video_codec_interface",
"../../api/environment",
"../../api/environment:environment_factory",
"../../api/test/metrics:global_metrics_logger_and_exporter",
"../../api/units:data_rate",
"../../api/units:frequency",

View File

@ -14,6 +14,8 @@
#include "absl/flags/flag.h"
#include "absl/functional/any_invocable.h"
#include "api/environment/environment.h"
#include "api/environment/environment_factory.h"
#include "api/test/metrics/global_metrics_logger_and_exporter.h"
#include "api/units/data_rate.h"
#include "api/units/frequency.h"
@ -178,6 +180,7 @@ std::string TestOutputPath() {
} // namespace
std::unique_ptr<VideoCodecStats> RunEncodeDecodeTest(
const Environment& env,
std::string encoder_impl,
std::string decoder_impl,
const VideoInfo& video_info,
@ -247,7 +250,7 @@ std::unique_ptr<VideoCodecStats> RunEncodeDecodeTest(
}
return VideoCodecTester::RunEncodeDecodeTest(
source_settings, encoder_factory.get(), decoder_factory.get(),
env, source_settings, encoder_factory.get(), decoder_factory.get(),
encoder_settings, decoder_settings, encoding_settings);
}
@ -313,6 +316,7 @@ class SpatialQualityTest : public ::testing::TestWithParam<std::tuple<
};
TEST_P(SpatialQualityTest, SpatialQuality) {
const Environment env = CreateEnvironment();
auto [codec_type, codec_impl, video_info, coding_settings] = GetParam();
auto [width, height, framerate_fps, bitrate_kbps, expected_min_psnr] =
coding_settings;
@ -324,8 +328,8 @@ TEST_P(SpatialQualityTest, SpatialQuality) {
codec_type, /*scalability_mode=*/"L1T1", width, height,
{bitrate_kbps}, framerate_fps, num_frames);
std::unique_ptr<VideoCodecStats> stats =
RunEncodeDecodeTest(codec_impl, codec_impl, video_info, frames_settings);
std::unique_ptr<VideoCodecStats> stats = RunEncodeDecodeTest(
env, codec_impl, codec_impl, video_info, frames_settings);
VideoCodecStats::Stream stream;
if (stats != nullptr) {
@ -527,6 +531,7 @@ INSTANTIATE_TEST_SUITE_P(
FramerateAdaptationTest::TestParamsToString);
TEST(VideoCodecTest, DISABLED_EncodeDecode) {
const Environment env = CreateEnvironment();
std::vector<std::string> bitrate_str = absl::GetFlag(FLAGS_bitrate_kbps);
std::vector<int> bitrate_kbps;
std::transform(bitrate_str.begin(), bitrate_str.end(),
@ -544,7 +549,7 @@ TEST(VideoCodecTest, DISABLED_EncodeDecode) {
// logged test name (implies lossing history in the chromeperf dashboard).
// Sync with changes in Stream::LogMetrics (see TODOs there).
std::unique_ptr<VideoCodecStats> stats = RunEncodeDecodeTest(
CodecNameToCodecImpl(absl::GetFlag(FLAGS_encoder)),
env, CodecNameToCodecImpl(absl::GetFlag(FLAGS_encoder)),
CodecNameToCodecImpl(absl::GetFlag(FLAGS_decoder)),
kRawVideos.at(absl::GetFlag(FLAGS_video_name)), frames_settings);
ASSERT_NE(nullptr, stats);

View File

@ -727,6 +727,8 @@ if (rtc_include_tests) {
"../api:mock_video_encoder",
"../api:scoped_refptr",
"../api:simulcast_test_fixture_api",
"../api/environment",
"../api/environment:environment_factory",
"../api/task_queue",
"../api/task_queue:task_queue_test",
"../api/test/video:function_video_factory",

View File

@ -772,10 +772,12 @@ class VideoCodecAnalyzer : public VideoCodecTester::VideoCodecStats {
class Decoder : public DecodedImageCallback {
public:
Decoder(VideoDecoderFactory* decoder_factory,
Decoder(const Environment& env,
VideoDecoderFactory* decoder_factory,
const DecoderSettings& decoder_settings,
VideoCodecAnalyzer* analyzer)
: decoder_factory_(decoder_factory),
: env_(env),
decoder_factory_(decoder_factory),
analyzer_(analyzer),
pacer_(decoder_settings.pacing_settings) {
RTC_CHECK(analyzer_) << "Analyzer must be provided";
@ -792,7 +794,7 @@ class Decoder : public DecodedImageCallback {
}
void Initialize(const SdpVideoFormat& sdp_video_format) {
decoder_ = decoder_factory_->CreateVideoDecoder(sdp_video_format);
decoder_ = decoder_factory_->Create(env_, sdp_video_format);
RTC_CHECK(decoder_) << "Could not create decoder for video format "
<< sdp_video_format.ToString();
@ -863,6 +865,7 @@ class Decoder : public DecodedImageCallback {
return WEBRTC_VIDEO_CODEC_OK;
}
const Environment env_;
VideoDecoderFactory* decoder_factory_;
std::unique_ptr<VideoDecoder> decoder_;
VideoCodecAnalyzer* const analyzer_;
@ -1476,13 +1479,14 @@ std::map<uint32_t, EncodingSettings> VideoCodecTester::CreateEncodingSettings(
}
std::unique_ptr<VideoCodecTester::VideoCodecStats>
VideoCodecTester::RunDecodeTest(CodedVideoSource* video_source,
VideoCodecTester::RunDecodeTest(const Environment& env,
CodedVideoSource* video_source,
VideoDecoderFactory* decoder_factory,
const DecoderSettings& decoder_settings,
const SdpVideoFormat& sdp_video_format) {
std::unique_ptr<VideoCodecAnalyzer> analyzer =
std::make_unique<VideoCodecAnalyzer>(/*video_source=*/nullptr);
Decoder decoder(decoder_factory, decoder_settings, analyzer.get());
Decoder decoder(env, decoder_factory, decoder_settings, analyzer.get());
decoder.Initialize(sdp_video_format);
while (auto frame = video_source->PullFrame()) {
@ -1522,6 +1526,7 @@ VideoCodecTester::RunEncodeTest(
std::unique_ptr<VideoCodecTester::VideoCodecStats>
VideoCodecTester::RunEncodeDecodeTest(
const Environment& env,
const VideoSourceSettings& source_settings,
VideoEncoderFactory* encoder_factory,
VideoDecoderFactory* decoder_factory,
@ -1539,8 +1544,8 @@ VideoCodecTester::RunEncodeDecodeTest(
ScalabilityModeToNumSpatialLayers(frame_settings.scalability_mode);
std::vector<std::unique_ptr<Decoder>> decoders;
for (int sidx = 0; sidx < num_spatial_layers; ++sidx) {
auto decoder = std::make_unique<Decoder>(decoder_factory, decoder_settings,
analyzer.get());
auto decoder = std::make_unique<Decoder>(env, decoder_factory,
decoder_settings, analyzer.get());
decoder->Initialize(frame_settings.sdp_video_format);
decoders.push_back(std::move(decoder));
}

View File

@ -199,6 +199,7 @@ class VideoCodecTester {
// Decodes video, collects and returns decode metrics.
static std::unique_ptr<VideoCodecStats> RunDecodeTest(
const Environment& env,
CodedVideoSource* video_source,
VideoDecoderFactory* decoder_factory,
const DecoderSettings& decoder_settings,
@ -213,6 +214,7 @@ class VideoCodecTester {
// Encodes and decodes video, collects and returns encode and decode metrics.
static std::unique_ptr<VideoCodecStats> RunEncodeDecodeTest(
const Environment& env,
const VideoSourceSettings& source_settings,
VideoEncoderFactory* encoder_factory,
VideoDecoderFactory* decoder_factory,

View File

@ -17,6 +17,8 @@
#include <utility>
#include <vector>
#include "api/environment/environment.h"
#include "api/environment/environment_factory.h"
#include "api/test/mock_video_decoder.h"
#include "api/test/mock_video_decoder_factory.h"
#include "api/test/mock_video_encoder.h"
@ -44,13 +46,12 @@ namespace {
using ::testing::_;
using ::testing::ElementsAre;
using ::testing::Field;
using ::testing::Invoke;
using ::testing::InvokeWithoutArgs;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::SizeIs;
using ::testing::UnorderedElementsAreArray;
using ::testing::Values;
using ::testing::WithoutArgs;
using VideoCodecStats = VideoCodecTester::VideoCodecStats;
using VideoSourceSettings = VideoCodecTester::VideoSourceSettings;
@ -200,30 +201,27 @@ class VideoCodecTesterTest : public ::testing::Test {
});
NiceMock<MockVideoDecoderFactory> decoder_factory;
ON_CALL(decoder_factory, CreateVideoDecoder)
.WillByDefault([&](const SdpVideoFormat&) {
// Video codec tester destroyes decoder at the end of test. Test
// decoder collects stats which we need to access after test. To keep
// the decode alive we wrap it into a wrapper and pass the wrapper to
// the tester.
class DecoderWrapper : public TestVideoDecoder {
public:
explicit DecoderWrapper(TestVideoDecoder* decoder)
: decoder_(decoder) {}
int32_t Decode(const EncodedImage& encoded_frame,
int64_t render_time_ms) {
return decoder_->Decode(encoded_frame, render_time_ms);
}
int32_t RegisterDecodeCompleteCallback(
DecodedImageCallback* callback) {
return decoder_->RegisterDecodeCompleteCallback(callback);
}
TestVideoDecoder* decoder_;
};
decoders_.push_back(std::make_unique<NiceMock<TestVideoDecoder>>());
return std::make_unique<NiceMock<DecoderWrapper>>(
decoders_.back().get());
});
ON_CALL(decoder_factory, Create).WillByDefault(WithoutArgs([&] {
// Video codec tester destroyes decoder at the end of test. Test
// decoder collects stats which we need to access after test. To keep
// the decode alive we wrap it into a wrapper and pass the wrapper to
// the tester.
class DecoderWrapper : public TestVideoDecoder {
public:
explicit DecoderWrapper(TestVideoDecoder* decoder)
: decoder_(decoder) {}
int32_t Decode(const EncodedImage& encoded_frame,
int64_t render_time_ms) {
return decoder_->Decode(encoded_frame, render_time_ms);
}
int32_t RegisterDecodeCompleteCallback(DecodedImageCallback* callback) {
return decoder_->RegisterDecodeCompleteCallback(callback);
}
TestVideoDecoder* decoder_;
};
decoders_.push_back(std::make_unique<NiceMock<TestVideoDecoder>>());
return std::make_unique<NiceMock<DecoderWrapper>>(decoders_.back().get());
}));
int num_spatial_layers =
ScalabilityModeToNumSpatialLayers(scalability_mode);
@ -252,7 +250,7 @@ class VideoCodecTesterTest : public ::testing::Test {
std::unique_ptr<VideoCodecStats> stats =
VideoCodecTester::RunEncodeDecodeTest(
video_source_settings, &encoder_factory, &decoder_factory,
env_, video_source_settings, &encoder_factory, &decoder_factory,
EncoderSettings{}, DecoderSettings{}, encoding_settings);
remove(yuv_path.c_str());
@ -260,6 +258,7 @@ class VideoCodecTesterTest : public ::testing::Test {
}
protected:
const Environment env_ = CreateEnvironment();
std::vector<std::unique_ptr<TestVideoDecoder>> decoders_;
};
@ -605,6 +604,7 @@ class VideoCodecTesterTestPacing
void TearDown() override { remove(source_yuv_file_path_.c_str()); }
protected:
const Environment env_ = CreateEnvironment();
std::string source_yuv_file_path_;
};
@ -644,15 +644,14 @@ TEST_P(VideoCodecTesterTestPacing, PaceDecode) {
MockCodedVideoSource video_source(kNumFrames, kTargetFramerate);
NiceMock<MockVideoDecoderFactory> decoder_factory;
ON_CALL(decoder_factory, CreateVideoDecoder(_))
.WillByDefault([](const SdpVideoFormat&) {
return std::make_unique<NiceMock<MockVideoDecoder>>();
});
ON_CALL(decoder_factory, Create).WillByDefault(WithoutArgs([] {
return std::make_unique<NiceMock<MockVideoDecoder>>();
}));
DecoderSettings decoder_settings;
decoder_settings.pacing_settings = pacing_settings;
std::vector<Frame> frames =
VideoCodecTester::RunDecodeTest(&video_source, &decoder_factory,
VideoCodecTester::RunDecodeTest(env_, &video_source, &decoder_factory,
decoder_settings, SdpVideoFormat("VP8"))
->Slice(/*filter=*/{}, /*merge=*/false);
ASSERT_THAT(frames, SizeIs(kNumFrames));