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/video/video_stream_decoder_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/video/video_stream_decoder_impl_unittest.cc')
-rw-r--r-- | third_party/libwebrtc/video/video_stream_decoder_impl_unittest.cc | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/third_party/libwebrtc/video/video_stream_decoder_impl_unittest.cc b/third_party/libwebrtc/video/video_stream_decoder_impl_unittest.cc new file mode 100644 index 0000000000..d0cf9255c3 --- /dev/null +++ b/third_party/libwebrtc/video/video_stream_decoder_impl_unittest.cc @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2020 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 "video/video_stream_decoder_impl.h" + +#include <vector> + +#include "api/video/i420_buffer.h" +#include "api/video_codecs/video_decoder.h" +#include "test/fake_encoded_frame.h" +#include "test/gmock.h" +#include "test/gtest.h" +#include "test/scoped_key_value_config.h" +#include "test/time_controller/simulated_time_controller.h" + +namespace webrtc { +namespace { +using ::testing::_; +using ::testing::NiceMock; +using ::testing::Return; + +class MockVideoStreamDecoderCallbacks + : public VideoStreamDecoderInterface::Callbacks { + public: + MOCK_METHOD(void, OnNonDecodableState, (), (override)); + MOCK_METHOD(void, OnContinuousUntil, (int64_t frame_id), (override)); + MOCK_METHOD( + void, + OnDecodedFrame, + (VideoFrame frame, + const VideoStreamDecoderInterface::Callbacks::FrameInfo& frame_info), + (override)); +}; + +class StubVideoDecoder : public VideoDecoder { + public: + StubVideoDecoder() { ON_CALL(*this, Configure).WillByDefault(Return(true)); } + + MOCK_METHOD(bool, Configure, (const Settings&), (override)); + + int32_t Decode(const EncodedImage& input_image, + bool missing_frames, + int64_t render_time_ms) override { + int32_t ret_code = DecodeCall(input_image, missing_frames, render_time_ms); + if (ret_code == WEBRTC_VIDEO_CODEC_OK || + ret_code == WEBRTC_VIDEO_CODEC_OK_REQUEST_KEYFRAME) { + VideoFrame frame = VideoFrame::Builder() + .set_video_frame_buffer(I420Buffer::Create(1, 1)) + .build(); + callback_->Decoded(frame); + } + return ret_code; + } + + MOCK_METHOD(int32_t, + DecodeCall, + (const EncodedImage& input_image, + bool missing_frames, + int64_t render_time_ms), + ()); + + int32_t Release() override { return 0; } + + int32_t RegisterDecodeCompleteCallback( + DecodedImageCallback* callback) override { + callback_ = callback; + return 0; + } + + private: + DecodedImageCallback* callback_; +}; + +class WrappedVideoDecoder : public VideoDecoder { + public: + explicit WrappedVideoDecoder(StubVideoDecoder* decoder) : decoder_(decoder) {} + + bool Configure(const Settings& settings) override { + return decoder_->Configure(settings); + } + int32_t Decode(const EncodedImage& input_image, + bool missing_frames, + int64_t render_time_ms) override { + return decoder_->Decode(input_image, missing_frames, render_time_ms); + } + int32_t Release() override { return decoder_->Release(); } + + int32_t RegisterDecodeCompleteCallback( + DecodedImageCallback* callback) override { + return decoder_->RegisterDecodeCompleteCallback(callback); + } + + private: + StubVideoDecoder* decoder_; +}; + +class FakeVideoDecoderFactory : public VideoDecoderFactory { + public: + std::vector<SdpVideoFormat> GetSupportedFormats() const override { + return {}; + } + std::unique_ptr<VideoDecoder> CreateVideoDecoder( + const SdpVideoFormat& format) override { + if (format.name == "VP8") { + return std::make_unique<WrappedVideoDecoder>(&vp8_decoder_); + } + + if (format.name == "AV1") { + return std::make_unique<WrappedVideoDecoder>(&av1_decoder_); + } + + return {}; + } + + StubVideoDecoder& Vp8Decoder() { return vp8_decoder_; } + StubVideoDecoder& Av1Decoder() { return av1_decoder_; } + + private: + NiceMock<StubVideoDecoder> vp8_decoder_; + NiceMock<StubVideoDecoder> av1_decoder_; +}; + +class VideoStreamDecoderImplTest : public ::testing::Test { + public: + VideoStreamDecoderImplTest() + : time_controller_(Timestamp::Seconds(0)), + video_stream_decoder_(&callbacks_, + &decoder_factory_, + time_controller_.GetTaskQueueFactory(), + {{1, std::make_pair(SdpVideoFormat("VP8"), 1)}, + {2, std::make_pair(SdpVideoFormat("AV1"), 1)}}, + &field_trials_) { + // Set the min playout delay to a value greater than zero to not activate + // the low-latency renderer. + video_stream_decoder_.SetMinPlayoutDelay(TimeDelta::Millis(10)); + } + + test::ScopedKeyValueConfig field_trials_; + NiceMock<MockVideoStreamDecoderCallbacks> callbacks_; + FakeVideoDecoderFactory decoder_factory_; + GlobalSimulatedTimeController time_controller_; + VideoStreamDecoderImpl video_stream_decoder_; +}; + +TEST_F(VideoStreamDecoderImplTest, InsertAndDecodeFrame) { + video_stream_decoder_.OnFrame( + test::FakeFrameBuilder().PayloadType(1).AsLast().Build()); + EXPECT_CALL(callbacks_, OnDecodedFrame); + time_controller_.AdvanceTime(TimeDelta::Millis(1)); +} + +TEST_F(VideoStreamDecoderImplTest, NonDecodableStateWaitingForKeyframe) { + EXPECT_CALL(callbacks_, OnNonDecodableState); + time_controller_.AdvanceTime(TimeDelta::Millis(200)); +} + +TEST_F(VideoStreamDecoderImplTest, NonDecodableStateWaitingForDeltaFrame) { + video_stream_decoder_.OnFrame( + test::FakeFrameBuilder().PayloadType(1).AsLast().Build()); + EXPECT_CALL(callbacks_, OnDecodedFrame); + time_controller_.AdvanceTime(TimeDelta::Millis(1)); + EXPECT_CALL(callbacks_, OnNonDecodableState); + time_controller_.AdvanceTime(TimeDelta::Millis(3000)); +} + +TEST_F(VideoStreamDecoderImplTest, InsertAndDecodeFrameWithKeyframeRequest) { + video_stream_decoder_.OnFrame( + test::FakeFrameBuilder().PayloadType(1).AsLast().Build()); + EXPECT_CALL(decoder_factory_.Vp8Decoder(), DecodeCall) + .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK_REQUEST_KEYFRAME)); + EXPECT_CALL(callbacks_, OnDecodedFrame); + EXPECT_CALL(callbacks_, OnNonDecodableState); + time_controller_.AdvanceTime(TimeDelta::Millis(1)); +} + +TEST_F(VideoStreamDecoderImplTest, FailToInitDecoder) { + video_stream_decoder_.OnFrame( + test::FakeFrameBuilder() + .ReceivedTime(time_controller_.GetClock()->CurrentTime()) + .PayloadType(1) + .AsLast() + .Build()); + ON_CALL(decoder_factory_.Vp8Decoder(), Configure) + .WillByDefault(Return(false)); + EXPECT_CALL(callbacks_, OnNonDecodableState); + time_controller_.AdvanceTime(TimeDelta::Millis(1)); +} + +TEST_F(VideoStreamDecoderImplTest, FailToDecodeFrame) { + video_stream_decoder_.OnFrame( + test::FakeFrameBuilder().PayloadType(1).AsLast().Build()); + ON_CALL(decoder_factory_.Vp8Decoder(), DecodeCall) + .WillByDefault(Return(WEBRTC_VIDEO_CODEC_ERROR)); + EXPECT_CALL(callbacks_, OnNonDecodableState); + time_controller_.AdvanceTime(TimeDelta::Millis(1)); +} + +TEST_F(VideoStreamDecoderImplTest, ChangeFramePayloadType) { + constexpr TimeDelta kFrameInterval = TimeDelta::Millis(1000 / 60); + video_stream_decoder_.OnFrame( + test::FakeFrameBuilder().PayloadType(1).Id(0).AsLast().Build()); + EXPECT_CALL(decoder_factory_.Vp8Decoder(), DecodeCall); + EXPECT_CALL(callbacks_, OnDecodedFrame); + time_controller_.AdvanceTime(kFrameInterval); + + video_stream_decoder_.OnFrame( + test::FakeFrameBuilder().PayloadType(2).Id(1).AsLast().Build()); + EXPECT_CALL(decoder_factory_.Av1Decoder(), DecodeCall); + EXPECT_CALL(callbacks_, OnDecodedFrame); + time_controller_.AdvanceTime(kFrameInterval); +} + +} // namespace +} // namespace webrtc |