blob: c5ce50399d08eacdef005645b6fbfade332541ce [file] [log] [blame]
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001/*
2 * libjingle
3 * Copyright 2004 Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include <map>
pbos@webrtc.org86f613d2014-06-10 08:53:05 +000029#include <vector>
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000030
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000031#include "talk/media/base/testutils.h"
32#include "talk/media/base/videoengine_unittest.h"
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +000033#include "talk/media/webrtc/fakewebrtcvideoengine.h"
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000034#include "talk/media/webrtc/webrtcvideochannelfactory.h"
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000035#include "talk/media/webrtc/webrtcvideoengine2.h"
pbos@webrtc.org86f613d2014-06-10 08:53:05 +000036#include "talk/media/webrtc/webrtcvideoengine2_unittest.h"
pbos@webrtc.org3bf3d232014-10-31 12:59:34 +000037#include "talk/media/webrtc/webrtcvoiceengine.h"
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000038#include "webrtc/base/gunit.h"
39#include "webrtc/base/stringutils.h"
pbos@webrtc.org42684be2014-10-03 11:25:45 +000040#include "webrtc/video_encoder.h"
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000041
42namespace {
43static const cricket::VideoCodec kVp8Codec720p(100, "VP8", 1280, 720, 30, 0);
44static const cricket::VideoCodec kVp8Codec360p(100, "VP8", 640, 360, 30, 0);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000045
46static const cricket::VideoCodec kVp8Codec(100, "VP8", 640, 400, 30, 0);
47static const cricket::VideoCodec kVp9Codec(101, "VP9", 640, 400, 30, 0);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +000048static const cricket::VideoCodec kH264Codec(102, "H264", 640, 400, 30, 0);
49
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000050static const cricket::VideoCodec kRedCodec(116, "red", 0, 0, 0, 0);
51static const cricket::VideoCodec kUlpfecCodec(117, "ulpfec", 0, 0, 0, 0);
52
53static const uint32 kSsrcs1[] = {1};
54static const uint32 kRtxSsrcs1[] = {4};
pbos@webrtc.org3c107582014-07-20 15:27:35 +000055static const char kUnsupportedExtensionName[] =
56 "urn:ietf:params:rtp-hdrext:unsupported";
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +000057
58void VerifyCodecHasDefaultFeedbackParams(const cricket::VideoCodec& codec) {
59 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
60 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty)));
61 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
62 cricket::kRtcpFbParamNack, cricket::kRtcpFbNackParamPli)));
63 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
64 cricket::kRtcpFbParamRemb, cricket::kParamValueEmpty)));
65 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
66 cricket::kRtcpFbParamCcm, cricket::kRtcpFbCcmParamFir)));
67}
68
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000069} // namespace
70
71namespace cricket {
pbos@webrtc.org86f613d2014-06-10 08:53:05 +000072FakeVideoSendStream::FakeVideoSendStream(
73 const webrtc::VideoSendStream::Config& config,
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +000074 const webrtc::VideoEncoderConfig& encoder_config)
pbos@webrtc.org42684be2014-10-03 11:25:45 +000075 : sending_(false),
76 config_(config),
77 codec_settings_set_(false),
78 num_swapped_frames_(0) {
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +000079 assert(config.encoder_settings.encoder != NULL);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +000080 ReconfigureVideoEncoder(encoder_config);
pbos@webrtc.org86f613d2014-06-10 08:53:05 +000081}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000082
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +000083webrtc::VideoSendStream::Config FakeVideoSendStream::GetConfig() const {
pbos@webrtc.org86f613d2014-06-10 08:53:05 +000084 return config_;
85}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000086
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +000087webrtc::VideoEncoderConfig FakeVideoSendStream::GetEncoderConfig() const {
88 return encoder_config_;
89}
90
pbos@webrtc.org86f613d2014-06-10 08:53:05 +000091std::vector<webrtc::VideoStream> FakeVideoSendStream::GetVideoStreams() {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +000092 return encoder_config_.streams;
pbos@webrtc.org86f613d2014-06-10 08:53:05 +000093}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000094
pbos@webrtc.org85f42942014-07-22 09:14:58 +000095bool FakeVideoSendStream::IsSending() const {
pbos@webrtc.org86f613d2014-06-10 08:53:05 +000096 return sending_;
97}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000098
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +000099bool FakeVideoSendStream::GetVp8Settings(
100 webrtc::VideoCodecVP8* settings) const {
101 if (!codec_settings_set_) {
102 return false;
103 }
104
105 *settings = vp8_settings_;
106 return true;
107}
108
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000109int FakeVideoSendStream::GetNumberOfSwappedFrames() const {
110 return num_swapped_frames_;
111}
112
113int FakeVideoSendStream::GetLastWidth() const {
114 return last_frame_.width();
115}
116
117int FakeVideoSendStream::GetLastHeight() const {
118 return last_frame_.height();
119}
120
121void FakeVideoSendStream::SwapFrame(webrtc::I420VideoFrame* frame) {
122 ++num_swapped_frames_;
123 last_frame_.SwapFrame(frame);
124}
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000125webrtc::VideoSendStream::Stats FakeVideoSendStream::GetStats() const {
126 return webrtc::VideoSendStream::Stats();
127}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000128
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000129bool FakeVideoSendStream::ReconfigureVideoEncoder(
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +0000130 const webrtc::VideoEncoderConfig& config) {
131 encoder_config_ = config;
132 if (config.encoder_specific_settings != NULL) {
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +0000133 assert(config_.encoder_settings.payload_name == "VP8");
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +0000134 vp8_settings_ = *reinterpret_cast<const webrtc::VideoCodecVP8*>(
135 config.encoder_specific_settings);
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +0000136 }
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +0000137 codec_settings_set_ = config.encoder_specific_settings != NULL;
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000138 return true;
139}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000140
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000141webrtc::VideoSendStreamInput* FakeVideoSendStream::Input() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000142 return this;
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000143}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000144
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000145void FakeVideoSendStream::Start() {
146 sending_ = true;
147}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000148
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000149void FakeVideoSendStream::Stop() {
150 sending_ = false;
151}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000152
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000153FakeVideoReceiveStream::FakeVideoReceiveStream(
154 const webrtc::VideoReceiveStream::Config& config)
155 : config_(config), receiving_(false) {
156}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000157
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000158webrtc::VideoReceiveStream::Config FakeVideoReceiveStream::GetConfig() {
159 return config_;
160}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000161
pbos@webrtc.org85f42942014-07-22 09:14:58 +0000162bool FakeVideoReceiveStream::IsReceiving() const {
163 return receiving_;
164}
165
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000166webrtc::VideoReceiveStream::Stats FakeVideoReceiveStream::GetStats() const {
167 return webrtc::VideoReceiveStream::Stats();
168}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000169
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000170void FakeVideoReceiveStream::Start() {
171 receiving_ = true;
172}
pbos@webrtc.org85f42942014-07-22 09:14:58 +0000173
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000174void FakeVideoReceiveStream::Stop() {
175 receiving_ = false;
176}
pbos@webrtc.org85f42942014-07-22 09:14:58 +0000177
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000178FakeCall::FakeCall(const webrtc::Call::Config& config)
179 : config_(config), network_state_(kNetworkUp) {
pbos@webrtc.org26c0c412014-09-03 16:17:12 +0000180 SetVideoCodecs(GetDefaultVideoCodecs());
181}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000182
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000183FakeCall::~FakeCall() {
184 EXPECT_EQ(0u, video_send_streams_.size());
185 EXPECT_EQ(0u, video_receive_streams_.size());
186}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000187
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000188void FakeCall::SetVideoCodecs(const std::vector<webrtc::VideoCodec> codecs) {
189 codecs_ = codecs;
190}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000191
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000192webrtc::Call::Config FakeCall::GetConfig() const {
193 return config_;
194}
195
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000196std::vector<FakeVideoSendStream*> FakeCall::GetVideoSendStreams() {
197 return video_send_streams_;
198}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000199
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000200std::vector<FakeVideoReceiveStream*> FakeCall::GetVideoReceiveStreams() {
201 return video_receive_streams_;
202}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000203
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000204webrtc::VideoCodec FakeCall::GetEmptyVideoCodec() {
205 webrtc::VideoCodec codec;
206 codec.minBitrate = 300;
207 codec.startBitrate = 800;
208 codec.maxBitrate = 1500;
209 codec.maxFramerate = 10;
210 codec.width = 640;
211 codec.height = 480;
212 codec.qpMax = 56;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000213
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000214 return codec;
215}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000216
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000217webrtc::VideoCodec FakeCall::GetVideoCodecVp8() {
218 webrtc::VideoCodec vp8_codec = GetEmptyVideoCodec();
219 vp8_codec.codecType = webrtc::kVideoCodecVP8;
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000220 rtc::strcpyn(
221 vp8_codec.plName, ARRAY_SIZE(vp8_codec.plName), kVp8Codec.name.c_str());
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000222 vp8_codec.plType = kVp8Codec.id;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000223
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000224 return vp8_codec;
225}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000226
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000227webrtc::VideoCodec FakeCall::GetVideoCodecVp9() {
228 webrtc::VideoCodec vp9_codec = GetEmptyVideoCodec();
229 // TODO(pbos): Add a correct codecType when webrtc has one.
230 vp9_codec.codecType = webrtc::kVideoCodecVP8;
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000231 rtc::strcpyn(
232 vp9_codec.plName, ARRAY_SIZE(vp9_codec.plName), kVp9Codec.name.c_str());
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000233 vp9_codec.plType = kVp9Codec.id;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000234
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000235 return vp9_codec;
236}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000237
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000238std::vector<webrtc::VideoCodec> FakeCall::GetDefaultVideoCodecs() {
239 std::vector<webrtc::VideoCodec> codecs;
240 codecs.push_back(GetVideoCodecVp8());
241 // codecs.push_back(GetVideoCodecVp9());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000242
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000243 return codecs;
244}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000245
pbos@webrtc.org26c0c412014-09-03 16:17:12 +0000246webrtc::Call::NetworkState FakeCall::GetNetworkState() const {
247 return network_state_;
248}
249
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000250webrtc::VideoSendStream* FakeCall::CreateVideoSendStream(
251 const webrtc::VideoSendStream::Config& config,
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +0000252 const webrtc::VideoEncoderConfig& encoder_config) {
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000253 FakeVideoSendStream* fake_stream =
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +0000254 new FakeVideoSendStream(config, encoder_config);
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000255 video_send_streams_.push_back(fake_stream);
256 return fake_stream;
257}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000258
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000259void FakeCall::DestroyVideoSendStream(webrtc::VideoSendStream* send_stream) {
260 FakeVideoSendStream* fake_stream =
261 static_cast<FakeVideoSendStream*>(send_stream);
262 for (size_t i = 0; i < video_send_streams_.size(); ++i) {
263 if (video_send_streams_[i] == fake_stream) {
264 delete video_send_streams_[i];
265 video_send_streams_.erase(video_send_streams_.begin() + i);
266 return;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000267 }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000268 }
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000269 ADD_FAILURE() << "DestroyVideoSendStream called with unknown paramter.";
270}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000271
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000272webrtc::VideoReceiveStream* FakeCall::CreateVideoReceiveStream(
273 const webrtc::VideoReceiveStream::Config& config) {
274 video_receive_streams_.push_back(new FakeVideoReceiveStream(config));
275 return video_receive_streams_[video_receive_streams_.size() - 1];
276}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000277
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000278void FakeCall::DestroyVideoReceiveStream(
279 webrtc::VideoReceiveStream* receive_stream) {
280 FakeVideoReceiveStream* fake_stream =
281 static_cast<FakeVideoReceiveStream*>(receive_stream);
282 for (size_t i = 0; i < video_receive_streams_.size(); ++i) {
283 if (video_receive_streams_[i] == fake_stream) {
284 delete video_receive_streams_[i];
285 video_receive_streams_.erase(video_receive_streams_.begin() + i);
286 return;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000287 }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000288 }
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000289 ADD_FAILURE() << "DestroyVideoReceiveStream called with unknown paramter.";
290}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000291
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000292webrtc::PacketReceiver* FakeCall::Receiver() {
293 // TODO(pbos): Fix this.
294 return NULL;
295}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000296
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000297uint32_t FakeCall::SendBitrateEstimate() {
298 return 0;
299}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000300
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000301uint32_t FakeCall::ReceiveBitrateEstimate() {
302 return 0;
303}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000304
pbos@webrtc.org26c0c412014-09-03 16:17:12 +0000305void FakeCall::SignalNetworkState(webrtc::Call::NetworkState state) {
306 network_state_ = state;
307}
308
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000309class WebRtcVideoEngine2Test : public ::testing::Test {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000310 public:
pbos@webrtc.orgb648b9d2014-08-26 11:08:06 +0000311 WebRtcVideoEngine2Test() {
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +0000312 std::vector<VideoCodec> engine_codecs = engine_.codecs();
313 assert(!engine_codecs.empty());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000314 bool codec_set = false;
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +0000315 for (size_t i = 0; i < engine_codecs.size(); ++i) {
316 if (engine_codecs[i].name == "red") {
317 default_red_codec_ = engine_codecs[i];
318 } else if (engine_codecs[i].name == "ulpfec") {
319 default_ulpfec_codec_ = engine_codecs[i];
320 } else if (engine_codecs[i].name == "rtx") {
321 default_rtx_codec_ = engine_codecs[i];
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000322 } else if (!codec_set) {
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +0000323 default_codec_ = engine_codecs[i];
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000324 codec_set = true;
325 }
326 }
327
328 assert(codec_set);
329 }
330
331 protected:
pbos@webrtc.org3bf3d232014-10-31 12:59:34 +0000332 class FakeCallFactory : public WebRtcCallFactory {
333 public:
334 FakeCallFactory() : fake_call_(NULL) {}
335 FakeCall* GetCall() { return fake_call_; }
336
337 private:
338 virtual webrtc::Call* CreateCall(
339 const webrtc::Call::Config& config) OVERRIDE {
340 assert(fake_call_ == NULL);
341 fake_call_ = new FakeCall(config);
342 return fake_call_;
343 }
344
345 FakeCall* fake_call_;
346 };
347
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000348 VideoMediaChannel* SetUpForExternalEncoderFactory(
349 cricket::WebRtcVideoEncoderFactory* encoder_factory,
350 const std::vector<VideoCodec>& codecs);
pbos@webrtc.orgfa553ef2014-10-20 11:07:07 +0000351
352 void TestStartBitrate(bool override_start_bitrate, int start_bitrate_bps);
353
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000354 WebRtcVideoEngine2 engine_;
355 VideoCodec default_codec_;
356 VideoCodec default_red_codec_;
357 VideoCodec default_ulpfec_codec_;
358 VideoCodec default_rtx_codec_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000359};
360
pbos@webrtc.org3bf3d232014-10-31 12:59:34 +0000361TEST_F(WebRtcVideoEngine2Test, ConfiguresAvSyncForFirstReceiveChannel) {
362 FakeCallFactory call_factory;
363 engine_.SetCallFactory(&call_factory);
364
365 WebRtcVoiceEngine voice_engine;
366 engine_.SetVoiceEngine(&voice_engine);
367 voice_engine.Init(rtc::Thread::Current());
368 engine_.Init(rtc::Thread::Current());
369
370 rtc::scoped_ptr<VoiceMediaChannel> voice_channel(
371 voice_engine.CreateChannel());
372 ASSERT_TRUE(voice_channel.get() != NULL);
373 WebRtcVoiceMediaChannel* webrtc_voice_channel =
374 static_cast<WebRtcVoiceMediaChannel*>(voice_channel.get());
375 ASSERT_NE(webrtc_voice_channel->voe_channel(), -1);
376 rtc::scoped_ptr<VideoMediaChannel> channel(
377 engine_.CreateChannel(cricket::VideoOptions(), voice_channel.get()));
378
379 FakeCall* fake_call = call_factory.GetCall();
380 ASSERT_TRUE(fake_call != NULL);
381
382 webrtc::Call::Config call_config = fake_call->GetConfig();
383
384 ASSERT_TRUE(voice_engine.voe()->engine() != NULL);
385 ASSERT_EQ(voice_engine.voe()->engine(), call_config.voice_engine);
386
387 EXPECT_TRUE(channel->AddRecvStream(StreamParams::CreateLegacy(kSsrc)));
388 EXPECT_TRUE(channel->AddRecvStream(StreamParams::CreateLegacy(kSsrc + 1)));
389 std::vector<FakeVideoReceiveStream*> receive_streams =
390 fake_call->GetVideoReceiveStreams();
391
392 ASSERT_EQ(2u, receive_streams.size());
393 EXPECT_EQ(webrtc_voice_channel->voe_channel(),
394 receive_streams[0]->GetConfig().audio_channel_id);
395 EXPECT_EQ(-1, receive_streams[1]->GetConfig().audio_channel_id)
396 << "AV sync should only be set up for the first receive channel.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000397}
398
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000399TEST_F(WebRtcVideoEngine2Test, FindCodec) {
400 const std::vector<cricket::VideoCodec>& c = engine_.codecs();
401 EXPECT_EQ(4U, c.size());
402
403 cricket::VideoCodec vp8(104, "VP8", 320, 200, 30, 0);
404 EXPECT_TRUE(engine_.FindCodec(vp8));
405
406 cricket::VideoCodec vp8_ci(104, "vp8", 320, 200, 30, 0);
407 EXPECT_TRUE(engine_.FindCodec(vp8));
408
409 cricket::VideoCodec vp8_diff_fr_diff_pref(104, "VP8", 320, 200, 50, 50);
410 EXPECT_TRUE(engine_.FindCodec(vp8_diff_fr_diff_pref));
411
412 cricket::VideoCodec vp8_diff_id(95, "VP8", 320, 200, 30, 0);
413 EXPECT_FALSE(engine_.FindCodec(vp8_diff_id));
414 vp8_diff_id.id = 97;
415 EXPECT_TRUE(engine_.FindCodec(vp8_diff_id));
416
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000417 // FindCodec ignores the codec size.
418 // Test that FindCodec can accept uncommon codec size.
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000419 cricket::VideoCodec vp8_diff_res(104, "VP8", 320, 111, 30, 0);
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000420 EXPECT_TRUE(engine_.FindCodec(vp8_diff_res));
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000421
422 // PeerConnection doesn't negotiate the resolution at this point.
423 // Test that FindCodec can handle the case when width/height is 0.
424 cricket::VideoCodec vp8_zero_res(104, "VP8", 0, 0, 30, 0);
425 EXPECT_TRUE(engine_.FindCodec(vp8_zero_res));
426
427 cricket::VideoCodec red(101, "RED", 0, 0, 30, 0);
428 EXPECT_TRUE(engine_.FindCodec(red));
429
430 cricket::VideoCodec red_ci(101, "red", 0, 0, 30, 0);
431 EXPECT_TRUE(engine_.FindCodec(red));
432
433 cricket::VideoCodec fec(102, "ULPFEC", 0, 0, 30, 0);
434 EXPECT_TRUE(engine_.FindCodec(fec));
435
436 cricket::VideoCodec fec_ci(102, "ulpfec", 0, 0, 30, 0);
437 EXPECT_TRUE(engine_.FindCodec(fec));
438
439 cricket::VideoCodec rtx(96, "rtx", 0, 0, 30, 0);
440 EXPECT_TRUE(engine_.FindCodec(rtx));
441}
442
443TEST_F(WebRtcVideoEngine2Test, DefaultRtxCodecHasAssociatedPayloadTypeSet) {
444 std::vector<VideoCodec> engine_codecs = engine_.codecs();
445 for (size_t i = 0; i < engine_codecs.size(); ++i) {
446 if (engine_codecs[i].name != kRtxCodecName)
447 continue;
448 int associated_payload_type;
449 EXPECT_TRUE(engine_codecs[i].GetParam(kCodecParamAssociatedPayloadType,
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000450 &associated_payload_type));
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000451 EXPECT_EQ(default_codec_.id, associated_payload_type);
452 return;
453 }
454 FAIL() << "No RTX codec found among default codecs.";
455}
456
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000457TEST_F(WebRtcVideoEngine2Test, SupportsTimestampOffsetHeaderExtension) {
458 std::vector<RtpHeaderExtension> extensions = engine_.rtp_header_extensions();
459 ASSERT_FALSE(extensions.empty());
460 for (size_t i = 0; i < extensions.size(); ++i) {
461 if (extensions[i].uri == kRtpTimestampOffsetHeaderExtension) {
462 EXPECT_EQ(kRtpTimestampOffsetHeaderExtensionDefaultId, extensions[i].id);
463 return;
464 }
465 }
466 FAIL() << "Timestamp offset extension not in header-extension list.";
467}
468
469TEST_F(WebRtcVideoEngine2Test, SupportsAbsoluteSenderTimeHeaderExtension) {
470 std::vector<RtpHeaderExtension> extensions = engine_.rtp_header_extensions();
471 ASSERT_FALSE(extensions.empty());
472 for (size_t i = 0; i < extensions.size(); ++i) {
473 if (extensions[i].uri == kRtpAbsoluteSenderTimeHeaderExtension) {
474 EXPECT_EQ(kRtpAbsoluteSenderTimeHeaderExtensionDefaultId,
475 extensions[i].id);
476 return;
477 }
478 }
479 FAIL() << "Absolute Sender Time extension not in header-extension list.";
480}
481
pbos@webrtc.orgfa553ef2014-10-20 11:07:07 +0000482void WebRtcVideoEngine2Test::TestStartBitrate(bool override_start_bitrate,
483 int start_bitrate_bps) {
pbos@webrtc.orgfa553ef2014-10-20 11:07:07 +0000484 FakeCallFactory call_factory;
485 engine_.SetCallFactory(&call_factory);
486
487 engine_.Init(rtc::Thread::Current());
488
489 cricket::VideoOptions options;
490 if (override_start_bitrate) {
491 options.video_start_bitrate.Set(start_bitrate_bps / 1000);
492 }
493
494 rtc::scoped_ptr<VideoMediaChannel> channel(
495 engine_.CreateChannel(options, NULL));
496
497 EXPECT_EQ(override_start_bitrate
498 ? start_bitrate_bps
499 : webrtc::Call::Config::kDefaultStartBitrateBps,
500 call_factory.GetCall()->GetConfig().stream_start_bitrate_bps);
501}
502
503TEST_F(WebRtcVideoEngine2Test, UsesCorrectDefaultStartBitrate) {
504 TestStartBitrate(false, -1);
505}
506
507TEST_F(WebRtcVideoEngine2Test, CreateChannelCanUseIncreasedStartBitrate) {
508 TestStartBitrate(true, 2 * webrtc::Call::Config::kDefaultStartBitrateBps);
509}
510
511TEST_F(WebRtcVideoEngine2Test, CreateChannelCanUseDecreasedStartBitrate) {
512 TestStartBitrate(true, webrtc::Call::Config::kDefaultStartBitrateBps / 2);
513}
514
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +0000515TEST_F(WebRtcVideoEngine2Test, SetSendFailsBeforeSettingCodecs) {
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000516 engine_.Init(rtc::Thread::Current());
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000517 rtc::scoped_ptr<VideoMediaChannel> channel(
518 engine_.CreateChannel(cricket::VideoOptions(), NULL));
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +0000519
520 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
521
522 EXPECT_FALSE(channel->SetSend(true))
523 << "Channel should not start without codecs.";
524 EXPECT_TRUE(channel->SetSend(false))
525 << "Channel should be stoppable even without set codecs.";
526}
527
pbos@webrtc.orgc3d2bd22014-08-12 20:55:10 +0000528TEST_F(WebRtcVideoEngine2Test, GetStatsWithoutSendCodecsSetDoesNotCrash) {
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000529 engine_.Init(rtc::Thread::Current());
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000530 rtc::scoped_ptr<VideoMediaChannel> channel(
531 engine_.CreateChannel(cricket::VideoOptions(), NULL));
pbos@webrtc.orgc3d2bd22014-08-12 20:55:10 +0000532 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
533 VideoMediaInfo info;
534 channel->GetStats(&info);
535}
536
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000537TEST_F(WebRtcVideoEngine2Test, UseExternalFactoryForVp8WhenSupported) {
538 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
539 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
540 std::vector<cricket::VideoCodec> codecs;
541 codecs.push_back(kVp8Codec);
542
543 rtc::scoped_ptr<VideoMediaChannel> channel(
544 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
545
546 EXPECT_TRUE(
547 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
548 ASSERT_EQ(1u, encoder_factory.encoders().size());
549 EXPECT_TRUE(channel->SetSend(true));
550
551 cricket::FakeVideoCapturer capturer;
552 EXPECT_TRUE(channel->SetCapturer(kSsrc, &capturer));
553 EXPECT_EQ(cricket::CS_RUNNING,
554 capturer.Start(capturer.GetSupportedFormats()->front()));
555 EXPECT_TRUE(capturer.CaptureFrame());
556
557 EXPECT_TRUE_WAIT(encoder_factory.encoders()[0]->GetNumEncodedFrames() > 0,
558 kTimeout);
559
560 // Setting codecs of the same type should not reallocate the encoder.
561 EXPECT_TRUE(channel->SetSendCodecs(codecs));
562 EXPECT_EQ(1, encoder_factory.GetNumCreatedEncoders());
563
564 // Remove stream previously added to free the external encoder instance.
565 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
566 EXPECT_EQ(0u, encoder_factory.encoders().size());
567}
568
569VideoMediaChannel* WebRtcVideoEngine2Test::SetUpForExternalEncoderFactory(
570 cricket::WebRtcVideoEncoderFactory* encoder_factory,
571 const std::vector<VideoCodec>& codecs) {
572 engine_.SetExternalEncoderFactory(encoder_factory);
573 engine_.Init(rtc::Thread::Current());
574
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000575 VideoMediaChannel* channel =
576 engine_.CreateChannel(cricket::VideoOptions(), NULL);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000577 EXPECT_TRUE(channel->SetSendCodecs(codecs));
578
579 return channel;
580}
581
582TEST_F(WebRtcVideoEngine2Test, ChannelWithExternalH264CanChangeToInternalVp8) {
583 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
584 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
585 std::vector<cricket::VideoCodec> codecs;
586 codecs.push_back(kH264Codec);
587
588 rtc::scoped_ptr<VideoMediaChannel> channel(
589 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
590
591 EXPECT_TRUE(
592 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
593 ASSERT_EQ(1u, encoder_factory.encoders().size());
594
595 codecs.clear();
596 codecs.push_back(kVp8Codec);
597 EXPECT_TRUE(channel->SetSendCodecs(codecs));
598
599 ASSERT_EQ(0u, encoder_factory.encoders().size());
600}
601
602TEST_F(WebRtcVideoEngine2Test,
603 DontUseExternalEncoderFactoryForUnsupportedCodecs) {
604 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
605 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
606 std::vector<cricket::VideoCodec> codecs;
607 codecs.push_back(kVp8Codec);
608
609 rtc::scoped_ptr<VideoMediaChannel> channel(
610 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
611
612 EXPECT_TRUE(
613 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
614 ASSERT_EQ(0u, encoder_factory.encoders().size());
615}
616
617// Test external codec with be added to the end of the supported codec list.
618TEST_F(WebRtcVideoEngine2Test, ReportSupportedExternalCodecs) {
619 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
620 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
621 engine_.SetExternalEncoderFactory(&encoder_factory);
622
623 engine_.Init(rtc::Thread::Current());
624
625 std::vector<cricket::VideoCodec> codecs(engine_.codecs());
626 ASSERT_GE(codecs.size(), 2u);
627 cricket::VideoCodec internal_codec = codecs.front();
628 cricket::VideoCodec external_codec = codecs.back();
629
630 // The external codec will appear at last.
631 EXPECT_EQ("VP8", internal_codec.name);
632 EXPECT_EQ("H264", external_codec.name);
633}
634
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000635class WebRtcVideoEngine2BaseTest
636 : public VideoEngineTest<cricket::WebRtcVideoEngine2> {
637 protected:
638 typedef VideoEngineTest<cricket::WebRtcVideoEngine2> Base;
639};
640
641#define WEBRTC_ENGINE_BASE_TEST(test) \
642 TEST_F(WebRtcVideoEngine2BaseTest, test) { Base::test##Body(); }
643
644WEBRTC_ENGINE_BASE_TEST(ConstrainNewCodec2);
645
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000646class WebRtcVideoChannel2BaseTest
647 : public VideoMediaChannelTest<WebRtcVideoEngine2, WebRtcVideoChannel2> {
648 protected:
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000649 typedef VideoMediaChannelTest<WebRtcVideoEngine2, WebRtcVideoChannel2> Base;
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000650
651 virtual cricket::VideoCodec DefaultCodec() OVERRIDE { return kVp8Codec; }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000652};
653
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000654#define WEBRTC_BASE_TEST(test) \
655 TEST_F(WebRtcVideoChannel2BaseTest, test) { Base::test(); }
656
657#define WEBRTC_DISABLED_BASE_TEST(test) \
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000658 TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_##test) { Base::test(); }
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000659
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000660// TODO(pbos): Fix WebRtcVideoEngine2BaseTest, where we want CheckCoInitialize.
661#if 0
662// TODO(juberti): Figure out why ViE is munging the COM refcount.
663#ifdef WIN32
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000664WEBRTC_DISABLED_BASE_TEST(CheckCoInitialize) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000665 Base::CheckCoInitialize();
666}
667#endif
668#endif
669
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000670WEBRTC_BASE_TEST(SetSend);
671WEBRTC_BASE_TEST(SetSendWithoutCodecs);
672WEBRTC_BASE_TEST(SetSendSetsTransportBufferSizes);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000673
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000674WEBRTC_BASE_TEST(GetStats);
675WEBRTC_BASE_TEST(GetStatsMultipleRecvStreams);
676WEBRTC_BASE_TEST(GetStatsMultipleSendStreams);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000677
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000678WEBRTC_BASE_TEST(SetSendBandwidth);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000679
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000680WEBRTC_BASE_TEST(SetSendSsrc);
681WEBRTC_BASE_TEST(SetSendSsrcAfterSetCodecs);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000682
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000683WEBRTC_BASE_TEST(SetRenderer);
684WEBRTC_BASE_TEST(AddRemoveRecvStreams);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000685
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000686WEBRTC_DISABLED_BASE_TEST(AddRemoveRecvStreamAndRender);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000687
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000688WEBRTC_BASE_TEST(AddRemoveRecvStreamsNoConference);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000689
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000690WEBRTC_BASE_TEST(AddRemoveSendStreams);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000691
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000692WEBRTC_BASE_TEST(SimulateConference);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000693
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000694WEBRTC_BASE_TEST(AddRemoveCapturer);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000695
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000696WEBRTC_BASE_TEST(RemoveCapturerWithoutAdd);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000697
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000698WEBRTC_BASE_TEST(AddRemoveCapturerMultipleSources);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000699
700// TODO(pbos): Figure out why this fails so often.
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000701WEBRTC_DISABLED_BASE_TEST(HighAspectHighHeightCapturer);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000702
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000703WEBRTC_BASE_TEST(RejectEmptyStreamParams);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000704
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000705WEBRTC_BASE_TEST(AdaptResolution16x10);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000706
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000707WEBRTC_BASE_TEST(AdaptResolution4x3);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000708
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000709// TODO(juberti): Restore this test once we support sending 0 fps.
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000710WEBRTC_DISABLED_BASE_TEST(AdaptDropAllFrames);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000711// TODO(juberti): Understand why we get decode errors on this test.
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000712WEBRTC_DISABLED_BASE_TEST(AdaptFramerate);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000713
pbos@webrtc.orgc4175b92014-09-03 15:25:49 +0000714WEBRTC_BASE_TEST(SendsLowerResolutionOnSmallerFrames);
715
716WEBRTC_BASE_TEST(MuteStream);
717
718WEBRTC_BASE_TEST(MultipleSendStreams);
719
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000720WEBRTC_BASE_TEST(SetSendStreamFormat0x0);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000721
722// TODO(zhurunz): Fix the flakey test.
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000723WEBRTC_DISABLED_BASE_TEST(SetSendStreamFormat);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000724
pbos@webrtc.org9359cb32014-07-23 15:44:48 +0000725TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8Vga) {
726 SendAndReceive(cricket::VideoCodec(100, "VP8", 640, 400, 30, 0));
727}
728
729TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8Qvga) {
730 SendAndReceive(cricket::VideoCodec(100, "VP8", 320, 200, 30, 0));
731}
732
733TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8SvcQqvga) {
734 SendAndReceive(cricket::VideoCodec(100, "VP8", 160, 100, 30, 0));
735}
736
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000737TEST_F(WebRtcVideoChannel2BaseTest, TwoStreamsSendAndReceive) {
738 Base::TwoStreamsSendAndReceive(kVp8Codec);
739}
740
741TEST_F(WebRtcVideoChannel2BaseTest, TwoStreamsReUseFirstStream) {
742 Base::TwoStreamsReUseFirstStream(kVp8Codec);
743}
744
pbos@webrtc.org9359cb32014-07-23 15:44:48 +0000745WEBRTC_BASE_TEST(SendManyResizeOnce);
746
747// TODO(pbos): Enable and figure out why this fails (or should work).
748TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_SendVp8HdAndReceiveAdaptedVp8Vga) {
749 EXPECT_TRUE(channel_->SetCapturer(kSsrc, NULL));
750 EXPECT_TRUE(channel_->SetRenderer(kDefaultReceiveSsrc, &renderer_));
751 channel_->UpdateAspectRatio(1280, 720);
752 video_capturer_.reset(new cricket::FakeVideoCapturer);
753 const std::vector<cricket::VideoFormat>* formats =
754 video_capturer_->GetSupportedFormats();
755 cricket::VideoFormat capture_format_hd = (*formats)[0];
756 EXPECT_EQ(cricket::CS_RUNNING, video_capturer_->Start(capture_format_hd));
757 EXPECT_TRUE(channel_->SetCapturer(kSsrc, video_capturer_.get()));
758
759 // Capture format HD -> adapt (OnOutputFormatRequest VGA) -> VGA.
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +0000760 cricket::VideoCodec codec = kVp8Codec720p;
pbos@webrtc.org9359cb32014-07-23 15:44:48 +0000761 EXPECT_TRUE(SetOneCodec(codec));
762 codec.width /= 2;
763 codec.height /= 2;
764 EXPECT_TRUE(SetSend(true));
765 EXPECT_TRUE(channel_->SetRender(true));
766 EXPECT_EQ(0, renderer_.num_rendered_frames());
767 EXPECT_TRUE(SendFrame());
768 EXPECT_FRAME_WAIT(1, codec.width, codec.height, kTimeout);
769}
770
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000771class WebRtcVideoChannel2Test : public WebRtcVideoEngine2Test,
772 public WebRtcCallFactory {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000773 public:
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000774 WebRtcVideoChannel2Test() : fake_call_(NULL) {}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000775 virtual void SetUp() OVERRIDE {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000776 engine_.SetCallFactory(this);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000777 engine_.Init(rtc::Thread::Current());
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000778 channel_.reset(engine_.CreateChannel(cricket::VideoOptions(), NULL));
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000779 ASSERT_TRUE(fake_call_ != NULL) << "Call not created through factory.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000780 last_ssrc_ = 123;
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000781 ASSERT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000782 }
783
784 protected:
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000785 virtual webrtc::Call* CreateCall(
786 const webrtc::Call::Config& config) OVERRIDE {
787 assert(fake_call_ == NULL);
788 fake_call_ = new FakeCall(config);
789 return fake_call_;
790 }
791
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000792 FakeVideoSendStream* AddSendStream() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000793 return AddSendStream(StreamParams::CreateLegacy(++last_ssrc_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000794 }
795
796 FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000797 size_t num_streams = fake_call_->GetVideoSendStreams().size();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000798 EXPECT_TRUE(channel_->AddSendStream(sp));
799 std::vector<FakeVideoSendStream*> streams =
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000800 fake_call_->GetVideoSendStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000801 EXPECT_EQ(num_streams + 1, streams.size());
802 return streams[streams.size() - 1];
803 }
804
805 std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000806 return fake_call_->GetVideoSendStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000807 }
808
809 FakeVideoReceiveStream* AddRecvStream() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000810 return AddRecvStream(StreamParams::CreateLegacy(++last_ssrc_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000811 }
812
813 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000814 size_t num_streams = fake_call_->GetVideoReceiveStreams().size();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000815 EXPECT_TRUE(channel_->AddRecvStream(sp));
816 std::vector<FakeVideoReceiveStream*> streams =
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000817 fake_call_->GetVideoReceiveStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000818 EXPECT_EQ(num_streams + 1, streams.size());
819 return streams[streams.size() - 1];
820 }
821
822 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate,
823 const char* max_bitrate) {
824 std::vector<VideoCodec> codecs;
825 codecs.push_back(kVp8Codec);
826 codecs[0].params[kCodecParamMinBitrate] = min_bitrate;
827 codecs[0].params[kCodecParamMaxBitrate] = max_bitrate;
828 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
829
830 FakeVideoSendStream* stream = AddSendStream();
831
pbos@webrtc.org6ae48c62014-06-06 10:49:19 +0000832 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
833 ASSERT_EQ(1u, video_streams.size());
834 EXPECT_EQ(atoi(min_bitrate), video_streams.back().min_bitrate_bps / 1000);
835 EXPECT_EQ(atoi(max_bitrate), video_streams.back().max_bitrate_bps / 1000);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000836
837 VideoCodec codec;
838 EXPECT_TRUE(channel_->GetSendCodec(&codec));
839 EXPECT_EQ(min_bitrate, codec.params[kCodecParamMinBitrate]);
840 EXPECT_EQ(max_bitrate, codec.params[kCodecParamMaxBitrate]);
841 }
842
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000843 void TestSetSendRtpHeaderExtensions(const std::string& cricket_ext,
844 const std::string& webrtc_ext) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000845 FakeCall* call = fake_call_;
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000846 // Enable extension.
847 const int id = 1;
848 std::vector<cricket::RtpHeaderExtension> extensions;
849 extensions.push_back(cricket::RtpHeaderExtension(cricket_ext, id));
850 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
851
852 FakeVideoSendStream* send_stream =
853 AddSendStream(cricket::StreamParams::CreateLegacy(123));
854
855 // Verify the send extension id.
856 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
857 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
858 EXPECT_EQ(webrtc_ext, send_stream->GetConfig().rtp.extensions[0].name);
859 // Verify call with same set of extensions returns true.
860 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
861 // Verify that SetSendRtpHeaderExtensions doesn't implicitly add them for
862 // receivers.
863 EXPECT_TRUE(AddRecvStream(cricket::StreamParams::CreateLegacy(123))
864 ->GetConfig()
865 .rtp.extensions.empty());
866
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +0000867 // Verify that existing RTP header extensions can be removed.
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000868 std::vector<cricket::RtpHeaderExtension> empty_extensions;
869 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(empty_extensions));
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +0000870 ASSERT_EQ(1u, call->GetVideoSendStreams().size());
871 send_stream = call->GetVideoSendStreams()[0];
872 EXPECT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
873
874 // Verify that adding receive RTP header extensions adds them for existing
875 // streams.
876 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
877 send_stream = call->GetVideoSendStreams()[0];
878 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
879 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
880 EXPECT_EQ(webrtc_ext, send_stream->GetConfig().rtp.extensions[0].name);
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000881 }
882
883 void TestSetRecvRtpHeaderExtensions(const std::string& cricket_ext,
884 const std::string& webrtc_ext) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000885 FakeCall* call = fake_call_;
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000886 // Enable extension.
887 const int id = 1;
888 std::vector<cricket::RtpHeaderExtension> extensions;
889 extensions.push_back(cricket::RtpHeaderExtension(cricket_ext, id));
890 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
891
892 FakeVideoReceiveStream* recv_stream =
893 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
894
895 // Verify the recv extension id.
896 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
897 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
898 EXPECT_EQ(webrtc_ext, recv_stream->GetConfig().rtp.extensions[0].name);
899 // Verify call with same set of extensions returns true.
900 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +0000901
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000902 // Verify that SetRecvRtpHeaderExtensions doesn't implicitly add them for
903 // senders.
904 EXPECT_TRUE(AddSendStream(cricket::StreamParams::CreateLegacy(123))
905 ->GetConfig()
906 .rtp.extensions.empty());
907
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +0000908 // Verify that existing RTP header extensions can be removed.
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000909 std::vector<cricket::RtpHeaderExtension> empty_extensions;
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +0000910 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(empty_extensions));
911 ASSERT_EQ(1u, call->GetVideoReceiveStreams().size());
912 recv_stream = call->GetVideoReceiveStreams()[0];
913 EXPECT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
914
915 // Verify that adding receive RTP header extensions adds them for existing
916 // streams.
917 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
918 recv_stream = call->GetVideoReceiveStreams()[0];
919 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
920 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
921 EXPECT_EQ(webrtc_ext, recv_stream->GetConfig().rtp.extensions[0].name);
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000922 }
923
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000924 void TestCpuAdaptation(bool enable_overuse);
925
926 FakeCall* fake_call_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000927 rtc::scoped_ptr<VideoMediaChannel> channel_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000928 uint32 last_ssrc_;
929};
930
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000931TEST_F(WebRtcVideoChannel2Test, RecvStreamWithSimAndRtx) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000932 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
933 EXPECT_TRUE(channel_->SetSend(true));
934 cricket::VideoOptions options;
935 options.conference_mode.Set(true);
936 EXPECT_TRUE(channel_->SetOptions(options));
937
938 // Send side.
939 const std::vector<uint32> ssrcs = MAKE_VECTOR(kSsrcs1);
940 const std::vector<uint32> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
941 FakeVideoSendStream* send_stream = AddSendStream(
942 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
943
944 ASSERT_EQ(rtx_ssrcs.size(), send_stream->GetConfig().rtp.rtx.ssrcs.size());
945 for (size_t i = 0; i < rtx_ssrcs.size(); ++i)
946 EXPECT_EQ(rtx_ssrcs[i], send_stream->GetConfig().rtp.rtx.ssrcs[i]);
947
948 // Receiver side.
949 FakeVideoReceiveStream* recv_stream = AddRecvStream(
950 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
951 ASSERT_GT(recv_stream->GetConfig().rtp.rtx.size(), 0u)
952 << "No SSRCs for RTX configured by AddRecvStream.";
953 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.rtx.size())
954 << "This test only works with one receive codec. Please update the test.";
955 EXPECT_EQ(rtx_ssrcs[0],
956 recv_stream->GetConfig().rtp.rtx.begin()->second.ssrc);
957 // TODO(pbos): Make sure we set the RTX for correct payloads etc.
958}
959
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000960TEST_F(WebRtcVideoChannel2Test, RecvStreamWithRtx) {
961 // Setup one channel with an associated RTX stream.
962 cricket::StreamParams params =
963 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
964 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
965 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
966 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.rtx.size());
967 EXPECT_EQ(kRtxSsrcs1[0],
968 recv_stream->GetConfig().rtp.rtx.begin()->second.ssrc);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000969}
970
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000971TEST_F(WebRtcVideoChannel2Test, RecvStreamNoRtx) {
972 // Setup one channel without an associated RTX stream.
973 cricket::StreamParams params =
974 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
975 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
976 ASSERT_TRUE(recv_stream->GetConfig().rtp.rtx.empty());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000977}
978
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000979TEST_F(WebRtcVideoChannel2Test, NoHeaderExtesionsByDefault) {
980 FakeVideoSendStream* send_stream =
981 AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
982 ASSERT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
983
984 FakeVideoReceiveStream* recv_stream =
985 AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
986 ASSERT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000987}
988
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000989// Test support for RTP timestamp offset header extension.
990TEST_F(WebRtcVideoChannel2Test, SendRtpTimestampOffsetHeaderExtensions) {
991 TestSetSendRtpHeaderExtensions(kRtpTimestampOffsetHeaderExtension,
992 webrtc::RtpExtension::kTOffset);
993}
994TEST_F(WebRtcVideoChannel2Test, RecvRtpTimestampOffsetHeaderExtensions) {
995 TestSetRecvRtpHeaderExtensions(kRtpTimestampOffsetHeaderExtension,
996 webrtc::RtpExtension::kTOffset);
997}
998
999// Test support for absolute send time header extension.
1000TEST_F(WebRtcVideoChannel2Test, SendAbsoluteSendTimeHeaderExtensions) {
1001 TestSetSendRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension,
1002 webrtc::RtpExtension::kAbsSendTime);
1003}
1004TEST_F(WebRtcVideoChannel2Test, RecvAbsoluteSendTimeHeaderExtensions) {
1005 TestSetRecvRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension,
1006 webrtc::RtpExtension::kAbsSendTime);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001007}
1008
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001009TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001010 SetSendRtpHeaderExtensionsExcludeUnsupportedExtensions) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001011 const int kUnsupportedId = 1;
1012 const int kTOffsetId = 2;
1013
1014 std::vector<cricket::RtpHeaderExtension> extensions;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001015 extensions.push_back(
1016 cricket::RtpHeaderExtension(kUnsupportedExtensionName, kUnsupportedId));
1017 extensions.push_back(
1018 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, kTOffsetId));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001019 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
1020 FakeVideoSendStream* send_stream =
1021 AddSendStream(cricket::StreamParams::CreateLegacy(123));
1022
1023 // Only timestamp offset extension is set to send stream,
1024 // unsupported rtp extension is ignored.
1025 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
1026 EXPECT_STREQ(webrtc::RtpExtension::kTOffset,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001027 send_stream->GetConfig().rtp.extensions[0].name.c_str());
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001028}
1029
1030TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001031 SetRecvRtpHeaderExtensionsExcludeUnsupportedExtensions) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001032 const int kUnsupportedId = 1;
1033 const int kTOffsetId = 2;
1034
1035 std::vector<cricket::RtpHeaderExtension> extensions;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001036 extensions.push_back(
1037 cricket::RtpHeaderExtension(kUnsupportedExtensionName, kUnsupportedId));
1038 extensions.push_back(
1039 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, kTOffsetId));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001040 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
1041 FakeVideoReceiveStream* recv_stream =
1042 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
1043
1044 // Only timestamp offset extension is set to receive stream,
1045 // unsupported rtp extension is ignored.
1046 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
1047 EXPECT_STREQ(webrtc::RtpExtension::kTOffset,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001048 recv_stream->GetConfig().rtp.extensions[0].name.c_str());
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001049}
1050
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001051TEST_F(WebRtcVideoChannel2Test, SetSendRtpHeaderExtensionsRejectsIncorrectIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001052 const size_t kNumIncorrectIds = 4;
1053 const int kIncorrectIds[kNumIncorrectIds] = {-2, -1, 15, 16};
1054 for (size_t i = 0; i < kNumIncorrectIds; ++i) {
1055 std::vector<cricket::RtpHeaderExtension> extensions;
1056 extensions.push_back(cricket::RtpHeaderExtension(
1057 webrtc::RtpExtension::kTOffset, kIncorrectIds[i]));
1058 EXPECT_FALSE(channel_->SetSendRtpHeaderExtensions(extensions))
1059 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
1060 }
1061}
1062
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001063TEST_F(WebRtcVideoChannel2Test, SetRecvRtpHeaderExtensionsRejectsIncorrectIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001064 const size_t kNumIncorrectIds = 4;
1065 const int kIncorrectIds[kNumIncorrectIds] = {-2, -1, 15, 16};
1066 for (size_t i = 0; i < kNumIncorrectIds; ++i) {
1067 std::vector<cricket::RtpHeaderExtension> extensions;
1068 extensions.push_back(cricket::RtpHeaderExtension(
1069 webrtc::RtpExtension::kTOffset, kIncorrectIds[i]));
1070 EXPECT_FALSE(channel_->SetRecvRtpHeaderExtensions(extensions))
1071 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
1072 }
1073}
1074
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001075TEST_F(WebRtcVideoChannel2Test, SetSendRtpHeaderExtensionsRejectsDuplicateIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001076 const int id = 1;
1077 std::vector<cricket::RtpHeaderExtension> extensions;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001078 extensions.push_back(
1079 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, id));
1080 extensions.push_back(
1081 cricket::RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, id));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001082 EXPECT_FALSE(channel_->SetSendRtpHeaderExtensions(extensions));
1083
1084 // Duplicate entries are also not supported.
1085 extensions.clear();
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001086 extensions.push_back(
1087 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, id));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001088 extensions.push_back(extensions.back());
1089 EXPECT_FALSE(channel_->SetSendRtpHeaderExtensions(extensions));
1090}
1091
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001092TEST_F(WebRtcVideoChannel2Test, SetRecvRtpHeaderExtensionsRejectsDuplicateIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001093 const int id = 1;
1094 std::vector<cricket::RtpHeaderExtension> extensions;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001095 extensions.push_back(
1096 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, id));
1097 extensions.push_back(
1098 cricket::RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, id));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001099 EXPECT_FALSE(channel_->SetRecvRtpHeaderExtensions(extensions));
1100
1101 // Duplicate entries are also not supported.
1102 extensions.clear();
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001103 extensions.push_back(
1104 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, id));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001105 extensions.push_back(extensions.back());
1106 EXPECT_FALSE(channel_->SetRecvRtpHeaderExtensions(extensions));
1107}
1108
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001109TEST_F(WebRtcVideoChannel2Test, DISABLED_LeakyBucketTest) {
1110 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1111}
1112
1113TEST_F(WebRtcVideoChannel2Test, DISABLED_BufferedModeLatency) {
1114 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1115}
1116
1117TEST_F(WebRtcVideoChannel2Test, DISABLED_AdditiveVideoOptions) {
1118 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1119}
1120
1121TEST_F(WebRtcVideoChannel2Test, AddRecvStreamOnlyUsesOneReceiveStream) {
1122 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001123 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001124}
1125
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001126TEST_F(WebRtcVideoChannel2Test, RembIsEnabledByDefault) {
1127 FakeVideoReceiveStream* stream = AddRecvStream();
1128 EXPECT_TRUE(stream->GetConfig().rtp.remb);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001129}
1130
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001131TEST_F(WebRtcVideoChannel2Test, RembCanBeEnabledAndDisabled) {
1132 FakeVideoReceiveStream* stream = AddRecvStream();
1133 EXPECT_TRUE(stream->GetConfig().rtp.remb);
1134
1135 // Verify that REMB is turned off when codecs without REMB are set.
1136 std::vector<VideoCodec> codecs;
1137 codecs.push_back(kVp8Codec);
1138 EXPECT_TRUE(codecs[0].feedback_params.params().empty());
1139 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001140 stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001141 EXPECT_FALSE(stream->GetConfig().rtp.remb);
1142
1143 // Verify that REMB is turned on when setting default codecs since the
1144 // default codecs have REMB enabled.
1145 EXPECT_TRUE(channel_->SetRecvCodecs(engine_.codecs()));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001146 stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001147 EXPECT_TRUE(stream->GetConfig().rtp.remb);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001148}
1149
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00001150TEST_F(WebRtcVideoChannel2Test, NackIsEnabledByDefault) {
1151 VerifyCodecHasDefaultFeedbackParams(default_codec_);
1152
pbos@webrtc.org19864742014-05-30 07:35:47 +00001153 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
1154 EXPECT_TRUE(channel_->SetSend(true));
1155
1156 // Send side.
1157 FakeVideoSendStream* send_stream =
1158 AddSendStream(cricket::StreamParams::CreateLegacy(1));
1159 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1160
1161 // Receiver side.
1162 FakeVideoReceiveStream* recv_stream =
1163 AddRecvStream(cricket::StreamParams::CreateLegacy(1));
1164 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1165
1166 // Nack history size should match between sender and receiver.
1167 EXPECT_EQ(send_stream->GetConfig().rtp.nack.rtp_history_ms,
1168 recv_stream->GetConfig().rtp.nack.rtp_history_ms);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001169}
1170
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00001171TEST_F(WebRtcVideoChannel2Test, NackCanBeDisabled) {
1172 std::vector<VideoCodec> codecs;
1173 codecs.push_back(kVp8Codec);
1174
1175 // Send side.
1176 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
1177 FakeVideoSendStream* send_stream =
1178 AddSendStream(cricket::StreamParams::CreateLegacy(1));
1179 EXPECT_EQ(0, send_stream->GetConfig().rtp.nack.rtp_history_ms);
1180
1181 // Receiver side.
1182 ASSERT_TRUE(channel_->SetRecvCodecs(codecs));
1183 FakeVideoReceiveStream* recv_stream =
1184 AddRecvStream(cricket::StreamParams::CreateLegacy(1));
1185 EXPECT_EQ(0, recv_stream->GetConfig().rtp.nack.rtp_history_ms);
1186}
1187
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001188TEST_F(WebRtcVideoChannel2Test, DISABLED_VideoProtectionInterop) {
1189 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1190}
1191
1192TEST_F(WebRtcVideoChannel2Test, DISABLED_VideoProtectionInteropReversed) {
1193 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1194}
1195
1196TEST_F(WebRtcVideoChannel2Test, DISABLED_HybridNackFecConference) {
1197 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1198}
1199
1200TEST_F(WebRtcVideoChannel2Test, DISABLED_AddRemoveRecvStreamConference) {
1201 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1202}
1203
1204TEST_F(WebRtcVideoChannel2Test, DISABLED_SetRender) {
1205 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1206}
1207
1208TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthAuto) {
1209 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1210}
1211
1212TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthAutoCapped) {
1213 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1214}
1215
1216TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthFixed) {
1217 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1218}
1219
1220TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthInConference) {
1221 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1222}
1223
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001224TEST_F(WebRtcVideoChannel2Test, UsesCorrectSettingsForScreencast) {
1225 static const int kScreenshareMinBitrateKbps = 800;
1226 cricket::VideoCodec codec = kVp8Codec360p;
1227 std::vector<cricket::VideoCodec> codecs;
1228 codecs.push_back(codec);
1229 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1230 VideoOptions options;
1231 options.screencast_min_bitrate.Set(kScreenshareMinBitrateKbps);
1232 channel_->SetOptions(options);
1233
1234 AddSendStream();
1235
1236 cricket::FakeVideoCapturer capturer;
1237 capturer.SetScreencast(false);
1238 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer));
1239 cricket::VideoFormat capture_format_hd =
1240 capturer.GetSupportedFormats()->front();
1241 EXPECT_EQ(1280, capture_format_hd.width);
1242 EXPECT_EQ(720, capture_format_hd.height);
1243 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format_hd));
1244
1245 EXPECT_TRUE(channel_->SetSend(true));
1246
1247 EXPECT_TRUE(capturer.CaptureFrame());
1248 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
1249 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
1250
1251 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
1252
1253 // Verify non-screencast settings.
1254 webrtc::VideoEncoderConfig encoder_config = send_stream->GetEncoderConfig();
1255 EXPECT_EQ(webrtc::VideoEncoderConfig::kRealtimeVideo,
1256 encoder_config.content_type);
1257 EXPECT_EQ(codec.width, encoder_config.streams.front().width);
1258 EXPECT_EQ(codec.height, encoder_config.streams.front().height);
1259 EXPECT_EQ(0, encoder_config.min_transmit_bitrate_bps)
1260 << "Non-screenshare shouldn't use min-transmit bitrate.";
1261
1262 capturer.SetScreencast(true);
1263 EXPECT_TRUE(capturer.CaptureFrame());
1264
1265 EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
1266
1267 // Verify screencast settings.
1268 encoder_config = send_stream->GetEncoderConfig();
1269 EXPECT_EQ(webrtc::VideoEncoderConfig::kScreenshare,
1270 encoder_config.content_type);
1271 EXPECT_EQ(kScreenshareMinBitrateKbps * 1000,
1272 encoder_config.min_transmit_bitrate_bps);
1273
1274 EXPECT_EQ(capture_format_hd.width, encoder_config.streams.front().width);
1275 EXPECT_EQ(capture_format_hd.height, encoder_config.streams.front().height);
1276
1277 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001278}
1279
1280TEST_F(WebRtcVideoChannel2Test, DISABLED_SetSendSsrcAndCname) {
1281 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1282}
1283
1284TEST_F(WebRtcVideoChannel2Test,
1285 DISABLED_SetSendSsrcAfterCreatingReceiveChannel) {
1286 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1287}
1288
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00001289TEST_F(WebRtcVideoChannel2Test, SuspendBelowMinBitrateDisabledByDefault) {
1290 FakeVideoSendStream* stream = AddSendStream();
1291 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
1292}
1293
1294TEST_F(WebRtcVideoChannel2Test, SetOptionsWithSuspendBelowMinBitrate) {
1295 VideoOptions options;
1296 options.suspend_below_min_bitrate.Set(true);
1297 channel_->SetOptions(options);
1298
1299 FakeVideoSendStream* stream = AddSendStream();
1300 EXPECT_TRUE(stream->GetConfig().suspend_below_min_bitrate);
1301
1302 options.suspend_below_min_bitrate.Set(false);
1303 channel_->SetOptions(options);
1304
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001305 stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00001306 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
1307}
1308
pbos@webrtc.org543e5892014-07-23 07:01:31 +00001309TEST_F(WebRtcVideoChannel2Test, RedundantPayloadsDisabledByDefault) {
1310 const std::vector<uint32> ssrcs = MAKE_VECTOR(kSsrcs1);
1311 const std::vector<uint32> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
1312 FakeVideoSendStream* stream = AddSendStream(
1313 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
1314 EXPECT_FALSE(stream->GetConfig().rtp.rtx.pad_with_redundant_payloads);
1315}
1316
1317TEST_F(WebRtcVideoChannel2Test, SetOptionsWithPayloadPadding) {
1318 VideoOptions options;
1319 options.use_payload_padding.Set(true);
1320 channel_->SetOptions(options);
1321
1322 const std::vector<uint32> ssrcs = MAKE_VECTOR(kSsrcs1);
1323 const std::vector<uint32> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
1324 FakeVideoSendStream* stream = AddSendStream(
1325 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
1326 EXPECT_TRUE(stream->GetConfig().rtp.rtx.pad_with_redundant_payloads);
1327
1328 options.use_payload_padding.Set(false);
1329 channel_->SetOptions(options);
1330
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001331 stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.org543e5892014-07-23 07:01:31 +00001332 EXPECT_FALSE(stream->GetConfig().rtp.rtx.pad_with_redundant_payloads);
1333}
1334
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001335TEST_F(WebRtcVideoChannel2Test, Vp8DenoisingEnabledByDefault) {
1336 FakeVideoSendStream* stream = AddSendStream();
1337 webrtc::VideoCodecVP8 vp8_settings;
1338 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1339 EXPECT_TRUE(vp8_settings.denoisingOn);
1340}
1341
1342TEST_F(WebRtcVideoChannel2Test, SetOptionsWithDenoising) {
1343 VideoOptions options;
1344 options.video_noise_reduction.Set(false);
1345 channel_->SetOptions(options);
1346
1347 FakeVideoSendStream* stream = AddSendStream();
1348 webrtc::VideoCodecVP8 vp8_settings;
1349 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1350 EXPECT_FALSE(vp8_settings.denoisingOn);
1351
1352 options.video_noise_reduction.Set(true);
1353 channel_->SetOptions(options);
1354
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001355 stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001356 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1357 EXPECT_TRUE(vp8_settings.denoisingOn);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001358}
1359
1360TEST_F(WebRtcVideoChannel2Test, DISABLED_MultipleSendStreamsWithOneCapturer) {
1361 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1362}
1363
pbos@webrtc.org8aed9452014-07-26 10:16:49 +00001364TEST_F(WebRtcVideoChannel2Test, DISABLED_SendReceiveBitratesStats) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001365 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1366}
1367
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001368TEST_F(WebRtcVideoChannel2Test, AdaptsOnOveruse) {
1369 TestCpuAdaptation(true);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001370}
1371
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001372TEST_F(WebRtcVideoChannel2Test, DoesNotAdaptOnOveruseWhenDisabled) {
1373 TestCpuAdaptation(false);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001374}
1375
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001376void WebRtcVideoChannel2Test::TestCpuAdaptation(bool enable_overuse) {
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001377 cricket::VideoCodec codec = kVp8Codec720p;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001378 std::vector<cricket::VideoCodec> codecs;
1379 codecs.push_back(codec);
1380 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1381
1382 if (enable_overuse) {
1383 VideoOptions options;
1384 options.cpu_overuse_detection.Set(true);
1385 channel_->SetOptions(options);
1386 }
1387
1388 AddSendStream();
1389
1390 cricket::FakeVideoCapturer capturer;
1391 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer));
1392 EXPECT_EQ(cricket::CS_RUNNING,
1393 capturer.Start(capturer.GetSupportedFormats()->front()));
1394
1395 EXPECT_TRUE(channel_->SetSend(true));
1396
1397 // Trigger overuse.
1398 webrtc::LoadObserver* overuse_callback =
1399 fake_call_->GetConfig().overuse_callback;
1400 ASSERT_TRUE(overuse_callback != NULL);
1401 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kOveruse);
1402
1403 EXPECT_TRUE(capturer.CaptureFrame());
1404 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
1405 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
1406
1407 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
1408
1409 if (enable_overuse) {
1410 EXPECT_LT(send_stream->GetLastWidth(), codec.width);
1411 EXPECT_LT(send_stream->GetLastHeight(), codec.height);
1412 } else {
1413 EXPECT_EQ(codec.width, send_stream->GetLastWidth());
1414 EXPECT_EQ(codec.height, send_stream->GetLastHeight());
1415 }
1416
1417 // Trigger underuse which should go back to normal resolution.
1418 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kUnderuse);
1419 EXPECT_TRUE(capturer.CaptureFrame());
1420
1421 EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
1422
1423 EXPECT_EQ(codec.width, send_stream->GetLastWidth());
1424 EXPECT_EQ(codec.height, send_stream->GetLastHeight());
1425
1426 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001427}
1428
1429TEST_F(WebRtcVideoChannel2Test, DISABLED_WebRtcShouldLog) {
1430 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1431}
1432
1433TEST_F(WebRtcVideoChannel2Test, DISABLED_WebRtcShouldNotLog) {
1434 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1435}
1436
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001437TEST_F(WebRtcVideoChannel2Test, SetDefaultSendCodecs) {
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +00001438 ASSERT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001439
1440 VideoCodec codec;
1441 EXPECT_TRUE(channel_->GetSendCodec(&codec));
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +00001442 EXPECT_TRUE(codec.Matches(engine_.codecs()[0]));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001443
1444 // Using a RTX setup to verify that the default RTX payload type is good.
1445 const std::vector<uint32> ssrcs = MAKE_VECTOR(kSsrcs1);
1446 const std::vector<uint32> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
1447 FakeVideoSendStream* stream = AddSendStream(
1448 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
1449 webrtc::VideoSendStream::Config config = stream->GetConfig();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001450
1451 // Make sure NACK and FEC are enabled on the correct payload types.
1452 EXPECT_EQ(1000, config.rtp.nack.rtp_history_ms);
1453 EXPECT_EQ(default_ulpfec_codec_.id, config.rtp.fec.ulpfec_payload_type);
1454 EXPECT_EQ(default_red_codec_.id, config.rtp.fec.red_payload_type);
pbos@webrtc.org269605c2014-06-26 08:49:03 +00001455
1456 EXPECT_EQ(1u, config.rtp.rtx.ssrcs.size());
1457 EXPECT_EQ(kRtxSsrcs1[0], config.rtp.rtx.ssrcs[0]);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001458 EXPECT_EQ(static_cast<int>(default_rtx_codec_.id),
1459 config.rtp.rtx.payload_type);
1460 // TODO(juberti): Check RTCP, PLI, TMMBR.
1461}
1462
1463TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithoutFec) {
1464 std::vector<VideoCodec> codecs;
1465 codecs.push_back(kVp8Codec);
1466 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
1467
1468 FakeVideoSendStream* stream = AddSendStream();
1469 webrtc::VideoSendStream::Config config = stream->GetConfig();
1470
1471 EXPECT_EQ(-1, config.rtp.fec.ulpfec_payload_type);
1472 EXPECT_EQ(-1, config.rtp.fec.red_payload_type);
1473}
1474
1475TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org269605c2014-06-26 08:49:03 +00001476 SetSendCodecRejectsRtxWithoutAssociatedPayloadType) {
1477 std::vector<VideoCodec> codecs;
1478 cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0);
1479 codecs.push_back(rtx_codec);
1480 EXPECT_FALSE(channel_->SetSendCodecs(codecs))
1481 << "RTX codec without associated payload type should be rejected.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001482}
1483
1484TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org269605c2014-06-26 08:49:03 +00001485 SetSendCodecRejectsRtxWithoutMatchingVideoCodec) {
1486 std::vector<VideoCodec> codecs;
1487 cricket::VideoCodec rtx_codec =
1488 cricket::VideoCodec::CreateRtxCodec(96, kVp8Codec.id);
1489 codecs.push_back(kVp8Codec);
1490 codecs.push_back(rtx_codec);
1491 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
1492
1493 cricket::VideoCodec rtx_codec2 =
1494 cricket::VideoCodec::CreateRtxCodec(96, kVp8Codec.id + 1);
1495 codecs.pop_back();
1496 codecs.push_back(rtx_codec2);
1497 EXPECT_FALSE(channel_->SetSendCodecs(codecs))
1498 << "RTX without matching video codec should be rejected.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001499}
1500
pbos@webrtc.org269605c2014-06-26 08:49:03 +00001501TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithoutFecDisablesFec) {
1502 std::vector<VideoCodec> codecs;
1503 codecs.push_back(kVp8Codec);
1504 codecs.push_back(kUlpfecCodec);
1505 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
1506
1507 FakeVideoSendStream* stream = AddSendStream();
1508 webrtc::VideoSendStream::Config config = stream->GetConfig();
1509
1510 EXPECT_EQ(kUlpfecCodec.id, config.rtp.fec.ulpfec_payload_type);
1511
1512 codecs.pop_back();
1513 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001514 stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.org269605c2014-06-26 08:49:03 +00001515 ASSERT_TRUE(stream != NULL);
1516 config = stream->GetConfig();
1517 EXPECT_EQ(-1, config.rtp.fec.ulpfec_payload_type)
1518 << "SetSendCodec without FEC should disable current FEC.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001519}
1520
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00001521TEST_F(WebRtcVideoChannel2Test, SetSendCodecsChangesExistingStreams) {
1522 std::vector<VideoCodec> codecs;
1523 codecs.push_back(kVp8Codec720p);
1524 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
1525
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001526 std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00001527 EXPECT_EQ(kVp8Codec720p.width, streams[0].width);
1528 EXPECT_EQ(kVp8Codec720p.height, streams[0].height);
1529
1530 codecs.clear();
1531 codecs.push_back(kVp8Codec360p);
1532 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001533 streams = fake_call_->GetVideoSendStreams()[0]->GetVideoStreams();
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00001534 EXPECT_EQ(kVp8Codec360p.width, streams[0].width);
1535 EXPECT_EQ(kVp8Codec360p.height, streams[0].height);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001536}
1537
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001538TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithMinMaxBitrate) {
1539 SetSendCodecsShouldWorkForBitrates("10", "20");
1540}
1541
1542TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectsMaxLessThanMinBitrate) {
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +00001543 std::vector<VideoCodec> video_codecs = engine_.codecs();
1544 video_codecs[0].params[kCodecParamMinBitrate] = "30";
1545 video_codecs[0].params[kCodecParamMaxBitrate] = "20";
1546 EXPECT_FALSE(channel_->SetSendCodecs(video_codecs));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001547}
1548
1549TEST_F(WebRtcVideoChannel2Test, SetSendCodecsAcceptLargeMinMaxBitrate) {
1550 SetSendCodecsShouldWorkForBitrates("1000", "2000");
1551}
1552
1553TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithMaxQuantization) {
1554 static const char* kMaxQuantization = "21";
1555 std::vector<VideoCodec> codecs;
1556 codecs.push_back(kVp8Codec);
1557 codecs[0].params[kCodecParamMaxQuantization] = kMaxQuantization;
1558 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
pbos@webrtc.org6ae48c62014-06-06 10:49:19 +00001559 EXPECT_EQ(static_cast<unsigned int>(atoi(kMaxQuantization)),
1560 AddSendStream()->GetVideoStreams().back().max_qp);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001561
1562 VideoCodec codec;
1563 EXPECT_TRUE(channel_->GetSendCodec(&codec));
1564 EXPECT_EQ(kMaxQuantization, codec.params[kCodecParamMaxQuantization]);
1565}
1566
1567TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectBadDimensions) {
1568 std::vector<cricket::VideoCodec> codecs;
1569 codecs.push_back(kVp8Codec);
1570
1571 codecs[0].width = 0;
1572 EXPECT_FALSE(channel_->SetSendCodecs(codecs))
1573 << "Codec set though codec width is zero.";
1574
1575 codecs[0].width = kVp8Codec.width;
1576 codecs[0].height = 0;
1577 EXPECT_FALSE(channel_->SetSendCodecs(codecs))
1578 << "Codec set though codec height is zero.";
1579}
1580
1581TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectBadPayloadTypes) {
1582 // TODO(pbos): Should we only allow the dynamic range?
1583 static const size_t kNumIncorrectPayloads = 4;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001584 static const int kIncorrectPayloads[kNumIncorrectPayloads] = {
1585 -2, -1, 128, 129};
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001586 std::vector<cricket::VideoCodec> codecs;
1587 codecs.push_back(kVp8Codec);
1588 for (size_t i = 0; i < kNumIncorrectPayloads; ++i) {
1589 int payload_type = kIncorrectPayloads[i];
1590 codecs[0].id = payload_type;
1591 EXPECT_FALSE(channel_->SetSendCodecs(codecs))
1592 << "Bad payload type '" << payload_type << "' accepted.";
1593 }
1594}
1595
1596TEST_F(WebRtcVideoChannel2Test, SetSendCodecsAcceptAllValidPayloadTypes) {
1597 std::vector<cricket::VideoCodec> codecs;
1598 codecs.push_back(kVp8Codec);
1599 for (int payload_type = 0; payload_type <= 127; ++payload_type) {
1600 codecs[0].id = payload_type;
1601 EXPECT_TRUE(channel_->SetSendCodecs(codecs))
1602 << "Payload type '" << payload_type << "' rejected.";
1603 }
1604}
1605
1606TEST_F(WebRtcVideoChannel2Test, DISABLED_ResetVieSendCodecOnNewFrameSize) {
1607 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1608}
1609
1610TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithOnlyVp8) {
1611 std::vector<cricket::VideoCodec> codecs;
1612 codecs.push_back(kVp8Codec);
1613 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
1614}
1615
pbos@webrtc.orge322a172014-06-13 11:47:28 +00001616// Test that we set our inbound RTX codecs properly.
1617TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithRtx) {
1618 std::vector<cricket::VideoCodec> codecs;
1619 codecs.push_back(kVp8Codec);
1620 cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0);
1621 codecs.push_back(rtx_codec);
1622 EXPECT_FALSE(channel_->SetRecvCodecs(codecs))
1623 << "RTX codec without associated payload should be rejected.";
1624
1625 codecs[1].SetParam("apt", kVp8Codec.id + 1);
1626 EXPECT_FALSE(channel_->SetRecvCodecs(codecs))
1627 << "RTX codec with invalid associated payload type should be rejected.";
1628
1629 codecs[1].SetParam("apt", kVp8Codec.id);
1630 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
1631
1632 cricket::VideoCodec rtx_codec2(97, "rtx", 0, 0, 0, 0);
1633 rtx_codec2.SetParam("apt", rtx_codec.id);
1634 codecs.push_back(rtx_codec2);
1635
1636 EXPECT_FALSE(channel_->SetRecvCodecs(codecs)) << "RTX codec with another RTX "
1637 "as associated payload type "
1638 "should be rejected.";
1639}
1640
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001641TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsDifferentPayloadType) {
1642 std::vector<cricket::VideoCodec> codecs;
1643 codecs.push_back(kVp8Codec);
1644 codecs[0].id = 99;
1645 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
1646}
1647
pbos@webrtc.orgccbed3b2014-07-11 13:02:54 +00001648TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsAcceptDefaultCodecs) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001649 EXPECT_TRUE(channel_->SetRecvCodecs(engine_.codecs()));
pbos@webrtc.orgccbed3b2014-07-11 13:02:54 +00001650
1651 FakeVideoReceiveStream* stream = AddRecvStream();
1652 webrtc::VideoReceiveStream::Config config = stream->GetConfig();
pbos@webrtc.org776e6f22014-10-29 15:28:39 +00001653 EXPECT_EQ(engine_.codecs()[0].name, config.decoders[0].payload_name);
1654 EXPECT_EQ(engine_.codecs()[0].id, config.decoders[0].payload_type);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001655}
1656
1657TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsRejectUnsupportedCodec) {
1658 std::vector<VideoCodec> codecs;
1659 codecs.push_back(kVp8Codec);
1660 codecs.push_back(VideoCodec(101, "WTF3", 640, 400, 30, 0));
1661 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
1662}
1663
1664// TODO(pbos): Enable VP9 through external codec support
1665TEST_F(WebRtcVideoChannel2Test,
1666 DISABLED_SetRecvCodecsAcceptsMultipleVideoCodecs) {
1667 std::vector<VideoCodec> codecs;
1668 codecs.push_back(kVp8Codec);
1669 codecs.push_back(kVp9Codec);
1670 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
1671}
1672
1673TEST_F(WebRtcVideoChannel2Test,
1674 DISABLED_SetRecvCodecsSetsFecForAllVideoCodecs) {
1675 std::vector<VideoCodec> codecs;
1676 codecs.push_back(kVp8Codec);
1677 codecs.push_back(kVp9Codec);
1678 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
1679 FAIL(); // TODO(pbos): Verify that the FEC parameters are set for all codecs.
1680}
1681
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001682TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithoutFecDisablesFec) {
1683 std::vector<VideoCodec> codecs;
1684 codecs.push_back(kVp8Codec);
1685 codecs.push_back(kUlpfecCodec);
1686 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
1687
1688 FakeVideoReceiveStream* stream = AddRecvStream();
1689 webrtc::VideoReceiveStream::Config config = stream->GetConfig();
1690
1691 EXPECT_EQ(kUlpfecCodec.id, config.rtp.fec.ulpfec_payload_type);
1692
1693 codecs.pop_back();
1694 ASSERT_TRUE(channel_->SetRecvCodecs(codecs));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001695 stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001696 ASSERT_TRUE(stream != NULL);
1697 config = stream->GetConfig();
1698 EXPECT_EQ(-1, config.rtp.fec.ulpfec_payload_type)
1699 << "SetSendCodec without FEC should disable current FEC.";
pbos@webrtc.org269605c2014-06-26 08:49:03 +00001700}
1701
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001702TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectDuplicateFecPayloads) {
1703 std::vector<VideoCodec> codecs;
1704 codecs.push_back(kVp8Codec);
1705 codecs.push_back(kRedCodec);
1706 codecs[1].id = codecs[0].id;
1707 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
1708}
1709
1710TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsRejectDuplicateCodecPayloads) {
1711 std::vector<VideoCodec> codecs;
1712 codecs.push_back(kVp8Codec);
1713 codecs.push_back(kVp9Codec);
1714 codecs[1].id = codecs[0].id;
1715 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
1716}
1717
1718TEST_F(WebRtcVideoChannel2Test,
1719 SetRecvCodecsAcceptSameCodecOnMultiplePayloadTypes) {
1720 std::vector<VideoCodec> codecs;
1721 codecs.push_back(kVp8Codec);
1722 codecs.push_back(kVp8Codec);
1723 codecs[1].id += 1;
1724 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
1725}
1726
1727TEST_F(WebRtcVideoChannel2Test, SendStreamNotSendingByDefault) {
1728 EXPECT_FALSE(AddSendStream()->IsSending());
1729}
1730
pbos@webrtc.org85f42942014-07-22 09:14:58 +00001731TEST_F(WebRtcVideoChannel2Test, ReceiveStreamReceivingByDefault) {
1732 EXPECT_TRUE(AddRecvStream()->IsReceiving());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001733}
1734
1735TEST_F(WebRtcVideoChannel2Test, SetSend) {
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +00001736 FakeVideoSendStream* stream = AddSendStream();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001737 EXPECT_FALSE(stream->IsSending());
1738
1739 // false->true
1740 EXPECT_TRUE(channel_->SetSend(true));
1741 EXPECT_TRUE(stream->IsSending());
1742 // true->true
1743 EXPECT_TRUE(channel_->SetSend(true));
1744 EXPECT_TRUE(stream->IsSending());
1745 // true->false
1746 EXPECT_TRUE(channel_->SetSend(false));
1747 EXPECT_FALSE(stream->IsSending());
1748 // false->false
1749 EXPECT_TRUE(channel_->SetSend(false));
1750 EXPECT_FALSE(stream->IsSending());
1751
1752 EXPECT_TRUE(channel_->SetSend(true));
1753 FakeVideoSendStream* new_stream = AddSendStream();
1754 EXPECT_TRUE(new_stream->IsSending())
1755 << "Send stream created after SetSend(true) not sending initially.";
1756}
1757
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001758TEST_F(WebRtcVideoChannel2Test, DISABLED_TestSetDscpOptions) {
1759 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1760}
1761
1762TEST_F(WebRtcVideoChannel2Test, DISABLED_SetOptionsWithMaxBitrate) {
1763 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1764}
1765
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001766TEST_F(WebRtcVideoChannel2Test, DISABLED_ResetCodecOnScreencast) {
1767 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1768}
1769
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001770TEST_F(WebRtcVideoChannel2Test, DISABLED_RegisterDecoderIfFactoryIsGiven) {
1771 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1772}
1773
1774TEST_F(WebRtcVideoChannel2Test, DISABLED_DontRegisterDecoderMultipleTimes) {
1775 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1776}
1777
1778TEST_F(WebRtcVideoChannel2Test, DISABLED_DontRegisterDecoderForNonVP8) {
1779 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1780}
1781
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001782TEST_F(WebRtcVideoChannel2Test, DISABLED_ExternalCodecIgnored) {
1783 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1784}
1785
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00001786TEST_F(WebRtcVideoChannel2Test, OnReadyToSendSignalsNetworkState) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001787 EXPECT_EQ(webrtc::Call::kNetworkUp, fake_call_->GetNetworkState());
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00001788
1789 channel_->OnReadyToSend(false);
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001790 EXPECT_EQ(webrtc::Call::kNetworkDown, fake_call_->GetNetworkState());
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00001791
1792 channel_->OnReadyToSend(true);
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001793 EXPECT_EQ(webrtc::Call::kNetworkUp, fake_call_->GetNetworkState());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001794}
1795
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001796} // namespace cricket