From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../libwebrtc/pc/video_rtp_receiver_unittest.cc | 200 +++++++++++++++++++++ 1 file changed, 200 insertions(+) create mode 100644 third_party/libwebrtc/pc/video_rtp_receiver_unittest.cc (limited to 'third_party/libwebrtc/pc/video_rtp_receiver_unittest.cc') diff --git a/third_party/libwebrtc/pc/video_rtp_receiver_unittest.cc b/third_party/libwebrtc/pc/video_rtp_receiver_unittest.cc new file mode 100644 index 0000000000..3ec9a28295 --- /dev/null +++ b/third_party/libwebrtc/pc/video_rtp_receiver_unittest.cc @@ -0,0 +1,200 @@ +/* + * Copyright 2019 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 "pc/video_rtp_receiver.h" + +#include +#include + +#include "api/task_queue/task_queue_base.h" +#include "api/video/recordable_encoded_frame.h" +#include "api/video/test/mock_recordable_encoded_frame.h" +#include "media/base/fake_media_engine.h" +#include "rtc_base/task_queue_for_test.h" +#include "test/gmock.h" +#include "test/gtest.h" + +using ::testing::_; +using ::testing::AnyNumber; +using ::testing::InSequence; +using ::testing::Mock; +using ::testing::NiceMock; +using ::testing::SaveArg; +using ::testing::StrictMock; + +namespace webrtc { +namespace { + +class VideoRtpReceiverTest : public testing::Test { + protected: + class MockVideoMediaChannel : public cricket::FakeVideoMediaChannel { + public: + MockVideoMediaChannel( + cricket::FakeVideoEngine* engine, + const cricket::VideoOptions& options, + TaskQueueBase* network_thread = rtc::Thread::Current()) + : FakeVideoMediaChannel(engine, options, network_thread) {} + MOCK_METHOD(void, + SetRecordableEncodedFrameCallback, + (uint32_t, std::function), + (override)); + MOCK_METHOD(void, + ClearRecordableEncodedFrameCallback, + (uint32_t), + (override)); + MOCK_METHOD(void, RequestRecvKeyFrame, (uint32_t), (override)); + MOCK_METHOD(void, + GenerateSendKeyFrame, + (uint32_t, const std::vector&), + (override)); + }; + + class MockVideoSink : public rtc::VideoSinkInterface { + public: + MOCK_METHOD(void, OnFrame, (const RecordableEncodedFrame&), (override)); + }; + + VideoRtpReceiverTest() + : worker_thread_(rtc::Thread::Create()), + channel_(nullptr, cricket::VideoOptions()), + receiver_(rtc::make_ref_counted( + worker_thread_.get(), + std::string("receiver"), + std::vector({"stream"}))) { + worker_thread_->Start(); + SetMediaChannel(&channel_); + } + + ~VideoRtpReceiverTest() override { + // Clear expectations that tests may have set up before calling + // SetMediaChannel(nullptr). + Mock::VerifyAndClearExpectations(&channel_); + receiver_->Stop(); + SetMediaChannel(nullptr); + } + + void SetMediaChannel(cricket::MediaChannel* media_channel) { + SendTask(worker_thread_.get(), + [&]() { receiver_->SetMediaChannel(media_channel); }); + } + + webrtc::VideoTrackSourceInterface* Source() { + return receiver_->streams()[0]->FindVideoTrack("receiver")->GetSource(); + } + + rtc::AutoThread main_thread_; + std::unique_ptr worker_thread_; + NiceMock channel_; + rtc::scoped_refptr receiver_; +}; + +TEST_F(VideoRtpReceiverTest, SupportsEncodedOutput) { + EXPECT_TRUE(Source()->SupportsEncodedOutput()); +} + +TEST_F(VideoRtpReceiverTest, GeneratesKeyFrame) { + EXPECT_CALL(channel_, RequestRecvKeyFrame(0)); + Source()->GenerateKeyFrame(); +} + +TEST_F(VideoRtpReceiverTest, + GenerateKeyFrameOnChannelSwitchUnlessGenerateKeyframeCalled) { + // A channel switch without previous call to GenerateKeyFrame shouldn't + // cause a call to happen on the new channel. + MockVideoMediaChannel channel2(nullptr, cricket::VideoOptions()); + EXPECT_CALL(channel_, RequestRecvKeyFrame).Times(0); + EXPECT_CALL(channel2, RequestRecvKeyFrame).Times(0); + SetMediaChannel(&channel2); + Mock::VerifyAndClearExpectations(&channel2); + + // Generate a key frame. When we switch channel next time, we will have to + // re-generate it as we don't know if it was eventually received + EXPECT_CALL(channel2, RequestRecvKeyFrame).Times(1); + Source()->GenerateKeyFrame(); + MockVideoMediaChannel channel3(nullptr, cricket::VideoOptions()); + EXPECT_CALL(channel3, RequestRecvKeyFrame); + SetMediaChannel(&channel3); + + // Switching to a new channel should now not cause calls to GenerateKeyFrame. + StrictMock channel4(nullptr, cricket::VideoOptions()); + SetMediaChannel(&channel4); + + // We must call SetMediaChannel(nullptr) here since the mock media channels + // live on the stack and `receiver_` still has a pointer to those objects. + SetMediaChannel(nullptr); +} + +TEST_F(VideoRtpReceiverTest, EnablesEncodedOutput) { + EXPECT_CALL(channel_, SetRecordableEncodedFrameCallback(/*ssrc=*/0, _)); + EXPECT_CALL(channel_, ClearRecordableEncodedFrameCallback).Times(0); + MockVideoSink sink; + Source()->AddEncodedSink(&sink); +} + +TEST_F(VideoRtpReceiverTest, DisablesEncodedOutput) { + EXPECT_CALL(channel_, ClearRecordableEncodedFrameCallback(/*ssrc=*/0)); + MockVideoSink sink; + Source()->AddEncodedSink(&sink); + Source()->RemoveEncodedSink(&sink); +} + +TEST_F(VideoRtpReceiverTest, DisablesEnablesEncodedOutputOnChannelSwitch) { + InSequence s; + EXPECT_CALL(channel_, SetRecordableEncodedFrameCallback); + EXPECT_CALL(channel_, ClearRecordableEncodedFrameCallback); + MockVideoSink sink; + Source()->AddEncodedSink(&sink); + MockVideoMediaChannel channel2(nullptr, cricket::VideoOptions()); + EXPECT_CALL(channel2, SetRecordableEncodedFrameCallback); + SetMediaChannel(&channel2); + Mock::VerifyAndClearExpectations(&channel2); + + // When clearing encoded frame buffer function, we need channel switches + // to NOT set the callback again. + EXPECT_CALL(channel2, ClearRecordableEncodedFrameCallback); + Source()->RemoveEncodedSink(&sink); + StrictMock channel3(nullptr, cricket::VideoOptions()); + SetMediaChannel(&channel3); + + // We must call SetMediaChannel(nullptr) here since the mock media channels + // live on the stack and `receiver_` still has a pointer to those objects. + SetMediaChannel(nullptr); +} + +TEST_F(VideoRtpReceiverTest, BroadcastsEncodedFramesWhenEnabled) { + std::function broadcast; + EXPECT_CALL(channel_, SetRecordableEncodedFrameCallback(_, _)) + .WillRepeatedly(SaveArg<1>(&broadcast)); + MockVideoSink sink; + Source()->AddEncodedSink(&sink); + + // Make sure SetEncodedFrameBufferFunction completes. + Mock::VerifyAndClearExpectations(&channel_); + + // Pass two frames on different contexts. + EXPECT_CALL(sink, OnFrame).Times(2); + MockRecordableEncodedFrame frame; + broadcast(frame); + SendTask(worker_thread_.get(), [&] { broadcast(frame); }); +} + +TEST_F(VideoRtpReceiverTest, EnablesEncodedOutputOnChannelRestart) { + InSequence s; + MockVideoSink sink; + Source()->AddEncodedSink(&sink); + EXPECT_CALL(channel_, SetRecordableEncodedFrameCallback(4711, _)); + receiver_->SetupMediaChannel(4711); + EXPECT_CALL(channel_, ClearRecordableEncodedFrameCallback(4711)); + EXPECT_CALL(channel_, SetRecordableEncodedFrameCallback(0, _)); + receiver_->SetupUnsignaledMediaChannel(); +} + +} // namespace +} // namespace webrtc -- cgit v1.2.3