blob: 0b190543e174d6df397b5f5b30d9072c908edac5 [file] [log] [blame]
jlmiller@webrtc.org5f93d0a2015-01-20 21:36:13 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
jlmiller@webrtc.org5f93d0a2015-01-20 21:36:13 +00003 *
kjellander1afca732016-02-07 20:46:45 -08004 * 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.
jlmiller@webrtc.org5f93d0a2015-01-20 21:36:13 +00009 */
henrike@webrtc.org28e20752013-07-10 00:45:36 +000010
kjellandera96e2d72016-02-04 23:52:28 -080011#ifndef WEBRTC_MEDIA_BASE_VIDEOENGINE_UNITTEST_H_ // NOLINT
12#define WEBRTC_MEDIA_BASE_VIDEOENGINE_UNITTEST_H_
henrike@webrtc.org28e20752013-07-10 00:45:36 +000013
14#include <string>
15#include <vector>
16
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000017#include "webrtc/base/bytebuffer.h"
18#include "webrtc/base/gunit.h"
19#include "webrtc/base/timeutils.h"
Fredrik Solenberg709ed672015-09-15 12:26:33 +020020#include "webrtc/call.h"
kjellandera96e2d72016-02-04 23:52:28 -080021#include "webrtc/media/base/fakenetworkinterface.h"
22#include "webrtc/media/base/fakevideocapturer.h"
23#include "webrtc/media/base/fakevideorenderer.h"
24#include "webrtc/media/base/mediachannel.h"
25#include "webrtc/media/base/streamparams.h"
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010026#include "webrtc/media/engine/fakewebrtccall.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000027
henrike@webrtc.org28e20752013-07-10 00:45:36 +000028#define EXPECT_FRAME_WAIT(c, w, h, t) \
29 EXPECT_EQ_WAIT((c), renderer_.num_rendered_frames(), (t)); \
30 EXPECT_EQ((w), renderer_.width()); \
31 EXPECT_EQ((h), renderer_.height()); \
32 EXPECT_EQ(0, renderer_.errors()); \
33
34#define EXPECT_FRAME_ON_RENDERER_WAIT(r, c, w, h, t) \
35 EXPECT_EQ_WAIT((c), (r).num_rendered_frames(), (t)); \
36 EXPECT_EQ((w), (r).width()); \
37 EXPECT_EQ((h), (r).height()); \
38 EXPECT_EQ(0, (r).errors()); \
39
wu@webrtc.org9caf2762013-12-11 18:25:07 +000040#define EXPECT_GT_FRAME_ON_RENDERER_WAIT(r, c, w, h, t) \
41 EXPECT_TRUE_WAIT((r).num_rendered_frames() >= (c) && \
42 (w) == (r).width() && \
43 (h) == (r).height(), (t)); \
Peter Boström0c4e06b2015-10-07 12:23:21 +020044 EXPECT_EQ(0, (r).errors());
wu@webrtc.org9caf2762013-12-11 18:25:07 +000045
Peter Boström0c4e06b2015-10-07 12:23:21 +020046static const uint32_t kTimeout = 5000U;
47static const uint32_t kDefaultReceiveSsrc = 0;
48static const uint32_t kSsrc = 1234u;
49static const uint32_t kRtxSsrc = 4321u;
50static const uint32_t kSsrcs4[] = {1, 2, 3, 4};
henrike@webrtc.org28e20752013-07-10 00:45:36 +000051
52inline bool IsEqualRes(const cricket::VideoCodec& a, int w, int h, int fps) {
53 return a.width == w && a.height == h && a.framerate == fps;
54}
55
56inline bool IsEqualCodec(const cricket::VideoCodec& a,
57 const cricket::VideoCodec& b) {
58 return a.id == b.id && a.name == b.name &&
59 IsEqualRes(a, b.width, b.height, b.framerate);
60}
61
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +000062namespace std {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000063inline std::ostream& operator<<(std::ostream& s, const cricket::VideoCodec& c) {
64 s << "{" << c.name << "(" << c.id << "), "
65 << c.width << "x" << c.height << "x" << c.framerate << "}";
66 return s;
67}
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +000068} // namespace std
henrike@webrtc.org28e20752013-07-10 00:45:36 +000069
70inline int TimeBetweenSend(const cricket::VideoCodec& codec) {
henrike@webrtc.org28654cb2013-07-22 21:07:49 +000071 return static_cast<int>(
henrike@webrtc.org28e20752013-07-10 00:45:36 +000072 cricket::VideoFormat::FpsToInterval(codec.framerate) /
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000073 rtc::kNumNanosecsPerMillisec);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000074}
75
76// Fake video engine that makes it possible to test enabling and disabling
77// capturer (checking that the engine state is updated and that the capturer
78// is indeed capturing) without having to create a channel. It also makes it
79// possible to test that the media processors are indeed being called when
80// registered.
81template<class T>
82class VideoEngineOverride : public T {
83 public:
Fredrik Solenberg709ed672015-09-15 12:26:33 +020084 VideoEngineOverride() : T() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000085 }
86 virtual ~VideoEngineOverride() {
87 }
88 bool is_camera_on() const { return T::GetVideoCapturer()->IsRunning(); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +000089
Peter Boström0c4e06b2015-10-07 12:23:21 +020090 void TriggerMediaFrame(uint32_t ssrc,
91 cricket::VideoFrame* frame,
92 bool* drop_frame) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000093 T::SignalMediaFrame(ssrc, frame, drop_frame);
94 }
95};
96
henrike@webrtc.org28e20752013-07-10 00:45:36 +000097template<class E, class C>
98class VideoMediaChannelTest : public testing::Test,
99 public sigslot::has_slots<> {
100 protected:
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200101 VideoMediaChannelTest<E, C>()
102 : call_(webrtc::Call::Create(webrtc::Call::Config())) {}
103
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000104 virtual cricket::VideoCodec DefaultCodec() = 0;
105
106 virtual cricket::StreamParams DefaultSendStreamParams() {
107 return cricket::StreamParams::CreateLegacy(kSsrc);
108 }
109
110 virtual void SetUp() {
111 cricket::Device device("test", "device");
Fredrik Solenberg9a416bd2015-05-22 09:04:09 +0200112 engine_.Init();
nisse51542be2016-02-12 02:27:06 -0800113 channel_.reset(engine_.CreateChannel(call_.get(), cricket::MediaConfig(),
114 cricket::VideoOptions()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000115 EXPECT_TRUE(channel_.get() != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000116 network_interface_.SetDestination(channel_.get());
117 channel_->SetInterface(&network_interface_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000118 media_error_ = cricket::VideoMediaChannel::ERROR_NONE;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200119 cricket::VideoRecvParameters parameters;
120 parameters.codecs = engine_.codecs();
121 channel_->SetRecvParameters(parameters);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000122 EXPECT_TRUE(channel_->AddSendStream(DefaultSendStreamParams()));
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000123 video_capturer_.reset(CreateFakeVideoCapturer());
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000124 cricket::VideoFormat format(640, 480,
125 cricket::VideoFormat::FpsToInterval(30),
126 cricket::FOURCC_I420);
127 EXPECT_EQ(cricket::CS_RUNNING, video_capturer_->Start(format));
128 EXPECT_TRUE(channel_->SetCapturer(kSsrc, video_capturer_.get()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000129 }
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000130
131 virtual cricket::FakeVideoCapturer* CreateFakeVideoCapturer() {
132 return new cricket::FakeVideoCapturer();
133 }
134
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000135 // Utility method to setup an additional stream to send and receive video.
136 // Used to test send and recv between two streams.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000137 void SetUpSecondStream() {
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000138 SetUpSecondStreamWithNoRecv();
139 // Setup recv for second stream.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000140 EXPECT_TRUE(channel_->AddRecvStream(
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000141 cricket::StreamParams::CreateLegacy(kSsrc + 2)));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000142 // Make the second renderer available for use by a new stream.
nisse08582ff2016-02-04 01:24:52 -0800143 EXPECT_TRUE(channel_->SetSink(kSsrc + 2, &renderer2_));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000144 }
145 // Setup an additional stream just to send video. Defer add recv stream.
146 // This is required if you want to test unsignalled recv of video rtp packets.
147 void SetUpSecondStreamWithNoRecv() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000148 // SetUp() already added kSsrc make sure duplicate SSRCs cant be added.
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000149 EXPECT_TRUE(channel_->AddRecvStream(
150 cricket::StreamParams::CreateLegacy(kSsrc)));
nisse08582ff2016-02-04 01:24:52 -0800151 EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000152 EXPECT_FALSE(channel_->AddSendStream(
153 cricket::StreamParams::CreateLegacy(kSsrc)));
154 EXPECT_TRUE(channel_->AddSendStream(
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000155 cricket::StreamParams::CreateLegacy(kSsrc + 2)));
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000156 // We dont add recv for the second stream.
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000157
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000158 // Setup the receive and renderer for second stream after send.
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000159 video_capturer_2_.reset(CreateFakeVideoCapturer());
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000160 cricket::VideoFormat format(640, 480,
161 cricket::VideoFormat::FpsToInterval(30),
162 cricket::FOURCC_I420);
163 EXPECT_EQ(cricket::CS_RUNNING, video_capturer_2_->Start(format));
164
165 EXPECT_TRUE(channel_->SetCapturer(kSsrc + 2, video_capturer_2_.get()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000166 }
167 virtual void TearDown() {
168 channel_.reset();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000169 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000170 bool SetDefaultCodec() {
171 return SetOneCodec(DefaultCodec());
172 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000173
174 bool SetOneCodec(int pt, const char* name, int w, int h, int fr) {
175 return SetOneCodec(cricket::VideoCodec(pt, name, w, h, fr, 0));
176 }
177 bool SetOneCodec(const cricket::VideoCodec& codec) {
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000178 cricket::VideoFormat capture_format(codec.width, codec.height,
179 cricket::VideoFormat::FpsToInterval(codec.framerate),
180 cricket::FOURCC_I420);
181
182 if (video_capturer_) {
183 EXPECT_EQ(cricket::CS_RUNNING, video_capturer_->Start(capture_format));
184 }
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000185 if (video_capturer_2_) {
186 EXPECT_EQ(cricket::CS_RUNNING, video_capturer_2_->Start(capture_format));
187 }
188
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000189 bool sending = channel_->sending();
190 bool success = SetSend(false);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200191 if (success) {
192 cricket::VideoSendParameters parameters;
193 parameters.codecs.push_back(codec);
194 success = channel_->SetSendParameters(parameters);
195 }
196 if (success) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000197 success = SetSend(sending);
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200198 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000199 return success;
200 }
201 bool SetSend(bool send) {
202 return channel_->SetSend(send);
203 }
204 int DrainOutgoingPackets() {
205 int packets = 0;
206 do {
207 packets = NumRtpPackets();
208 // 100 ms should be long enough.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000209 rtc::Thread::Current()->ProcessMessages(100);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000210 } while (NumRtpPackets() > packets);
211 return NumRtpPackets();
212 }
213 bool SendFrame() {
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000214 if (video_capturer_2_) {
215 video_capturer_2_->CaptureFrame();
216 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000217 return video_capturer_.get() &&
218 video_capturer_->CaptureFrame();
219 }
220 bool WaitAndSendFrame(int wait_ms) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000221 bool ret = rtc::Thread::Current()->ProcessMessages(wait_ms);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000222 ret &= SendFrame();
223 return ret;
224 }
225 // Sends frames and waits for the decoder to be fully initialized.
226 // Returns the number of frames that were sent.
227 int WaitForDecoder() {
228#if defined(HAVE_OPENMAX)
229 // Send enough frames for the OpenMAX decoder to continue processing, and
230 // return the number of frames sent.
231 // Send frames for a full kTimeout's worth of 15fps video.
232 int frame_count = 0;
233 while (frame_count < static_cast<int>(kTimeout) / 66) {
234 EXPECT_TRUE(WaitAndSendFrame(66));
235 ++frame_count;
236 }
237 return frame_count;
238#else
239 return 0;
240#endif
241 }
242 bool SendCustomVideoFrame(int w, int h) {
243 if (!video_capturer_.get()) return false;
244 return video_capturer_->CaptureCustomFrame(w, h, cricket::FOURCC_I420);
245 }
246 int NumRtpBytes() {
247 return network_interface_.NumRtpBytes();
248 }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200249 int NumRtpBytes(uint32_t ssrc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000250 return network_interface_.NumRtpBytes(ssrc);
251 }
252 int NumRtpPackets() {
253 return network_interface_.NumRtpPackets();
254 }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200255 int NumRtpPackets(uint32_t ssrc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000256 return network_interface_.NumRtpPackets(ssrc);
257 }
258 int NumSentSsrcs() {
259 return network_interface_.NumSentSsrcs();
260 }
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000261 const rtc::Buffer* GetRtpPacket(int index) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000262 return network_interface_.GetRtpPacket(index);
263 }
264 int NumRtcpPackets() {
265 return network_interface_.NumRtcpPackets();
266 }
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000267 const rtc::Buffer* GetRtcpPacket(int index) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000268 return network_interface_.GetRtcpPacket(index);
269 }
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000270 static int GetPayloadType(const rtc::Buffer* p) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000271 int pt = -1;
272 ParseRtpPacket(p, NULL, &pt, NULL, NULL, NULL, NULL);
273 return pt;
274 }
Peter Boström0c4e06b2015-10-07 12:23:21 +0200275 static bool ParseRtpPacket(const rtc::Buffer* p,
276 bool* x,
277 int* pt,
278 int* seqnum,
279 uint32_t* tstamp,
280 uint32_t* ssrc,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000281 std::string* payload) {
Karl Wiberg94784372015-04-20 14:03:07 +0200282 rtc::ByteBuffer buf(*p);
Peter Boström0c4e06b2015-10-07 12:23:21 +0200283 uint8_t u08 = 0;
284 uint16_t u16 = 0;
285 uint32_t u32 = 0;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000286
287 // Read X and CC fields.
288 if (!buf.ReadUInt8(&u08)) return false;
289 bool extension = ((u08 & 0x10) != 0);
Peter Boström0c4e06b2015-10-07 12:23:21 +0200290 uint8_t cc = (u08 & 0x0F);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000291 if (x) *x = extension;
292
293 // Read PT field.
294 if (!buf.ReadUInt8(&u08)) return false;
295 if (pt) *pt = (u08 & 0x7F);
296
297 // Read Sequence Number field.
298 if (!buf.ReadUInt16(&u16)) return false;
299 if (seqnum) *seqnum = u16;
300
301 // Read Timestamp field.
302 if (!buf.ReadUInt32(&u32)) return false;
303 if (tstamp) *tstamp = u32;
304
305 // Read SSRC field.
306 if (!buf.ReadUInt32(&u32)) return false;
307 if (ssrc) *ssrc = u32;
308
309 // Skip CSRCs.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200310 for (uint8_t i = 0; i < cc; ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000311 if (!buf.ReadUInt32(&u32)) return false;
312 }
313
314 // Skip extension header.
315 if (extension) {
316 // Read Profile-specific extension header ID
317 if (!buf.ReadUInt16(&u16)) return false;
318
319 // Read Extension header length
320 if (!buf.ReadUInt16(&u16)) return false;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200321 uint16_t ext_header_len = u16;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000322
323 // Read Extension header
Peter Boström0c4e06b2015-10-07 12:23:21 +0200324 for (uint16_t i = 0; i < ext_header_len; ++i) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000325 if (!buf.ReadUInt32(&u32)) return false;
326 }
327 }
328
329 if (payload) {
330 return buf.ReadString(payload, buf.Length());
331 }
332 return true;
333 }
334
335 // Parse all RTCP packet, from start_index to stop_index, and count how many
336 // FIR (PT=206 and FMT=4 according to RFC 5104). If successful, set the count
337 // and return true.
338 bool CountRtcpFir(int start_index, int stop_index, int* fir_count) {
339 int count = 0;
340 for (int i = start_index; i < stop_index; ++i) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000341 rtc::scoped_ptr<const rtc::Buffer> p(GetRtcpPacket(i));
Karl Wiberg94784372015-04-20 14:03:07 +0200342 rtc::ByteBuffer buf(*p);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000343 size_t total_len = 0;
344 // The packet may be a compound RTCP packet.
kwiberg@webrtc.orgeebcab52015-03-24 09:19:06 +0000345 while (total_len < p->size()) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000346 // Read FMT, type and length.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200347 uint8_t fmt = 0;
348 uint8_t type = 0;
349 uint16_t length = 0;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000350 if (!buf.ReadUInt8(&fmt)) return false;
351 fmt &= 0x1F;
352 if (!buf.ReadUInt8(&type)) return false;
353 if (!buf.ReadUInt16(&length)) return false;
354 buf.Consume(length * 4); // Skip RTCP data.
355 total_len += (length + 1) * 4;
356 if ((192 == type) || ((206 == type) && (4 == fmt))) {
357 ++count;
358 }
359 }
360 }
361
362 if (fir_count) {
363 *fir_count = count;
364 }
365 return true;
366 }
367
Peter Boström0c4e06b2015-10-07 12:23:21 +0200368 void OnVideoChannelError(uint32_t ssrc,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000369 cricket::VideoMediaChannel::Error error) {
370 media_error_ = error;
371 }
372
373 // Test that SetSend works.
374 void SetSend() {
375 EXPECT_FALSE(channel_->sending());
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000376 EXPECT_TRUE(channel_->SetCapturer(kSsrc, video_capturer_.get()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000377 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
378 EXPECT_FALSE(channel_->sending());
379 EXPECT_TRUE(SetSend(true));
380 EXPECT_TRUE(channel_->sending());
381 EXPECT_TRUE(SendFrame());
382 EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
383 EXPECT_TRUE(SetSend(false));
384 EXPECT_FALSE(channel_->sending());
385 }
386 // Test that SetSend fails without codecs being set.
387 void SetSendWithoutCodecs() {
388 EXPECT_FALSE(channel_->sending());
389 EXPECT_FALSE(SetSend(true));
390 EXPECT_FALSE(channel_->sending());
391 }
392 // Test that we properly set the send and recv buffer sizes by the time
393 // SetSend is called.
394 void SetSendSetsTransportBufferSizes() {
395 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
396 EXPECT_TRUE(SetSend(true));
buildbot@webrtc.orgae694ef2014-10-28 17:37:17 +0000397 EXPECT_EQ(64 * 1024, network_interface_.sendbuf_size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000398 EXPECT_EQ(64 * 1024, network_interface_.recvbuf_size());
399 }
400 // Tests that we can send frames and the right payload type is used.
401 void Send(const cricket::VideoCodec& codec) {
402 EXPECT_TRUE(SetOneCodec(codec));
403 EXPECT_TRUE(SetSend(true));
404 EXPECT_TRUE(SendFrame());
405 EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000406 rtc::scoped_ptr<const rtc::Buffer> p(GetRtpPacket(0));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000407 EXPECT_EQ(codec.id, GetPayloadType(p.get()));
408 }
409 // Tests that we can send and receive frames.
410 void SendAndReceive(const cricket::VideoCodec& codec) {
411 EXPECT_TRUE(SetOneCodec(codec));
412 EXPECT_TRUE(SetSend(true));
nisse08582ff2016-02-04 01:24:52 -0800413 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000414 EXPECT_EQ(0, renderer_.num_rendered_frames());
415 EXPECT_TRUE(SendFrame());
416 EXPECT_FRAME_WAIT(1, codec.width, codec.height, kTimeout);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000417 rtc::scoped_ptr<const rtc::Buffer> p(GetRtpPacket(0));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000418 EXPECT_EQ(codec.id, GetPayloadType(p.get()));
419 }
buildbot@webrtc.org3eb2c2f2014-06-10 09:39:06 +0000420 void SendReceiveManyAndGetStats(const cricket::VideoCodec& codec,
421 int duration_sec, int fps) {
422 EXPECT_TRUE(SetOneCodec(codec));
423 EXPECT_TRUE(SetSend(true));
nisse08582ff2016-02-04 01:24:52 -0800424 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
buildbot@webrtc.org3eb2c2f2014-06-10 09:39:06 +0000425 EXPECT_EQ(0, renderer_.num_rendered_frames());
426 for (int i = 0; i < duration_sec; ++i) {
427 for (int frame = 1; frame <= fps; ++frame) {
428 EXPECT_TRUE(WaitAndSendFrame(1000 / fps));
429 EXPECT_FRAME_WAIT(frame + i * fps, codec.width, codec.height, kTimeout);
430 }
buildbot@webrtc.org3eb2c2f2014-06-10 09:39:06 +0000431 }
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000432 rtc::scoped_ptr<const rtc::Buffer> p(GetRtpPacket(0));
buildbot@webrtc.org3eb2c2f2014-06-10 09:39:06 +0000433 EXPECT_EQ(codec.id, GetPayloadType(p.get()));
434 }
435
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000436 // Test that stats work properly for a 1-1 call.
437 void GetStats() {
buildbot@webrtc.org3eb2c2f2014-06-10 09:39:06 +0000438 const int kDurationSec = 3;
439 const int kFps = 10;
440 SendReceiveManyAndGetStats(DefaultCodec(), kDurationSec, kFps);
441
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000442 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +0000443 EXPECT_TRUE(channel_->GetStats(&info));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000444
445 ASSERT_EQ(1U, info.senders.size());
446 // TODO(whyuan): bytes_sent and bytes_rcvd are different. Are both payload?
buildbot@webrtc.org3eb2c2f2014-06-10 09:39:06 +0000447 // For webrtc, bytes_sent does not include the RTP header length.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000448 EXPECT_GT(info.senders[0].bytes_sent, 0);
449 EXPECT_EQ(NumRtpPackets(), info.senders[0].packets_sent);
450 EXPECT_EQ(0.0, info.senders[0].fraction_lost);
451 EXPECT_EQ(0, info.senders[0].firs_rcvd);
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000452 EXPECT_EQ(0, info.senders[0].plis_rcvd);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000453 EXPECT_EQ(0, info.senders[0].nacks_rcvd);
wu@webrtc.org987f2c92014-03-28 16:22:19 +0000454 EXPECT_EQ(DefaultCodec().width, info.senders[0].send_frame_width);
455 EXPECT_EQ(DefaultCodec().height, info.senders[0].send_frame_height);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000456 EXPECT_GT(info.senders[0].framerate_input, 0);
457 EXPECT_GT(info.senders[0].framerate_sent, 0);
458
459 ASSERT_EQ(1U, info.receivers.size());
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +0000460 EXPECT_EQ(1U, info.senders[0].ssrcs().size());
461 EXPECT_EQ(1U, info.receivers[0].ssrcs().size());
462 EXPECT_EQ(info.senders[0].ssrcs()[0], info.receivers[0].ssrcs()[0]);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000463 EXPECT_EQ(NumRtpBytes(), info.receivers[0].bytes_rcvd);
464 EXPECT_EQ(NumRtpPackets(), info.receivers[0].packets_rcvd);
465 EXPECT_EQ(0.0, info.receivers[0].fraction_lost);
466 EXPECT_EQ(0, info.receivers[0].packets_lost);
buildbot@webrtc.org3eb2c2f2014-06-10 09:39:06 +0000467 // TODO(asapersson): Not set for webrtc. Handle missing stats.
468 // EXPECT_EQ(0, info.receivers[0].packets_concealed);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000469 EXPECT_EQ(0, info.receivers[0].firs_sent);
henrike@webrtc.org704bf9e2014-02-27 17:52:04 +0000470 EXPECT_EQ(0, info.receivers[0].plis_sent);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000471 EXPECT_EQ(0, info.receivers[0].nacks_sent);
472 EXPECT_EQ(DefaultCodec().width, info.receivers[0].frame_width);
473 EXPECT_EQ(DefaultCodec().height, info.receivers[0].frame_height);
474 EXPECT_GT(info.receivers[0].framerate_rcvd, 0);
475 EXPECT_GT(info.receivers[0].framerate_decoded, 0);
476 EXPECT_GT(info.receivers[0].framerate_output, 0);
477 }
Stefan Holmer586b19b2015-09-18 11:14:31 +0200478
479 cricket::VideoSenderInfo GetSenderStats(size_t i) {
480 cricket::VideoMediaInfo info;
481 EXPECT_TRUE(channel_->GetStats(&info));
482 return info.senders[i];
483 }
484
485 cricket::VideoReceiverInfo GetReceiverStats(size_t i) {
486 cricket::VideoMediaInfo info;
487 EXPECT_TRUE(channel_->GetStats(&info));
488 return info.receivers[i];
489 }
490
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000491 // Test that stats work properly for a conf call with multiple recv streams.
492 void GetStatsMultipleRecvStreams() {
493 cricket::FakeVideoRenderer renderer1, renderer2;
494 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200495 cricket::VideoSendParameters parameters;
496 parameters.codecs.push_back(DefaultCodec());
nisse4b4dc862016-02-17 05:25:36 -0800497 parameters.conference_mode = true;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200498 EXPECT_TRUE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000499 EXPECT_TRUE(SetSend(true));
500 EXPECT_TRUE(channel_->AddRecvStream(
501 cricket::StreamParams::CreateLegacy(1)));
502 EXPECT_TRUE(channel_->AddRecvStream(
503 cricket::StreamParams::CreateLegacy(2)));
nisse08582ff2016-02-04 01:24:52 -0800504 EXPECT_TRUE(channel_->SetSink(1, &renderer1));
505 EXPECT_TRUE(channel_->SetSink(2, &renderer2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000506 EXPECT_EQ(0, renderer1.num_rendered_frames());
507 EXPECT_EQ(0, renderer2.num_rendered_frames());
Peter Boström0c4e06b2015-10-07 12:23:21 +0200508 std::vector<uint32_t> ssrcs;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000509 ssrcs.push_back(1);
510 ssrcs.push_back(2);
511 network_interface_.SetConferenceMode(true, ssrcs);
512 EXPECT_TRUE(SendFrame());
513 EXPECT_FRAME_ON_RENDERER_WAIT(
514 renderer1, 1, DefaultCodec().width, DefaultCodec().height, kTimeout);
515 EXPECT_FRAME_ON_RENDERER_WAIT(
516 renderer2, 1, DefaultCodec().width, DefaultCodec().height, kTimeout);
Stefan Holmer586b19b2015-09-18 11:14:31 +0200517
518 EXPECT_TRUE(channel_->SetSend(false));
519
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000520 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +0000521 EXPECT_TRUE(channel_->GetStats(&info));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000522 ASSERT_EQ(1U, info.senders.size());
523 // TODO(whyuan): bytes_sent and bytes_rcvd are different. Are both payload?
buildbot@webrtc.org3eb2c2f2014-06-10 09:39:06 +0000524 // For webrtc, bytes_sent does not include the RTP header length.
Stefan Holmer586b19b2015-09-18 11:14:31 +0200525 EXPECT_GT(GetSenderStats(0).bytes_sent, 0);
526 EXPECT_EQ_WAIT(NumRtpPackets(), GetSenderStats(0).packets_sent, kTimeout);
527 EXPECT_EQ(DefaultCodec().width, GetSenderStats(0).send_frame_width);
528 EXPECT_EQ(DefaultCodec().height, GetSenderStats(0).send_frame_height);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000529
530 ASSERT_EQ(2U, info.receivers.size());
531 for (size_t i = 0; i < info.receivers.size(); ++i) {
Stefan Holmer586b19b2015-09-18 11:14:31 +0200532 EXPECT_EQ(1U, GetReceiverStats(i).ssrcs().size());
533 EXPECT_EQ(i + 1, GetReceiverStats(i).ssrcs()[0]);
534 EXPECT_EQ_WAIT(NumRtpBytes(), GetReceiverStats(i).bytes_rcvd, kTimeout);
535 EXPECT_EQ_WAIT(NumRtpPackets(), GetReceiverStats(i).packets_rcvd,
536 kTimeout);
537 EXPECT_EQ(DefaultCodec().width, GetReceiverStats(i).frame_width);
538 EXPECT_EQ(DefaultCodec().height, GetReceiverStats(i).frame_height);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000539 }
540 }
541 // Test that stats work properly for a conf call with multiple send streams.
542 void GetStatsMultipleSendStreams() {
543 // Normal setup; note that we set the SSRC explicitly to ensure that
544 // it will come first in the senders map.
545 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200546 cricket::VideoSendParameters parameters;
547 parameters.codecs.push_back(DefaultCodec());
nisse4b4dc862016-02-17 05:25:36 -0800548 parameters.conference_mode = true;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200549 EXPECT_TRUE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000550 EXPECT_TRUE(channel_->AddRecvStream(
buildbot@webrtc.org99f63082014-07-18 23:31:30 +0000551 cricket::StreamParams::CreateLegacy(kSsrc)));
nisse08582ff2016-02-04 01:24:52 -0800552 EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000553 EXPECT_TRUE(SetSend(true));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000554 EXPECT_TRUE(SendFrame());
555 EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
556 EXPECT_FRAME_WAIT(1, DefaultCodec().width, DefaultCodec().height, kTimeout);
557
558 // Add an additional capturer, and hook up a renderer to receive it.
pbos@webrtc.orgec45e3b2015-02-20 10:24:53 +0000559 cricket::FakeVideoRenderer renderer2;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000560 rtc::scoped_ptr<cricket::FakeVideoCapturer> capturer(
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000561 CreateFakeVideoCapturer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000562 capturer->SetScreencast(true);
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000563 const int kTestWidth = 160;
564 const int kTestHeight = 120;
565 cricket::VideoFormat format(kTestWidth, kTestHeight,
566 cricket::VideoFormat::FpsToInterval(5),
567 cricket::FOURCC_I420);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000568 EXPECT_EQ(cricket::CS_RUNNING, capturer->Start(format));
569 EXPECT_TRUE(channel_->AddSendStream(
570 cricket::StreamParams::CreateLegacy(5678)));
571 EXPECT_TRUE(channel_->SetCapturer(5678, capturer.get()));
572 EXPECT_TRUE(channel_->AddRecvStream(
573 cricket::StreamParams::CreateLegacy(5678)));
nisse08582ff2016-02-04 01:24:52 -0800574 EXPECT_TRUE(channel_->SetSink(5678, &renderer2));
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000575 EXPECT_TRUE(capturer->CaptureCustomFrame(
576 kTestWidth, kTestHeight, cricket::FOURCC_I420));
577 EXPECT_FRAME_ON_RENDERER_WAIT(
pbos@webrtc.orgec45e3b2015-02-20 10:24:53 +0000578 renderer2, 1, kTestWidth, kTestHeight, kTimeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000579
pbos@webrtc.orgec45e3b2015-02-20 10:24:53 +0000580 // Get stats, and make sure they are correct for two senders. We wait until
581 // the number of expected packets have been sent to avoid races where we
582 // check stats before it has been updated.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000583 cricket::VideoMediaInfo info;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200584 for (uint32_t i = 0; i < kTimeout; ++i) {
pbos@webrtc.orgec45e3b2015-02-20 10:24:53 +0000585 rtc::Thread::Current()->ProcessMessages(1);
pbos@webrtc.org058b1f12015-03-04 08:54:32 +0000586 EXPECT_TRUE(channel_->GetStats(&info));
pbos@webrtc.orgec45e3b2015-02-20 10:24:53 +0000587 ASSERT_EQ(2U, info.senders.size());
588 if (info.senders[0].packets_sent + info.senders[1].packets_sent ==
589 NumRtpPackets()) {
590 // Stats have been updated for both sent frames, expectations can be
591 // checked now.
592 break;
593 }
594 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000595 EXPECT_EQ(NumRtpPackets(),
pbos@webrtc.orgec45e3b2015-02-20 10:24:53 +0000596 info.senders[0].packets_sent + info.senders[1].packets_sent)
597 << "Timed out while waiting for packet counts for all sent packets.";
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +0000598 EXPECT_EQ(1U, info.senders[0].ssrcs().size());
599 EXPECT_EQ(1234U, info.senders[0].ssrcs()[0]);
wu@webrtc.org987f2c92014-03-28 16:22:19 +0000600 EXPECT_EQ(DefaultCodec().width, info.senders[0].send_frame_width);
601 EXPECT_EQ(DefaultCodec().height, info.senders[0].send_frame_height);
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +0000602 EXPECT_EQ(1U, info.senders[1].ssrcs().size());
603 EXPECT_EQ(5678U, info.senders[1].ssrcs()[0]);
wu@webrtc.org987f2c92014-03-28 16:22:19 +0000604 EXPECT_EQ(kTestWidth, info.senders[1].send_frame_width);
605 EXPECT_EQ(kTestHeight, info.senders[1].send_frame_height);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000606 // The capturer must be unregistered here as it runs out of it's scope next.
607 EXPECT_TRUE(channel_->SetCapturer(5678, NULL));
608 }
609
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000610 // Test that we can set the bandwidth.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000611 void SetSendBandwidth() {
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200612 cricket::VideoSendParameters parameters;
613 parameters.codecs.push_back(DefaultCodec());
614 parameters.max_bandwidth_bps = -1; // <= 0 means unlimited.
615 EXPECT_TRUE(channel_->SetSendParameters(parameters));
616 parameters.max_bandwidth_bps = 128 * 1024;
617 EXPECT_TRUE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000618 }
619 // Test that we can set the SSRC for the default send source.
620 void SetSendSsrc() {
621 EXPECT_TRUE(SetDefaultCodec());
622 EXPECT_TRUE(SetSend(true));
623 EXPECT_TRUE(SendFrame());
624 EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
Peter Boström0c4e06b2015-10-07 12:23:21 +0200625 uint32_t ssrc = 0;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000626 rtc::scoped_ptr<const rtc::Buffer> p(GetRtpPacket(0));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000627 ParseRtpPacket(p.get(), NULL, NULL, NULL, NULL, &ssrc, NULL);
628 EXPECT_EQ(kSsrc, ssrc);
Peter Boström718b6c72015-11-11 16:19:33 +0000629 // Packets are being paced out, so these can mismatch between the first and
630 // second call to NumRtpPackets until pending packets are paced out.
631 EXPECT_EQ_WAIT(NumRtpPackets(), NumRtpPackets(ssrc), kTimeout);
632 EXPECT_EQ_WAIT(NumRtpBytes(), NumRtpBytes(ssrc), kTimeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000633 EXPECT_EQ(1, NumSentSsrcs());
634 EXPECT_EQ(0, NumRtpPackets(kSsrc - 1));
635 EXPECT_EQ(0, NumRtpBytes(kSsrc - 1));
636 }
637 // Test that we can set the SSRC even after codecs are set.
638 void SetSendSsrcAfterSetCodecs() {
639 // Remove stream added in Setup.
640 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
641 EXPECT_TRUE(SetDefaultCodec());
642 EXPECT_TRUE(channel_->AddSendStream(
643 cricket::StreamParams::CreateLegacy(999)));
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000644 EXPECT_TRUE(channel_->SetCapturer(999u, video_capturer_.get()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000645 EXPECT_TRUE(SetSend(true));
646 EXPECT_TRUE(WaitAndSendFrame(0));
647 EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
Peter Boström0c4e06b2015-10-07 12:23:21 +0200648 uint32_t ssrc = 0;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000649 rtc::scoped_ptr<const rtc::Buffer> p(GetRtpPacket(0));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000650 ParseRtpPacket(p.get(), NULL, NULL, NULL, NULL, &ssrc, NULL);
651 EXPECT_EQ(999u, ssrc);
Peter Boström718b6c72015-11-11 16:19:33 +0000652 // Packets are being paced out, so these can mismatch between the first and
653 // second call to NumRtpPackets until pending packets are paced out.
654 EXPECT_EQ_WAIT(NumRtpPackets(), NumRtpPackets(ssrc), kTimeout);
655 EXPECT_EQ_WAIT(NumRtpBytes(), NumRtpBytes(ssrc), kTimeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000656 EXPECT_EQ(1, NumSentSsrcs());
657 EXPECT_EQ(0, NumRtpPackets(kSsrc));
658 EXPECT_EQ(0, NumRtpBytes(kSsrc));
659 }
660 // Test that we can set the default video renderer before and after
661 // media is received.
nisse08582ff2016-02-04 01:24:52 -0800662 void SetSink() {
Peter Boström0c4e06b2015-10-07 12:23:21 +0200663 uint8_t data1[] = {
664 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000665
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000666 rtc::Buffer packet1(data1, sizeof(data1));
667 rtc::SetBE32(packet1.data() + 8, kSsrc);
nisse08582ff2016-02-04 01:24:52 -0800668 channel_->SetSink(kDefaultReceiveSsrc, NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000669 EXPECT_TRUE(SetDefaultCodec());
670 EXPECT_TRUE(SetSend(true));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000671 EXPECT_EQ(0, renderer_.num_rendered_frames());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000672 channel_->OnPacketReceived(&packet1, rtc::PacketTime());
nisse08582ff2016-02-04 01:24:52 -0800673 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000674 EXPECT_TRUE(SendFrame());
675 EXPECT_FRAME_WAIT(1, DefaultCodec().width, DefaultCodec().height, kTimeout);
676 }
677
678 // Tests empty StreamParams is rejected.
679 void RejectEmptyStreamParams() {
680 // Remove the send stream that was added during Setup.
681 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
682
683 cricket::StreamParams empty;
684 EXPECT_FALSE(channel_->AddSendStream(empty));
685 EXPECT_TRUE(channel_->AddSendStream(
686 cricket::StreamParams::CreateLegacy(789u)));
687 }
688
689 // Tests setting up and configuring a send stream.
690 void AddRemoveSendStreams() {
691 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
692 EXPECT_TRUE(SetSend(true));
nisse08582ff2016-02-04 01:24:52 -0800693 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000694 EXPECT_TRUE(SendFrame());
695 EXPECT_FRAME_WAIT(1, DefaultCodec().width, DefaultCodec().height, kTimeout);
Stefan Holmer586b19b2015-09-18 11:14:31 +0200696 EXPECT_GT(NumRtpPackets(), 0);
Peter Boström0c4e06b2015-10-07 12:23:21 +0200697 uint32_t ssrc = 0;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000698 size_t last_packet = NumRtpPackets() - 1;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000699 rtc::scoped_ptr<const rtc::Buffer>
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000700 p(GetRtpPacket(static_cast<int>(last_packet)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000701 ParseRtpPacket(p.get(), NULL, NULL, NULL, NULL, &ssrc, NULL);
702 EXPECT_EQ(kSsrc, ssrc);
703
704 // Remove the send stream that was added during Setup.
705 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
706 int rtp_packets = NumRtpPackets();
707
708 EXPECT_TRUE(channel_->AddSendStream(
709 cricket::StreamParams::CreateLegacy(789u)));
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000710 EXPECT_TRUE(channel_->SetCapturer(789u, video_capturer_.get()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000711 EXPECT_EQ(rtp_packets, NumRtpPackets());
712 // Wait 30ms to guarantee the engine does not drop the frame.
713 EXPECT_TRUE(WaitAndSendFrame(30));
714 EXPECT_TRUE_WAIT(NumRtpPackets() > rtp_packets, kTimeout);
715
716 last_packet = NumRtpPackets() - 1;
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000717 p.reset(GetRtpPacket(static_cast<int>(last_packet)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000718 ParseRtpPacket(p.get(), NULL, NULL, NULL, NULL, &ssrc, NULL);
719 EXPECT_EQ(789u, ssrc);
720 }
721
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000722 // Tests the behavior of incoming streams in a conference scenario.
723 void SimulateConference() {
724 cricket::FakeVideoRenderer renderer1, renderer2;
725 EXPECT_TRUE(SetDefaultCodec());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200726 cricket::VideoSendParameters parameters;
727 parameters.codecs.push_back(DefaultCodec());
nisse4b4dc862016-02-17 05:25:36 -0800728 parameters.conference_mode = true;
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200729 EXPECT_TRUE(channel_->SetSendParameters(parameters));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000730 EXPECT_TRUE(SetSend(true));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000731 EXPECT_TRUE(channel_->AddRecvStream(
732 cricket::StreamParams::CreateLegacy(1)));
733 EXPECT_TRUE(channel_->AddRecvStream(
734 cricket::StreamParams::CreateLegacy(2)));
nisse08582ff2016-02-04 01:24:52 -0800735 EXPECT_TRUE(channel_->SetSink(1, &renderer1));
736 EXPECT_TRUE(channel_->SetSink(2, &renderer2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000737 EXPECT_EQ(0, renderer1.num_rendered_frames());
738 EXPECT_EQ(0, renderer2.num_rendered_frames());
Peter Boström0c4e06b2015-10-07 12:23:21 +0200739 std::vector<uint32_t> ssrcs;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000740 ssrcs.push_back(1);
741 ssrcs.push_back(2);
742 network_interface_.SetConferenceMode(true, ssrcs);
743 EXPECT_TRUE(SendFrame());
744 EXPECT_FRAME_ON_RENDERER_WAIT(
745 renderer1, 1, DefaultCodec().width, DefaultCodec().height, kTimeout);
746 EXPECT_FRAME_ON_RENDERER_WAIT(
747 renderer2, 1, DefaultCodec().width, DefaultCodec().height, kTimeout);
748
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000749 rtc::scoped_ptr<const rtc::Buffer> p(GetRtpPacket(0));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000750 EXPECT_EQ(DefaultCodec().id, GetPayloadType(p.get()));
751 EXPECT_EQ(DefaultCodec().width, renderer1.width());
752 EXPECT_EQ(DefaultCodec().height, renderer1.height());
753 EXPECT_EQ(DefaultCodec().width, renderer2.width());
754 EXPECT_EQ(DefaultCodec().height, renderer2.height());
755 EXPECT_TRUE(channel_->RemoveRecvStream(2));
756 EXPECT_TRUE(channel_->RemoveRecvStream(1));
757 }
758
759 // Tests that we can add and remove capturers and frames are sent out properly
760 void AddRemoveCapturer() {
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000761 cricket::VideoCodec codec = DefaultCodec();
762 codec.width = 320;
763 codec.height = 240;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000764 const int time_between_send = TimeBetweenSend(codec);
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000765 EXPECT_TRUE(SetOneCodec(codec));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000766 EXPECT_TRUE(SetSend(true));
nisse08582ff2016-02-04 01:24:52 -0800767 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000768 EXPECT_EQ(0, renderer_.num_rendered_frames());
769 EXPECT_TRUE(SendFrame());
770 EXPECT_FRAME_WAIT(1, codec.width, codec.height, kTimeout);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000771 rtc::scoped_ptr<cricket::FakeVideoCapturer> capturer(
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000772 CreateFakeVideoCapturer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000773 capturer->SetScreencast(true);
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000774 cricket::VideoFormat format(480, 360,
775 cricket::VideoFormat::FpsToInterval(30),
776 cricket::FOURCC_I420);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000777 EXPECT_EQ(cricket::CS_RUNNING, capturer->Start(format));
778 // All capturers start generating frames with the same timestamp. ViE does
779 // not allow the same timestamp to be used. Capture one frame before
780 // associating the capturer with the channel.
781 EXPECT_TRUE(capturer->CaptureCustomFrame(format.width, format.height,
782 cricket::FOURCC_I420));
783
784 int captured_frames = 1;
785 for (int iterations = 0; iterations < 2; ++iterations) {
786 EXPECT_TRUE(channel_->SetCapturer(kSsrc, capturer.get()));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000787 rtc::Thread::Current()->ProcessMessages(time_between_send);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000788 EXPECT_TRUE(capturer->CaptureCustomFrame(format.width, format.height,
789 cricket::FOURCC_I420));
790 ++captured_frames;
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000791 // Wait until frame of right size is captured.
792 EXPECT_TRUE_WAIT(renderer_.num_rendered_frames() >= captured_frames &&
793 format.width == renderer_.width() &&
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000794 format.height == renderer_.height() &&
795 !renderer_.black_frame(), kTimeout);
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000796 EXPECT_GE(renderer_.num_rendered_frames(), captured_frames);
797 EXPECT_EQ(format.width, renderer_.width());
798 EXPECT_EQ(format.height, renderer_.height());
799 captured_frames = renderer_.num_rendered_frames() + 1;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000800 EXPECT_FALSE(renderer_.black_frame());
801 EXPECT_TRUE(channel_->SetCapturer(kSsrc, NULL));
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000802 // Make sure a black frame is generated within the specified timeout.
pbos@webrtc.orgb4987bf2015-02-18 10:13:09 +0000803 // The black frame should be the resolution of the previous frame to
804 // prevent expensive encoder reconfigurations.
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000805 EXPECT_TRUE_WAIT(renderer_.num_rendered_frames() >= captured_frames &&
pbos@webrtc.orgb4987bf2015-02-18 10:13:09 +0000806 format.width == renderer_.width() &&
807 format.height == renderer_.height() &&
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000808 renderer_.black_frame(), kTimeout);
809 EXPECT_GE(renderer_.num_rendered_frames(), captured_frames);
pbos@webrtc.orgb4987bf2015-02-18 10:13:09 +0000810 EXPECT_EQ(format.width, renderer_.width());
811 EXPECT_EQ(format.height, renderer_.height());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000812 EXPECT_TRUE(renderer_.black_frame());
813
814 // The black frame has the same timestamp as the next frame since it's
815 // timestamp is set to the last frame's timestamp + interval. WebRTC will
816 // not render a frame with the same timestamp so capture another frame
817 // with the frame capturer to increment the next frame's timestamp.
818 EXPECT_TRUE(capturer->CaptureCustomFrame(format.width, format.height,
819 cricket::FOURCC_I420));
820 }
821 }
822
823 // Tests that if RemoveCapturer is called without a capturer ever being
824 // added, the plugin shouldn't crash (and no black frame should be sent).
825 void RemoveCapturerWithoutAdd() {
826 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
827 EXPECT_TRUE(SetSend(true));
nisse08582ff2016-02-04 01:24:52 -0800828 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000829 EXPECT_EQ(0, renderer_.num_rendered_frames());
830 EXPECT_TRUE(SendFrame());
831 EXPECT_FRAME_WAIT(1, 640, 400, kTimeout);
pbos@webrtc.org776e6f22014-10-29 15:28:39 +0000832 // Wait for one frame so they don't get dropped because we send frames too
833 // tightly.
834 rtc::Thread::Current()->ProcessMessages(30);
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000835 // Remove the capturer.
836 EXPECT_TRUE(channel_->SetCapturer(kSsrc, NULL));
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000837 // Wait for one black frame for removing the capturer.
838 EXPECT_FRAME_WAIT(2, 640, 400, kTimeout);
839
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000840 // No capturer was added, so this RemoveCapturer should
841 // fail.
842 EXPECT_FALSE(channel_->SetCapturer(kSsrc, NULL));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000843 rtc::Thread::Current()->ProcessMessages(300);
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000844 // Verify no more frames were sent.
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000845 EXPECT_EQ(2, renderer_.num_rendered_frames());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000846 }
847
848 // Tests that we can add and remove capturer as unique sources.
849 void AddRemoveCapturerMultipleSources() {
850 // WebRTC implementation will drop frames if pushed to quickly. Wait the
851 // interval time to avoid that.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000852 // WebRTC implementation will drop frames if pushed to quickly. Wait the
853 // interval time to avoid that.
854 // Set up the stream associated with the engine.
855 EXPECT_TRUE(channel_->AddRecvStream(
856 cricket::StreamParams::CreateLegacy(kSsrc)));
nisse08582ff2016-02-04 01:24:52 -0800857 EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000858 cricket::VideoFormat capture_format; // default format
859 capture_format.interval = cricket::VideoFormat::FpsToInterval(30);
860 // Set up additional stream 1.
861 cricket::FakeVideoRenderer renderer1;
nisse08582ff2016-02-04 01:24:52 -0800862 EXPECT_FALSE(channel_->SetSink(1, &renderer1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000863 EXPECT_TRUE(channel_->AddRecvStream(
864 cricket::StreamParams::CreateLegacy(1)));
nisse08582ff2016-02-04 01:24:52 -0800865 EXPECT_TRUE(channel_->SetSink(1, &renderer1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000866 EXPECT_TRUE(channel_->AddSendStream(
867 cricket::StreamParams::CreateLegacy(1)));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000868 rtc::scoped_ptr<cricket::FakeVideoCapturer> capturer1(
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000869 CreateFakeVideoCapturer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000870 capturer1->SetScreencast(true);
871 EXPECT_EQ(cricket::CS_RUNNING, capturer1->Start(capture_format));
872 // Set up additional stream 2.
873 cricket::FakeVideoRenderer renderer2;
nisse08582ff2016-02-04 01:24:52 -0800874 EXPECT_FALSE(channel_->SetSink(2, &renderer2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000875 EXPECT_TRUE(channel_->AddRecvStream(
876 cricket::StreamParams::CreateLegacy(2)));
nisse08582ff2016-02-04 01:24:52 -0800877 EXPECT_TRUE(channel_->SetSink(2, &renderer2));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000878 EXPECT_TRUE(channel_->AddSendStream(
879 cricket::StreamParams::CreateLegacy(2)));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000880 rtc::scoped_ptr<cricket::FakeVideoCapturer> capturer2(
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000881 CreateFakeVideoCapturer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000882 capturer2->SetScreencast(true);
883 EXPECT_EQ(cricket::CS_RUNNING, capturer2->Start(capture_format));
884 // State for all the streams.
885 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
886 // A limitation in the lmi implementation requires that SetCapturer() is
887 // called after SetOneCodec().
888 // TODO(hellner): this seems like an unnecessary constraint, fix it.
889 EXPECT_TRUE(channel_->SetCapturer(1, capturer1.get()));
890 EXPECT_TRUE(channel_->SetCapturer(2, capturer2.get()));
891 EXPECT_TRUE(SetSend(true));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000892 // Test capturer associated with engine.
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000893 const int kTestWidth = 160;
894 const int kTestHeight = 120;
895 EXPECT_TRUE(capturer1->CaptureCustomFrame(
896 kTestWidth, kTestHeight, cricket::FOURCC_I420));
897 EXPECT_FRAME_ON_RENDERER_WAIT(
898 renderer1, 1, kTestWidth, kTestHeight, kTimeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000899 // Capture a frame with additional capturer2, frames should be received
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000900 EXPECT_TRUE(capturer2->CaptureCustomFrame(
901 kTestWidth, kTestHeight, cricket::FOURCC_I420));
902 EXPECT_FRAME_ON_RENDERER_WAIT(
903 renderer2, 1, kTestWidth, kTestHeight, kTimeout);
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000904 // Successfully remove the capturer.
905 EXPECT_TRUE(channel_->SetCapturer(kSsrc, NULL));
906 // Fail to re-remove the capturer.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000907 EXPECT_FALSE(channel_->SetCapturer(kSsrc, NULL));
908 // The capturers must be unregistered here as it runs out of it's scope
909 // next.
910 EXPECT_TRUE(channel_->SetCapturer(1, NULL));
911 EXPECT_TRUE(channel_->SetCapturer(2, NULL));
912 }
913
914 void HighAspectHighHeightCapturer() {
915 const int kWidth = 80;
916 const int kHeight = 10000;
917 const int kScaledWidth = 20;
918 const int kScaledHeight = 2500;
919
920 cricket::VideoCodec codec(DefaultCodec());
921 EXPECT_TRUE(SetOneCodec(codec));
922 EXPECT_TRUE(SetSend(true));
923
924 cricket::FakeVideoRenderer renderer;
925 EXPECT_TRUE(channel_->AddRecvStream(
926 cricket::StreamParams::CreateLegacy(kSsrc)));
nisse08582ff2016-02-04 01:24:52 -0800927 EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000928 EXPECT_EQ(0, renderer.num_rendered_frames());
929
930 EXPECT_TRUE(SendFrame());
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000931 EXPECT_GT_FRAME_ON_RENDERER_WAIT(
932 renderer, 1, codec.width, codec.height, kTimeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000933
934 // Registering an external capturer is currently the same as screen casting
935 // (update the test when this changes).
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000936 rtc::scoped_ptr<cricket::FakeVideoCapturer> capturer(
buildbot@webrtc.org4f0d4012014-08-07 04:47:36 +0000937 CreateFakeVideoCapturer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000938 capturer->SetScreencast(true);
939 const std::vector<cricket::VideoFormat>* formats =
940 capturer->GetSupportedFormats();
941 cricket::VideoFormat capture_format = (*formats)[0];
942 EXPECT_EQ(cricket::CS_RUNNING, capturer->Start(capture_format));
943 // Capture frame to not get same frame timestamps as previous capturer.
944 capturer->CaptureFrame();
945 EXPECT_TRUE(channel_->SetCapturer(kSsrc, capturer.get()));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000946 EXPECT_TRUE(rtc::Thread::Current()->ProcessMessages(30));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000947 EXPECT_TRUE(capturer->CaptureCustomFrame(kWidth, kHeight,
948 cricket::FOURCC_ARGB));
wu@webrtc.org9caf2762013-12-11 18:25:07 +0000949 EXPECT_GT_FRAME_ON_RENDERER_WAIT(
950 renderer, 2, kScaledWidth, kScaledHeight, kTimeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000951 EXPECT_TRUE(channel_->SetCapturer(kSsrc, NULL));
952 }
953
954 // Tests that we can adapt video resolution with 16:10 aspect ratio properly.
955 void AdaptResolution16x10() {
nisse08582ff2016-02-04 01:24:52 -0800956 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000957 cricket::VideoCodec codec(DefaultCodec());
958 codec.width = 640;
959 codec.height = 400;
960 SendAndReceive(codec);
961 codec.width /= 2;
962 codec.height /= 2;
963 // Adapt the resolution.
964 EXPECT_TRUE(SetOneCodec(codec));
965 EXPECT_TRUE(WaitAndSendFrame(30));
966 EXPECT_FRAME_WAIT(2, codec.width, codec.height, kTimeout);
967 }
968 // Tests that we can adapt video resolution with 4:3 aspect ratio properly.
969 void AdaptResolution4x3() {
nisse08582ff2016-02-04 01:24:52 -0800970 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000971 cricket::VideoCodec codec(DefaultCodec());
972 codec.width = 640;
973 codec.height = 400;
974 SendAndReceive(codec);
975 codec.width /= 2;
976 codec.height /= 2;
977 // Adapt the resolution.
978 EXPECT_TRUE(SetOneCodec(codec));
979 EXPECT_TRUE(WaitAndSendFrame(30));
980 EXPECT_FRAME_WAIT(2, codec.width, codec.height, kTimeout);
981 }
982 // Tests that we can drop all frames properly.
983 void AdaptDropAllFrames() {
984 // Set the channel codec's resolution to 0, which will require the adapter
985 // to drop all frames.
986 cricket::VideoCodec codec(DefaultCodec());
987 codec.width = codec.height = codec.framerate = 0;
988 EXPECT_TRUE(SetOneCodec(codec));
989 EXPECT_TRUE(SetSend(true));
nisse08582ff2016-02-04 01:24:52 -0800990 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000991 EXPECT_EQ(0, renderer_.num_rendered_frames());
992 EXPECT_TRUE(SendFrame());
993 EXPECT_TRUE(SendFrame());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000994 rtc::Thread::Current()->ProcessMessages(500);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000995 EXPECT_EQ(0, renderer_.num_rendered_frames());
996 }
997 // Tests that we can reduce the frame rate on demand properly.
998 // TODO(fbarchard): This test is flakey on pulse. Fix and re-enable
999 void AdaptFramerate() {
1000 cricket::VideoCodec codec(DefaultCodec());
1001 int frame_count = 0;
1002 // The capturer runs at 30 fps. The channel requires 30 fps.
1003 EXPECT_TRUE(SetOneCodec(codec));
1004 EXPECT_TRUE(SetSend(true));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001005 EXPECT_EQ(frame_count, renderer_.num_rendered_frames());
1006 EXPECT_TRUE(WaitAndSendFrame(0)); // Should be rendered.
1007 EXPECT_TRUE(WaitAndSendFrame(30)); // Should be rendered.
1008 frame_count += 2;
1009 EXPECT_FRAME_WAIT(frame_count, codec.width, codec.height, kTimeout);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001010 rtc::scoped_ptr<const rtc::Buffer> p(GetRtpPacket(0));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001011 EXPECT_EQ(codec.id, GetPayloadType(p.get()));
1012
1013 // The channel requires 15 fps.
1014 codec.framerate = 15;
1015 EXPECT_TRUE(SetOneCodec(codec));
1016 EXPECT_TRUE(WaitAndSendFrame(0)); // Should be rendered.
1017 EXPECT_TRUE(WaitAndSendFrame(30)); // Should be dropped.
1018 EXPECT_TRUE(WaitAndSendFrame(30)); // Should be rendered.
1019 frame_count += 2;
1020 EXPECT_EQ_WAIT(frame_count, renderer_.num_rendered_frames(), kTimeout);
1021
1022 // The channel requires 10 fps.
1023 codec.framerate = 10;
1024 EXPECT_TRUE(SetOneCodec(codec));
1025 EXPECT_TRUE(WaitAndSendFrame(0)); // Should be rendered.
1026 EXPECT_TRUE(WaitAndSendFrame(30)); // Should be dropped.
1027 EXPECT_TRUE(WaitAndSendFrame(30)); // Should be dropped.
1028 EXPECT_TRUE(WaitAndSendFrame(30)); // Should be rendered.
1029 frame_count += 2;
1030 EXPECT_EQ_WAIT(frame_count, renderer_.num_rendered_frames(), kTimeout);
1031
1032 // The channel requires 8 fps. The adapter adapts to 10 fps, which is the
1033 // closest factor of 30.
1034 codec.framerate = 8;
1035 EXPECT_TRUE(SetOneCodec(codec));
1036 EXPECT_TRUE(WaitAndSendFrame(0)); // Should be rendered.
1037 EXPECT_TRUE(WaitAndSendFrame(30)); // Should be dropped.
1038 EXPECT_TRUE(WaitAndSendFrame(30)); // Should be dropped.
1039 EXPECT_TRUE(WaitAndSendFrame(30)); // Should be rendered.
1040 frame_count += 2;
1041 EXPECT_EQ_WAIT(frame_count, renderer_.num_rendered_frames(), kTimeout);
1042 }
pbos@webrtc.orgc4175b92014-09-03 15:25:49 +00001043 // Tests that adapted frames won't be upscaled to a higher resolution.
1044 void SendsLowerResolutionOnSmallerFrames() {
1045 cricket::VideoCodec codec = DefaultCodec();
1046 codec.width = 320;
1047 codec.height = 240;
1048 EXPECT_TRUE(SetOneCodec(codec));
1049 EXPECT_TRUE(SetSend(true));
nisse08582ff2016-02-04 01:24:52 -08001050 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
pbos@webrtc.orgc4175b92014-09-03 15:25:49 +00001051 EXPECT_EQ(0, renderer_.num_rendered_frames());
1052 EXPECT_TRUE(SendFrame());
1053 EXPECT_FRAME_WAIT(1, codec.width, codec.height, kTimeout);
1054
1055 // Check that we send smaller frames at the new resolution.
pbos@webrtc.orgebee4012014-09-03 15:52:02 +00001056 EXPECT_TRUE(rtc::Thread::Current()->ProcessMessages(33));
pbos@webrtc.orgc4175b92014-09-03 15:25:49 +00001057 EXPECT_TRUE(video_capturer_->CaptureCustomFrame(
1058 codec.width / 2, codec.height / 2, cricket::FOURCC_I420));
1059 EXPECT_FRAME_WAIT(2, codec.width / 2, codec.height / 2, kTimeout);
1060 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001061
1062 // Tests that we can mute and unmute the channel properly.
1063 void MuteStream() {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001064 EXPECT_TRUE(SetDefaultCodec());
1065 cricket::FakeVideoCapturer video_capturer;
1066 video_capturer.Start(
1067 cricket::VideoFormat(
1068 640, 480,
1069 cricket::VideoFormat::FpsToInterval(30),
1070 cricket::FOURCC_I420));
1071 EXPECT_TRUE(channel_->SetCapturer(kSsrc, &video_capturer));
1072 EXPECT_TRUE(SetSend(true));
nisse08582ff2016-02-04 01:24:52 -08001073 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
buildbot@webrtc.org99f63082014-07-18 23:31:30 +00001074 EXPECT_EQ(0, renderer_.num_rendered_frames());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001075 // Mute the channel and expect black output frame.
buildbot@webrtc.org99f63082014-07-18 23:31:30 +00001076 int frame_count = 0;
solenbergdfc8f4f2015-10-01 02:31:10 -07001077 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, false, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001078 EXPECT_TRUE(video_capturer.CaptureFrame());
1079 ++frame_count;
1080 EXPECT_EQ_WAIT(frame_count, renderer_.num_rendered_frames(), kTimeout);
1081 EXPECT_TRUE(renderer_.black_frame());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001082 // Unmute the channel and expect non-black output frame.
solenbergdfc8f4f2015-10-01 02:31:10 -07001083 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, true, nullptr));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001084 EXPECT_TRUE(rtc::Thread::Current()->ProcessMessages(30));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001085 EXPECT_TRUE(video_capturer.CaptureFrame());
1086 ++frame_count;
1087 EXPECT_EQ_WAIT(frame_count, renderer_.num_rendered_frames(), kTimeout);
1088 EXPECT_FALSE(renderer_.black_frame());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001089 // Test that we can also Mute using the correct send stream SSRC.
solenbergdfc8f4f2015-10-01 02:31:10 -07001090 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, false, nullptr));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001091 EXPECT_TRUE(rtc::Thread::Current()->ProcessMessages(30));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001092 EXPECT_TRUE(video_capturer.CaptureFrame());
1093 ++frame_count;
1094 EXPECT_EQ_WAIT(frame_count, renderer_.num_rendered_frames(), kTimeout);
1095 EXPECT_TRUE(renderer_.black_frame());
solenbergdfc8f4f2015-10-01 02:31:10 -07001096 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, true, nullptr));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001097 EXPECT_TRUE(rtc::Thread::Current()->ProcessMessages(30));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001098 EXPECT_TRUE(video_capturer.CaptureFrame());
1099 ++frame_count;
1100 EXPECT_EQ_WAIT(frame_count, renderer_.num_rendered_frames(), kTimeout);
1101 EXPECT_FALSE(renderer_.black_frame());
pbos@webrtc.orgef8bb8d2014-08-13 21:36:18 +00001102 // Test that muting an existing stream succeeds even if it's muted.
solenbergdfc8f4f2015-10-01 02:31:10 -07001103 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, false, nullptr));
1104 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, false, nullptr));
pbos@webrtc.orgef8bb8d2014-08-13 21:36:18 +00001105 // Test that unmuting an existing stream succeeds even if it's not muted.
solenbergdfc8f4f2015-10-01 02:31:10 -07001106 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, true, nullptr));
1107 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, true, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001108 // Test that muting an invalid stream fails.
solenbergdfc8f4f2015-10-01 02:31:10 -07001109 EXPECT_FALSE(channel_->SetVideoSend(kSsrc+1, false, nullptr));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001110 EXPECT_TRUE(channel_->SetCapturer(kSsrc, NULL));
1111 }
1112
1113 // Test that multiple send streams can be created and deleted properly.
1114 void MultipleSendStreams() {
1115 // Remove stream added in Setup. I.e. remove stream corresponding to default
1116 // channel.
1117 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
1118 const unsigned int kSsrcsSize = sizeof(kSsrcs4)/sizeof(kSsrcs4[0]);
1119 for (unsigned int i = 0; i < kSsrcsSize; ++i) {
1120 EXPECT_TRUE(channel_->AddSendStream(
1121 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1122 }
1123 // Delete one of the non default channel streams, let the destructor delete
1124 // the remaining ones.
1125 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[kSsrcsSize - 1]));
1126 // Stream should already be deleted.
1127 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[kSsrcsSize - 1]));
1128 }
1129
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001130 // Two streams one channel tests.
1131
1132 // Tests that we can send and receive frames.
1133 void TwoStreamsSendAndReceive(const cricket::VideoCodec& codec) {
1134 SetUpSecondStream();
1135 // Test sending and receiving on first stream.
1136 SendAndReceive(codec);
1137 // Test sending and receiving on second stream.
1138 EXPECT_EQ_WAIT(1, renderer2_.num_rendered_frames(), kTimeout);
Stefan Holmer586b19b2015-09-18 11:14:31 +02001139 EXPECT_GT(NumRtpPackets(), 0);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001140 EXPECT_EQ(1, renderer2_.num_rendered_frames());
1141 }
1142
henrike@webrtc.org6e3dbc22014-03-25 17:09:47 +00001143 // Set up 2 streams where the first stream uses the default channel.
1144 // Then disconnect the first stream and verify default channel becomes
1145 // available.
1146 // Then add a new stream with |new_ssrc|. The new stream should re-use the
1147 // default channel.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001148 void TwoStreamsReUseFirstStream(const cricket::VideoCodec& codec) {
1149 SetUpSecondStream();
henrike@webrtc.org6e3dbc22014-03-25 17:09:47 +00001150 // Default channel used by the first stream.
buildbot@webrtc.org2c0fb052014-08-13 16:47:12 +00001151 EXPECT_EQ(kSsrc, channel_->GetDefaultSendChannelSsrc());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001152 EXPECT_TRUE(channel_->RemoveRecvStream(kSsrc));
1153 EXPECT_FALSE(channel_->RemoveRecvStream(kSsrc));
henrike@webrtc.org6e3dbc22014-03-25 17:09:47 +00001154 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001155 EXPECT_FALSE(channel_->RemoveSendStream(kSsrc));
henrike@webrtc.org6e3dbc22014-03-25 17:09:47 +00001156 // Default channel is no longer used by a stream.
buildbot@webrtc.org2c0fb052014-08-13 16:47:12 +00001157 EXPECT_EQ(0u, channel_->GetDefaultSendChannelSsrc());
Peter Boström0c4e06b2015-10-07 12:23:21 +02001158 uint32_t new_ssrc = kSsrc + 100;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001159 EXPECT_TRUE(channel_->AddSendStream(
henrike@webrtc.org6e3dbc22014-03-25 17:09:47 +00001160 cricket::StreamParams::CreateLegacy(new_ssrc)));
1161 // Re-use default channel.
buildbot@webrtc.org2c0fb052014-08-13 16:47:12 +00001162 EXPECT_EQ(new_ssrc, channel_->GetDefaultSendChannelSsrc());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001163 EXPECT_FALSE(channel_->AddSendStream(
henrike@webrtc.org6e3dbc22014-03-25 17:09:47 +00001164 cricket::StreamParams::CreateLegacy(new_ssrc)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001165 EXPECT_TRUE(channel_->AddRecvStream(
henrike@webrtc.org6e3dbc22014-03-25 17:09:47 +00001166 cricket::StreamParams::CreateLegacy(new_ssrc)));
nisse08582ff2016-02-04 01:24:52 -08001167 EXPECT_TRUE(channel_->SetSink(new_ssrc, &renderer_));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001168 EXPECT_FALSE(channel_->AddRecvStream(
henrike@webrtc.org6e3dbc22014-03-25 17:09:47 +00001169 cricket::StreamParams::CreateLegacy(new_ssrc)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001170
henrike@webrtc.org6e3dbc22014-03-25 17:09:47 +00001171 EXPECT_TRUE(channel_->SetCapturer(new_ssrc, video_capturer_.get()));
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00001172
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001173 SendAndReceive(codec);
henrike@webrtc.org6e3dbc22014-03-25 17:09:47 +00001174 EXPECT_TRUE(channel_->RemoveSendStream(new_ssrc));
buildbot@webrtc.org2c0fb052014-08-13 16:47:12 +00001175 EXPECT_EQ(0u, channel_->GetDefaultSendChannelSsrc());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001176 }
1177
Fredrik Solenberg709ed672015-09-15 12:26:33 +02001178 const rtc::scoped_ptr<webrtc::Call> call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001179 VideoEngineOverride<E> engine_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001180 rtc::scoped_ptr<cricket::FakeVideoCapturer> video_capturer_;
1181 rtc::scoped_ptr<cricket::FakeVideoCapturer> video_capturer_2_;
1182 rtc::scoped_ptr<C> channel_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001183 cricket::FakeNetworkInterface network_interface_;
1184 cricket::FakeVideoRenderer renderer_;
1185 cricket::VideoMediaChannel::Error media_error_;
1186
1187 // Used by test cases where 2 streams are run on the same channel.
1188 cricket::FakeVideoRenderer renderer2_;
1189};
1190
kjellandera96e2d72016-02-04 23:52:28 -08001191#endif // WEBRTC_MEDIA_BASE_VIDEOENGINE_UNITTEST_H_ NOLINT