blob: c7718454fbefcc4e787f4fd40107f3b47bb77410 [file] [log] [blame]
Tommiae4d0972020-05-18 08:45:38 +02001/*
2 * Copyright 2017 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 "video/video_receive_stream2.h"
12
13#include <algorithm>
Markus Handell588f9b32021-04-08 19:19:50 +020014#include <limits>
Tommiae4d0972020-05-18 08:45:38 +020015#include <memory>
Evan Shrubsole9a999052021-12-12 15:27:00 +010016#include <tuple>
Tommiae4d0972020-05-18 08:45:38 +020017#include <utility>
18#include <vector>
19
20#include "api/task_queue/default_task_queue_factory.h"
Danil Chapovalov9cd4d492021-08-03 14:59:00 +020021#include "api/test/mock_video_decoder.h"
22#include "api/test/mock_video_decoder_factory.h"
Tommiae4d0972020-05-18 08:45:38 +020023#include "api/test/video/function_video_decoder_factory.h"
Markus Handell588f9b32021-04-08 19:19:50 +020024#include "api/video/video_frame.h"
Tommiae4d0972020-05-18 08:45:38 +020025#include "api/video_codecs/video_decoder.h"
26#include "call/rtp_stream_receiver_controller.h"
27#include "common_video/test/utilities.h"
28#include "media/base/fake_video_renderer.h"
Tommi90738dd2021-05-31 17:36:47 +020029#include "media/engine/fake_webrtc_call.h"
Tommiae4d0972020-05-18 08:45:38 +020030#include "modules/pacing/packet_router.h"
31#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
Tommiae4d0972020-05-18 08:45:38 +020032#include "modules/video_coding/encoded_frame.h"
Tommiae4d0972020-05-18 08:45:38 +020033#include "rtc_base/event.h"
34#include "system_wrappers/include/clock.h"
35#include "test/fake_decoder.h"
Tommiae4d0972020-05-18 08:45:38 +020036#include "test/gmock.h"
37#include "test/gtest.h"
Danil Chapovalov9cd4d492021-08-03 14:59:00 +020038#include "test/mock_transport.h"
Tommiae4d0972020-05-18 08:45:38 +020039#include "test/run_loop.h"
Jonas Oreland8ca06132022-03-14 12:52:48 +010040#include "test/scoped_key_value_config.h"
Tommiae4d0972020-05-18 08:45:38 +020041#include "test/time_controller/simulated_time_controller.h"
42#include "test/video_decoder_proxy_factory.h"
43#include "video/call_stats2.h"
44
45namespace webrtc {
46namespace {
47
48using ::testing::_;
Markus Handell588f9b32021-04-08 19:19:50 +020049using ::testing::AllOf;
Tommiae4d0972020-05-18 08:45:38 +020050using ::testing::ElementsAreArray;
Markus Handell588f9b32021-04-08 19:19:50 +020051using ::testing::Field;
52using ::testing::InSequence;
Tommiae4d0972020-05-18 08:45:38 +020053using ::testing::Invoke;
54using ::testing::IsEmpty;
Markus Handell588f9b32021-04-08 19:19:50 +020055using ::testing::Property;
Tommiae4d0972020-05-18 08:45:38 +020056using ::testing::SizeIs;
Danil Chapovalovd08930d2021-08-12 13:26:55 +020057using ::testing::WithoutArgs;
Tommiae4d0972020-05-18 08:45:38 +020058
59constexpr int kDefaultTimeOutMs = 50;
60
philipelca188092021-03-23 12:00:49 +010061class FrameObjectFake : public EncodedFrame {
Tommiae4d0972020-05-18 08:45:38 +020062 public:
63 void SetPayloadType(uint8_t payload_type) { _payloadType = payload_type; }
64
65 void SetRotation(const VideoRotation& rotation) { rotation_ = rotation; }
66
67 void SetNtpTime(int64_t ntp_time_ms) { ntp_time_ms_ = ntp_time_ms; }
68
69 int64_t ReceivedTime() const override { return 0; }
70
71 int64_t RenderTime() const override { return _renderTimeMs; }
72};
73
74} // namespace
75
76class VideoReceiveStream2Test : public ::testing::Test {
77 public:
78 VideoReceiveStream2Test()
Markus Handelleb61b7f2021-06-22 10:46:48 +020079 : task_queue_factory_(CreateDefaultTaskQueueFactory()),
Tommi9e2b3152021-06-21 22:15:39 +020080 h264_decoder_factory_(&mock_h264_video_decoder_),
81 config_(&mock_transport_, &h264_decoder_factory_),
Jonas Oreland8ca06132022-03-14 12:52:48 +010082 call_stats_(Clock::GetRealTimeClock(), loop_.task_queue()) {
83 fake_call_.SetFieldTrial("WebRTC-FrameBuffer3/arm:FrameBuffer3/");
84 }
Tommi90738dd2021-05-31 17:36:47 +020085 ~VideoReceiveStream2Test() override {
86 if (video_receive_stream_)
87 video_receive_stream_->UnregisterFromTransport();
88 }
Tommiae4d0972020-05-18 08:45:38 +020089
Tommi90738dd2021-05-31 17:36:47 +020090 void SetUp() override {
Tommiae4d0972020-05-18 08:45:38 +020091 constexpr int kDefaultNumCpuCores = 2;
92 config_.rtp.remote_ssrc = 1111;
93 config_.rtp.local_ssrc = 2222;
94 config_.renderer = &fake_renderer_;
95 VideoReceiveStream::Decoder h264_decoder;
96 h264_decoder.payload_type = 99;
97 h264_decoder.video_format = SdpVideoFormat("H264");
98 h264_decoder.video_format.parameters.insert(
99 {"sprop-parameter-sets", "Z0IACpZTBYmI,aMljiA=="});
Johannes Kron16359f62021-02-18 23:37:22 +0100100 config_.decoders.clear();
Tommiae4d0972020-05-18 08:45:38 +0200101 config_.decoders.push_back(h264_decoder);
Tommiae4d0972020-05-18 08:45:38 +0200102
103 clock_ = Clock::GetRealTimeClock();
104 timing_ = new VCMTiming(clock_);
105
106 video_receive_stream_ =
107 std::make_unique<webrtc::internal::VideoReceiveStream2>(
Tommi90738dd2021-05-31 17:36:47 +0200108 task_queue_factory_.get(), &fake_call_, kDefaultNumCpuCores,
Markus Handell0e62f7a2021-07-20 13:32:02 +0200109 &packet_router_, config_.Copy(), &call_stats_, clock_, timing_,
Evan Shrubsole5723d852022-02-14 14:09:57 +0100110 &nack_periodic_processor_, nullptr);
Tommi90738dd2021-05-31 17:36:47 +0200111 video_receive_stream_->RegisterWithTransport(
112 &rtp_stream_receiver_controller_);
Tommiae4d0972020-05-18 08:45:38 +0200113 }
114
115 protected:
116 test::RunLoop loop_;
Tommiae4d0972020-05-18 08:45:38 +0200117 const std::unique_ptr<TaskQueueFactory> task_queue_factory_;
Tommi9e2b3152021-06-21 22:15:39 +0200118 test::VideoDecoderProxyFactory h264_decoder_factory_;
Markus Handell0e62f7a2021-07-20 13:32:02 +0200119 NackPeriodicProcessor nack_periodic_processor_;
Tommiae4d0972020-05-18 08:45:38 +0200120 VideoReceiveStream::Config config_;
121 internal::CallStats call_stats_;
122 MockVideoDecoder mock_h264_video_decoder_;
Tommiae4d0972020-05-18 08:45:38 +0200123 cricket::FakeVideoRenderer fake_renderer_;
Tommi90738dd2021-05-31 17:36:47 +0200124 cricket::FakeCall fake_call_;
Tommiae4d0972020-05-18 08:45:38 +0200125 MockTransport mock_transport_;
126 PacketRouter packet_router_;
127 RtpStreamReceiverController rtp_stream_receiver_controller_;
128 std::unique_ptr<webrtc::internal::VideoReceiveStream2> video_receive_stream_;
129 Clock* clock_;
130 VCMTiming* timing_;
131};
132
133TEST_F(VideoReceiveStream2Test, CreateFrameFromH264FmtpSpropAndIdr) {
134 constexpr uint8_t idr_nalu[] = {0x05, 0xFF, 0xFF, 0xFF};
135 RtpPacketToSend rtppacket(nullptr);
136 uint8_t* payload = rtppacket.AllocatePayload(sizeof(idr_nalu));
137 memcpy(payload, idr_nalu, sizeof(idr_nalu));
138 rtppacket.SetMarker(true);
139 rtppacket.SetSsrc(1111);
140 rtppacket.SetPayloadType(99);
141 rtppacket.SetSequenceNumber(1);
142 rtppacket.SetTimestamp(0);
Danil Chapovalovd08930d2021-08-12 13:26:55 +0200143 rtc::Event init_decode_event;
144 EXPECT_CALL(mock_h264_video_decoder_, Configure).WillOnce(WithoutArgs([&] {
145 init_decode_event.Set();
146 return true;
147 }));
Tommiae4d0972020-05-18 08:45:38 +0200148 EXPECT_CALL(mock_h264_video_decoder_, RegisterDecodeCompleteCallback(_));
149 video_receive_stream_->Start();
150 EXPECT_CALL(mock_h264_video_decoder_, Decode(_, false, _));
151 RtpPacketReceived parsed_packet;
152 ASSERT_TRUE(parsed_packet.Parse(rtppacket.data(), rtppacket.size()));
153 rtp_stream_receiver_controller_.OnRtpPacket(parsed_packet);
154 EXPECT_CALL(mock_h264_video_decoder_, Release());
155 // Make sure the decoder thread had a chance to run.
Danil Chapovalovd08930d2021-08-12 13:26:55 +0200156 init_decode_event.Wait(kDefaultTimeOutMs);
Tommiae4d0972020-05-18 08:45:38 +0200157}
158
159TEST_F(VideoReceiveStream2Test, PlayoutDelay) {
Niels Möllerd381eed2020-09-02 15:34:40 +0200160 const VideoPlayoutDelay kPlayoutDelayMs = {123, 321};
Tommiae4d0972020-05-18 08:45:38 +0200161 std::unique_ptr<FrameObjectFake> test_frame(new FrameObjectFake());
philipel9aa9b8d2021-02-15 13:31:29 +0100162 test_frame->SetId(0);
Tommiae4d0972020-05-18 08:45:38 +0200163 test_frame->SetPlayoutDelay(kPlayoutDelayMs);
164
165 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100166 EXPECT_EQ(kPlayoutDelayMs.min_ms, timing_->min_playout_delay().ms());
167 EXPECT_EQ(kPlayoutDelayMs.max_ms, timing_->max_playout_delay().ms());
Tommiae4d0972020-05-18 08:45:38 +0200168
169 // Check that the biggest minimum delay is chosen.
170 video_receive_stream_->SetMinimumPlayoutDelay(400);
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100171 EXPECT_EQ(400, timing_->min_playout_delay().ms());
Tommiae4d0972020-05-18 08:45:38 +0200172
173 // Check base minimum delay validation.
174 EXPECT_FALSE(video_receive_stream_->SetBaseMinimumPlayoutDelayMs(12345));
175 EXPECT_FALSE(video_receive_stream_->SetBaseMinimumPlayoutDelayMs(-1));
176 EXPECT_TRUE(video_receive_stream_->SetBaseMinimumPlayoutDelayMs(500));
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100177 EXPECT_EQ(500, timing_->min_playout_delay().ms());
Tommiae4d0972020-05-18 08:45:38 +0200178
179 // Check that intermidiate values are remembered and the biggest remembered
180 // is chosen.
181 video_receive_stream_->SetBaseMinimumPlayoutDelayMs(0);
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100182 EXPECT_EQ(400, timing_->min_playout_delay().ms());
Tommiae4d0972020-05-18 08:45:38 +0200183
184 video_receive_stream_->SetMinimumPlayoutDelay(0);
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100185 EXPECT_EQ(123, timing_->min_playout_delay().ms());
Tommiae4d0972020-05-18 08:45:38 +0200186}
187
188TEST_F(VideoReceiveStream2Test, PlayoutDelayPreservesDefaultMaxValue) {
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100189 const TimeDelta default_max_playout_latency = timing_->max_playout_delay();
Niels Möllerd381eed2020-09-02 15:34:40 +0200190 const VideoPlayoutDelay kPlayoutDelayMs = {123, -1};
Tommiae4d0972020-05-18 08:45:38 +0200191
192 std::unique_ptr<FrameObjectFake> test_frame(new FrameObjectFake());
philipel9aa9b8d2021-02-15 13:31:29 +0100193 test_frame->SetId(0);
Tommiae4d0972020-05-18 08:45:38 +0200194 test_frame->SetPlayoutDelay(kPlayoutDelayMs);
195
196 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
197
Artem Titovab30d722021-07-27 16:22:11 +0200198 // Ensure that -1 preserves default maximum value from `timing_`.
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100199 EXPECT_EQ(kPlayoutDelayMs.min_ms, timing_->min_playout_delay().ms());
200 EXPECT_NE(kPlayoutDelayMs.max_ms, timing_->max_playout_delay().ms());
Tommiae4d0972020-05-18 08:45:38 +0200201 EXPECT_EQ(default_max_playout_latency, timing_->max_playout_delay());
202}
203
204TEST_F(VideoReceiveStream2Test, PlayoutDelayPreservesDefaultMinValue) {
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100205 const TimeDelta default_min_playout_latency = timing_->min_playout_delay();
Niels Möllerd381eed2020-09-02 15:34:40 +0200206 const VideoPlayoutDelay kPlayoutDelayMs = {-1, 321};
Tommiae4d0972020-05-18 08:45:38 +0200207
208 std::unique_ptr<FrameObjectFake> test_frame(new FrameObjectFake());
philipel9aa9b8d2021-02-15 13:31:29 +0100209 test_frame->SetId(0);
Tommiae4d0972020-05-18 08:45:38 +0200210 test_frame->SetPlayoutDelay(kPlayoutDelayMs);
211
212 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
213
Artem Titovab30d722021-07-27 16:22:11 +0200214 // Ensure that -1 preserves default minimum value from `timing_`.
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100215 EXPECT_NE(kPlayoutDelayMs.min_ms, timing_->min_playout_delay().ms());
216 EXPECT_EQ(kPlayoutDelayMs.max_ms, timing_->max_playout_delay().ms());
Tommiae4d0972020-05-18 08:45:38 +0200217 EXPECT_EQ(default_min_playout_latency, timing_->min_playout_delay());
218}
219
Johannes Kron111e9812020-10-26 13:54:40 +0100220TEST_F(VideoReceiveStream2Test, MaxCompositionDelayNotSetByDefault) {
221 // Default with no playout delay set.
222 std::unique_ptr<FrameObjectFake> test_frame0(new FrameObjectFake());
philipel9aa9b8d2021-02-15 13:31:29 +0100223 test_frame0->SetId(0);
Johannes Kron111e9812020-10-26 13:54:40 +0100224 video_receive_stream_->OnCompleteFrame(std::move(test_frame0));
225 EXPECT_FALSE(timing_->MaxCompositionDelayInFrames());
226
227 // Max composition delay not set for playout delay 0,0.
228 std::unique_ptr<FrameObjectFake> test_frame1(new FrameObjectFake());
philipel9aa9b8d2021-02-15 13:31:29 +0100229 test_frame1->SetId(1);
Johannes Kron111e9812020-10-26 13:54:40 +0100230 test_frame1->SetPlayoutDelay({0, 0});
231 video_receive_stream_->OnCompleteFrame(std::move(test_frame1));
232 EXPECT_FALSE(timing_->MaxCompositionDelayInFrames());
233
234 // Max composition delay not set for playout delay X,Y, where X,Y>0.
235 std::unique_ptr<FrameObjectFake> test_frame2(new FrameObjectFake());
philipel9aa9b8d2021-02-15 13:31:29 +0100236 test_frame2->SetId(2);
Johannes Kron111e9812020-10-26 13:54:40 +0100237 test_frame2->SetPlayoutDelay({10, 30});
238 video_receive_stream_->OnCompleteFrame(std::move(test_frame2));
239 EXPECT_FALSE(timing_->MaxCompositionDelayInFrames());
240}
241
242TEST_F(VideoReceiveStream2Test, MaxCompositionDelaySetFromMaxPlayoutDelay) {
243 // Max composition delay set if playout delay X,Y, where X=0,Y>0.
244 const VideoPlayoutDelay kPlayoutDelayMs = {0, 50};
245 const int kExpectedMaxCompositionDelayInFrames = 3; // ~50 ms at 60 fps.
246 std::unique_ptr<FrameObjectFake> test_frame(new FrameObjectFake());
philipel9aa9b8d2021-02-15 13:31:29 +0100247 test_frame->SetId(0);
Johannes Kron111e9812020-10-26 13:54:40 +0100248 test_frame->SetPlayoutDelay(kPlayoutDelayMs);
249 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
250 EXPECT_EQ(kExpectedMaxCompositionDelayInFrames,
251 timing_->MaxCompositionDelayInFrames());
252}
253
Tommiae4d0972020-05-18 08:45:38 +0200254class VideoReceiveStream2TestWithFakeDecoder : public ::testing::Test {
255 public:
256 VideoReceiveStream2TestWithFakeDecoder()
257 : fake_decoder_factory_(
258 []() { return std::make_unique<test::FakeDecoder>(); }),
Tommiae4d0972020-05-18 08:45:38 +0200259 task_queue_factory_(CreateDefaultTaskQueueFactory()),
Tommi9e2b3152021-06-21 22:15:39 +0200260 config_(&mock_transport_, &fake_decoder_factory_),
Tommiae4d0972020-05-18 08:45:38 +0200261 call_stats_(Clock::GetRealTimeClock(), loop_.task_queue()) {}
Tommi90738dd2021-05-31 17:36:47 +0200262 ~VideoReceiveStream2TestWithFakeDecoder() override {
263 if (video_receive_stream_)
264 video_receive_stream_->UnregisterFromTransport();
265 }
Tommiae4d0972020-05-18 08:45:38 +0200266
Tommi90738dd2021-05-31 17:36:47 +0200267 void SetUp() override {
Tommiae4d0972020-05-18 08:45:38 +0200268 config_.rtp.remote_ssrc = 1111;
269 config_.rtp.local_ssrc = 2222;
270 config_.renderer = &fake_renderer_;
271 VideoReceiveStream::Decoder fake_decoder;
272 fake_decoder.payload_type = 99;
273 fake_decoder.video_format = SdpVideoFormat("VP8");
Tommiae4d0972020-05-18 08:45:38 +0200274 config_.decoders.push_back(fake_decoder);
275 clock_ = Clock::GetRealTimeClock();
276 ReCreateReceiveStream(VideoReceiveStream::RecordingState());
277 }
278
279 void ReCreateReceiveStream(VideoReceiveStream::RecordingState state) {
280 constexpr int kDefaultNumCpuCores = 2;
Tommi90738dd2021-05-31 17:36:47 +0200281 if (video_receive_stream_) {
282 video_receive_stream_->UnregisterFromTransport();
283 video_receive_stream_ = nullptr;
284 }
Tommiae4d0972020-05-18 08:45:38 +0200285 timing_ = new VCMTiming(clock_);
286 video_receive_stream_.reset(new webrtc::internal::VideoReceiveStream2(
Tommi90738dd2021-05-31 17:36:47 +0200287 task_queue_factory_.get(), &fake_call_, kDefaultNumCpuCores,
Markus Handell0e62f7a2021-07-20 13:32:02 +0200288 &packet_router_, config_.Copy(), &call_stats_, clock_, timing_,
Evan Shrubsole5723d852022-02-14 14:09:57 +0100289 &nack_periodic_processor_, nullptr));
Tommi90738dd2021-05-31 17:36:47 +0200290 video_receive_stream_->RegisterWithTransport(
291 &rtp_stream_receiver_controller_);
Tommiae4d0972020-05-18 08:45:38 +0200292 video_receive_stream_->SetAndGetRecordingState(std::move(state), false);
293 }
294
295 protected:
296 test::RunLoop loop_;
297 test::FunctionVideoDecoderFactory fake_decoder_factory_;
Tommiae4d0972020-05-18 08:45:38 +0200298 const std::unique_ptr<TaskQueueFactory> task_queue_factory_;
Markus Handell0e62f7a2021-07-20 13:32:02 +0200299 NackPeriodicProcessor nack_periodic_processor_;
Tommiae4d0972020-05-18 08:45:38 +0200300 VideoReceiveStream::Config config_;
301 internal::CallStats call_stats_;
302 cricket::FakeVideoRenderer fake_renderer_;
303 MockTransport mock_transport_;
304 PacketRouter packet_router_;
305 RtpStreamReceiverController rtp_stream_receiver_controller_;
Tommi90738dd2021-05-31 17:36:47 +0200306 cricket::FakeCall fake_call_;
Tommiae4d0972020-05-18 08:45:38 +0200307 std::unique_ptr<webrtc::internal::VideoReceiveStream2> video_receive_stream_;
308 Clock* clock_;
309 VCMTiming* timing_;
310};
311
312TEST_F(VideoReceiveStream2TestWithFakeDecoder, PassesNtpTime) {
313 const int64_t kNtpTimestamp = 12345;
314 auto test_frame = std::make_unique<FrameObjectFake>();
315 test_frame->SetPayloadType(99);
philipel9aa9b8d2021-02-15 13:31:29 +0100316 test_frame->SetId(0);
Tommiae4d0972020-05-18 08:45:38 +0200317 test_frame->SetNtpTime(kNtpTimestamp);
318
319 video_receive_stream_->Start();
320 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
321 EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOutMs));
322 EXPECT_EQ(kNtpTimestamp, fake_renderer_.ntp_time_ms());
323}
324
325TEST_F(VideoReceiveStream2TestWithFakeDecoder, PassesRotation) {
326 const webrtc::VideoRotation kRotation = webrtc::kVideoRotation_180;
327 auto test_frame = std::make_unique<FrameObjectFake>();
328 test_frame->SetPayloadType(99);
philipel9aa9b8d2021-02-15 13:31:29 +0100329 test_frame->SetId(0);
Tommiae4d0972020-05-18 08:45:38 +0200330 test_frame->SetRotation(kRotation);
331
332 video_receive_stream_->Start();
333 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
334 EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOutMs));
335
336 EXPECT_EQ(kRotation, fake_renderer_.rotation());
337}
338
339TEST_F(VideoReceiveStream2TestWithFakeDecoder, PassesPacketInfos) {
340 auto test_frame = std::make_unique<FrameObjectFake>();
341 test_frame->SetPayloadType(99);
philipel9aa9b8d2021-02-15 13:31:29 +0100342 test_frame->SetId(0);
Tommiae4d0972020-05-18 08:45:38 +0200343 RtpPacketInfos packet_infos = CreatePacketInfos(3);
344 test_frame->SetPacketInfos(packet_infos);
345
346 video_receive_stream_->Start();
347 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
348 EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOutMs));
349
350 EXPECT_THAT(fake_renderer_.packet_infos(), ElementsAreArray(packet_infos));
351}
352
353TEST_F(VideoReceiveStream2TestWithFakeDecoder, RenderedFrameUpdatesGetSources) {
354 constexpr uint32_t kSsrc = 1111;
355 constexpr uint32_t kCsrc = 9001;
356 constexpr uint32_t kRtpTimestamp = 12345;
357
358 // Prepare one video frame with per-packet information.
359 auto test_frame = std::make_unique<FrameObjectFake>();
360 test_frame->SetPayloadType(99);
philipel9aa9b8d2021-02-15 13:31:29 +0100361 test_frame->SetId(0);
Tommiae4d0972020-05-18 08:45:38 +0200362 RtpPacketInfos packet_infos;
363 {
364 RtpPacketInfos::vector_type infos;
365
366 RtpPacketInfo info;
367 info.set_ssrc(kSsrc);
368 info.set_csrcs({kCsrc});
369 info.set_rtp_timestamp(kRtpTimestamp);
370
Johannes Kronf7de74c2021-04-30 13:10:56 +0200371 info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(5000));
Tommiae4d0972020-05-18 08:45:38 +0200372 infos.push_back(info);
373
Johannes Kronf7de74c2021-04-30 13:10:56 +0200374 info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(3000));
Tommiae4d0972020-05-18 08:45:38 +0200375 infos.push_back(info);
376
Johannes Kronf7de74c2021-04-30 13:10:56 +0200377 info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(2000));
Tommiae4d0972020-05-18 08:45:38 +0200378 infos.push_back(info);
379
Johannes Kronf7de74c2021-04-30 13:10:56 +0200380 info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(1000));
Tommiae4d0972020-05-18 08:45:38 +0200381 infos.push_back(info);
382
383 packet_infos = RtpPacketInfos(std::move(infos));
384 }
385 test_frame->SetPacketInfos(packet_infos);
386
387 // Start receive stream.
388 video_receive_stream_->Start();
389 EXPECT_THAT(video_receive_stream_->GetSources(), IsEmpty());
390
391 // Render one video frame.
392 int64_t timestamp_ms_min = clock_->TimeInMilliseconds();
393 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
394 EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOutMs));
395 int64_t timestamp_ms_max = clock_->TimeInMilliseconds();
396
397 // Verify that the per-packet information is passed to the renderer.
398 EXPECT_THAT(fake_renderer_.packet_infos(), ElementsAreArray(packet_infos));
399
Artem Titovab30d722021-07-27 16:22:11 +0200400 // Verify that the per-packet information also updates `GetSources()`.
Tommiae4d0972020-05-18 08:45:38 +0200401 std::vector<RtpSource> sources = video_receive_stream_->GetSources();
402 ASSERT_THAT(sources, SizeIs(2));
403 {
404 auto it = std::find_if(sources.begin(), sources.end(),
405 [](const RtpSource& source) {
406 return source.source_type() == RtpSourceType::SSRC;
407 });
408 ASSERT_NE(it, sources.end());
409
410 EXPECT_EQ(it->source_id(), kSsrc);
411 EXPECT_EQ(it->source_type(), RtpSourceType::SSRC);
412 EXPECT_EQ(it->rtp_timestamp(), kRtpTimestamp);
413 EXPECT_GE(it->timestamp_ms(), timestamp_ms_min);
414 EXPECT_LE(it->timestamp_ms(), timestamp_ms_max);
415 }
416 {
417 auto it = std::find_if(sources.begin(), sources.end(),
418 [](const RtpSource& source) {
419 return source.source_type() == RtpSourceType::CSRC;
420 });
421 ASSERT_NE(it, sources.end());
422
423 EXPECT_EQ(it->source_id(), kCsrc);
424 EXPECT_EQ(it->source_type(), RtpSourceType::CSRC);
425 EXPECT_EQ(it->rtp_timestamp(), kRtpTimestamp);
426 EXPECT_GE(it->timestamp_ms(), timestamp_ms_min);
427 EXPECT_LE(it->timestamp_ms(), timestamp_ms_max);
428 }
429}
430
Markus Handell588f9b32021-04-08 19:19:50 +0200431std::unique_ptr<FrameObjectFake> MakeFrameWithResolution(
432 VideoFrameType frame_type,
433 int picture_id,
434 int width,
435 int height) {
Tommiae4d0972020-05-18 08:45:38 +0200436 auto frame = std::make_unique<FrameObjectFake>();
437 frame->SetPayloadType(99);
philipel9aa9b8d2021-02-15 13:31:29 +0100438 frame->SetId(picture_id);
Tommiae4d0972020-05-18 08:45:38 +0200439 frame->SetFrameType(frame_type);
Markus Handell588f9b32021-04-08 19:19:50 +0200440 frame->_encodedWidth = width;
441 frame->_encodedHeight = height;
Tommiae4d0972020-05-18 08:45:38 +0200442 return frame;
443}
444
Markus Handell588f9b32021-04-08 19:19:50 +0200445std::unique_ptr<FrameObjectFake> MakeFrame(VideoFrameType frame_type,
446 int picture_id) {
447 return MakeFrameWithResolution(frame_type, picture_id, 320, 240);
448}
449
Tommiae4d0972020-05-18 08:45:38 +0200450TEST_F(VideoReceiveStream2TestWithFakeDecoder,
451 PassesFrameWhenEncodedFramesCallbackSet) {
452 testing::MockFunction<void(const RecordableEncodedFrame&)> callback;
453 video_receive_stream_->Start();
454 // Expect a keyframe request to be generated
455 EXPECT_CALL(mock_transport_, SendRtcp);
456 EXPECT_CALL(callback, Call);
457 video_receive_stream_->SetAndGetRecordingState(
458 VideoReceiveStream::RecordingState(callback.AsStdFunction()), true);
459 video_receive_stream_->OnCompleteFrame(
460 MakeFrame(VideoFrameType::kVideoFrameKey, 0));
461 EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOutMs));
462 video_receive_stream_->Stop();
463}
464
465TEST_F(VideoReceiveStream2TestWithFakeDecoder,
466 MovesEncodedFrameDispatchStateWhenReCreating) {
467 testing::MockFunction<void(const RecordableEncodedFrame&)> callback;
468 video_receive_stream_->Start();
469 // Expect a key frame request over RTCP.
470 EXPECT_CALL(mock_transport_, SendRtcp).Times(1);
471 video_receive_stream_->SetAndGetRecordingState(
472 VideoReceiveStream::RecordingState(callback.AsStdFunction()), true);
473 video_receive_stream_->Stop();
474 VideoReceiveStream::RecordingState old_state =
475 video_receive_stream_->SetAndGetRecordingState(
476 VideoReceiveStream::RecordingState(), false);
477 ReCreateReceiveStream(std::move(old_state));
478 video_receive_stream_->Stop();
479}
480
Philipp Hancke006206d2021-03-24 17:49:02 +0100481class VideoReceiveStream2TestWithSimulatedClock
Evan Shrubsole9a999052021-12-12 15:27:00 +0100482 : public ::testing::TestWithParam<std::tuple<int, bool>> {
Tommiae4d0972020-05-18 08:45:38 +0200483 public:
Markus Handell588f9b32021-04-08 19:19:50 +0200484 class FakeRenderer : public rtc::VideoSinkInterface<webrtc::VideoFrame> {
485 public:
486 void SignalDoneAfterFrames(int num_frames_received) {
487 signal_after_frame_count_ = num_frames_received;
488 if (frame_count_ == signal_after_frame_count_)
489 event_.Set();
490 }
491
492 void OnFrame(const webrtc::VideoFrame& frame) override {
493 if (++frame_count_ == signal_after_frame_count_)
494 event_.Set();
495 }
496
497 void WaitUntilDone() { event_.Wait(rtc::Event::kForever); }
498
499 private:
500 int signal_after_frame_count_ = std::numeric_limits<int>::max();
501 int frame_count_ = 0;
502 rtc::Event event_;
503 };
504
Tommiae4d0972020-05-18 08:45:38 +0200505 class FakeDecoder2 : public test::FakeDecoder {
506 public:
507 explicit FakeDecoder2(std::function<void()> decode_callback)
508 : callback_(decode_callback) {}
509
510 int32_t Decode(const EncodedImage& input,
511 bool missing_frames,
512 int64_t render_time_ms) override {
513 int32_t result =
514 FakeDecoder::Decode(input, missing_frames, render_time_ms);
515 callback_();
516 return result;
517 }
518
519 private:
520 std::function<void()> callback_;
521 };
522
523 static VideoReceiveStream::Config GetConfig(
524 Transport* transport,
525 VideoDecoderFactory* decoder_factory,
526 rtc::VideoSinkInterface<webrtc::VideoFrame>* renderer) {
Tommi9e2b3152021-06-21 22:15:39 +0200527 VideoReceiveStream::Config config(transport, decoder_factory);
Tommiae4d0972020-05-18 08:45:38 +0200528 config.rtp.remote_ssrc = 1111;
529 config.rtp.local_ssrc = 2222;
Evan Shrubsole9a999052021-12-12 15:27:00 +0100530 config.rtp.nack.rtp_history_ms = std::get<0>(GetParam()); // rtx-time.
Tommiae4d0972020-05-18 08:45:38 +0200531 config.renderer = renderer;
532 VideoReceiveStream::Decoder fake_decoder;
533 fake_decoder.payload_type = 99;
534 fake_decoder.video_format = SdpVideoFormat("VP8");
Tommiae4d0972020-05-18 08:45:38 +0200535 config.decoders.push_back(fake_decoder);
536 return config;
537 }
538
539 VideoReceiveStream2TestWithSimulatedClock()
540 : time_controller_(Timestamp::Millis(4711)),
541 fake_decoder_factory_([this] {
542 return std::make_unique<FakeDecoder2>([this] { OnFrameDecoded(); });
543 }),
Tommiae4d0972020-05-18 08:45:38 +0200544 config_(GetConfig(&mock_transport_,
545 &fake_decoder_factory_,
546 &fake_renderer_)),
547 call_stats_(time_controller_.GetClock(), loop_.task_queue()),
548 video_receive_stream_(time_controller_.GetTaskQueueFactory(),
Tommi90738dd2021-05-31 17:36:47 +0200549 &fake_call_,
Tommiae4d0972020-05-18 08:45:38 +0200550 /*num_cores=*/2,
551 &packet_router_,
552 config_.Copy(),
Tommiae4d0972020-05-18 08:45:38 +0200553 &call_stats_,
554 time_controller_.GetClock(),
Markus Handell0e62f7a2021-07-20 13:32:02 +0200555 new VCMTiming(time_controller_.GetClock()),
Evan Shrubsole5723d852022-02-14 14:09:57 +0100556 &nack_periodic_processor_,
557 nullptr) {
Jonas Oreland8ca06132022-03-14 12:52:48 +0100558 if (std::get<1>(GetParam())) {
559 fake_call_.SetFieldTrial("WebRTC-FrameBuffer3/arm:FrameBuffer3/");
560 } else {
561 fake_call_.SetFieldTrial("WebRTC-FrameBuffer3/arm:FrameBuffer2/");
562 }
Tommi90738dd2021-05-31 17:36:47 +0200563 video_receive_stream_.RegisterWithTransport(
564 &rtp_stream_receiver_controller_);
Tommiae4d0972020-05-18 08:45:38 +0200565 video_receive_stream_.Start();
566 }
567
Tommi90738dd2021-05-31 17:36:47 +0200568 ~VideoReceiveStream2TestWithSimulatedClock() override {
569 video_receive_stream_.UnregisterFromTransport();
570 }
571
Tommiae4d0972020-05-18 08:45:38 +0200572 void OnFrameDecoded() { event_->Set(); }
573
philipelca188092021-03-23 12:00:49 +0100574 void PassEncodedFrameAndWait(std::unique_ptr<EncodedFrame> frame) {
Tommiae4d0972020-05-18 08:45:38 +0200575 event_ = std::make_unique<rtc::Event>();
576 // This call will eventually end up in the Decoded method where the
577 // event is set.
578 video_receive_stream_.OnCompleteFrame(std::move(frame));
Evan Shrubsole9a999052021-12-12 15:27:00 +0100579 // FrameBuffer3 runs on the test sequence so flush to ensure that decoding
580 // happens.
581 loop_.Flush();
582 ASSERT_TRUE(event_->Wait(1000));
Tommiae4d0972020-05-18 08:45:38 +0200583 }
584
585 protected:
586 GlobalSimulatedTimeController time_controller_;
587 test::RunLoop loop_;
588 test::FunctionVideoDecoderFactory fake_decoder_factory_;
Tommiae4d0972020-05-18 08:45:38 +0200589 MockTransport mock_transport_;
Markus Handell588f9b32021-04-08 19:19:50 +0200590 FakeRenderer fake_renderer_;
Tommi90738dd2021-05-31 17:36:47 +0200591 cricket::FakeCall fake_call_;
Markus Handell0e62f7a2021-07-20 13:32:02 +0200592 NackPeriodicProcessor nack_periodic_processor_;
Tommiae4d0972020-05-18 08:45:38 +0200593 VideoReceiveStream::Config config_;
594 internal::CallStats call_stats_;
595 PacketRouter packet_router_;
596 RtpStreamReceiverController rtp_stream_receiver_controller_;
597 webrtc::internal::VideoReceiveStream2 video_receive_stream_;
598 std::unique_ptr<rtc::Event> event_;
599};
600
Philipp Hancke006206d2021-03-24 17:49:02 +0100601TEST_P(VideoReceiveStream2TestWithSimulatedClock,
Tommiae4d0972020-05-18 08:45:38 +0200602 RequestsKeyFramesUntilKeyFrameReceived) {
Evan Shrubsole9a999052021-12-12 15:27:00 +0100603 auto tick = TimeDelta::Millis(std::get<0>(GetParam()) / 2);
604 bool sent_rtcp = false;
605 EXPECT_CALL(mock_transport_, SendRtcp)
606 .Times(1)
607 .WillOnce(Invoke([&sent_rtcp]() {
608 sent_rtcp = true;
609 return 0;
610 }));
Tommiae4d0972020-05-18 08:45:38 +0200611 video_receive_stream_.GenerateKeyFrame();
612 PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameDelta, 0));
613 time_controller_.AdvanceTime(tick);
Evan Shrubsole9a999052021-12-12 15:27:00 +0100614 loop_.Flush();
Tommiae4d0972020-05-18 08:45:38 +0200615 PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameDelta, 1));
Tommiae4d0972020-05-18 08:45:38 +0200616 testing::Mock::VerifyAndClearExpectations(&mock_transport_);
Evan Shrubsole9a999052021-12-12 15:27:00 +0100617 EXPECT_TRUE(sent_rtcp);
Tommiae4d0972020-05-18 08:45:38 +0200618
Philipp Hancke006206d2021-03-24 17:49:02 +0100619 // T+keyframetimeout: still no key frame received, expect key frame request
620 // sent again.
Evan Shrubsole9a999052021-12-12 15:27:00 +0100621 sent_rtcp = false;
622 EXPECT_CALL(mock_transport_, SendRtcp)
623 .Times(1)
624 .WillOnce(Invoke([&sent_rtcp]() {
625 sent_rtcp = true;
626 return 0;
627 }));
Tommiae4d0972020-05-18 08:45:38 +0200628 time_controller_.AdvanceTime(tick);
629 PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameDelta, 2));
Evan Shrubsole9a999052021-12-12 15:27:00 +0100630 loop_.PostTask([this]() { loop_.Quit(); });
Tommiae4d0972020-05-18 08:45:38 +0200631 loop_.Run();
632 testing::Mock::VerifyAndClearExpectations(&mock_transport_);
Evan Shrubsole9a999052021-12-12 15:27:00 +0100633 EXPECT_TRUE(sent_rtcp);
Tommiae4d0972020-05-18 08:45:38 +0200634
Philipp Hancke006206d2021-03-24 17:49:02 +0100635 // T+keyframetimeout: now send a key frame - we should not observe new key
636 // frame requests after this.
Tommiae4d0972020-05-18 08:45:38 +0200637 EXPECT_CALL(mock_transport_, SendRtcp).Times(0);
638 PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameKey, 3));
639 time_controller_.AdvanceTime(2 * tick);
640 PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameDelta, 4));
641 loop_.PostTask([this]() { loop_.Quit(); });
642 loop_.Run();
643}
644
Markus Handell588f9b32021-04-08 19:19:50 +0200645TEST_P(VideoReceiveStream2TestWithSimulatedClock,
646 DispatchesEncodedFrameSequenceStartingWithKeyframeWithoutResolution) {
647 video_receive_stream_.Start();
648 testing::MockFunction<void(const RecordableEncodedFrame&)> callback;
649 video_receive_stream_.SetAndGetRecordingState(
650 VideoReceiveStream::RecordingState(callback.AsStdFunction()),
651 /*generate_key_frame=*/false);
652
653 InSequence s;
654 EXPECT_CALL(
655 callback,
656 Call(AllOf(
657 Property(&RecordableEncodedFrame::resolution,
658 Field(&RecordableEncodedFrame::EncodedResolution::width,
659 test::FakeDecoder::kDefaultWidth)),
660 Property(&RecordableEncodedFrame::resolution,
661 Field(&RecordableEncodedFrame::EncodedResolution::height,
662 test::FakeDecoder::kDefaultHeight)))));
663 EXPECT_CALL(callback, Call);
664
665 fake_renderer_.SignalDoneAfterFrames(2);
666 PassEncodedFrameAndWait(
667 MakeFrameWithResolution(VideoFrameType::kVideoFrameKey, 0, 0, 0));
668 PassEncodedFrameAndWait(
669 MakeFrameWithResolution(VideoFrameType::kVideoFrameDelta, 1, 0, 0));
670 fake_renderer_.WaitUntilDone();
671
672 video_receive_stream_.Stop();
673}
674
675TEST_P(VideoReceiveStream2TestWithSimulatedClock,
676 DispatchesEncodedFrameSequenceStartingWithKeyframeWithResolution) {
677 video_receive_stream_.Start();
678 testing::MockFunction<void(const RecordableEncodedFrame&)> callback;
679 video_receive_stream_.SetAndGetRecordingState(
680 VideoReceiveStream::RecordingState(callback.AsStdFunction()),
681 /*generate_key_frame=*/false);
682
683 InSequence s;
684 EXPECT_CALL(
685 callback,
686 Call(AllOf(
687 Property(
688 &RecordableEncodedFrame::resolution,
689 Field(&RecordableEncodedFrame::EncodedResolution::width, 1080)),
690 Property(&RecordableEncodedFrame::resolution,
691 Field(&RecordableEncodedFrame::EncodedResolution::height,
692 720)))));
693 EXPECT_CALL(callback, Call);
694
695 fake_renderer_.SignalDoneAfterFrames(2);
696 PassEncodedFrameAndWait(
697 MakeFrameWithResolution(VideoFrameType::kVideoFrameKey, 0, 1080, 720));
698 PassEncodedFrameAndWait(
699 MakeFrameWithResolution(VideoFrameType::kVideoFrameDelta, 1, 0, 0));
700 fake_renderer_.WaitUntilDone();
701
702 video_receive_stream_.Stop();
703}
704
Philipp Hancke006206d2021-03-24 17:49:02 +0100705INSTANTIATE_TEST_SUITE_P(
706 RtxTime,
707 VideoReceiveStream2TestWithSimulatedClock,
Evan Shrubsole9a999052021-12-12 15:27:00 +0100708 ::testing::Combine(
709 ::testing::Values(internal::VideoReceiveStream2::kMaxWaitForKeyFrameMs,
710 50 /*ms*/),
711 ::testing::Bool()));
Philipp Hancke006206d2021-03-24 17:49:02 +0100712
Johannes Kron16359f62021-02-18 23:37:22 +0100713class VideoReceiveStream2TestWithLazyDecoderCreation : public ::testing::Test {
714 public:
715 VideoReceiveStream2TestWithLazyDecoderCreation()
Markus Handelleb61b7f2021-06-22 10:46:48 +0200716 : task_queue_factory_(CreateDefaultTaskQueueFactory()),
Tommi9e2b3152021-06-21 22:15:39 +0200717 config_(&mock_transport_, &mock_h264_decoder_factory_),
Johannes Kron16359f62021-02-18 23:37:22 +0100718 call_stats_(Clock::GetRealTimeClock(), loop_.task_queue()) {}
719
Tommi90738dd2021-05-31 17:36:47 +0200720 ~VideoReceiveStream2TestWithLazyDecoderCreation() override {
721 video_receive_stream_->UnregisterFromTransport();
722 }
723
724 void SetUp() override {
Jonas Oreland8ca06132022-03-14 12:52:48 +0100725 fake_call_.SetFieldTrial("WebRTC-PreStreamDecoders/max:0/");
Johannes Kron16359f62021-02-18 23:37:22 +0100726 constexpr int kDefaultNumCpuCores = 2;
727 config_.rtp.remote_ssrc = 1111;
728 config_.rtp.local_ssrc = 2222;
729 config_.renderer = &fake_renderer_;
Johannes Kron16359f62021-02-18 23:37:22 +0100730 VideoReceiveStream::Decoder h264_decoder;
731 h264_decoder.payload_type = 99;
732 h264_decoder.video_format = SdpVideoFormat("H264");
733 h264_decoder.video_format.parameters.insert(
734 {"sprop-parameter-sets", "Z0IACpZTBYmI,aMljiA=="});
735 config_.decoders.clear();
736 config_.decoders.push_back(h264_decoder);
737
738 clock_ = Clock::GetRealTimeClock();
739 timing_ = new VCMTiming(clock_);
740
741 video_receive_stream_ =
742 std::make_unique<webrtc::internal::VideoReceiveStream2>(
Tommi90738dd2021-05-31 17:36:47 +0200743 task_queue_factory_.get(), &fake_call_, kDefaultNumCpuCores,
Markus Handell0e62f7a2021-07-20 13:32:02 +0200744 &packet_router_, config_.Copy(), &call_stats_, clock_, timing_,
Evan Shrubsole5723d852022-02-14 14:09:57 +0100745 &nack_periodic_processor_, nullptr);
Tommi90738dd2021-05-31 17:36:47 +0200746 video_receive_stream_->RegisterWithTransport(
747 &rtp_stream_receiver_controller_);
Johannes Kron16359f62021-02-18 23:37:22 +0100748 }
749
750 protected:
751 test::RunLoop loop_;
Johannes Kron16359f62021-02-18 23:37:22 +0100752 const std::unique_ptr<TaskQueueFactory> task_queue_factory_;
Tommi9e2b3152021-06-21 22:15:39 +0200753 MockVideoDecoderFactory mock_h264_decoder_factory_;
Markus Handell0e62f7a2021-07-20 13:32:02 +0200754 NackPeriodicProcessor nack_periodic_processor_;
Johannes Kron16359f62021-02-18 23:37:22 +0100755 VideoReceiveStream::Config config_;
756 internal::CallStats call_stats_;
757 MockVideoDecoder mock_h264_video_decoder_;
Johannes Kron16359f62021-02-18 23:37:22 +0100758 cricket::FakeVideoRenderer fake_renderer_;
Tommi90738dd2021-05-31 17:36:47 +0200759 cricket::FakeCall fake_call_;
Johannes Kron16359f62021-02-18 23:37:22 +0100760 MockTransport mock_transport_;
761 PacketRouter packet_router_;
762 RtpStreamReceiverController rtp_stream_receiver_controller_;
763 std::unique_ptr<webrtc::internal::VideoReceiveStream2> video_receive_stream_;
764 Clock* clock_;
765 VCMTiming* timing_;
766};
767
768TEST_F(VideoReceiveStream2TestWithLazyDecoderCreation, LazyDecoderCreation) {
769 constexpr uint8_t idr_nalu[] = {0x05, 0xFF, 0xFF, 0xFF};
770 RtpPacketToSend rtppacket(nullptr);
771 uint8_t* payload = rtppacket.AllocatePayload(sizeof(idr_nalu));
772 memcpy(payload, idr_nalu, sizeof(idr_nalu));
773 rtppacket.SetMarker(true);
774 rtppacket.SetSsrc(1111);
775 rtppacket.SetPayloadType(99);
776 rtppacket.SetSequenceNumber(1);
777 rtppacket.SetTimestamp(0);
778
779 // No decoder is created here.
780 EXPECT_CALL(mock_h264_decoder_factory_, CreateVideoDecoder(_)).Times(0);
781 video_receive_stream_->Start();
782
783 EXPECT_CALL(mock_h264_decoder_factory_, CreateVideoDecoder(_))
784 .WillOnce(Invoke([this](const SdpVideoFormat& format) {
785 test::VideoDecoderProxyFactory h264_decoder_factory(
786 &mock_h264_video_decoder_);
787 return h264_decoder_factory.CreateVideoDecoder(format);
788 }));
Danil Chapovalovd08930d2021-08-12 13:26:55 +0200789 rtc::Event init_decode_event;
790 EXPECT_CALL(mock_h264_video_decoder_, Configure).WillOnce(WithoutArgs([&] {
791 init_decode_event.Set();
792 return true;
793 }));
Johannes Kron16359f62021-02-18 23:37:22 +0100794 EXPECT_CALL(mock_h264_video_decoder_, RegisterDecodeCompleteCallback(_));
795 EXPECT_CALL(mock_h264_video_decoder_, Decode(_, false, _));
796 RtpPacketReceived parsed_packet;
797 ASSERT_TRUE(parsed_packet.Parse(rtppacket.data(), rtppacket.size()));
798 rtp_stream_receiver_controller_.OnRtpPacket(parsed_packet);
799 EXPECT_CALL(mock_h264_video_decoder_, Release());
800
801 // Make sure the decoder thread had a chance to run.
Danil Chapovalovd08930d2021-08-12 13:26:55 +0200802 init_decode_event.Wait(kDefaultTimeOutMs);
Johannes Kron16359f62021-02-18 23:37:22 +0100803}
804
805TEST_F(VideoReceiveStream2TestWithLazyDecoderCreation,
806 DeregisterDecoderThatsNotCreated) {
807 // No decoder is created here.
808 EXPECT_CALL(mock_h264_decoder_factory_, CreateVideoDecoder(_)).Times(0);
809 video_receive_stream_->Start();
810 video_receive_stream_->Stop();
811}
812
Tommiae4d0972020-05-18 08:45:38 +0200813} // namespace webrtc