blob: bb1dc193debd9cfdf197005e4c8e21945b93b1a4 [file] [log] [blame]
Markus Handell15f2ff42019-11-22 10:34:37 +01001/*
2 * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "pc/video_rtp_track_source.h"
12
Harald Alvestrandc24a2182022-02-23 13:44:59 +000013#include "absl/types/optional.h"
14#include "api/scoped_refptr.h"
15#include "api/units/timestamp.h"
16#include "api/video/color_space.h"
17#include "api/video/encoded_image.h"
18#include "api/video/video_codec_type.h"
Markus Handell15f2ff42019-11-22 10:34:37 +010019#include "rtc_base/ref_counted_object.h"
20#include "test/gmock.h"
21#include "test/gtest.h"
22
23namespace webrtc {
24namespace {
25
Markus Handelld5e2f212019-11-26 09:30:08 +010026class MockCallback : public VideoRtpTrackSource::Callback {
27 public:
Danil Chapovalov3a353122020-05-15 11:16:53 +020028 MOCK_METHOD(void, OnGenerateKeyFrame, (), (override));
29 MOCK_METHOD(void, OnEncodedSinkEnabled, (bool), (override));
Markus Handelld5e2f212019-11-26 09:30:08 +010030};
31
32class MockSink : public rtc::VideoSinkInterface<RecordableEncodedFrame> {
33 public:
Danil Chapovalov3a353122020-05-15 11:16:53 +020034 MOCK_METHOD(void, OnFrame, (const RecordableEncodedFrame&), (override));
Markus Handelld5e2f212019-11-26 09:30:08 +010035};
36
37rtc::scoped_refptr<VideoRtpTrackSource> MakeSource(
38 VideoRtpTrackSource::Callback* callback) {
Tommi87f70902021-04-27 14:43:08 +020039 return rtc::make_ref_counted<VideoRtpTrackSource>(callback);
Markus Handelld5e2f212019-11-26 09:30:08 +010040}
41
42TEST(VideoRtpTrackSourceTest, CreatesWithRemoteAtttributeSet) {
43 EXPECT_TRUE(MakeSource(nullptr)->remote());
44}
45
46TEST(VideoRtpTrackSourceTest, EnablesEncodingOutputOnAddingSink) {
47 MockCallback mock_callback;
48 EXPECT_CALL(mock_callback, OnGenerateKeyFrame).Times(0);
49 auto source = MakeSource(&mock_callback);
50 MockSink sink;
51 EXPECT_CALL(mock_callback, OnEncodedSinkEnabled(true));
52 source->AddEncodedSink(&sink);
53}
54
55TEST(VideoRtpTrackSourceTest, EnablesEncodingOutputOnceOnAddingTwoSinks) {
56 MockCallback mock_callback;
57 EXPECT_CALL(mock_callback, OnGenerateKeyFrame).Times(0);
58 auto source = MakeSource(&mock_callback);
59 MockSink sink;
60 EXPECT_CALL(mock_callback, OnEncodedSinkEnabled(true)).Times(1);
61 source->AddEncodedSink(&sink);
62 MockSink sink2;
63 source->AddEncodedSink(&sink2);
64}
65
66TEST(VideoRtpTrackSourceTest, DisablesEncodingOutputOnOneSinkRemoved) {
67 MockCallback mock_callback;
68 EXPECT_CALL(mock_callback, OnGenerateKeyFrame).Times(0);
69 EXPECT_CALL(mock_callback, OnEncodedSinkEnabled(true));
70 EXPECT_CALL(mock_callback, OnEncodedSinkEnabled(false)).Times(0);
71 auto source = MakeSource(&mock_callback);
72 MockSink sink;
73 source->AddEncodedSink(&sink);
74 testing::Mock::VerifyAndClearExpectations(&mock_callback);
75 EXPECT_CALL(mock_callback, OnEncodedSinkEnabled(false));
76 source->RemoveEncodedSink(&sink);
77}
78
79TEST(VideoRtpTrackSourceTest, DisablesEncodingOutputOnLastSinkRemoved) {
80 MockCallback mock_callback;
81 EXPECT_CALL(mock_callback, OnGenerateKeyFrame).Times(0);
82 EXPECT_CALL(mock_callback, OnEncodedSinkEnabled(true));
83 auto source = MakeSource(&mock_callback);
84 MockSink sink;
85 source->AddEncodedSink(&sink);
86 MockSink sink2;
87 source->AddEncodedSink(&sink2);
88 source->RemoveEncodedSink(&sink);
89 testing::Mock::VerifyAndClearExpectations(&mock_callback);
90 EXPECT_CALL(mock_callback, OnEncodedSinkEnabled(false));
91 source->RemoveEncodedSink(&sink2);
92}
93
94TEST(VideoRtpTrackSourceTest, GeneratesKeyFrameWhenRequested) {
95 MockCallback mock_callback;
96 auto source = MakeSource(&mock_callback);
97 EXPECT_CALL(mock_callback, OnGenerateKeyFrame);
98 source->GenerateKeyFrame();
99}
100
101TEST(VideoRtpTrackSourceTest, NoCallbacksAfterClearedCallback) {
102 testing::StrictMock<MockCallback> mock_callback;
103 auto source = MakeSource(&mock_callback);
104 source->ClearCallback();
105 MockSink sink;
106 source->AddEncodedSink(&sink);
107 source->GenerateKeyFrame();
108 source->RemoveEncodedSink(&sink);
109}
110
111class TestFrame : public RecordableEncodedFrame {
112 public:
113 rtc::scoped_refptr<const webrtc::EncodedImageBufferInterface> encoded_buffer()
114 const override {
115 return nullptr;
116 }
117 absl::optional<webrtc::ColorSpace> color_space() const override {
118 return absl::nullopt;
119 }
120 VideoCodecType codec() const override { return kVideoCodecGeneric; }
121 bool is_key_frame() const override { return false; }
122 EncodedResolution resolution() const override {
123 return EncodedResolution{0, 0};
124 }
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100125 Timestamp render_time() const override { return Timestamp::Millis(0); }
Markus Handelld5e2f212019-11-26 09:30:08 +0100126};
127
128TEST(VideoRtpTrackSourceTest, BroadcastsFrames) {
129 auto source = MakeSource(nullptr);
130 MockSink sink;
131 source->AddEncodedSink(&sink);
132 MockSink sink2;
133 source->AddEncodedSink(&sink2);
134 TestFrame frame;
135 EXPECT_CALL(sink, OnFrame);
136 EXPECT_CALL(sink2, OnFrame);
137 source->BroadcastRecordableEncodedFrame(frame);
Markus Handell15f2ff42019-11-22 10:34:37 +0100138}
139
140} // namespace
141} // namespace webrtc