diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_tester_impl_unittest.cc | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_tester_impl_unittest.cc')
-rw-r--r-- | third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_tester_impl_unittest.cc | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_tester_impl_unittest.cc b/third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_tester_impl_unittest.cc new file mode 100644 index 0000000000..a8c118ef20 --- /dev/null +++ b/third_party/libwebrtc/modules/video_coding/codecs/test/video_codec_tester_impl_unittest.cc @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "modules/video_coding/codecs/test/video_codec_tester_impl.h" + +#include <memory> +#include <tuple> +#include <utility> +#include <vector> + +#include "api/units/frequency.h" +#include "api/units/time_delta.h" +#include "api/video/encoded_image.h" +#include "api/video/i420_buffer.h" +#include "api/video/video_frame.h" +#include "rtc_base/fake_clock.h" +#include "rtc_base/gunit.h" +#include "rtc_base/task_queue_for_test.h" +#include "rtc_base/time_utils.h" +#include "test/gmock.h" +#include "test/gtest.h" + +namespace webrtc { +namespace test { + +namespace { +using ::testing::_; +using ::testing::Invoke; +using ::testing::InvokeWithoutArgs; +using ::testing::Return; + +using Decoder = VideoCodecTester::Decoder; +using Encoder = VideoCodecTester::Encoder; +using CodedVideoSource = VideoCodecTester::CodedVideoSource; +using RawVideoSource = VideoCodecTester::RawVideoSource; +using DecoderSettings = VideoCodecTester::DecoderSettings; +using EncoderSettings = VideoCodecTester::EncoderSettings; +using PacingSettings = VideoCodecTester::PacingSettings; +using PacingMode = PacingSettings::PacingMode; + +constexpr Frequency k90kHz = Frequency::Hertz(90000); + +struct PacingTestParams { + PacingSettings pacing_settings; + Frequency framerate; + int num_frames; + std::vector<int> expected_delta_ms; +}; + +VideoFrame CreateVideoFrame(uint32_t timestamp_rtp) { + rtc::scoped_refptr<I420Buffer> buffer(I420Buffer::Create(2, 2)); + return VideoFrame::Builder() + .set_video_frame_buffer(buffer) + .set_timestamp_rtp(timestamp_rtp) + .build(); +} + +EncodedImage CreateEncodedImage(uint32_t timestamp_rtp) { + EncodedImage encoded_image; + encoded_image.SetRtpTimestamp(timestamp_rtp); + return encoded_image; +} + +class MockRawVideoSource : public RawVideoSource { + public: + MockRawVideoSource(int num_frames, Frequency framerate) + : num_frames_(num_frames), frame_num_(0), framerate_(framerate) {} + + absl::optional<VideoFrame> PullFrame() override { + if (frame_num_ >= num_frames_) { + return absl::nullopt; + } + uint32_t timestamp_rtp = frame_num_ * k90kHz / framerate_; + ++frame_num_; + return CreateVideoFrame(timestamp_rtp); + } + + MOCK_METHOD(VideoFrame, + GetFrame, + (uint32_t timestamp_rtp, Resolution), + (override)); + + private: + int num_frames_; + int frame_num_; + Frequency framerate_; +}; + +class MockCodedVideoSource : public CodedVideoSource { + public: + MockCodedVideoSource(int num_frames, Frequency framerate) + : num_frames_(num_frames), frame_num_(0), framerate_(framerate) {} + + absl::optional<EncodedImage> PullFrame() override { + if (frame_num_ >= num_frames_) { + return absl::nullopt; + } + uint32_t timestamp_rtp = frame_num_ * k90kHz / framerate_; + ++frame_num_; + return CreateEncodedImage(timestamp_rtp); + } + + private: + int num_frames_; + int frame_num_; + Frequency framerate_; +}; + +class MockDecoder : public Decoder { + public: + MOCK_METHOD(void, Initialize, (), (override)); + MOCK_METHOD(void, + Decode, + (const EncodedImage& frame, DecodeCallback callback), + (override)); + MOCK_METHOD(void, Flush, (), (override)); +}; + +class MockEncoder : public Encoder { + public: + MOCK_METHOD(void, Initialize, (), (override)); + MOCK_METHOD(void, + Encode, + (const VideoFrame& frame, EncodeCallback callback), + (override)); + MOCK_METHOD(void, Flush, (), (override)); +}; + +} // namespace + +class VideoCodecTesterImplPacingTest + : public ::testing::TestWithParam<PacingTestParams> { + public: + VideoCodecTesterImplPacingTest() : test_params_(GetParam()) {} + + protected: + PacingTestParams test_params_; +}; + +TEST_P(VideoCodecTesterImplPacingTest, PaceEncode) { + MockRawVideoSource video_source(test_params_.num_frames, + test_params_.framerate); + MockEncoder encoder; + EncoderSettings encoder_settings; + encoder_settings.pacing = test_params_.pacing_settings; + + VideoCodecTesterImpl tester; + auto fs = + tester.RunEncodeTest(&video_source, &encoder, encoder_settings)->Slice(); + ASSERT_EQ(static_cast<int>(fs.size()), test_params_.num_frames); + + for (size_t i = 1; i < fs.size(); ++i) { + int delta_ms = (fs[i].encode_start - fs[i - 1].encode_start).ms(); + EXPECT_NEAR(delta_ms, test_params_.expected_delta_ms[i - 1], 10); + } +} + +TEST_P(VideoCodecTesterImplPacingTest, PaceDecode) { + MockCodedVideoSource video_source(test_params_.num_frames, + test_params_.framerate); + MockDecoder decoder; + DecoderSettings decoder_settings; + decoder_settings.pacing = test_params_.pacing_settings; + + VideoCodecTesterImpl tester; + auto fs = + tester.RunDecodeTest(&video_source, &decoder, decoder_settings)->Slice(); + ASSERT_EQ(static_cast<int>(fs.size()), test_params_.num_frames); + + for (size_t i = 1; i < fs.size(); ++i) { + int delta_ms = (fs[i].decode_start - fs[i - 1].decode_start).ms(); + EXPECT_NEAR(delta_ms, test_params_.expected_delta_ms[i - 1], 20); + } +} + +INSTANTIATE_TEST_SUITE_P( + DISABLED_All, + VideoCodecTesterImplPacingTest, + ::testing::ValuesIn( + {// No pacing. + PacingTestParams({.pacing_settings = {.mode = PacingMode::kNoPacing}, + .framerate = Frequency::Hertz(10), + .num_frames = 3, + .expected_delta_ms = {0, 0}}), + // Real-time pacing. + PacingTestParams({.pacing_settings = {.mode = PacingMode::kRealTime}, + .framerate = Frequency::Hertz(10), + .num_frames = 3, + .expected_delta_ms = {100, 100}}), + // Pace with specified constant rate. + PacingTestParams( + {.pacing_settings = {.mode = PacingMode::kConstantRate, + .constant_rate = Frequency::Hertz(20)}, + .framerate = Frequency::Hertz(10), + .num_frames = 3, + .expected_delta_ms = {50, 50}})})); +} // namespace test +} // namespace webrtc |