blob: 4f2dca73381c21a9a2aed0fa3bf14ad1c426369b [file] [log] [blame]
johan62d02c32017-01-24 04:38:27 -08001/*
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 "webrtc/test/gtest.h"
12#include "webrtc/test/gmock.h"
13
johan62d02c32017-01-24 04:38:27 -080014#include "webrtc/common_video/h264/h264_common.h"
15#include "webrtc/media/base/mediaconstants.h"
16#include "webrtc/modules/pacing/packet_router.h"
eladalonc0d481a2017-08-02 07:39:07 -070017#include "webrtc/modules/rtp_rtcp/source/rtp_packet_received.h"
Edward Lemurc20978e2017-07-06 19:44:34 +020018#include "webrtc/modules/utility/include/process_thread.h"
Henrik Kjellandera80c16a2017-07-01 16:48:15 +020019#include "webrtc/modules/video_coding/frame_object.h"
Edward Lemurc20978e2017-07-06 19:44:34 +020020#include "webrtc/modules/video_coding/include/video_coding_defines.h"
johan62d02c32017-01-24 04:38:27 -080021#include "webrtc/modules/video_coding/packet.h"
22#include "webrtc/modules/video_coding/rtp_frame_reference_finder.h"
23#include "webrtc/modules/video_coding/timing.h"
Edward Lemurc20978e2017-07-06 19:44:34 +020024#include "webrtc/rtc_base/bytebuffer.h"
25#include "webrtc/rtc_base/logging.h"
eladalonc0d481a2017-08-02 07:39:07 -070026#include "webrtc/rtc_base/ptr_util.h"
johan62d02c32017-01-24 04:38:27 -080027#include "webrtc/system_wrappers/include/clock.h"
28#include "webrtc/system_wrappers/include/field_trial_default.h"
29#include "webrtc/test/field_trial.h"
nisseb1f2ff92017-06-09 04:01:55 -070030#include "webrtc/video/rtp_video_stream_receiver.h"
johan62d02c32017-01-24 04:38:27 -080031
32using testing::_;
33
34namespace webrtc {
35
36namespace {
37
38const char kNewJitterBufferFieldTrialEnabled[] =
39 "WebRTC-NewVideoJitterBuffer/Enabled/";
40const uint8_t kH264StartCode[] = {0x00, 0x00, 0x00, 0x01};
41
42class MockTransport : public Transport {
43 public:
44 MOCK_METHOD3(SendRtp,
45 bool(const uint8_t* packet,
46 size_t length,
47 const PacketOptions& options));
48 MOCK_METHOD2(SendRtcp, bool(const uint8_t* packet, size_t length));
49};
50
51class MockNackSender : public NackSender {
52 public:
53 MOCK_METHOD1(SendNack, void(const std::vector<uint16_t>& sequence_numbers));
54};
55
56class MockKeyFrameRequestSender : public KeyFrameRequestSender {
57 public:
58 MOCK_METHOD0(RequestKeyFrame, void());
59};
60
61class MockOnCompleteFrameCallback
62 : public video_coding::OnCompleteFrameCallback {
63 public:
64 MockOnCompleteFrameCallback() : buffer_(rtc::ByteBuffer::ORDER_NETWORK) {}
65
66 MOCK_METHOD1(DoOnCompleteFrame, void(video_coding::FrameObject* frame));
67 MOCK_METHOD1(DoOnCompleteFrameFailNullptr,
68 void(video_coding::FrameObject* frame));
69 MOCK_METHOD1(DoOnCompleteFrameFailLength,
70 void(video_coding::FrameObject* frame));
71 MOCK_METHOD1(DoOnCompleteFrameFailBitstream,
72 void(video_coding::FrameObject* frame));
73 void OnCompleteFrame(std::unique_ptr<video_coding::FrameObject> frame) {
74 if (!frame) {
75 DoOnCompleteFrameFailNullptr(nullptr);
76 return;
77 }
78 EXPECT_EQ(buffer_.Length(), frame->size());
79 if (buffer_.Length() != frame->size()) {
80 DoOnCompleteFrameFailLength(frame.get());
81 return;
82 }
83 std::vector<uint8_t> actual_data(frame->size());
84 frame->GetBitstream(actual_data.data());
85 if (memcmp(buffer_.Data(), actual_data.data(), buffer_.Length()) != 0) {
86 DoOnCompleteFrameFailBitstream(frame.get());
87 return;
88 }
89 DoOnCompleteFrame(frame.get());
90 }
91 void AppendExpectedBitstream(const uint8_t data[], size_t size_in_bytes) {
92 // TODO(Johan): Let rtc::ByteBuffer handle uint8_t* instead of char*.
93 buffer_.WriteBytes(reinterpret_cast<const char*>(data), size_in_bytes);
94 }
95 rtc::ByteBufferWriter buffer_;
96};
97
eladalonc0d481a2017-08-02 07:39:07 -070098class MockRtpPacketSink : public RtpPacketSinkInterface {
99 public:
100 MOCK_METHOD1(OnRtpPacket, void(const RtpPacketReceived&));
101};
102
103constexpr uint32_t kSsrc = 111;
104constexpr uint16_t kSequenceNumber = 222;
105std::unique_ptr<RtpPacketReceived> CreateRtpPacketReceived(
106 uint32_t ssrc = kSsrc,
107 uint16_t sequence_number = kSequenceNumber) {
108 auto packet = rtc::MakeUnique<RtpPacketReceived>();
109 packet->SetSsrc(ssrc);
110 packet->SetSequenceNumber(sequence_number);
111 return packet;
112}
113
114MATCHER_P(SamePacketAs, other, "") {
115 return arg.Ssrc() == other.Ssrc() &&
116 arg.SequenceNumber() == other.SequenceNumber();
117}
118
johan62d02c32017-01-24 04:38:27 -0800119} // namespace
120
nisseb1f2ff92017-06-09 04:01:55 -0700121class RtpVideoStreamReceiverTest : public testing::Test {
johan62d02c32017-01-24 04:38:27 -0800122 public:
nisseb1f2ff92017-06-09 04:01:55 -0700123 RtpVideoStreamReceiverTest()
johan62d02c32017-01-24 04:38:27 -0800124 : config_(CreateConfig()),
125 timing_(Clock::GetRealTimeClock()),
126 process_thread_(ProcessThread::Create("TestThread")) {}
127
128 void SetUp() {
nisseca5706d2017-09-11 02:32:16 -0700129 rtp_receive_statistics_ =
130 rtc::WrapUnique(ReceiveStatistics::Create(Clock::GetRealTimeClock()));
131 rtp_video_stream_receiver_ = rtc::MakeUnique<RtpVideoStreamReceiver>(
nisse05843312017-04-18 23:38:35 -0700132 &mock_transport_, nullptr, &packet_router_, &config_,
nisseca5706d2017-09-11 02:32:16 -0700133 rtp_receive_statistics_.get(), nullptr, process_thread_.get(),
134 &mock_nack_sender_,
philipela45102f2017-02-22 05:30:39 -0800135 &mock_key_frame_request_sender_, &mock_on_complete_frame_callback_,
nisseca5706d2017-09-11 02:32:16 -0700136 &timing_);
johan62d02c32017-01-24 04:38:27 -0800137 }
138
139 WebRtcRTPHeader GetDefaultPacket() {
140 WebRtcRTPHeader packet;
141 memset(&packet, 0, sizeof(packet));
142 packet.type.Video.codec = kRtpVideoH264;
143 return packet;
144 }
145
146 // TODO(Johan): refactor h264_sps_pps_tracker_unittests.cc to avoid duplicate
147 // code.
philipel83c97da2017-06-21 07:22:40 -0700148 void AddSps(WebRtcRTPHeader* packet,
149 uint8_t sps_id,
150 std::vector<uint8_t>* data) {
johan62d02c32017-01-24 04:38:27 -0800151 NaluInfo info;
152 info.type = H264::NaluType::kSps;
153 info.sps_id = sps_id;
154 info.pps_id = -1;
johan62d02c32017-01-24 04:38:27 -0800155 data->push_back(H264::NaluType::kSps);
156 data->push_back(sps_id);
157 packet->type.Video.codecHeader.H264
158 .nalus[packet->type.Video.codecHeader.H264.nalus_length++] = info;
159 }
160
161 void AddPps(WebRtcRTPHeader* packet,
philipel83c97da2017-06-21 07:22:40 -0700162 uint8_t sps_id,
163 uint8_t pps_id,
johan62d02c32017-01-24 04:38:27 -0800164 std::vector<uint8_t>* data) {
165 NaluInfo info;
166 info.type = H264::NaluType::kPps;
167 info.sps_id = sps_id;
168 info.pps_id = pps_id;
johan62d02c32017-01-24 04:38:27 -0800169 data->push_back(H264::NaluType::kPps);
170 data->push_back(pps_id);
171 packet->type.Video.codecHeader.H264
172 .nalus[packet->type.Video.codecHeader.H264.nalus_length++] = info;
173 }
174
175 void AddIdr(WebRtcRTPHeader* packet, int pps_id) {
176 NaluInfo info;
177 info.type = H264::NaluType::kIdr;
178 info.sps_id = -1;
179 info.pps_id = pps_id;
180 packet->type.Video.codecHeader.H264
181 .nalus[packet->type.Video.codecHeader.H264.nalus_length++] = info;
182 }
183
184 protected:
185 static VideoReceiveStream::Config CreateConfig() {
186 VideoReceiveStream::Config config(nullptr);
187 config.rtp.remote_ssrc = 1111;
188 config.rtp.local_ssrc = 2222;
189 return config;
190 }
191
192 webrtc::test::ScopedFieldTrials override_field_trials_{
193 kNewJitterBufferFieldTrialEnabled};
194 VideoReceiveStream::Config config_;
195 MockNackSender mock_nack_sender_;
196 MockKeyFrameRequestSender mock_key_frame_request_sender_;
197 MockTransport mock_transport_;
198 MockOnCompleteFrameCallback mock_on_complete_frame_callback_;
199 PacketRouter packet_router_;
200 VCMTiming timing_;
201 std::unique_ptr<ProcessThread> process_thread_;
nisseca5706d2017-09-11 02:32:16 -0700202 std::unique_ptr<ReceiveStatistics> rtp_receive_statistics_;
nisseb1f2ff92017-06-09 04:01:55 -0700203 std::unique_ptr<RtpVideoStreamReceiver> rtp_video_stream_receiver_;
johan62d02c32017-01-24 04:38:27 -0800204};
205
nisseb1f2ff92017-06-09 04:01:55 -0700206TEST_F(RtpVideoStreamReceiverTest, GenericKeyFrame) {
johan62d02c32017-01-24 04:38:27 -0800207 WebRtcRTPHeader rtp_header;
208 const std::vector<uint8_t> data({1, 2, 3, 4});
209 memset(&rtp_header, 0, sizeof(rtp_header));
210 rtp_header.header.sequenceNumber = 1;
211 rtp_header.header.markerBit = 1;
212 rtp_header.type.Video.is_first_packet_in_frame = true;
213 rtp_header.frameType = kVideoFrameKey;
214 rtp_header.type.Video.codec = kRtpVideoGeneric;
215 mock_on_complete_frame_callback_.AppendExpectedBitstream(data.data(),
216 data.size());
217 EXPECT_CALL(mock_on_complete_frame_callback_, DoOnCompleteFrame(_));
nisseb1f2ff92017-06-09 04:01:55 -0700218 rtp_video_stream_receiver_->OnReceivedPayloadData(data.data(), data.size(),
219 &rtp_header);
johan62d02c32017-01-24 04:38:27 -0800220}
221
nisseb1f2ff92017-06-09 04:01:55 -0700222TEST_F(RtpVideoStreamReceiverTest, GenericKeyFrameBitstreamError) {
johan62d02c32017-01-24 04:38:27 -0800223 WebRtcRTPHeader rtp_header;
224 const std::vector<uint8_t> data({1, 2, 3, 4});
225 memset(&rtp_header, 0, sizeof(rtp_header));
226 rtp_header.header.sequenceNumber = 1;
227 rtp_header.header.markerBit = 1;
228 rtp_header.type.Video.is_first_packet_in_frame = true;
229 rtp_header.frameType = kVideoFrameKey;
230 rtp_header.type.Video.codec = kRtpVideoGeneric;
231 constexpr uint8_t expected_bitsteam[] = {1, 2, 3, 0xff};
232 mock_on_complete_frame_callback_.AppendExpectedBitstream(
233 expected_bitsteam, sizeof(expected_bitsteam));
234 EXPECT_CALL(mock_on_complete_frame_callback_,
235 DoOnCompleteFrameFailBitstream(_));
nisseb1f2ff92017-06-09 04:01:55 -0700236 rtp_video_stream_receiver_->OnReceivedPayloadData(data.data(), data.size(),
237 &rtp_header);
johan62d02c32017-01-24 04:38:27 -0800238}
239
nisseb1f2ff92017-06-09 04:01:55 -0700240TEST_F(RtpVideoStreamReceiverTest, InBandSpsPps) {
johan62d02c32017-01-24 04:38:27 -0800241 std::vector<uint8_t> sps_data;
242 WebRtcRTPHeader sps_packet = GetDefaultPacket();
243 AddSps(&sps_packet, 0, &sps_data);
244 sps_packet.header.sequenceNumber = 0;
philipel83c97da2017-06-21 07:22:40 -0700245 sps_packet.type.Video.is_first_packet_in_frame = true;
johan62d02c32017-01-24 04:38:27 -0800246 mock_on_complete_frame_callback_.AppendExpectedBitstream(
247 kH264StartCode, sizeof(kH264StartCode));
248 mock_on_complete_frame_callback_.AppendExpectedBitstream(sps_data.data(),
249 sps_data.size());
nisseb1f2ff92017-06-09 04:01:55 -0700250 rtp_video_stream_receiver_->OnReceivedPayloadData(
251 sps_data.data(), sps_data.size(), &sps_packet);
johan62d02c32017-01-24 04:38:27 -0800252
253 std::vector<uint8_t> pps_data;
254 WebRtcRTPHeader pps_packet = GetDefaultPacket();
255 AddPps(&pps_packet, 0, 1, &pps_data);
256 pps_packet.header.sequenceNumber = 1;
philipel83c97da2017-06-21 07:22:40 -0700257 pps_packet.type.Video.is_first_packet_in_frame = true;
johan62d02c32017-01-24 04:38:27 -0800258 mock_on_complete_frame_callback_.AppendExpectedBitstream(
259 kH264StartCode, sizeof(kH264StartCode));
260 mock_on_complete_frame_callback_.AppendExpectedBitstream(pps_data.data(),
261 pps_data.size());
nisseb1f2ff92017-06-09 04:01:55 -0700262 rtp_video_stream_receiver_->OnReceivedPayloadData(
263 pps_data.data(), pps_data.size(), &pps_packet);
johan62d02c32017-01-24 04:38:27 -0800264
265 std::vector<uint8_t> idr_data;
266 WebRtcRTPHeader idr_packet = GetDefaultPacket();
267 AddIdr(&idr_packet, 1);
268 idr_packet.type.Video.is_first_packet_in_frame = true;
269 idr_packet.header.sequenceNumber = 2;
270 idr_packet.header.markerBit = 1;
johan62d02c32017-01-24 04:38:27 -0800271 idr_packet.frameType = kVideoFrameKey;
johan62d02c32017-01-24 04:38:27 -0800272 idr_data.insert(idr_data.end(), {0x65, 1, 2, 3});
273 mock_on_complete_frame_callback_.AppendExpectedBitstream(
274 kH264StartCode, sizeof(kH264StartCode));
275 mock_on_complete_frame_callback_.AppendExpectedBitstream(idr_data.data(),
276 idr_data.size());
277 EXPECT_CALL(mock_on_complete_frame_callback_, DoOnCompleteFrame(_));
nisseb1f2ff92017-06-09 04:01:55 -0700278 rtp_video_stream_receiver_->OnReceivedPayloadData(
279 idr_data.data(), idr_data.size(), &idr_packet);
johan62d02c32017-01-24 04:38:27 -0800280}
281
nisseb1f2ff92017-06-09 04:01:55 -0700282TEST_F(RtpVideoStreamReceiverTest, OutOfBandFmtpSpsPps) {
johan62d02c32017-01-24 04:38:27 -0800283 constexpr int kPayloadType = 99;
284 VideoCodec codec;
285 codec.plType = kPayloadType;
286 std::map<std::string, std::string> codec_params;
287 // Example parameter sets from https://tools.ietf.org/html/rfc3984#section-8.2
288 // .
289 codec_params.insert(
290 {cricket::kH264FmtpSpropParameterSets, "Z0IACpZTBYmI,aMljiA=="});
nisseb1f2ff92017-06-09 04:01:55 -0700291 rtp_video_stream_receiver_->AddReceiveCodec(codec, codec_params);
johan62d02c32017-01-24 04:38:27 -0800292 const uint8_t binary_sps[] = {0x67, 0x42, 0x00, 0x0a, 0x96,
293 0x53, 0x05, 0x89, 0x88};
294 mock_on_complete_frame_callback_.AppendExpectedBitstream(
295 kH264StartCode, sizeof(kH264StartCode));
296 mock_on_complete_frame_callback_.AppendExpectedBitstream(binary_sps,
297 sizeof(binary_sps));
298 const uint8_t binary_pps[] = {0x68, 0xc9, 0x63, 0x88};
299 mock_on_complete_frame_callback_.AppendExpectedBitstream(
300 kH264StartCode, sizeof(kH264StartCode));
301 mock_on_complete_frame_callback_.AppendExpectedBitstream(binary_pps,
302 sizeof(binary_pps));
303
304 std::vector<uint8_t> data;
305 WebRtcRTPHeader idr_packet = GetDefaultPacket();
306 AddIdr(&idr_packet, 0);
307 idr_packet.header.payloadType = kPayloadType;
308 idr_packet.type.Video.is_first_packet_in_frame = true;
309 idr_packet.header.sequenceNumber = 2;
310 idr_packet.header.markerBit = 1;
311 idr_packet.type.Video.is_first_packet_in_frame = true;
312 idr_packet.frameType = kVideoFrameKey;
313 idr_packet.type.Video.codec = kRtpVideoH264;
314 data.insert(data.end(), {1, 2, 3});
315 mock_on_complete_frame_callback_.AppendExpectedBitstream(
316 kH264StartCode, sizeof(kH264StartCode));
317 mock_on_complete_frame_callback_.AppendExpectedBitstream(data.data(),
318 data.size());
319 EXPECT_CALL(mock_on_complete_frame_callback_, DoOnCompleteFrame(_));
nisseb1f2ff92017-06-09 04:01:55 -0700320 rtp_video_stream_receiver_->OnReceivedPayloadData(data.data(), data.size(),
321 &idr_packet);
johan62d02c32017-01-24 04:38:27 -0800322}
323
nisseb1f2ff92017-06-09 04:01:55 -0700324TEST_F(RtpVideoStreamReceiverTest, PaddingInMediaStream) {
philipel54ca9192017-03-21 05:45:18 -0700325 WebRtcRTPHeader header = GetDefaultPacket();
326 std::vector<uint8_t> data;
327 data.insert(data.end(), {1, 2, 3});
328 header.header.payloadType = 99;
329 header.type.Video.is_first_packet_in_frame = true;
330 header.header.sequenceNumber = 2;
331 header.header.markerBit = true;
332 header.frameType = kVideoFrameKey;
333 header.type.Video.codec = kRtpVideoGeneric;
334 mock_on_complete_frame_callback_.AppendExpectedBitstream(data.data(),
335 data.size());
336
337 EXPECT_CALL(mock_on_complete_frame_callback_, DoOnCompleteFrame(_));
nisseb1f2ff92017-06-09 04:01:55 -0700338 rtp_video_stream_receiver_->OnReceivedPayloadData(data.data(), data.size(),
339 &header);
philipel54ca9192017-03-21 05:45:18 -0700340
341 header.header.sequenceNumber = 3;
nisseb1f2ff92017-06-09 04:01:55 -0700342 rtp_video_stream_receiver_->OnReceivedPayloadData(nullptr, 0, &header);
philipel54ca9192017-03-21 05:45:18 -0700343
344 header.frameType = kVideoFrameDelta;
345 header.header.sequenceNumber = 4;
346 EXPECT_CALL(mock_on_complete_frame_callback_, DoOnCompleteFrame(_));
nisseb1f2ff92017-06-09 04:01:55 -0700347 rtp_video_stream_receiver_->OnReceivedPayloadData(data.data(), data.size(),
348 &header);
philipel54ca9192017-03-21 05:45:18 -0700349
350 header.header.sequenceNumber = 6;
nisseb1f2ff92017-06-09 04:01:55 -0700351 rtp_video_stream_receiver_->OnReceivedPayloadData(data.data(), data.size(),
352 &header);
philipel54ca9192017-03-21 05:45:18 -0700353
354 EXPECT_CALL(mock_on_complete_frame_callback_, DoOnCompleteFrame(_));
355 header.header.sequenceNumber = 5;
nisseb1f2ff92017-06-09 04:01:55 -0700356 rtp_video_stream_receiver_->OnReceivedPayloadData(nullptr, 0, &header);
philipel54ca9192017-03-21 05:45:18 -0700357}
358
nisseb1f2ff92017-06-09 04:01:55 -0700359TEST_F(RtpVideoStreamReceiverTest, RequestKeyframeIfFirstFrameIsDelta) {
philipel2c53b132017-05-16 08:06:30 -0700360 WebRtcRTPHeader rtp_header;
361 const std::vector<uint8_t> data({1, 2, 3, 4});
362 memset(&rtp_header, 0, sizeof(rtp_header));
363 rtp_header.header.sequenceNumber = 1;
364 rtp_header.header.markerBit = 1;
365 rtp_header.type.Video.is_first_packet_in_frame = true;
366 rtp_header.frameType = kVideoFrameDelta;
367 rtp_header.type.Video.codec = kRtpVideoGeneric;
368
369 EXPECT_CALL(mock_key_frame_request_sender_, RequestKeyFrame());
nisseb1f2ff92017-06-09 04:01:55 -0700370 rtp_video_stream_receiver_->OnReceivedPayloadData(data.data(), data.size(),
371 &rtp_header);
philipel2c53b132017-05-16 08:06:30 -0700372}
373
eladalonc0d481a2017-08-02 07:39:07 -0700374TEST_F(RtpVideoStreamReceiverTest, SecondarySinksGetRtpNotifications) {
375 rtp_video_stream_receiver_->StartReceive();
376
377 MockRtpPacketSink secondary_sink_1;
378 MockRtpPacketSink secondary_sink_2;
379
380 rtp_video_stream_receiver_->AddSecondarySink(&secondary_sink_1);
381 rtp_video_stream_receiver_->AddSecondarySink(&secondary_sink_2);
382
383 auto rtp_packet = CreateRtpPacketReceived();
384 EXPECT_CALL(secondary_sink_1, OnRtpPacket(SamePacketAs(*rtp_packet)));
385 EXPECT_CALL(secondary_sink_2, OnRtpPacket(SamePacketAs(*rtp_packet)));
386
387 rtp_video_stream_receiver_->OnRtpPacket(*rtp_packet);
388
389 // Test tear-down.
390 rtp_video_stream_receiver_->StopReceive();
391 rtp_video_stream_receiver_->RemoveSecondarySink(&secondary_sink_1);
392 rtp_video_stream_receiver_->RemoveSecondarySink(&secondary_sink_2);
393}
394
395TEST_F(RtpVideoStreamReceiverTest, RemovedSecondarySinksGetNoRtpNotifications) {
396 rtp_video_stream_receiver_->StartReceive();
397
398 MockRtpPacketSink secondary_sink;
399
400 rtp_video_stream_receiver_->AddSecondarySink(&secondary_sink);
401 rtp_video_stream_receiver_->RemoveSecondarySink(&secondary_sink);
402
403 auto rtp_packet = CreateRtpPacketReceived();
404
405 EXPECT_CALL(secondary_sink, OnRtpPacket(_)).Times(0);
406
407 rtp_video_stream_receiver_->OnRtpPacket(*rtp_packet);
408
409 // Test tear-down.
410 rtp_video_stream_receiver_->StopReceive();
411}
412
413TEST_F(RtpVideoStreamReceiverTest,
414 OnlyRemovedSecondarySinksExcludedFromNotifications) {
415 rtp_video_stream_receiver_->StartReceive();
416
417 MockRtpPacketSink kept_secondary_sink;
418 MockRtpPacketSink removed_secondary_sink;
419
420 rtp_video_stream_receiver_->AddSecondarySink(&kept_secondary_sink);
421 rtp_video_stream_receiver_->AddSecondarySink(&removed_secondary_sink);
422 rtp_video_stream_receiver_->RemoveSecondarySink(&removed_secondary_sink);
423
424 auto rtp_packet = CreateRtpPacketReceived();
425 EXPECT_CALL(kept_secondary_sink, OnRtpPacket(SamePacketAs(*rtp_packet)));
426
427 rtp_video_stream_receiver_->OnRtpPacket(*rtp_packet);
428
429 // Test tear-down.
430 rtp_video_stream_receiver_->StopReceive();
431 rtp_video_stream_receiver_->RemoveSecondarySink(&kept_secondary_sink);
432}
433
434TEST_F(RtpVideoStreamReceiverTest,
435 SecondariesOfNonStartedStreamGetNoNotifications) {
436 // Explicitly showing that the stream is not in the |started| state,
437 // regardless of whether streams start out |started| or |stopped|.
438 rtp_video_stream_receiver_->StopReceive();
439
440 MockRtpPacketSink secondary_sink;
441 rtp_video_stream_receiver_->AddSecondarySink(&secondary_sink);
442
443 auto rtp_packet = CreateRtpPacketReceived();
444 EXPECT_CALL(secondary_sink, OnRtpPacket(_)).Times(0);
445
446 rtp_video_stream_receiver_->OnRtpPacket(*rtp_packet);
447
448 // Test tear-down.
449 rtp_video_stream_receiver_->RemoveSecondarySink(&secondary_sink);
450}
451
452#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
453TEST_F(RtpVideoStreamReceiverTest, RepeatedSecondarySinkDisallowed) {
454 MockRtpPacketSink secondary_sink;
455
456 rtp_video_stream_receiver_->AddSecondarySink(&secondary_sink);
457 EXPECT_DEATH(rtp_video_stream_receiver_->AddSecondarySink(&secondary_sink),
458 "");
459
460 // Test tear-down.
461 rtp_video_stream_receiver_->RemoveSecondarySink(&secondary_sink);
462}
463#endif
464
johan62d02c32017-01-24 04:38:27 -0800465} // namespace webrtc