1 /*
2 * Copyright (c) 2015 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 "call/rtp_video_sender.h"
12
13 #include <atomic>
14 #include <memory>
15 #include <string>
16 #include <utility>
17
18 #include "absl/functional/any_invocable.h"
19 #include "call/rtp_transport_controller_send.h"
20 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
21 #include "modules/rtp_rtcp/source/byte_io.h"
22 #include "modules/rtp_rtcp/source/rtcp_packet/nack.h"
23 #include "modules/rtp_rtcp/source/rtp_dependency_descriptor_extension.h"
24 #include "modules/rtp_rtcp/source/rtp_packet.h"
25 #include "modules/video_coding/fec_controller_default.h"
26 #include "modules/video_coding/include/video_codec_interface.h"
27 #include "rtc_base/rate_limiter.h"
28 #include "test/gmock.h"
29 #include "test/gtest.h"
30 #include "test/mock_frame_transformer.h"
31 #include "test/mock_transport.h"
32 #include "test/scenario/scenario.h"
33 #include "test/scoped_key_value_config.h"
34 #include "test/time_controller/simulated_time_controller.h"
35 #include "video/send_delay_stats.h"
36 #include "video/send_statistics_proxy.h"
37
38 namespace webrtc {
39 namespace {
40
41 using ::testing::_;
42 using ::testing::NiceMock;
43 using ::testing::SaveArg;
44 using ::testing::SizeIs;
45
46 const int8_t kPayloadType = 96;
47 const uint32_t kSsrc1 = 12345;
48 const uint32_t kSsrc2 = 23456;
49 const uint32_t kRtxSsrc1 = 34567;
50 const uint32_t kRtxSsrc2 = 45678;
51 const int16_t kInitialPictureId1 = 222;
52 const int16_t kInitialPictureId2 = 44;
53 const int16_t kInitialTl0PicIdx1 = 99;
54 const int16_t kInitialTl0PicIdx2 = 199;
55 const int64_t kRetransmitWindowSizeMs = 500;
56 const int kTransportsSequenceExtensionId = 7;
57 const int kDependencyDescriptorExtensionId = 8;
58
59 class MockRtcpIntraFrameObserver : public RtcpIntraFrameObserver {
60 public:
61 MOCK_METHOD(void, OnReceivedIntraFrameRequest, (uint32_t), (override));
62 };
63
CreateObservers(RtcpRttStats * rtcp_rtt_stats,RtcpIntraFrameObserver * intra_frame_callback,ReportBlockDataObserver * report_block_data_observer,StreamDataCountersCallback * rtp_stats,BitrateStatisticsObserver * bitrate_observer,FrameCountObserver * frame_count_observer,RtcpPacketTypeCounterObserver * rtcp_type_observer,SendSideDelayObserver * send_delay_observer,SendPacketObserver * send_packet_observer)64 RtpSenderObservers CreateObservers(
65 RtcpRttStats* rtcp_rtt_stats,
66 RtcpIntraFrameObserver* intra_frame_callback,
67 ReportBlockDataObserver* report_block_data_observer,
68 StreamDataCountersCallback* rtp_stats,
69 BitrateStatisticsObserver* bitrate_observer,
70 FrameCountObserver* frame_count_observer,
71 RtcpPacketTypeCounterObserver* rtcp_type_observer,
72 SendSideDelayObserver* send_delay_observer,
73 SendPacketObserver* send_packet_observer) {
74 RtpSenderObservers observers;
75 observers.rtcp_rtt_stats = rtcp_rtt_stats;
76 observers.intra_frame_callback = intra_frame_callback;
77 observers.rtcp_loss_notification_observer = nullptr;
78 observers.report_block_data_observer = report_block_data_observer;
79 observers.rtp_stats = rtp_stats;
80 observers.bitrate_observer = bitrate_observer;
81 observers.frame_count_observer = frame_count_observer;
82 observers.rtcp_type_observer = rtcp_type_observer;
83 observers.send_delay_observer = send_delay_observer;
84 observers.send_packet_observer = send_packet_observer;
85 return observers;
86 }
87
GetBitrateConfig()88 BitrateConstraints GetBitrateConfig() {
89 BitrateConstraints bitrate_config;
90 bitrate_config.min_bitrate_bps = 30000;
91 bitrate_config.start_bitrate_bps = 300000;
92 bitrate_config.max_bitrate_bps = 3000000;
93 return bitrate_config;
94 }
95
CreateVideoSendStreamConfig(Transport * transport,const std::vector<uint32_t> & ssrcs,const std::vector<uint32_t> & rtx_ssrcs,int payload_type)96 VideoSendStream::Config CreateVideoSendStreamConfig(
97 Transport* transport,
98 const std::vector<uint32_t>& ssrcs,
99 const std::vector<uint32_t>& rtx_ssrcs,
100 int payload_type) {
101 VideoSendStream::Config config(transport);
102 config.rtp.ssrcs = ssrcs;
103 config.rtp.rtx.ssrcs = rtx_ssrcs;
104 config.rtp.payload_type = payload_type;
105 config.rtp.rtx.payload_type = payload_type + 1;
106 config.rtp.nack.rtp_history_ms = 1000;
107 config.rtp.extensions.emplace_back(RtpExtension::kTransportSequenceNumberUri,
108 kTransportsSequenceExtensionId);
109 config.rtp.extensions.emplace_back(RtpDependencyDescriptorExtension::Uri(),
110 kDependencyDescriptorExtensionId);
111 config.rtp.extmap_allow_mixed = true;
112 return config;
113 }
114
115 class RtpVideoSenderTestFixture {
116 public:
RtpVideoSenderTestFixture(const std::vector<uint32_t> & ssrcs,const std::vector<uint32_t> & rtx_ssrcs,int payload_type,const std::map<uint32_t,RtpPayloadState> & suspended_payload_states,FrameCountObserver * frame_count_observer,rtc::scoped_refptr<FrameTransformerInterface> frame_transformer,const FieldTrialsView * field_trials=nullptr)117 RtpVideoSenderTestFixture(
118 const std::vector<uint32_t>& ssrcs,
119 const std::vector<uint32_t>& rtx_ssrcs,
120 int payload_type,
121 const std::map<uint32_t, RtpPayloadState>& suspended_payload_states,
122 FrameCountObserver* frame_count_observer,
123 rtc::scoped_refptr<FrameTransformerInterface> frame_transformer,
124 const FieldTrialsView* field_trials = nullptr)
125 : time_controller_(Timestamp::Millis(1000000)),
126 config_(CreateVideoSendStreamConfig(&transport_,
127 ssrcs,
128 rtx_ssrcs,
129 payload_type)),
130 send_delay_stats_(time_controller_.GetClock()),
131 bitrate_config_(GetBitrateConfig()),
132 transport_controller_(
133 time_controller_.GetClock(),
134 RtpTransportConfig{
135 .bitrate_config = bitrate_config_,
136 .event_log = &event_log_,
137 .task_queue_factory = time_controller_.GetTaskQueueFactory(),
138 .trials = field_trials ? field_trials : &field_trials_,
139 }),
140 stats_proxy_(time_controller_.GetClock(),
141 config_,
142 VideoEncoderConfig::ContentType::kRealtimeVideo,
143 field_trials ? *field_trials : field_trials_),
144 retransmission_rate_limiter_(time_controller_.GetClock(),
145 kRetransmitWindowSizeMs) {
146 transport_controller_.EnsureStarted();
147 std::map<uint32_t, RtpState> suspended_ssrcs;
148 router_ = std::make_unique<RtpVideoSender>(
149 time_controller_.GetClock(), suspended_ssrcs, suspended_payload_states,
150 config_.rtp, config_.rtcp_report_interval_ms, &transport_,
151 CreateObservers(nullptr, &encoder_feedback_, &stats_proxy_,
152 &stats_proxy_, &stats_proxy_, frame_count_observer,
153 &stats_proxy_, &stats_proxy_, &send_delay_stats_),
154 &transport_controller_, &event_log_, &retransmission_rate_limiter_,
155 std::make_unique<FecControllerDefault>(time_controller_.GetClock()),
156 nullptr, CryptoOptions{}, frame_transformer,
157 field_trials ? *field_trials : field_trials_,
158 time_controller_.GetTaskQueueFactory());
159 }
160
RtpVideoSenderTestFixture(const std::vector<uint32_t> & ssrcs,const std::vector<uint32_t> & rtx_ssrcs,int payload_type,const std::map<uint32_t,RtpPayloadState> & suspended_payload_states,FrameCountObserver * frame_count_observer,const FieldTrialsView * field_trials=nullptr)161 RtpVideoSenderTestFixture(
162 const std::vector<uint32_t>& ssrcs,
163 const std::vector<uint32_t>& rtx_ssrcs,
164 int payload_type,
165 const std::map<uint32_t, RtpPayloadState>& suspended_payload_states,
166 FrameCountObserver* frame_count_observer,
167 const FieldTrialsView* field_trials = nullptr)
168 : RtpVideoSenderTestFixture(ssrcs,
169 rtx_ssrcs,
170 payload_type,
171 suspended_payload_states,
172 frame_count_observer,
173 /*frame_transformer=*/nullptr,
174 field_trials) {}
175
RtpVideoSenderTestFixture(const std::vector<uint32_t> & ssrcs,const std::vector<uint32_t> & rtx_ssrcs,int payload_type,const std::map<uint32_t,RtpPayloadState> & suspended_payload_states,const FieldTrialsView * field_trials=nullptr)176 RtpVideoSenderTestFixture(
177 const std::vector<uint32_t>& ssrcs,
178 const std::vector<uint32_t>& rtx_ssrcs,
179 int payload_type,
180 const std::map<uint32_t, RtpPayloadState>& suspended_payload_states,
181 const FieldTrialsView* field_trials = nullptr)
182 : RtpVideoSenderTestFixture(ssrcs,
183 rtx_ssrcs,
184 payload_type,
185 suspended_payload_states,
186 /*frame_count_observer=*/nullptr,
187 /*frame_transformer=*/nullptr,
188 field_trials) {}
189
~RtpVideoSenderTestFixture()190 ~RtpVideoSenderTestFixture() { Stop(); }
191
router()192 RtpVideoSender* router() { return router_.get(); }
transport()193 MockTransport& transport() { return transport_; }
AdvanceTime(TimeDelta delta)194 void AdvanceTime(TimeDelta delta) { time_controller_.AdvanceTime(delta); }
195
Stop()196 void Stop() {
197 RunOnTransportQueue([&]() { router_->Stop(); });
198 }
199
SetActiveModules(const std::vector<bool> & active_modules)200 void SetActiveModules(const std::vector<bool>& active_modules) {
201 RunOnTransportQueue([&]() { router_->SetActiveModules(active_modules); });
202 }
203
204 // Several RtpVideoSender methods expect to be called on the task queue as
205 // owned by the send transport. While the SequenceChecker may pick up the
206 // default thread as the transport queue, explicit checks for the transport
207 // queue (not just using a SequenceChecker) aren't possible unless such a
208 // queue is actually active. So RunOnTransportQueue is a convenience function
209 // that allow for running a `task` on the transport queue, similar to
210 // SendTask().
RunOnTransportQueue(absl::AnyInvocable<void ()&&> task)211 void RunOnTransportQueue(absl::AnyInvocable<void() &&> task) {
212 transport_controller_.GetWorkerQueue()->RunOrPost(std::move(task));
213 AdvanceTime(TimeDelta::Zero());
214 }
215
216 private:
217 test::ScopedKeyValueConfig field_trials_;
218 NiceMock<MockTransport> transport_;
219 NiceMock<MockRtcpIntraFrameObserver> encoder_feedback_;
220 GlobalSimulatedTimeController time_controller_;
221 RtcEventLogNull event_log_;
222 VideoSendStream::Config config_;
223 SendDelayStats send_delay_stats_;
224 BitrateConstraints bitrate_config_;
225 RtpTransportControllerSend transport_controller_;
226 SendStatisticsProxy stats_proxy_;
227 RateLimiter retransmission_rate_limiter_;
228 std::unique_ptr<RtpVideoSender> router_;
229 };
230
CreateBitrateAllocationUpdate(int target_bitrate_bps)231 BitrateAllocationUpdate CreateBitrateAllocationUpdate(int target_bitrate_bps) {
232 BitrateAllocationUpdate update;
233 update.target_bitrate = DataRate::BitsPerSec(target_bitrate_bps);
234 update.round_trip_time = TimeDelta::Zero();
235 return update;
236 }
237
238 } // namespace
239
TEST(RtpVideoSenderTest,SendOnOneModule)240 TEST(RtpVideoSenderTest, SendOnOneModule) {
241 constexpr uint8_t kPayload = 'a';
242 EncodedImage encoded_image;
243 encoded_image.SetTimestamp(1);
244 encoded_image.capture_time_ms_ = 2;
245 encoded_image._frameType = VideoFrameType::kVideoFrameKey;
246 encoded_image.SetEncodedData(EncodedImageBuffer::Create(&kPayload, 1));
247
248 RtpVideoSenderTestFixture test({kSsrc1}, {kRtxSsrc1}, kPayloadType, {});
249 EXPECT_NE(EncodedImageCallback::Result::OK,
250 test.router()->OnEncodedImage(encoded_image, nullptr).error);
251
252 test.SetActiveModules({true});
253 EXPECT_EQ(EncodedImageCallback::Result::OK,
254 test.router()->OnEncodedImage(encoded_image, nullptr).error);
255
256 test.SetActiveModules({false});
257 EXPECT_NE(EncodedImageCallback::Result::OK,
258 test.router()->OnEncodedImage(encoded_image, nullptr).error);
259
260 test.SetActiveModules({true});
261 EXPECT_EQ(EncodedImageCallback::Result::OK,
262 test.router()->OnEncodedImage(encoded_image, nullptr).error);
263 }
264
TEST(RtpVideoSenderTest,SendSimulcastSetActive)265 TEST(RtpVideoSenderTest, SendSimulcastSetActive) {
266 constexpr uint8_t kPayload = 'a';
267 EncodedImage encoded_image_1;
268 encoded_image_1.SetTimestamp(1);
269 encoded_image_1.capture_time_ms_ = 2;
270 encoded_image_1._frameType = VideoFrameType::kVideoFrameKey;
271 encoded_image_1.SetEncodedData(EncodedImageBuffer::Create(&kPayload, 1));
272
273 RtpVideoSenderTestFixture test({kSsrc1, kSsrc2}, {kRtxSsrc1, kRtxSsrc2},
274 kPayloadType, {});
275
276 CodecSpecificInfo codec_info;
277 codec_info.codecType = kVideoCodecVP8;
278
279 test.SetActiveModules({true, true});
280 EXPECT_EQ(EncodedImageCallback::Result::OK,
281 test.router()->OnEncodedImage(encoded_image_1, &codec_info).error);
282
283 EncodedImage encoded_image_2(encoded_image_1);
284 encoded_image_2.SetSpatialIndex(1);
285 EXPECT_EQ(EncodedImageCallback::Result::OK,
286 test.router()->OnEncodedImage(encoded_image_2, &codec_info).error);
287
288 // Inactive.
289 test.Stop();
290 EXPECT_NE(EncodedImageCallback::Result::OK,
291 test.router()->OnEncodedImage(encoded_image_1, &codec_info).error);
292 EXPECT_NE(EncodedImageCallback::Result::OK,
293 test.router()->OnEncodedImage(encoded_image_2, &codec_info).error);
294 }
295
296 // Tests how setting individual rtp modules to active affects the overall
297 // behavior of the payload router. First sets one module to active and checks
298 // that outgoing data can be sent on this module, and checks that no data can
299 // be sent if both modules are inactive.
TEST(RtpVideoSenderTest,SendSimulcastSetActiveModules)300 TEST(RtpVideoSenderTest, SendSimulcastSetActiveModules) {
301 constexpr uint8_t kPayload = 'a';
302 EncodedImage encoded_image_1;
303 encoded_image_1.SetTimestamp(1);
304 encoded_image_1.capture_time_ms_ = 2;
305 encoded_image_1._frameType = VideoFrameType::kVideoFrameKey;
306 encoded_image_1.SetEncodedData(EncodedImageBuffer::Create(&kPayload, 1));
307
308 EncodedImage encoded_image_2(encoded_image_1);
309 encoded_image_2.SetSpatialIndex(1);
310
311 RtpVideoSenderTestFixture test({kSsrc1, kSsrc2}, {kRtxSsrc1, kRtxSsrc2},
312 kPayloadType, {});
313 CodecSpecificInfo codec_info;
314 codec_info.codecType = kVideoCodecVP8;
315
316 // Only setting one stream to active will still set the payload router to
317 // active and allow sending data on the active stream.
318 std::vector<bool> active_modules({true, false});
319 test.SetActiveModules(active_modules);
320 EXPECT_EQ(EncodedImageCallback::Result::OK,
321 test.router()->OnEncodedImage(encoded_image_1, &codec_info).error);
322
323 // Setting both streams to inactive will turn the payload router to
324 // inactive.
325 active_modules = {false, false};
326 test.SetActiveModules(active_modules);
327 // An incoming encoded image will not ask the module to send outgoing data
328 // because the payload router is inactive.
329 EXPECT_NE(EncodedImageCallback::Result::OK,
330 test.router()->OnEncodedImage(encoded_image_1, &codec_info).error);
331 EXPECT_NE(EncodedImageCallback::Result::OK,
332 test.router()->OnEncodedImage(encoded_image_1, &codec_info).error);
333 }
334
TEST(RtpVideoSenderTest,DiscardsHigherSpatialVideoFramesAfterLayerDisabledInVideoLayersAllocation)335 TEST(
336 RtpVideoSenderTest,
337 DiscardsHigherSpatialVideoFramesAfterLayerDisabledInVideoLayersAllocation) {
338 constexpr uint8_t kPayload = 'a';
339 EncodedImage encoded_image_1;
340 encoded_image_1.SetTimestamp(1);
341 encoded_image_1.capture_time_ms_ = 2;
342 encoded_image_1._frameType = VideoFrameType::kVideoFrameKey;
343 encoded_image_1.SetEncodedData(EncodedImageBuffer::Create(&kPayload, 1));
344 EncodedImage encoded_image_2(encoded_image_1);
345 encoded_image_2.SetSpatialIndex(1);
346 CodecSpecificInfo codec_info;
347 codec_info.codecType = kVideoCodecVP8;
348 RtpVideoSenderTestFixture test({kSsrc1, kSsrc2}, {kRtxSsrc1, kRtxSsrc2},
349 kPayloadType, {});
350 test.SetActiveModules({true, true});
351 // A layer is sent on both rtp streams.
352 test.router()->OnVideoLayersAllocationUpdated(
353 {.active_spatial_layers = {{.rtp_stream_index = 0},
354 {.rtp_stream_index = 1}}});
355
356 EXPECT_EQ(EncodedImageCallback::Result::OK,
357 test.router()->OnEncodedImage(encoded_image_1, &codec_info).error);
358 EXPECT_EQ(EncodedImageCallback::Result::OK,
359 test.router()->OnEncodedImage(encoded_image_2, &codec_info).error);
360
361 // Only rtp stream index 0 is configured to send a stream.
362 test.router()->OnVideoLayersAllocationUpdated(
363 {.active_spatial_layers = {{.rtp_stream_index = 0}}});
364 EXPECT_EQ(EncodedImageCallback::Result::OK,
365 test.router()->OnEncodedImage(encoded_image_1, &codec_info).error);
366 EXPECT_NE(EncodedImageCallback::Result::OK,
367 test.router()->OnEncodedImage(encoded_image_2, &codec_info).error);
368 }
369
TEST(RtpVideoSenderTest,CreateWithNoPreviousStates)370 TEST(RtpVideoSenderTest, CreateWithNoPreviousStates) {
371 RtpVideoSenderTestFixture test({kSsrc1, kSsrc2}, {kRtxSsrc1, kRtxSsrc2},
372 kPayloadType, {});
373 test.SetActiveModules({true, true});
374
375 std::map<uint32_t, RtpPayloadState> initial_states =
376 test.router()->GetRtpPayloadStates();
377 EXPECT_EQ(2u, initial_states.size());
378 EXPECT_NE(initial_states.find(kSsrc1), initial_states.end());
379 EXPECT_NE(initial_states.find(kSsrc2), initial_states.end());
380 }
381
TEST(RtpVideoSenderTest,CreateWithPreviousStates)382 TEST(RtpVideoSenderTest, CreateWithPreviousStates) {
383 const int64_t kState1SharedFrameId = 123;
384 const int64_t kState2SharedFrameId = 234;
385 RtpPayloadState state1;
386 state1.picture_id = kInitialPictureId1;
387 state1.tl0_pic_idx = kInitialTl0PicIdx1;
388 state1.shared_frame_id = kState1SharedFrameId;
389 RtpPayloadState state2;
390 state2.picture_id = kInitialPictureId2;
391 state2.tl0_pic_idx = kInitialTl0PicIdx2;
392 state2.shared_frame_id = kState2SharedFrameId;
393 std::map<uint32_t, RtpPayloadState> states = {{kSsrc1, state1},
394 {kSsrc2, state2}};
395
396 RtpVideoSenderTestFixture test({kSsrc1, kSsrc2}, {kRtxSsrc1, kRtxSsrc2},
397 kPayloadType, states);
398 test.SetActiveModules({true, true});
399
400 std::map<uint32_t, RtpPayloadState> initial_states =
401 test.router()->GetRtpPayloadStates();
402 EXPECT_EQ(2u, initial_states.size());
403 EXPECT_EQ(kInitialPictureId1, initial_states[kSsrc1].picture_id);
404 EXPECT_EQ(kInitialTl0PicIdx1, initial_states[kSsrc1].tl0_pic_idx);
405 EXPECT_EQ(kInitialPictureId2, initial_states[kSsrc2].picture_id);
406 EXPECT_EQ(kInitialTl0PicIdx2, initial_states[kSsrc2].tl0_pic_idx);
407 EXPECT_EQ(kState2SharedFrameId, initial_states[kSsrc1].shared_frame_id);
408 EXPECT_EQ(kState2SharedFrameId, initial_states[kSsrc2].shared_frame_id);
409 }
410
TEST(RtpVideoSenderTest,FrameCountCallbacks)411 TEST(RtpVideoSenderTest, FrameCountCallbacks) {
412 class MockFrameCountObserver : public FrameCountObserver {
413 public:
414 MOCK_METHOD(void,
415 FrameCountUpdated,
416 (const FrameCounts& frame_counts, uint32_t ssrc),
417 (override));
418 } callback;
419
420 RtpVideoSenderTestFixture test({kSsrc1}, {kRtxSsrc1}, kPayloadType, {},
421 &callback);
422
423 constexpr uint8_t kPayload = 'a';
424 EncodedImage encoded_image;
425 encoded_image.SetTimestamp(1);
426 encoded_image.capture_time_ms_ = 2;
427 encoded_image._frameType = VideoFrameType::kVideoFrameKey;
428 encoded_image.SetEncodedData(EncodedImageBuffer::Create(&kPayload, 1));
429
430 encoded_image._frameType = VideoFrameType::kVideoFrameKey;
431
432 // No callbacks when not active.
433 EXPECT_CALL(callback, FrameCountUpdated).Times(0);
434 EXPECT_NE(EncodedImageCallback::Result::OK,
435 test.router()->OnEncodedImage(encoded_image, nullptr).error);
436 ::testing::Mock::VerifyAndClearExpectations(&callback);
437
438 test.SetActiveModules({true});
439
440 FrameCounts frame_counts;
441 EXPECT_CALL(callback, FrameCountUpdated(_, kSsrc1))
442 .WillOnce(SaveArg<0>(&frame_counts));
443 EXPECT_EQ(EncodedImageCallback::Result::OK,
444 test.router()->OnEncodedImage(encoded_image, nullptr).error);
445
446 EXPECT_EQ(1, frame_counts.key_frames);
447 EXPECT_EQ(0, frame_counts.delta_frames);
448
449 ::testing::Mock::VerifyAndClearExpectations(&callback);
450
451 encoded_image._frameType = VideoFrameType::kVideoFrameDelta;
452 EXPECT_CALL(callback, FrameCountUpdated(_, kSsrc1))
453 .WillOnce(SaveArg<0>(&frame_counts));
454 EXPECT_EQ(EncodedImageCallback::Result::OK,
455 test.router()->OnEncodedImage(encoded_image, nullptr).error);
456
457 EXPECT_EQ(1, frame_counts.key_frames);
458 EXPECT_EQ(1, frame_counts.delta_frames);
459 }
460
461 // Integration test verifying that ack of packet via TransportFeedback means
462 // that the packet is removed from RtpPacketHistory and won't be retransmitted
463 // again.
TEST(RtpVideoSenderTest,DoesNotRetrasmitAckedPackets)464 TEST(RtpVideoSenderTest, DoesNotRetrasmitAckedPackets) {
465 RtpVideoSenderTestFixture test({kSsrc1, kSsrc2}, {kRtxSsrc1, kRtxSsrc2},
466 kPayloadType, {});
467 test.SetActiveModules({true, true});
468
469 constexpr uint8_t kPayload = 'a';
470 EncodedImage encoded_image;
471 encoded_image.SetTimestamp(1);
472 encoded_image.capture_time_ms_ = 2;
473 encoded_image._frameType = VideoFrameType::kVideoFrameKey;
474 encoded_image.SetEncodedData(EncodedImageBuffer::Create(&kPayload, 1));
475
476 // Send two tiny images, mapping to two RTP packets. Capture sequence numbers.
477 std::vector<uint16_t> rtp_sequence_numbers;
478 std::vector<uint16_t> transport_sequence_numbers;
479 EXPECT_CALL(test.transport(), SendRtp)
480 .Times(2)
481 .WillRepeatedly([&rtp_sequence_numbers, &transport_sequence_numbers](
482 const uint8_t* packet, size_t length,
483 const PacketOptions& options) {
484 RtpPacket rtp_packet;
485 EXPECT_TRUE(rtp_packet.Parse(packet, length));
486 rtp_sequence_numbers.push_back(rtp_packet.SequenceNumber());
487 transport_sequence_numbers.push_back(options.packet_id);
488 return true;
489 });
490 EXPECT_EQ(EncodedImageCallback::Result::OK,
491 test.router()->OnEncodedImage(encoded_image, nullptr).error);
492 encoded_image.SetTimestamp(2);
493 encoded_image.capture_time_ms_ = 3;
494 EXPECT_EQ(EncodedImageCallback::Result::OK,
495 test.router()->OnEncodedImage(encoded_image, nullptr).error);
496
497 test.AdvanceTime(TimeDelta::Millis(33));
498
499 // Construct a NACK message for requesting retransmission of both packet.
500 rtcp::Nack nack;
501 nack.SetMediaSsrc(kSsrc1);
502 nack.SetPacketIds(rtp_sequence_numbers);
503 rtc::Buffer nack_buffer = nack.Build();
504
505 std::vector<uint16_t> retransmitted_rtp_sequence_numbers;
506 EXPECT_CALL(test.transport(), SendRtp)
507 .Times(2)
508 .WillRepeatedly([&retransmitted_rtp_sequence_numbers](
509 const uint8_t* packet, size_t length,
510 const PacketOptions& options) {
511 RtpPacket rtp_packet;
512 EXPECT_TRUE(rtp_packet.Parse(packet, length));
513 EXPECT_EQ(rtp_packet.Ssrc(), kRtxSsrc1);
514 // Capture the retransmitted sequence number from the RTX header.
515 rtc::ArrayView<const uint8_t> payload = rtp_packet.payload();
516 retransmitted_rtp_sequence_numbers.push_back(
517 ByteReader<uint16_t>::ReadBigEndian(payload.data()));
518 return true;
519 });
520 test.router()->DeliverRtcp(nack_buffer.data(), nack_buffer.size());
521 test.AdvanceTime(TimeDelta::Millis(33));
522
523 // Verify that both packets were retransmitted.
524 EXPECT_EQ(retransmitted_rtp_sequence_numbers, rtp_sequence_numbers);
525
526 // Simulate transport feedback indicating fist packet received, next packet
527 // lost (not other way around as that would trigger early retransmit).
528 StreamFeedbackObserver::StreamPacketInfo lost_packet_feedback;
529 lost_packet_feedback.rtp_sequence_number = rtp_sequence_numbers[0];
530 lost_packet_feedback.ssrc = kSsrc1;
531 lost_packet_feedback.received = false;
532 lost_packet_feedback.is_retransmission = false;
533
534 StreamFeedbackObserver::StreamPacketInfo received_packet_feedback;
535 received_packet_feedback.rtp_sequence_number = rtp_sequence_numbers[1];
536 received_packet_feedback.ssrc = kSsrc1;
537 received_packet_feedback.received = true;
538 lost_packet_feedback.is_retransmission = false;
539
540 test.router()->OnPacketFeedbackVector(
541 {lost_packet_feedback, received_packet_feedback});
542
543 // Advance time to make sure retransmission would be allowed and try again.
544 // This time the retransmission should not happen for the first packet since
545 // the history has been notified of the ack and removed the packet. The
546 // second packet, included in the feedback but not marked as received, should
547 // still be retransmitted.
548 test.AdvanceTime(TimeDelta::Millis(33));
549 EXPECT_CALL(test.transport(), SendRtp)
550 .WillOnce([&lost_packet_feedback](const uint8_t* packet, size_t length,
551 const PacketOptions& options) {
552 RtpPacket rtp_packet;
553 EXPECT_TRUE(rtp_packet.Parse(packet, length));
554 EXPECT_EQ(rtp_packet.Ssrc(), kRtxSsrc1);
555 // Capture the retransmitted sequence number from the RTX header.
556 rtc::ArrayView<const uint8_t> payload = rtp_packet.payload();
557 EXPECT_EQ(lost_packet_feedback.rtp_sequence_number,
558 ByteReader<uint16_t>::ReadBigEndian(payload.data()));
559 return true;
560 });
561 test.router()->DeliverRtcp(nack_buffer.data(), nack_buffer.size());
562 test.AdvanceTime(TimeDelta::Millis(33));
563 }
564
565 // This tests that we utilize transport wide feedback to retransmit lost
566 // packets. This is tested by dropping all ordinary packets from a "lossy"
567 // stream sent along with a secondary untouched stream. The transport wide
568 // feedback packets from the secondary stream allows the sending side to
569 // detect and retreansmit the lost packets from the lossy stream.
TEST(RtpVideoSenderTest,RetransmitsOnTransportWideLossInfo)570 TEST(RtpVideoSenderTest, RetransmitsOnTransportWideLossInfo) {
571 int rtx_packets;
572 test::Scenario s(test_info_);
573 test::CallClientConfig call_conf;
574 // Keeping the bitrate fixed to avoid RTX due to probing.
575 call_conf.transport.rates.max_rate = DataRate::KilobitsPerSec(300);
576 call_conf.transport.rates.start_rate = DataRate::KilobitsPerSec(300);
577 test::NetworkSimulationConfig net_conf;
578 net_conf.bandwidth = DataRate::KilobitsPerSec(300);
579 auto send_node = s.CreateSimulationNode(net_conf);
580 auto* callee = s.CreateClient("return", call_conf);
581 auto* route = s.CreateRoutes(s.CreateClient("send", call_conf), {send_node},
582 callee, {s.CreateSimulationNode(net_conf)});
583
584 test::VideoStreamConfig lossy_config;
585 lossy_config.source.framerate = 5;
586 auto* lossy = s.CreateVideoStream(route->forward(), lossy_config);
587 // The secondary stream acts a driver for transport feedback messages,
588 // ensuring that lost packets on the lossy stream are retransmitted.
589 s.CreateVideoStream(route->forward(), test::VideoStreamConfig());
590
591 send_node->router()->SetFilter([&](const EmulatedIpPacket& packet) {
592 RtpPacket rtp;
593 if (rtp.Parse(packet.data)) {
594 // Drops all regular packets for the lossy stream and counts all RTX
595 // packets. Since no packets are let trough, NACKs can't be triggered
596 // by the receiving side.
597 if (lossy->send()->UsingSsrc(rtp.Ssrc())) {
598 return false;
599 } else if (lossy->send()->UsingRtxSsrc(rtp.Ssrc())) {
600 ++rtx_packets;
601 }
602 }
603 return true;
604 });
605
606 // Run for a short duration and reset counters to avoid counting RTX packets
607 // from initial probing.
608 s.RunFor(TimeDelta::Seconds(1));
609 rtx_packets = 0;
610 int decoded_baseline = 0;
611 callee->SendTask([&decoded_baseline, &lossy]() {
612 decoded_baseline = lossy->receive()->GetStats().frames_decoded;
613 });
614 s.RunFor(TimeDelta::Seconds(1));
615 // We expect both that RTX packets were sent and that an appropriate number of
616 // frames were received. This is somewhat redundant but reduces the risk of
617 // false positives in future regressions (e.g. RTX is send due to probing).
618 EXPECT_GE(rtx_packets, 1);
619 int frames_decoded = 0;
620 callee->SendTask([&decoded_baseline, &frames_decoded, &lossy]() {
621 frames_decoded =
622 lossy->receive()->GetStats().frames_decoded - decoded_baseline;
623 });
624 EXPECT_EQ(frames_decoded, 5);
625 }
626
627 // Integration test verifying that retransmissions are sent for packets which
628 // can be detected as lost early, using transport wide feedback.
TEST(RtpVideoSenderTest,EarlyRetransmits)629 TEST(RtpVideoSenderTest, EarlyRetransmits) {
630 RtpVideoSenderTestFixture test({kSsrc1, kSsrc2}, {kRtxSsrc1, kRtxSsrc2},
631 kPayloadType, {});
632 test.SetActiveModules({true, true});
633
634 const uint8_t kPayload[1] = {'a'};
635 EncodedImage encoded_image;
636 encoded_image.SetTimestamp(1);
637 encoded_image.capture_time_ms_ = 2;
638 encoded_image._frameType = VideoFrameType::kVideoFrameKey;
639 encoded_image.SetEncodedData(
640 EncodedImageBuffer::Create(kPayload, sizeof(kPayload)));
641 encoded_image.SetSpatialIndex(0);
642
643 CodecSpecificInfo codec_specific;
644 codec_specific.codecType = VideoCodecType::kVideoCodecGeneric;
645
646 // Send two tiny images, mapping to single RTP packets. Capture sequence
647 // numbers.
648 uint16_t frame1_rtp_sequence_number = 0;
649 uint16_t frame1_transport_sequence_number = 0;
650 EXPECT_CALL(test.transport(), SendRtp)
651 .WillOnce(
652 [&frame1_rtp_sequence_number, &frame1_transport_sequence_number](
653 const uint8_t* packet, size_t length,
654 const PacketOptions& options) {
655 RtpPacket rtp_packet;
656 EXPECT_TRUE(rtp_packet.Parse(packet, length));
657 frame1_rtp_sequence_number = rtp_packet.SequenceNumber();
658 frame1_transport_sequence_number = options.packet_id;
659 EXPECT_EQ(rtp_packet.Ssrc(), kSsrc1);
660 return true;
661 });
662 EXPECT_EQ(test.router()->OnEncodedImage(encoded_image, &codec_specific).error,
663 EncodedImageCallback::Result::OK);
664
665 test.AdvanceTime(TimeDelta::Millis(33));
666
667 uint16_t frame2_rtp_sequence_number = 0;
668 uint16_t frame2_transport_sequence_number = 0;
669 encoded_image.SetSpatialIndex(1);
670 EXPECT_CALL(test.transport(), SendRtp)
671 .WillOnce(
672 [&frame2_rtp_sequence_number, &frame2_transport_sequence_number](
673 const uint8_t* packet, size_t length,
674 const PacketOptions& options) {
675 RtpPacket rtp_packet;
676 EXPECT_TRUE(rtp_packet.Parse(packet, length));
677 frame2_rtp_sequence_number = rtp_packet.SequenceNumber();
678 frame2_transport_sequence_number = options.packet_id;
679 EXPECT_EQ(rtp_packet.Ssrc(), kSsrc2);
680 return true;
681 });
682 EXPECT_EQ(test.router()->OnEncodedImage(encoded_image, &codec_specific).error,
683 EncodedImageCallback::Result::OK);
684 test.AdvanceTime(TimeDelta::Millis(33));
685
686 EXPECT_NE(frame1_transport_sequence_number, frame2_transport_sequence_number);
687
688 // Inject a transport feedback where the packet for the first frame is lost,
689 // expect a retransmission for it.
690 EXPECT_CALL(test.transport(), SendRtp)
691 .WillOnce([&frame1_rtp_sequence_number](const uint8_t* packet,
692 size_t length,
693 const PacketOptions& options) {
694 RtpPacket rtp_packet;
695 EXPECT_TRUE(rtp_packet.Parse(packet, length));
696 EXPECT_EQ(rtp_packet.Ssrc(), kRtxSsrc1);
697
698 // Retransmitted sequence number from the RTX header should match
699 // the lost packet.
700 rtc::ArrayView<const uint8_t> payload = rtp_packet.payload();
701 EXPECT_EQ(ByteReader<uint16_t>::ReadBigEndian(payload.data()),
702 frame1_rtp_sequence_number);
703 return true;
704 });
705
706 StreamFeedbackObserver::StreamPacketInfo first_packet_feedback;
707 first_packet_feedback.rtp_sequence_number = frame1_rtp_sequence_number;
708 first_packet_feedback.ssrc = kSsrc1;
709 first_packet_feedback.received = false;
710 first_packet_feedback.is_retransmission = false;
711
712 StreamFeedbackObserver::StreamPacketInfo second_packet_feedback;
713 second_packet_feedback.rtp_sequence_number = frame2_rtp_sequence_number;
714 second_packet_feedback.ssrc = kSsrc2;
715 second_packet_feedback.received = true;
716 first_packet_feedback.is_retransmission = false;
717
718 test.router()->OnPacketFeedbackVector(
719 {first_packet_feedback, second_packet_feedback});
720
721 // Wait for pacer to run and send the RTX packet.
722 test.AdvanceTime(TimeDelta::Millis(33));
723 }
724
TEST(RtpVideoSenderTest,SupportsDependencyDescriptor)725 TEST(RtpVideoSenderTest, SupportsDependencyDescriptor) {
726 RtpVideoSenderTestFixture test({kSsrc1}, {}, kPayloadType, {});
727 test.SetActiveModules({true});
728
729 RtpHeaderExtensionMap extensions;
730 extensions.Register<RtpDependencyDescriptorExtension>(
731 kDependencyDescriptorExtensionId);
732 std::vector<RtpPacket> sent_packets;
733 ON_CALL(test.transport(), SendRtp)
734 .WillByDefault([&](const uint8_t* packet, size_t length,
735 const PacketOptions& options) {
736 sent_packets.emplace_back(&extensions);
737 EXPECT_TRUE(sent_packets.back().Parse(packet, length));
738 return true;
739 });
740
741 const uint8_t kPayload[1] = {'a'};
742 EncodedImage encoded_image;
743 encoded_image.SetTimestamp(1);
744 encoded_image.capture_time_ms_ = 2;
745 encoded_image.SetEncodedData(
746 EncodedImageBuffer::Create(kPayload, sizeof(kPayload)));
747
748 CodecSpecificInfo codec_specific;
749 codec_specific.codecType = VideoCodecType::kVideoCodecGeneric;
750 codec_specific.template_structure.emplace();
751 codec_specific.template_structure->num_decode_targets = 1;
752 codec_specific.template_structure->templates = {
753 FrameDependencyTemplate().T(0).Dtis("S"),
754 FrameDependencyTemplate().T(0).Dtis("S").FrameDiffs({2}),
755 FrameDependencyTemplate().T(1).Dtis("D").FrameDiffs({1}),
756 };
757
758 // Send two tiny images, mapping to single RTP packets.
759 // Send in key frame.
760 encoded_image._frameType = VideoFrameType::kVideoFrameKey;
761 codec_specific.generic_frame_info =
762 GenericFrameInfo::Builder().T(0).Dtis("S").Build();
763 codec_specific.generic_frame_info->encoder_buffers = {{0, false, true}};
764 EXPECT_EQ(test.router()->OnEncodedImage(encoded_image, &codec_specific).error,
765 EncodedImageCallback::Result::OK);
766 test.AdvanceTime(TimeDelta::Millis(33));
767 ASSERT_THAT(sent_packets, SizeIs(1));
768 EXPECT_TRUE(
769 sent_packets.back().HasExtension<RtpDependencyDescriptorExtension>());
770
771 // Send in delta frame.
772 encoded_image._frameType = VideoFrameType::kVideoFrameDelta;
773 codec_specific.template_structure = absl::nullopt;
774 codec_specific.generic_frame_info =
775 GenericFrameInfo::Builder().T(1).Dtis("D").Build();
776 codec_specific.generic_frame_info->encoder_buffers = {{0, true, false}};
777 EXPECT_EQ(test.router()->OnEncodedImage(encoded_image, &codec_specific).error,
778 EncodedImageCallback::Result::OK);
779 test.AdvanceTime(TimeDelta::Millis(33));
780 ASSERT_THAT(sent_packets, SizeIs(2));
781 EXPECT_TRUE(
782 sent_packets.back().HasExtension<RtpDependencyDescriptorExtension>());
783 }
784
TEST(RtpVideoSenderTest,SupportsDependencyDescriptorForVp8NotProvidedByEncoder)785 TEST(RtpVideoSenderTest,
786 SupportsDependencyDescriptorForVp8NotProvidedByEncoder) {
787 constexpr uint8_t kPayload[1] = {'a'};
788 RtpVideoSenderTestFixture test({kSsrc1}, {}, kPayloadType, {});
789 RtpHeaderExtensionMap extensions;
790 extensions.Register<RtpDependencyDescriptorExtension>(
791 kDependencyDescriptorExtensionId);
792 std::vector<RtpPacket> sent_packets;
793 ON_CALL(test.transport(), SendRtp)
794 .WillByDefault(
795 [&](const uint8_t* packet, size_t length, const PacketOptions&) {
796 EXPECT_TRUE(
797 sent_packets.emplace_back(&extensions).Parse(packet, length));
798 return true;
799 });
800 test.SetActiveModules({true});
801
802 EncodedImage key_frame_image;
803 key_frame_image._frameType = VideoFrameType::kVideoFrameKey;
804 key_frame_image.SetEncodedData(
805 EncodedImageBuffer::Create(kPayload, sizeof(kPayload)));
806 CodecSpecificInfo key_frame_info;
807 key_frame_info.codecType = VideoCodecType::kVideoCodecVP8;
808 ASSERT_EQ(
809 test.router()->OnEncodedImage(key_frame_image, &key_frame_info).error,
810 EncodedImageCallback::Result::OK);
811
812 EncodedImage delta_image;
813 delta_image._frameType = VideoFrameType::kVideoFrameDelta;
814 delta_image.SetEncodedData(
815 EncodedImageBuffer::Create(kPayload, sizeof(kPayload)));
816 CodecSpecificInfo delta_info;
817 delta_info.codecType = VideoCodecType::kVideoCodecVP8;
818 ASSERT_EQ(test.router()->OnEncodedImage(delta_image, &delta_info).error,
819 EncodedImageCallback::Result::OK);
820
821 test.AdvanceTime(TimeDelta::Millis(123));
822
823 DependencyDescriptor key_frame_dd;
824 DependencyDescriptor delta_dd;
825 ASSERT_THAT(sent_packets, SizeIs(2));
826 EXPECT_TRUE(sent_packets[0].GetExtension<RtpDependencyDescriptorExtension>(
827 /*structure=*/nullptr, &key_frame_dd));
828 EXPECT_TRUE(sent_packets[1].GetExtension<RtpDependencyDescriptorExtension>(
829 key_frame_dd.attached_structure.get(), &delta_dd));
830 }
831
TEST(RtpVideoSenderTest,SupportsDependencyDescriptorForVp9)832 TEST(RtpVideoSenderTest, SupportsDependencyDescriptorForVp9) {
833 RtpVideoSenderTestFixture test({kSsrc1}, {}, kPayloadType, {});
834 test.SetActiveModules({true});
835
836 RtpHeaderExtensionMap extensions;
837 extensions.Register<RtpDependencyDescriptorExtension>(
838 kDependencyDescriptorExtensionId);
839 std::vector<RtpPacket> sent_packets;
840 ON_CALL(test.transport(), SendRtp)
841 .WillByDefault([&](const uint8_t* packet, size_t length,
842 const PacketOptions& options) {
843 sent_packets.emplace_back(&extensions);
844 EXPECT_TRUE(sent_packets.back().Parse(packet, length));
845 return true;
846 });
847
848 const uint8_t kPayload[1] = {'a'};
849 EncodedImage encoded_image;
850 encoded_image.SetTimestamp(1);
851 encoded_image.capture_time_ms_ = 2;
852 encoded_image._frameType = VideoFrameType::kVideoFrameKey;
853 encoded_image.SetEncodedData(
854 EncodedImageBuffer::Create(kPayload, sizeof(kPayload)));
855
856 CodecSpecificInfo codec_specific;
857 codec_specific.codecType = VideoCodecType::kVideoCodecVP9;
858 codec_specific.template_structure.emplace();
859 codec_specific.template_structure->num_decode_targets = 2;
860 codec_specific.template_structure->templates = {
861 FrameDependencyTemplate().S(0).Dtis("SS"),
862 FrameDependencyTemplate().S(1).Dtis("-S").FrameDiffs({1}),
863 };
864
865 // Send two tiny images, each mapping to single RTP packet.
866 // Send in key frame for the base spatial layer.
867 codec_specific.generic_frame_info =
868 GenericFrameInfo::Builder().S(0).Dtis("SS").Build();
869 codec_specific.generic_frame_info->encoder_buffers = {{0, false, true}};
870 EXPECT_EQ(test.router()->OnEncodedImage(encoded_image, &codec_specific).error,
871 EncodedImageCallback::Result::OK);
872 // Send in 2nd spatial layer.
873 codec_specific.template_structure = absl::nullopt;
874 codec_specific.generic_frame_info =
875 GenericFrameInfo::Builder().S(1).Dtis("-S").Build();
876 codec_specific.generic_frame_info->encoder_buffers = {{0, true, false},
877 {1, false, true}};
878 EXPECT_EQ(test.router()->OnEncodedImage(encoded_image, &codec_specific).error,
879 EncodedImageCallback::Result::OK);
880
881 test.AdvanceTime(TimeDelta::Millis(33));
882 ASSERT_THAT(sent_packets, SizeIs(2));
883 EXPECT_TRUE(sent_packets[0].HasExtension<RtpDependencyDescriptorExtension>());
884 EXPECT_TRUE(sent_packets[1].HasExtension<RtpDependencyDescriptorExtension>());
885 }
886
TEST(RtpVideoSenderTest,SupportsDependencyDescriptorForVp9NotProvidedByEncoder)887 TEST(RtpVideoSenderTest,
888 SupportsDependencyDescriptorForVp9NotProvidedByEncoder) {
889 RtpVideoSenderTestFixture test({kSsrc1}, {}, kPayloadType, {});
890 test.SetActiveModules({true});
891
892 RtpHeaderExtensionMap extensions;
893 extensions.Register<RtpDependencyDescriptorExtension>(
894 kDependencyDescriptorExtensionId);
895 std::vector<RtpPacket> sent_packets;
896 ON_CALL(test.transport(), SendRtp)
897 .WillByDefault([&](const uint8_t* packet, size_t length,
898 const PacketOptions& options) {
899 sent_packets.emplace_back(&extensions);
900 EXPECT_TRUE(sent_packets.back().Parse(packet, length));
901 return true;
902 });
903
904 const uint8_t kPayload[1] = {'a'};
905 EncodedImage encoded_image;
906 encoded_image.SetTimestamp(1);
907 encoded_image.capture_time_ms_ = 2;
908 encoded_image._frameType = VideoFrameType::kVideoFrameKey;
909 encoded_image._encodedWidth = 320;
910 encoded_image._encodedHeight = 180;
911 encoded_image.SetEncodedData(
912 EncodedImageBuffer::Create(kPayload, sizeof(kPayload)));
913
914 CodecSpecificInfo codec_specific;
915 codec_specific.codecType = VideoCodecType::kVideoCodecVP9;
916 codec_specific.codecSpecific.VP9.num_spatial_layers = 1;
917 codec_specific.codecSpecific.VP9.temporal_idx = kNoTemporalIdx;
918 codec_specific.codecSpecific.VP9.first_frame_in_picture = true;
919 codec_specific.end_of_picture = true;
920 codec_specific.codecSpecific.VP9.inter_pic_predicted = false;
921
922 // Send two tiny images, each mapping to single RTP packet.
923 EXPECT_EQ(test.router()->OnEncodedImage(encoded_image, &codec_specific).error,
924 EncodedImageCallback::Result::OK);
925
926 // Send in 2nd picture.
927 encoded_image._frameType = VideoFrameType::kVideoFrameDelta;
928 encoded_image.SetTimestamp(3000);
929 codec_specific.codecSpecific.VP9.inter_pic_predicted = true;
930 codec_specific.codecSpecific.VP9.num_ref_pics = 1;
931 codec_specific.codecSpecific.VP9.p_diff[0] = 1;
932 EXPECT_EQ(test.router()->OnEncodedImage(encoded_image, &codec_specific).error,
933 EncodedImageCallback::Result::OK);
934
935 test.AdvanceTime(TimeDelta::Millis(33));
936 ASSERT_THAT(sent_packets, SizeIs(2));
937 EXPECT_TRUE(sent_packets[0].HasExtension<RtpDependencyDescriptorExtension>());
938 EXPECT_TRUE(sent_packets[1].HasExtension<RtpDependencyDescriptorExtension>());
939 }
940
TEST(RtpVideoSenderTest,GenerateDependecyDescriptorForGenericCodecs)941 TEST(RtpVideoSenderTest, GenerateDependecyDescriptorForGenericCodecs) {
942 test::ScopedKeyValueConfig field_trials(
943 "WebRTC-GenericCodecDependencyDescriptor/Enabled/");
944 RtpVideoSenderTestFixture test({kSsrc1}, {}, kPayloadType, {}, &field_trials);
945 test.SetActiveModules({true});
946
947 RtpHeaderExtensionMap extensions;
948 extensions.Register<RtpDependencyDescriptorExtension>(
949 kDependencyDescriptorExtensionId);
950 std::vector<RtpPacket> sent_packets;
951 ON_CALL(test.transport(), SendRtp)
952 .WillByDefault([&](const uint8_t* packet, size_t length,
953 const PacketOptions& options) {
954 sent_packets.emplace_back(&extensions);
955 EXPECT_TRUE(sent_packets.back().Parse(packet, length));
956 return true;
957 });
958
959 const uint8_t kPayload[1] = {'a'};
960 EncodedImage encoded_image;
961 encoded_image.SetTimestamp(1);
962 encoded_image.capture_time_ms_ = 2;
963 encoded_image._frameType = VideoFrameType::kVideoFrameKey;
964 encoded_image._encodedWidth = 320;
965 encoded_image._encodedHeight = 180;
966 encoded_image.SetEncodedData(
967 EncodedImageBuffer::Create(kPayload, sizeof(kPayload)));
968
969 CodecSpecificInfo codec_specific;
970 codec_specific.codecType = VideoCodecType::kVideoCodecGeneric;
971 codec_specific.end_of_picture = true;
972
973 // Send two tiny images, each mapping to single RTP packet.
974 EXPECT_EQ(test.router()->OnEncodedImage(encoded_image, &codec_specific).error,
975 EncodedImageCallback::Result::OK);
976
977 // Send in 2nd picture.
978 encoded_image._frameType = VideoFrameType::kVideoFrameDelta;
979 encoded_image.SetTimestamp(3000);
980 EXPECT_EQ(test.router()->OnEncodedImage(encoded_image, &codec_specific).error,
981 EncodedImageCallback::Result::OK);
982
983 test.AdvanceTime(TimeDelta::Millis(33));
984 ASSERT_THAT(sent_packets, SizeIs(2));
985 EXPECT_TRUE(sent_packets[0].HasExtension<RtpDependencyDescriptorExtension>());
986 EXPECT_TRUE(sent_packets[1].HasExtension<RtpDependencyDescriptorExtension>());
987 }
988
TEST(RtpVideoSenderTest,SupportsStoppingUsingDependencyDescriptor)989 TEST(RtpVideoSenderTest, SupportsStoppingUsingDependencyDescriptor) {
990 RtpVideoSenderTestFixture test({kSsrc1}, {}, kPayloadType, {});
991 test.SetActiveModules({true});
992
993 RtpHeaderExtensionMap extensions;
994 extensions.Register<RtpDependencyDescriptorExtension>(
995 kDependencyDescriptorExtensionId);
996 std::vector<RtpPacket> sent_packets;
997 ON_CALL(test.transport(), SendRtp)
998 .WillByDefault([&](const uint8_t* packet, size_t length,
999 const PacketOptions& options) {
1000 sent_packets.emplace_back(&extensions);
1001 EXPECT_TRUE(sent_packets.back().Parse(packet, length));
1002 return true;
1003 });
1004
1005 const uint8_t kPayload[1] = {'a'};
1006 EncodedImage encoded_image;
1007 encoded_image.SetTimestamp(1);
1008 encoded_image.capture_time_ms_ = 2;
1009 encoded_image.SetEncodedData(
1010 EncodedImageBuffer::Create(kPayload, sizeof(kPayload)));
1011
1012 CodecSpecificInfo codec_specific;
1013 codec_specific.codecType = VideoCodecType::kVideoCodecGeneric;
1014 codec_specific.template_structure.emplace();
1015 codec_specific.template_structure->num_decode_targets = 1;
1016 codec_specific.template_structure->templates = {
1017 FrameDependencyTemplate().T(0).Dtis("S"),
1018 FrameDependencyTemplate().T(0).Dtis("S").FrameDiffs({2}),
1019 FrameDependencyTemplate().T(1).Dtis("D").FrameDiffs({1}),
1020 };
1021
1022 // Send two tiny images, mapping to single RTP packets.
1023 // Send in a key frame.
1024 encoded_image._frameType = VideoFrameType::kVideoFrameKey;
1025 codec_specific.generic_frame_info =
1026 GenericFrameInfo::Builder().T(0).Dtis("S").Build();
1027 codec_specific.generic_frame_info->encoder_buffers = {{0, false, true}};
1028 EXPECT_EQ(test.router()->OnEncodedImage(encoded_image, &codec_specific).error,
1029 EncodedImageCallback::Result::OK);
1030 test.AdvanceTime(TimeDelta::Millis(33));
1031 ASSERT_THAT(sent_packets, SizeIs(1));
1032 EXPECT_TRUE(
1033 sent_packets.back().HasExtension<RtpDependencyDescriptorExtension>());
1034
1035 // Send in a new key frame without the support for the dependency descriptor.
1036 encoded_image._frameType = VideoFrameType::kVideoFrameKey;
1037 codec_specific.template_structure = absl::nullopt;
1038 EXPECT_EQ(test.router()->OnEncodedImage(encoded_image, &codec_specific).error,
1039 EncodedImageCallback::Result::OK);
1040 test.AdvanceTime(TimeDelta::Millis(33));
1041 ASSERT_THAT(sent_packets, SizeIs(2));
1042 EXPECT_FALSE(
1043 sent_packets.back().HasExtension<RtpDependencyDescriptorExtension>());
1044 }
1045
TEST(RtpVideoSenderTest,CanSetZeroBitrate)1046 TEST(RtpVideoSenderTest, CanSetZeroBitrate) {
1047 RtpVideoSenderTestFixture test({kSsrc1}, {kRtxSsrc1}, kPayloadType, {});
1048 test.router()->OnBitrateUpdated(CreateBitrateAllocationUpdate(0),
1049 /*framerate*/ 0);
1050 }
1051
TEST(RtpVideoSenderTest,SimulcastSenderRegistersFrameTransformers)1052 TEST(RtpVideoSenderTest, SimulcastSenderRegistersFrameTransformers) {
1053 rtc::scoped_refptr<MockFrameTransformer> transformer =
1054 rtc::make_ref_counted<MockFrameTransformer>();
1055
1056 EXPECT_CALL(*transformer, RegisterTransformedFrameSinkCallback(_, kSsrc1));
1057 EXPECT_CALL(*transformer, RegisterTransformedFrameSinkCallback(_, kSsrc2));
1058 RtpVideoSenderTestFixture test({kSsrc1, kSsrc2}, {kRtxSsrc1, kRtxSsrc2},
1059 kPayloadType, {}, nullptr, transformer);
1060
1061 EXPECT_CALL(*transformer, UnregisterTransformedFrameSinkCallback(kSsrc1));
1062 EXPECT_CALL(*transformer, UnregisterTransformedFrameSinkCallback(kSsrc2));
1063 }
1064
TEST(RtpVideoSenderTest,OverheadIsSubtractedFromTargetBitrate)1065 TEST(RtpVideoSenderTest, OverheadIsSubtractedFromTargetBitrate) {
1066 test::ScopedKeyValueConfig field_trials(
1067 "WebRTC-Video-UseFrameRateForOverhead/Enabled/");
1068
1069 // TODO(jakobi): RTP header size should not be hard coded.
1070 constexpr uint32_t kRtpHeaderSizeBytes = 20;
1071 constexpr uint32_t kTransportPacketOverheadBytes = 40;
1072 constexpr uint32_t kOverheadPerPacketBytes =
1073 kRtpHeaderSizeBytes + kTransportPacketOverheadBytes;
1074 RtpVideoSenderTestFixture test({kSsrc1}, {}, kPayloadType, {}, &field_trials);
1075 test.router()->OnTransportOverheadChanged(kTransportPacketOverheadBytes);
1076 test.SetActiveModules({true});
1077
1078 {
1079 test.router()->OnBitrateUpdated(CreateBitrateAllocationUpdate(300000),
1080 /*framerate*/ 15);
1081 // 1 packet per frame.
1082 EXPECT_EQ(test.router()->GetPayloadBitrateBps(),
1083 300000 - kOverheadPerPacketBytes * 8 * 30);
1084 }
1085 {
1086 test.router()->OnBitrateUpdated(CreateBitrateAllocationUpdate(150000),
1087 /*framerate*/ 15);
1088 // 1 packet per frame.
1089 EXPECT_EQ(test.router()->GetPayloadBitrateBps(),
1090 150000 - kOverheadPerPacketBytes * 8 * 15);
1091 }
1092 {
1093 test.router()->OnBitrateUpdated(CreateBitrateAllocationUpdate(1000000),
1094 /*framerate*/ 30);
1095 // 3 packets per frame.
1096 EXPECT_EQ(test.router()->GetPayloadBitrateBps(),
1097 1000000 - kOverheadPerPacketBytes * 8 * 30 * 3);
1098 }
1099 }
1100
1101 } // namespace webrtc
1102