blob: 6a719e7d8478acd7cdeed1a0a72852400fee9fd4 [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
Evan Shrubsole6dbc1722022-03-22 12:20:11 +010020#include "absl/memory/memory.h"
Tommiae4d0972020-05-18 08:45:38 +020021#include "api/task_queue/default_task_queue_factory.h"
Danil Chapovalov9cd4d492021-08-03 14:59:00 +020022#include "api/test/mock_video_decoder.h"
23#include "api/test/mock_video_decoder_factory.h"
Tommiae4d0972020-05-18 08:45:38 +020024#include "api/test/video/function_video_decoder_factory.h"
Markus Handell588f9b32021-04-08 19:19:50 +020025#include "api/video/video_frame.h"
Tommiae4d0972020-05-18 08:45:38 +020026#include "api/video_codecs/video_decoder.h"
27#include "call/rtp_stream_receiver_controller.h"
28#include "common_video/test/utilities.h"
29#include "media/base/fake_video_renderer.h"
Tommi90738dd2021-05-31 17:36:47 +020030#include "media/engine/fake_webrtc_call.h"
Tommiae4d0972020-05-18 08:45:38 +020031#include "modules/pacing/packet_router.h"
32#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
Tommiae4d0972020-05-18 08:45:38 +020033#include "modules/video_coding/encoded_frame.h"
Tommiae4d0972020-05-18 08:45:38 +020034#include "rtc_base/event.h"
35#include "system_wrappers/include/clock.h"
36#include "test/fake_decoder.h"
Tommiae4d0972020-05-18 08:45:38 +020037#include "test/gmock.h"
38#include "test/gtest.h"
Danil Chapovalov9cd4d492021-08-03 14:59:00 +020039#include "test/mock_transport.h"
Tommiae4d0972020-05-18 08:45:38 +020040#include "test/run_loop.h"
Jonas Oreland8ca06132022-03-14 12:52:48 +010041#include "test/scoped_key_value_config.h"
Tommiae4d0972020-05-18 08:45:38 +020042#include "test/time_controller/simulated_time_controller.h"
43#include "test/video_decoder_proxy_factory.h"
44#include "video/call_stats2.h"
45
46namespace webrtc {
47namespace {
48
49using ::testing::_;
Markus Handell588f9b32021-04-08 19:19:50 +020050using ::testing::AllOf;
Tommiae4d0972020-05-18 08:45:38 +020051using ::testing::ElementsAreArray;
Markus Handell588f9b32021-04-08 19:19:50 +020052using ::testing::Field;
53using ::testing::InSequence;
Tommiae4d0972020-05-18 08:45:38 +020054using ::testing::Invoke;
55using ::testing::IsEmpty;
Markus Handell588f9b32021-04-08 19:19:50 +020056using ::testing::Property;
Tommiae4d0972020-05-18 08:45:38 +020057using ::testing::SizeIs;
Danil Chapovalovd08930d2021-08-12 13:26:55 +020058using ::testing::WithoutArgs;
Tommiae4d0972020-05-18 08:45:38 +020059
60constexpr int kDefaultTimeOutMs = 50;
61
philipelca188092021-03-23 12:00:49 +010062class FrameObjectFake : public EncodedFrame {
Tommiae4d0972020-05-18 08:45:38 +020063 public:
64 void SetPayloadType(uint8_t payload_type) { _payloadType = payload_type; }
65
66 void SetRotation(const VideoRotation& rotation) { rotation_ = rotation; }
67
68 void SetNtpTime(int64_t ntp_time_ms) { ntp_time_ms_ = ntp_time_ms; }
69
70 int64_t ReceivedTime() const override { return 0; }
71
72 int64_t RenderTime() const override { return _renderTimeMs; }
73};
74
75} // namespace
76
77class VideoReceiveStream2Test : public ::testing::Test {
78 public:
79 VideoReceiveStream2Test()
Markus Handelleb61b7f2021-06-22 10:46:48 +020080 : task_queue_factory_(CreateDefaultTaskQueueFactory()),
Tommi9e2b3152021-06-21 22:15:39 +020081 h264_decoder_factory_(&mock_h264_video_decoder_),
82 config_(&mock_transport_, &h264_decoder_factory_),
Jonas Oreland8ca06132022-03-14 12:52:48 +010083 call_stats_(Clock::GetRealTimeClock(), loop_.task_queue()) {
84 fake_call_.SetFieldTrial("WebRTC-FrameBuffer3/arm:FrameBuffer3/");
85 }
Tommi90738dd2021-05-31 17:36:47 +020086 ~VideoReceiveStream2Test() override {
87 if (video_receive_stream_)
88 video_receive_stream_->UnregisterFromTransport();
89 }
Tommiae4d0972020-05-18 08:45:38 +020090
Tommi90738dd2021-05-31 17:36:47 +020091 void SetUp() override {
Tommiae4d0972020-05-18 08:45:38 +020092 constexpr int kDefaultNumCpuCores = 2;
93 config_.rtp.remote_ssrc = 1111;
94 config_.rtp.local_ssrc = 2222;
95 config_.renderer = &fake_renderer_;
96 VideoReceiveStream::Decoder h264_decoder;
97 h264_decoder.payload_type = 99;
98 h264_decoder.video_format = SdpVideoFormat("H264");
99 h264_decoder.video_format.parameters.insert(
100 {"sprop-parameter-sets", "Z0IACpZTBYmI,aMljiA=="});
Johannes Kron16359f62021-02-18 23:37:22 +0100101 config_.decoders.clear();
Tommiae4d0972020-05-18 08:45:38 +0200102 config_.decoders.push_back(h264_decoder);
Tommiae4d0972020-05-18 08:45:38 +0200103
104 clock_ = Clock::GetRealTimeClock();
105 timing_ = new VCMTiming(clock_);
106
107 video_receive_stream_ =
108 std::make_unique<webrtc::internal::VideoReceiveStream2>(
Tommi90738dd2021-05-31 17:36:47 +0200109 task_queue_factory_.get(), &fake_call_, kDefaultNumCpuCores,
Evan Shrubsole6dbc1722022-03-22 12:20:11 +0100110 &packet_router_, config_.Copy(), &call_stats_, clock_,
111 absl::WrapUnique(timing_), &nack_periodic_processor_, nullptr);
Tommi90738dd2021-05-31 17:36:47 +0200112 video_receive_stream_->RegisterWithTransport(
113 &rtp_stream_receiver_controller_);
Tommiae4d0972020-05-18 08:45:38 +0200114 }
115
116 protected:
117 test::RunLoop loop_;
Tommiae4d0972020-05-18 08:45:38 +0200118 const std::unique_ptr<TaskQueueFactory> task_queue_factory_;
Tommi9e2b3152021-06-21 22:15:39 +0200119 test::VideoDecoderProxyFactory h264_decoder_factory_;
Markus Handell0e62f7a2021-07-20 13:32:02 +0200120 NackPeriodicProcessor nack_periodic_processor_;
Tommiae4d0972020-05-18 08:45:38 +0200121 VideoReceiveStream::Config config_;
122 internal::CallStats call_stats_;
123 MockVideoDecoder mock_h264_video_decoder_;
Tommiae4d0972020-05-18 08:45:38 +0200124 cricket::FakeVideoRenderer fake_renderer_;
Tommi90738dd2021-05-31 17:36:47 +0200125 cricket::FakeCall fake_call_;
Tommiae4d0972020-05-18 08:45:38 +0200126 MockTransport mock_transport_;
127 PacketRouter packet_router_;
128 RtpStreamReceiverController rtp_stream_receiver_controller_;
129 std::unique_ptr<webrtc::internal::VideoReceiveStream2> video_receive_stream_;
130 Clock* clock_;
131 VCMTiming* timing_;
132};
133
134TEST_F(VideoReceiveStream2Test, CreateFrameFromH264FmtpSpropAndIdr) {
135 constexpr uint8_t idr_nalu[] = {0x05, 0xFF, 0xFF, 0xFF};
136 RtpPacketToSend rtppacket(nullptr);
137 uint8_t* payload = rtppacket.AllocatePayload(sizeof(idr_nalu));
138 memcpy(payload, idr_nalu, sizeof(idr_nalu));
139 rtppacket.SetMarker(true);
140 rtppacket.SetSsrc(1111);
141 rtppacket.SetPayloadType(99);
142 rtppacket.SetSequenceNumber(1);
143 rtppacket.SetTimestamp(0);
Danil Chapovalovd08930d2021-08-12 13:26:55 +0200144 rtc::Event init_decode_event;
145 EXPECT_CALL(mock_h264_video_decoder_, Configure).WillOnce(WithoutArgs([&] {
146 init_decode_event.Set();
147 return true;
148 }));
Tommiae4d0972020-05-18 08:45:38 +0200149 EXPECT_CALL(mock_h264_video_decoder_, RegisterDecodeCompleteCallback(_));
150 video_receive_stream_->Start();
151 EXPECT_CALL(mock_h264_video_decoder_, Decode(_, false, _));
152 RtpPacketReceived parsed_packet;
153 ASSERT_TRUE(parsed_packet.Parse(rtppacket.data(), rtppacket.size()));
154 rtp_stream_receiver_controller_.OnRtpPacket(parsed_packet);
155 EXPECT_CALL(mock_h264_video_decoder_, Release());
156 // Make sure the decoder thread had a chance to run.
Danil Chapovalovd08930d2021-08-12 13:26:55 +0200157 init_decode_event.Wait(kDefaultTimeOutMs);
Tommiae4d0972020-05-18 08:45:38 +0200158}
159
160TEST_F(VideoReceiveStream2Test, PlayoutDelay) {
Niels Möllerd381eed2020-09-02 15:34:40 +0200161 const VideoPlayoutDelay kPlayoutDelayMs = {123, 321};
Tommiae4d0972020-05-18 08:45:38 +0200162 std::unique_ptr<FrameObjectFake> test_frame(new FrameObjectFake());
philipel9aa9b8d2021-02-15 13:31:29 +0100163 test_frame->SetId(0);
Tommiae4d0972020-05-18 08:45:38 +0200164 test_frame->SetPlayoutDelay(kPlayoutDelayMs);
165
166 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100167 EXPECT_EQ(kPlayoutDelayMs.min_ms, timing_->min_playout_delay().ms());
168 EXPECT_EQ(kPlayoutDelayMs.max_ms, timing_->max_playout_delay().ms());
Tommiae4d0972020-05-18 08:45:38 +0200169
170 // Check that the biggest minimum delay is chosen.
171 video_receive_stream_->SetMinimumPlayoutDelay(400);
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100172 EXPECT_EQ(400, timing_->min_playout_delay().ms());
Tommiae4d0972020-05-18 08:45:38 +0200173
174 // Check base minimum delay validation.
175 EXPECT_FALSE(video_receive_stream_->SetBaseMinimumPlayoutDelayMs(12345));
176 EXPECT_FALSE(video_receive_stream_->SetBaseMinimumPlayoutDelayMs(-1));
177 EXPECT_TRUE(video_receive_stream_->SetBaseMinimumPlayoutDelayMs(500));
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100178 EXPECT_EQ(500, timing_->min_playout_delay().ms());
Tommiae4d0972020-05-18 08:45:38 +0200179
180 // Check that intermidiate values are remembered and the biggest remembered
181 // is chosen.
182 video_receive_stream_->SetBaseMinimumPlayoutDelayMs(0);
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100183 EXPECT_EQ(400, timing_->min_playout_delay().ms());
Tommiae4d0972020-05-18 08:45:38 +0200184
185 video_receive_stream_->SetMinimumPlayoutDelay(0);
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100186 EXPECT_EQ(123, timing_->min_playout_delay().ms());
Tommiae4d0972020-05-18 08:45:38 +0200187}
188
189TEST_F(VideoReceiveStream2Test, PlayoutDelayPreservesDefaultMaxValue) {
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100190 const TimeDelta default_max_playout_latency = timing_->max_playout_delay();
Niels Möllerd381eed2020-09-02 15:34:40 +0200191 const VideoPlayoutDelay kPlayoutDelayMs = {123, -1};
Tommiae4d0972020-05-18 08:45:38 +0200192
193 std::unique_ptr<FrameObjectFake> test_frame(new FrameObjectFake());
philipel9aa9b8d2021-02-15 13:31:29 +0100194 test_frame->SetId(0);
Tommiae4d0972020-05-18 08:45:38 +0200195 test_frame->SetPlayoutDelay(kPlayoutDelayMs);
196
197 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
198
Artem Titovab30d722021-07-27 16:22:11 +0200199 // Ensure that -1 preserves default maximum value from `timing_`.
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100200 EXPECT_EQ(kPlayoutDelayMs.min_ms, timing_->min_playout_delay().ms());
201 EXPECT_NE(kPlayoutDelayMs.max_ms, timing_->max_playout_delay().ms());
Tommiae4d0972020-05-18 08:45:38 +0200202 EXPECT_EQ(default_max_playout_latency, timing_->max_playout_delay());
203}
204
205TEST_F(VideoReceiveStream2Test, PlayoutDelayPreservesDefaultMinValue) {
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100206 const TimeDelta default_min_playout_latency = timing_->min_playout_delay();
Niels Möllerd381eed2020-09-02 15:34:40 +0200207 const VideoPlayoutDelay kPlayoutDelayMs = {-1, 321};
Tommiae4d0972020-05-18 08:45:38 +0200208
209 std::unique_ptr<FrameObjectFake> test_frame(new FrameObjectFake());
philipel9aa9b8d2021-02-15 13:31:29 +0100210 test_frame->SetId(0);
Tommiae4d0972020-05-18 08:45:38 +0200211 test_frame->SetPlayoutDelay(kPlayoutDelayMs);
212
213 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
214
Artem Titovab30d722021-07-27 16:22:11 +0200215 // Ensure that -1 preserves default minimum value from `timing_`.
Evan Shrubsoled6cdf802022-03-02 15:13:55 +0100216 EXPECT_NE(kPlayoutDelayMs.min_ms, timing_->min_playout_delay().ms());
217 EXPECT_EQ(kPlayoutDelayMs.max_ms, timing_->max_playout_delay().ms());
Tommiae4d0972020-05-18 08:45:38 +0200218 EXPECT_EQ(default_min_playout_latency, timing_->min_playout_delay());
219}
220
Johannes Kron111e9812020-10-26 13:54:40 +0100221TEST_F(VideoReceiveStream2Test, MaxCompositionDelayNotSetByDefault) {
222 // Default with no playout delay set.
223 std::unique_ptr<FrameObjectFake> test_frame0(new FrameObjectFake());
philipel9aa9b8d2021-02-15 13:31:29 +0100224 test_frame0->SetId(0);
Johannes Kron111e9812020-10-26 13:54:40 +0100225 video_receive_stream_->OnCompleteFrame(std::move(test_frame0));
226 EXPECT_FALSE(timing_->MaxCompositionDelayInFrames());
227
228 // Max composition delay not set for playout delay 0,0.
229 std::unique_ptr<FrameObjectFake> test_frame1(new FrameObjectFake());
philipel9aa9b8d2021-02-15 13:31:29 +0100230 test_frame1->SetId(1);
Johannes Kron111e9812020-10-26 13:54:40 +0100231 test_frame1->SetPlayoutDelay({0, 0});
232 video_receive_stream_->OnCompleteFrame(std::move(test_frame1));
233 EXPECT_FALSE(timing_->MaxCompositionDelayInFrames());
234
235 // Max composition delay not set for playout delay X,Y, where X,Y>0.
236 std::unique_ptr<FrameObjectFake> test_frame2(new FrameObjectFake());
philipel9aa9b8d2021-02-15 13:31:29 +0100237 test_frame2->SetId(2);
Johannes Kron111e9812020-10-26 13:54:40 +0100238 test_frame2->SetPlayoutDelay({10, 30});
239 video_receive_stream_->OnCompleteFrame(std::move(test_frame2));
240 EXPECT_FALSE(timing_->MaxCompositionDelayInFrames());
241}
242
243TEST_F(VideoReceiveStream2Test, MaxCompositionDelaySetFromMaxPlayoutDelay) {
244 // Max composition delay set if playout delay X,Y, where X=0,Y>0.
245 const VideoPlayoutDelay kPlayoutDelayMs = {0, 50};
246 const int kExpectedMaxCompositionDelayInFrames = 3; // ~50 ms at 60 fps.
247 std::unique_ptr<FrameObjectFake> test_frame(new FrameObjectFake());
philipel9aa9b8d2021-02-15 13:31:29 +0100248 test_frame->SetId(0);
Johannes Kron111e9812020-10-26 13:54:40 +0100249 test_frame->SetPlayoutDelay(kPlayoutDelayMs);
250 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
251 EXPECT_EQ(kExpectedMaxCompositionDelayInFrames,
252 timing_->MaxCompositionDelayInFrames());
253}
254
Tommiae4d0972020-05-18 08:45:38 +0200255class VideoReceiveStream2TestWithFakeDecoder : public ::testing::Test {
256 public:
257 VideoReceiveStream2TestWithFakeDecoder()
258 : fake_decoder_factory_(
259 []() { return std::make_unique<test::FakeDecoder>(); }),
Tommiae4d0972020-05-18 08:45:38 +0200260 task_queue_factory_(CreateDefaultTaskQueueFactory()),
Tommi9e2b3152021-06-21 22:15:39 +0200261 config_(&mock_transport_, &fake_decoder_factory_),
Tommiae4d0972020-05-18 08:45:38 +0200262 call_stats_(Clock::GetRealTimeClock(), loop_.task_queue()) {}
Tommi90738dd2021-05-31 17:36:47 +0200263 ~VideoReceiveStream2TestWithFakeDecoder() override {
264 if (video_receive_stream_)
265 video_receive_stream_->UnregisterFromTransport();
266 }
Tommiae4d0972020-05-18 08:45:38 +0200267
Tommi90738dd2021-05-31 17:36:47 +0200268 void SetUp() override {
Tommiae4d0972020-05-18 08:45:38 +0200269 config_.rtp.remote_ssrc = 1111;
270 config_.rtp.local_ssrc = 2222;
271 config_.renderer = &fake_renderer_;
272 VideoReceiveStream::Decoder fake_decoder;
273 fake_decoder.payload_type = 99;
274 fake_decoder.video_format = SdpVideoFormat("VP8");
Tommiae4d0972020-05-18 08:45:38 +0200275 config_.decoders.push_back(fake_decoder);
276 clock_ = Clock::GetRealTimeClock();
277 ReCreateReceiveStream(VideoReceiveStream::RecordingState());
278 }
279
280 void ReCreateReceiveStream(VideoReceiveStream::RecordingState state) {
281 constexpr int kDefaultNumCpuCores = 2;
Tommi90738dd2021-05-31 17:36:47 +0200282 if (video_receive_stream_) {
283 video_receive_stream_->UnregisterFromTransport();
284 video_receive_stream_ = nullptr;
285 }
Tommiae4d0972020-05-18 08:45:38 +0200286 timing_ = new VCMTiming(clock_);
Evan Shrubsole6dbc1722022-03-22 12:20:11 +0100287 video_receive_stream_ =
288 std::make_unique<webrtc::internal::VideoReceiveStream2>(
289 task_queue_factory_.get(), &fake_call_, kDefaultNumCpuCores,
290 &packet_router_, config_.Copy(), &call_stats_, clock_,
291 absl::WrapUnique(timing_), &nack_periodic_processor_, nullptr);
Tommi90738dd2021-05-31 17:36:47 +0200292 video_receive_stream_->RegisterWithTransport(
293 &rtp_stream_receiver_controller_);
Tommiae4d0972020-05-18 08:45:38 +0200294 video_receive_stream_->SetAndGetRecordingState(std::move(state), false);
295 }
296
297 protected:
298 test::RunLoop loop_;
299 test::FunctionVideoDecoderFactory fake_decoder_factory_;
Tommiae4d0972020-05-18 08:45:38 +0200300 const std::unique_ptr<TaskQueueFactory> task_queue_factory_;
Markus Handell0e62f7a2021-07-20 13:32:02 +0200301 NackPeriodicProcessor nack_periodic_processor_;
Tommiae4d0972020-05-18 08:45:38 +0200302 VideoReceiveStream::Config config_;
303 internal::CallStats call_stats_;
304 cricket::FakeVideoRenderer fake_renderer_;
305 MockTransport mock_transport_;
306 PacketRouter packet_router_;
307 RtpStreamReceiverController rtp_stream_receiver_controller_;
Tommi90738dd2021-05-31 17:36:47 +0200308 cricket::FakeCall fake_call_;
Tommiae4d0972020-05-18 08:45:38 +0200309 std::unique_ptr<webrtc::internal::VideoReceiveStream2> video_receive_stream_;
310 Clock* clock_;
311 VCMTiming* timing_;
312};
313
314TEST_F(VideoReceiveStream2TestWithFakeDecoder, PassesNtpTime) {
315 const int64_t kNtpTimestamp = 12345;
316 auto test_frame = std::make_unique<FrameObjectFake>();
317 test_frame->SetPayloadType(99);
philipel9aa9b8d2021-02-15 13:31:29 +0100318 test_frame->SetId(0);
Tommiae4d0972020-05-18 08:45:38 +0200319 test_frame->SetNtpTime(kNtpTimestamp);
320
321 video_receive_stream_->Start();
322 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
323 EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOutMs));
324 EXPECT_EQ(kNtpTimestamp, fake_renderer_.ntp_time_ms());
325}
326
327TEST_F(VideoReceiveStream2TestWithFakeDecoder, PassesRotation) {
328 const webrtc::VideoRotation kRotation = webrtc::kVideoRotation_180;
329 auto test_frame = std::make_unique<FrameObjectFake>();
330 test_frame->SetPayloadType(99);
philipel9aa9b8d2021-02-15 13:31:29 +0100331 test_frame->SetId(0);
Tommiae4d0972020-05-18 08:45:38 +0200332 test_frame->SetRotation(kRotation);
333
334 video_receive_stream_->Start();
335 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
336 EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOutMs));
337
338 EXPECT_EQ(kRotation, fake_renderer_.rotation());
339}
340
341TEST_F(VideoReceiveStream2TestWithFakeDecoder, PassesPacketInfos) {
342 auto test_frame = std::make_unique<FrameObjectFake>();
343 test_frame->SetPayloadType(99);
philipel9aa9b8d2021-02-15 13:31:29 +0100344 test_frame->SetId(0);
Tommiae4d0972020-05-18 08:45:38 +0200345 RtpPacketInfos packet_infos = CreatePacketInfos(3);
346 test_frame->SetPacketInfos(packet_infos);
347
348 video_receive_stream_->Start();
349 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
350 EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOutMs));
351
352 EXPECT_THAT(fake_renderer_.packet_infos(), ElementsAreArray(packet_infos));
353}
354
355TEST_F(VideoReceiveStream2TestWithFakeDecoder, RenderedFrameUpdatesGetSources) {
356 constexpr uint32_t kSsrc = 1111;
357 constexpr uint32_t kCsrc = 9001;
358 constexpr uint32_t kRtpTimestamp = 12345;
359
360 // Prepare one video frame with per-packet information.
361 auto test_frame = std::make_unique<FrameObjectFake>();
362 test_frame->SetPayloadType(99);
philipel9aa9b8d2021-02-15 13:31:29 +0100363 test_frame->SetId(0);
Tommiae4d0972020-05-18 08:45:38 +0200364 RtpPacketInfos packet_infos;
365 {
366 RtpPacketInfos::vector_type infos;
367
368 RtpPacketInfo info;
369 info.set_ssrc(kSsrc);
370 info.set_csrcs({kCsrc});
371 info.set_rtp_timestamp(kRtpTimestamp);
372
Johannes Kronf7de74c2021-04-30 13:10:56 +0200373 info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(5000));
Tommiae4d0972020-05-18 08:45:38 +0200374 infos.push_back(info);
375
Johannes Kronf7de74c2021-04-30 13:10:56 +0200376 info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(3000));
Tommiae4d0972020-05-18 08:45:38 +0200377 infos.push_back(info);
378
Johannes Kronf7de74c2021-04-30 13:10:56 +0200379 info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(2000));
Tommiae4d0972020-05-18 08:45:38 +0200380 infos.push_back(info);
381
Johannes Kronf7de74c2021-04-30 13:10:56 +0200382 info.set_receive_time(clock_->CurrentTime() - TimeDelta::Millis(1000));
Tommiae4d0972020-05-18 08:45:38 +0200383 infos.push_back(info);
384
385 packet_infos = RtpPacketInfos(std::move(infos));
386 }
387 test_frame->SetPacketInfos(packet_infos);
388
389 // Start receive stream.
390 video_receive_stream_->Start();
391 EXPECT_THAT(video_receive_stream_->GetSources(), IsEmpty());
392
393 // Render one video frame.
394 int64_t timestamp_ms_min = clock_->TimeInMilliseconds();
395 video_receive_stream_->OnCompleteFrame(std::move(test_frame));
396 EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOutMs));
397 int64_t timestamp_ms_max = clock_->TimeInMilliseconds();
398
399 // Verify that the per-packet information is passed to the renderer.
400 EXPECT_THAT(fake_renderer_.packet_infos(), ElementsAreArray(packet_infos));
401
Artem Titovab30d722021-07-27 16:22:11 +0200402 // Verify that the per-packet information also updates `GetSources()`.
Tommiae4d0972020-05-18 08:45:38 +0200403 std::vector<RtpSource> sources = video_receive_stream_->GetSources();
404 ASSERT_THAT(sources, SizeIs(2));
405 {
406 auto it = std::find_if(sources.begin(), sources.end(),
407 [](const RtpSource& source) {
408 return source.source_type() == RtpSourceType::SSRC;
409 });
410 ASSERT_NE(it, sources.end());
411
412 EXPECT_EQ(it->source_id(), kSsrc);
413 EXPECT_EQ(it->source_type(), RtpSourceType::SSRC);
414 EXPECT_EQ(it->rtp_timestamp(), kRtpTimestamp);
415 EXPECT_GE(it->timestamp_ms(), timestamp_ms_min);
416 EXPECT_LE(it->timestamp_ms(), timestamp_ms_max);
417 }
418 {
419 auto it = std::find_if(sources.begin(), sources.end(),
420 [](const RtpSource& source) {
421 return source.source_type() == RtpSourceType::CSRC;
422 });
423 ASSERT_NE(it, sources.end());
424
425 EXPECT_EQ(it->source_id(), kCsrc);
426 EXPECT_EQ(it->source_type(), RtpSourceType::CSRC);
427 EXPECT_EQ(it->rtp_timestamp(), kRtpTimestamp);
428 EXPECT_GE(it->timestamp_ms(), timestamp_ms_min);
429 EXPECT_LE(it->timestamp_ms(), timestamp_ms_max);
430 }
431}
432
Markus Handell588f9b32021-04-08 19:19:50 +0200433std::unique_ptr<FrameObjectFake> MakeFrameWithResolution(
434 VideoFrameType frame_type,
435 int picture_id,
436 int width,
437 int height) {
Tommiae4d0972020-05-18 08:45:38 +0200438 auto frame = std::make_unique<FrameObjectFake>();
439 frame->SetPayloadType(99);
philipel9aa9b8d2021-02-15 13:31:29 +0100440 frame->SetId(picture_id);
Tommiae4d0972020-05-18 08:45:38 +0200441 frame->SetFrameType(frame_type);
Markus Handell588f9b32021-04-08 19:19:50 +0200442 frame->_encodedWidth = width;
443 frame->_encodedHeight = height;
Tommiae4d0972020-05-18 08:45:38 +0200444 return frame;
445}
446
Markus Handell588f9b32021-04-08 19:19:50 +0200447std::unique_ptr<FrameObjectFake> MakeFrame(VideoFrameType frame_type,
448 int picture_id) {
449 return MakeFrameWithResolution(frame_type, picture_id, 320, 240);
450}
451
Tommiae4d0972020-05-18 08:45:38 +0200452TEST_F(VideoReceiveStream2TestWithFakeDecoder,
453 PassesFrameWhenEncodedFramesCallbackSet) {
454 testing::MockFunction<void(const RecordableEncodedFrame&)> callback;
455 video_receive_stream_->Start();
456 // Expect a keyframe request to be generated
457 EXPECT_CALL(mock_transport_, SendRtcp);
458 EXPECT_CALL(callback, Call);
459 video_receive_stream_->SetAndGetRecordingState(
460 VideoReceiveStream::RecordingState(callback.AsStdFunction()), true);
461 video_receive_stream_->OnCompleteFrame(
462 MakeFrame(VideoFrameType::kVideoFrameKey, 0));
463 EXPECT_TRUE(fake_renderer_.WaitForRenderedFrame(kDefaultTimeOutMs));
464 video_receive_stream_->Stop();
465}
466
467TEST_F(VideoReceiveStream2TestWithFakeDecoder,
468 MovesEncodedFrameDispatchStateWhenReCreating) {
469 testing::MockFunction<void(const RecordableEncodedFrame&)> callback;
470 video_receive_stream_->Start();
471 // Expect a key frame request over RTCP.
472 EXPECT_CALL(mock_transport_, SendRtcp).Times(1);
473 video_receive_stream_->SetAndGetRecordingState(
474 VideoReceiveStream::RecordingState(callback.AsStdFunction()), true);
475 video_receive_stream_->Stop();
476 VideoReceiveStream::RecordingState old_state =
477 video_receive_stream_->SetAndGetRecordingState(
478 VideoReceiveStream::RecordingState(), false);
479 ReCreateReceiveStream(std::move(old_state));
480 video_receive_stream_->Stop();
481}
482
Philipp Hancke006206d2021-03-24 17:49:02 +0100483class VideoReceiveStream2TestWithSimulatedClock
Evan Shrubsole9a999052021-12-12 15:27:00 +0100484 : public ::testing::TestWithParam<std::tuple<int, bool>> {
Tommiae4d0972020-05-18 08:45:38 +0200485 public:
Markus Handell588f9b32021-04-08 19:19:50 +0200486 class FakeRenderer : public rtc::VideoSinkInterface<webrtc::VideoFrame> {
487 public:
488 void SignalDoneAfterFrames(int num_frames_received) {
489 signal_after_frame_count_ = num_frames_received;
490 if (frame_count_ == signal_after_frame_count_)
491 event_.Set();
492 }
493
494 void OnFrame(const webrtc::VideoFrame& frame) override {
495 if (++frame_count_ == signal_after_frame_count_)
496 event_.Set();
497 }
498
499 void WaitUntilDone() { event_.Wait(rtc::Event::kForever); }
500
501 private:
502 int signal_after_frame_count_ = std::numeric_limits<int>::max();
503 int frame_count_ = 0;
504 rtc::Event event_;
505 };
506
Tommiae4d0972020-05-18 08:45:38 +0200507 class FakeDecoder2 : public test::FakeDecoder {
508 public:
509 explicit FakeDecoder2(std::function<void()> decode_callback)
510 : callback_(decode_callback) {}
511
512 int32_t Decode(const EncodedImage& input,
513 bool missing_frames,
514 int64_t render_time_ms) override {
515 int32_t result =
516 FakeDecoder::Decode(input, missing_frames, render_time_ms);
517 callback_();
518 return result;
519 }
520
521 private:
522 std::function<void()> callback_;
523 };
524
525 static VideoReceiveStream::Config GetConfig(
526 Transport* transport,
527 VideoDecoderFactory* decoder_factory,
528 rtc::VideoSinkInterface<webrtc::VideoFrame>* renderer) {
Tommi9e2b3152021-06-21 22:15:39 +0200529 VideoReceiveStream::Config config(transport, decoder_factory);
Tommiae4d0972020-05-18 08:45:38 +0200530 config.rtp.remote_ssrc = 1111;
531 config.rtp.local_ssrc = 2222;
Evan Shrubsole9a999052021-12-12 15:27:00 +0100532 config.rtp.nack.rtp_history_ms = std::get<0>(GetParam()); // rtx-time.
Tommiae4d0972020-05-18 08:45:38 +0200533 config.renderer = renderer;
534 VideoReceiveStream::Decoder fake_decoder;
535 fake_decoder.payload_type = 99;
536 fake_decoder.video_format = SdpVideoFormat("VP8");
Tommiae4d0972020-05-18 08:45:38 +0200537 config.decoders.push_back(fake_decoder);
538 return config;
539 }
540
541 VideoReceiveStream2TestWithSimulatedClock()
542 : time_controller_(Timestamp::Millis(4711)),
543 fake_decoder_factory_([this] {
544 return std::make_unique<FakeDecoder2>([this] { OnFrameDecoded(); });
545 }),
Tommiae4d0972020-05-18 08:45:38 +0200546 config_(GetConfig(&mock_transport_,
547 &fake_decoder_factory_,
548 &fake_renderer_)),
549 call_stats_(time_controller_.GetClock(), loop_.task_queue()),
Evan Shrubsole6dbc1722022-03-22 12:20:11 +0100550 video_receive_stream_(
551 time_controller_.GetTaskQueueFactory(),
552 &fake_call_,
553 /*num_cores=*/2,
554 &packet_router_,
555 config_.Copy(),
556 &call_stats_,
557 time_controller_.GetClock(),
558 std::make_unique<VCMTiming>(time_controller_.GetClock()),
559 &nack_periodic_processor_,
560 nullptr) {
Jonas Oreland8ca06132022-03-14 12:52:48 +0100561 if (std::get<1>(GetParam())) {
562 fake_call_.SetFieldTrial("WebRTC-FrameBuffer3/arm:FrameBuffer3/");
563 } else {
564 fake_call_.SetFieldTrial("WebRTC-FrameBuffer3/arm:FrameBuffer2/");
565 }
Tommi90738dd2021-05-31 17:36:47 +0200566 video_receive_stream_.RegisterWithTransport(
567 &rtp_stream_receiver_controller_);
Tommiae4d0972020-05-18 08:45:38 +0200568 video_receive_stream_.Start();
569 }
570
Tommi90738dd2021-05-31 17:36:47 +0200571 ~VideoReceiveStream2TestWithSimulatedClock() override {
572 video_receive_stream_.UnregisterFromTransport();
573 }
574
Tommiae4d0972020-05-18 08:45:38 +0200575 void OnFrameDecoded() { event_->Set(); }
576
philipelca188092021-03-23 12:00:49 +0100577 void PassEncodedFrameAndWait(std::unique_ptr<EncodedFrame> frame) {
Tommiae4d0972020-05-18 08:45:38 +0200578 event_ = std::make_unique<rtc::Event>();
579 // This call will eventually end up in the Decoded method where the
580 // event is set.
581 video_receive_stream_.OnCompleteFrame(std::move(frame));
Evan Shrubsole9a999052021-12-12 15:27:00 +0100582 // FrameBuffer3 runs on the test sequence so flush to ensure that decoding
583 // happens.
584 loop_.Flush();
585 ASSERT_TRUE(event_->Wait(1000));
Tommiae4d0972020-05-18 08:45:38 +0200586 }
587
588 protected:
589 GlobalSimulatedTimeController time_controller_;
590 test::RunLoop loop_;
591 test::FunctionVideoDecoderFactory fake_decoder_factory_;
Tommiae4d0972020-05-18 08:45:38 +0200592 MockTransport mock_transport_;
Markus Handell588f9b32021-04-08 19:19:50 +0200593 FakeRenderer fake_renderer_;
Tommi90738dd2021-05-31 17:36:47 +0200594 cricket::FakeCall fake_call_;
Markus Handell0e62f7a2021-07-20 13:32:02 +0200595 NackPeriodicProcessor nack_periodic_processor_;
Tommiae4d0972020-05-18 08:45:38 +0200596 VideoReceiveStream::Config config_;
597 internal::CallStats call_stats_;
598 PacketRouter packet_router_;
599 RtpStreamReceiverController rtp_stream_receiver_controller_;
600 webrtc::internal::VideoReceiveStream2 video_receive_stream_;
601 std::unique_ptr<rtc::Event> event_;
602};
603
Philipp Hancke006206d2021-03-24 17:49:02 +0100604TEST_P(VideoReceiveStream2TestWithSimulatedClock,
Tommiae4d0972020-05-18 08:45:38 +0200605 RequestsKeyFramesUntilKeyFrameReceived) {
Evan Shrubsole9a999052021-12-12 15:27:00 +0100606 auto tick = TimeDelta::Millis(std::get<0>(GetParam()) / 2);
607 bool sent_rtcp = false;
608 EXPECT_CALL(mock_transport_, SendRtcp)
609 .Times(1)
610 .WillOnce(Invoke([&sent_rtcp]() {
611 sent_rtcp = true;
612 return 0;
613 }));
Tommiae4d0972020-05-18 08:45:38 +0200614 video_receive_stream_.GenerateKeyFrame();
615 PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameDelta, 0));
616 time_controller_.AdvanceTime(tick);
Evan Shrubsole9a999052021-12-12 15:27:00 +0100617 loop_.Flush();
Tommiae4d0972020-05-18 08:45:38 +0200618 PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameDelta, 1));
Tommiae4d0972020-05-18 08:45:38 +0200619 testing::Mock::VerifyAndClearExpectations(&mock_transport_);
Evan Shrubsole9a999052021-12-12 15:27:00 +0100620 EXPECT_TRUE(sent_rtcp);
Tommiae4d0972020-05-18 08:45:38 +0200621
Philipp Hancke006206d2021-03-24 17:49:02 +0100622 // T+keyframetimeout: still no key frame received, expect key frame request
623 // sent again.
Evan Shrubsole9a999052021-12-12 15:27:00 +0100624 sent_rtcp = false;
625 EXPECT_CALL(mock_transport_, SendRtcp)
626 .Times(1)
627 .WillOnce(Invoke([&sent_rtcp]() {
628 sent_rtcp = true;
629 return 0;
630 }));
Tommiae4d0972020-05-18 08:45:38 +0200631 time_controller_.AdvanceTime(tick);
632 PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameDelta, 2));
Evan Shrubsole9a999052021-12-12 15:27:00 +0100633 loop_.PostTask([this]() { loop_.Quit(); });
Tommiae4d0972020-05-18 08:45:38 +0200634 loop_.Run();
635 testing::Mock::VerifyAndClearExpectations(&mock_transport_);
Evan Shrubsole9a999052021-12-12 15:27:00 +0100636 EXPECT_TRUE(sent_rtcp);
Tommiae4d0972020-05-18 08:45:38 +0200637
Philipp Hancke006206d2021-03-24 17:49:02 +0100638 // T+keyframetimeout: now send a key frame - we should not observe new key
639 // frame requests after this.
Tommiae4d0972020-05-18 08:45:38 +0200640 EXPECT_CALL(mock_transport_, SendRtcp).Times(0);
641 PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameKey, 3));
642 time_controller_.AdvanceTime(2 * tick);
643 PassEncodedFrameAndWait(MakeFrame(VideoFrameType::kVideoFrameDelta, 4));
644 loop_.PostTask([this]() { loop_.Quit(); });
645 loop_.Run();
646}
647
Markus Handell588f9b32021-04-08 19:19:50 +0200648TEST_P(VideoReceiveStream2TestWithSimulatedClock,
649 DispatchesEncodedFrameSequenceStartingWithKeyframeWithoutResolution) {
650 video_receive_stream_.Start();
651 testing::MockFunction<void(const RecordableEncodedFrame&)> callback;
652 video_receive_stream_.SetAndGetRecordingState(
653 VideoReceiveStream::RecordingState(callback.AsStdFunction()),
654 /*generate_key_frame=*/false);
655
656 InSequence s;
657 EXPECT_CALL(
658 callback,
659 Call(AllOf(
660 Property(&RecordableEncodedFrame::resolution,
661 Field(&RecordableEncodedFrame::EncodedResolution::width,
662 test::FakeDecoder::kDefaultWidth)),
663 Property(&RecordableEncodedFrame::resolution,
664 Field(&RecordableEncodedFrame::EncodedResolution::height,
665 test::FakeDecoder::kDefaultHeight)))));
666 EXPECT_CALL(callback, Call);
667
668 fake_renderer_.SignalDoneAfterFrames(2);
669 PassEncodedFrameAndWait(
670 MakeFrameWithResolution(VideoFrameType::kVideoFrameKey, 0, 0, 0));
671 PassEncodedFrameAndWait(
672 MakeFrameWithResolution(VideoFrameType::kVideoFrameDelta, 1, 0, 0));
673 fake_renderer_.WaitUntilDone();
674
675 video_receive_stream_.Stop();
676}
677
678TEST_P(VideoReceiveStream2TestWithSimulatedClock,
679 DispatchesEncodedFrameSequenceStartingWithKeyframeWithResolution) {
680 video_receive_stream_.Start();
681 testing::MockFunction<void(const RecordableEncodedFrame&)> callback;
682 video_receive_stream_.SetAndGetRecordingState(
683 VideoReceiveStream::RecordingState(callback.AsStdFunction()),
684 /*generate_key_frame=*/false);
685
686 InSequence s;
687 EXPECT_CALL(
688 callback,
689 Call(AllOf(
690 Property(
691 &RecordableEncodedFrame::resolution,
692 Field(&RecordableEncodedFrame::EncodedResolution::width, 1080)),
693 Property(&RecordableEncodedFrame::resolution,
694 Field(&RecordableEncodedFrame::EncodedResolution::height,
695 720)))));
696 EXPECT_CALL(callback, Call);
697
698 fake_renderer_.SignalDoneAfterFrames(2);
699 PassEncodedFrameAndWait(
700 MakeFrameWithResolution(VideoFrameType::kVideoFrameKey, 0, 1080, 720));
701 PassEncodedFrameAndWait(
702 MakeFrameWithResolution(VideoFrameType::kVideoFrameDelta, 1, 0, 0));
703 fake_renderer_.WaitUntilDone();
704
705 video_receive_stream_.Stop();
706}
707
Philipp Hancke006206d2021-03-24 17:49:02 +0100708INSTANTIATE_TEST_SUITE_P(
709 RtxTime,
710 VideoReceiveStream2TestWithSimulatedClock,
Evan Shrubsole9a999052021-12-12 15:27:00 +0100711 ::testing::Combine(
712 ::testing::Values(internal::VideoReceiveStream2::kMaxWaitForKeyFrameMs,
713 50 /*ms*/),
714 ::testing::Bool()));
Philipp Hancke006206d2021-03-24 17:49:02 +0100715
Johannes Kron16359f62021-02-18 23:37:22 +0100716class VideoReceiveStream2TestWithLazyDecoderCreation : public ::testing::Test {
717 public:
718 VideoReceiveStream2TestWithLazyDecoderCreation()
Markus Handelleb61b7f2021-06-22 10:46:48 +0200719 : task_queue_factory_(CreateDefaultTaskQueueFactory()),
Tommi9e2b3152021-06-21 22:15:39 +0200720 config_(&mock_transport_, &mock_h264_decoder_factory_),
Johannes Kron16359f62021-02-18 23:37:22 +0100721 call_stats_(Clock::GetRealTimeClock(), loop_.task_queue()) {}
722
Tommi90738dd2021-05-31 17:36:47 +0200723 ~VideoReceiveStream2TestWithLazyDecoderCreation() override {
724 video_receive_stream_->UnregisterFromTransport();
725 }
726
727 void SetUp() override {
Jonas Oreland8ca06132022-03-14 12:52:48 +0100728 fake_call_.SetFieldTrial("WebRTC-PreStreamDecoders/max:0/");
Johannes Kron16359f62021-02-18 23:37:22 +0100729 constexpr int kDefaultNumCpuCores = 2;
730 config_.rtp.remote_ssrc = 1111;
731 config_.rtp.local_ssrc = 2222;
732 config_.renderer = &fake_renderer_;
Johannes Kron16359f62021-02-18 23:37:22 +0100733 VideoReceiveStream::Decoder h264_decoder;
734 h264_decoder.payload_type = 99;
735 h264_decoder.video_format = SdpVideoFormat("H264");
736 h264_decoder.video_format.parameters.insert(
737 {"sprop-parameter-sets", "Z0IACpZTBYmI,aMljiA=="});
738 config_.decoders.clear();
739 config_.decoders.push_back(h264_decoder);
740
741 clock_ = Clock::GetRealTimeClock();
742 timing_ = new VCMTiming(clock_);
743
744 video_receive_stream_ =
745 std::make_unique<webrtc::internal::VideoReceiveStream2>(
Tommi90738dd2021-05-31 17:36:47 +0200746 task_queue_factory_.get(), &fake_call_, kDefaultNumCpuCores,
Evan Shrubsole6dbc1722022-03-22 12:20:11 +0100747 &packet_router_, config_.Copy(), &call_stats_, clock_,
748 absl::WrapUnique(timing_), &nack_periodic_processor_, nullptr);
Tommi90738dd2021-05-31 17:36:47 +0200749 video_receive_stream_->RegisterWithTransport(
750 &rtp_stream_receiver_controller_);
Johannes Kron16359f62021-02-18 23:37:22 +0100751 }
752
753 protected:
754 test::RunLoop loop_;
Johannes Kron16359f62021-02-18 23:37:22 +0100755 const std::unique_ptr<TaskQueueFactory> task_queue_factory_;
Tommi9e2b3152021-06-21 22:15:39 +0200756 MockVideoDecoderFactory mock_h264_decoder_factory_;
Markus Handell0e62f7a2021-07-20 13:32:02 +0200757 NackPeriodicProcessor nack_periodic_processor_;
Johannes Kron16359f62021-02-18 23:37:22 +0100758 VideoReceiveStream::Config config_;
759 internal::CallStats call_stats_;
760 MockVideoDecoder mock_h264_video_decoder_;
Johannes Kron16359f62021-02-18 23:37:22 +0100761 cricket::FakeVideoRenderer fake_renderer_;
Tommi90738dd2021-05-31 17:36:47 +0200762 cricket::FakeCall fake_call_;
Johannes Kron16359f62021-02-18 23:37:22 +0100763 MockTransport mock_transport_;
764 PacketRouter packet_router_;
765 RtpStreamReceiverController rtp_stream_receiver_controller_;
766 std::unique_ptr<webrtc::internal::VideoReceiveStream2> video_receive_stream_;
767 Clock* clock_;
768 VCMTiming* timing_;
769};
770
771TEST_F(VideoReceiveStream2TestWithLazyDecoderCreation, LazyDecoderCreation) {
772 constexpr uint8_t idr_nalu[] = {0x05, 0xFF, 0xFF, 0xFF};
773 RtpPacketToSend rtppacket(nullptr);
774 uint8_t* payload = rtppacket.AllocatePayload(sizeof(idr_nalu));
775 memcpy(payload, idr_nalu, sizeof(idr_nalu));
776 rtppacket.SetMarker(true);
777 rtppacket.SetSsrc(1111);
778 rtppacket.SetPayloadType(99);
779 rtppacket.SetSequenceNumber(1);
780 rtppacket.SetTimestamp(0);
781
782 // No decoder is created here.
783 EXPECT_CALL(mock_h264_decoder_factory_, CreateVideoDecoder(_)).Times(0);
784 video_receive_stream_->Start();
785
786 EXPECT_CALL(mock_h264_decoder_factory_, CreateVideoDecoder(_))
787 .WillOnce(Invoke([this](const SdpVideoFormat& format) {
788 test::VideoDecoderProxyFactory h264_decoder_factory(
789 &mock_h264_video_decoder_);
790 return h264_decoder_factory.CreateVideoDecoder(format);
791 }));
Danil Chapovalovd08930d2021-08-12 13:26:55 +0200792 rtc::Event init_decode_event;
793 EXPECT_CALL(mock_h264_video_decoder_, Configure).WillOnce(WithoutArgs([&] {
794 init_decode_event.Set();
795 return true;
796 }));
Johannes Kron16359f62021-02-18 23:37:22 +0100797 EXPECT_CALL(mock_h264_video_decoder_, RegisterDecodeCompleteCallback(_));
798 EXPECT_CALL(mock_h264_video_decoder_, Decode(_, false, _));
799 RtpPacketReceived parsed_packet;
800 ASSERT_TRUE(parsed_packet.Parse(rtppacket.data(), rtppacket.size()));
801 rtp_stream_receiver_controller_.OnRtpPacket(parsed_packet);
802 EXPECT_CALL(mock_h264_video_decoder_, Release());
803
804 // Make sure the decoder thread had a chance to run.
Danil Chapovalovd08930d2021-08-12 13:26:55 +0200805 init_decode_event.Wait(kDefaultTimeOutMs);
Johannes Kron16359f62021-02-18 23:37:22 +0100806}
807
808TEST_F(VideoReceiveStream2TestWithLazyDecoderCreation,
809 DeregisterDecoderThatsNotCreated) {
810 // No decoder is created here.
811 EXPECT_CALL(mock_h264_decoder_factory_, CreateVideoDecoder(_)).Times(0);
812 video_receive_stream_->Start();
813 video_receive_stream_->Stop();
814}
815
Tommiae4d0972020-05-18 08:45:38 +0200816} // namespace webrtc