blob: 835bb7c4512448867acf9f74afad09ec743569c1 [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"
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000037#include "webrtc/base/gunit.h"
38#include "webrtc/base/stringutils.h"
pbos@webrtc.org42684be2014-10-03 11:25:45 +000039#include "webrtc/video_encoder.h"
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000040
41namespace {
42static const cricket::VideoCodec kVp8Codec720p(100, "VP8", 1280, 720, 30, 0);
43static const cricket::VideoCodec kVp8Codec360p(100, "VP8", 640, 360, 30, 0);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000044
45static const cricket::VideoCodec kVp8Codec(100, "VP8", 640, 400, 30, 0);
46static const cricket::VideoCodec kVp9Codec(101, "VP9", 640, 400, 30, 0);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +000047static const cricket::VideoCodec kH264Codec(102, "H264", 640, 400, 30, 0);
48
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000049static const cricket::VideoCodec kRedCodec(116, "red", 0, 0, 0, 0);
50static const cricket::VideoCodec kUlpfecCodec(117, "ulpfec", 0, 0, 0, 0);
51
52static const uint32 kSsrcs1[] = {1};
53static const uint32 kRtxSsrcs1[] = {4};
pbos@webrtc.org3c107582014-07-20 15:27:35 +000054static const char kUnsupportedExtensionName[] =
55 "urn:ietf:params:rtp-hdrext:unsupported";
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +000056
57void VerifyCodecHasDefaultFeedbackParams(const cricket::VideoCodec& codec) {
58 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
59 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty)));
60 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
61 cricket::kRtcpFbParamNack, cricket::kRtcpFbNackParamPli)));
62 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
63 cricket::kRtcpFbParamRemb, cricket::kParamValueEmpty)));
64 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
65 cricket::kRtcpFbParamCcm, cricket::kRtcpFbCcmParamFir)));
66}
67
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000068} // namespace
69
70namespace cricket {
pbos@webrtc.org86f613d2014-06-10 08:53:05 +000071FakeVideoSendStream::FakeVideoSendStream(
72 const webrtc::VideoSendStream::Config& config,
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +000073 const webrtc::VideoEncoderConfig& encoder_config)
pbos@webrtc.org42684be2014-10-03 11:25:45 +000074 : sending_(false),
75 config_(config),
76 codec_settings_set_(false),
77 num_swapped_frames_(0) {
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +000078 assert(config.encoder_settings.encoder != NULL);
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +000079 ReconfigureVideoEncoder(encoder_config);
pbos@webrtc.org86f613d2014-06-10 08:53:05 +000080}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000081
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +000082webrtc::VideoSendStream::Config FakeVideoSendStream::GetConfig() const {
pbos@webrtc.org86f613d2014-06-10 08:53:05 +000083 return config_;
84}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000085
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +000086webrtc::VideoEncoderConfig FakeVideoSendStream::GetEncoderConfig() const {
87 return encoder_config_;
88}
89
pbos@webrtc.org86f613d2014-06-10 08:53:05 +000090std::vector<webrtc::VideoStream> FakeVideoSendStream::GetVideoStreams() {
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +000091 return encoder_config_.streams;
pbos@webrtc.org86f613d2014-06-10 08:53:05 +000092}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000093
pbos@webrtc.org85f42942014-07-22 09:14:58 +000094bool FakeVideoSendStream::IsSending() const {
pbos@webrtc.org86f613d2014-06-10 08:53:05 +000095 return sending_;
96}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000097
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +000098bool FakeVideoSendStream::GetVp8Settings(
99 webrtc::VideoCodecVP8* settings) const {
100 if (!codec_settings_set_) {
101 return false;
102 }
103
104 *settings = vp8_settings_;
105 return true;
106}
107
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000108int FakeVideoSendStream::GetNumberOfSwappedFrames() const {
109 return num_swapped_frames_;
110}
111
112int FakeVideoSendStream::GetLastWidth() const {
113 return last_frame_.width();
114}
115
116int FakeVideoSendStream::GetLastHeight() const {
117 return last_frame_.height();
118}
119
120void FakeVideoSendStream::SwapFrame(webrtc::I420VideoFrame* frame) {
121 ++num_swapped_frames_;
122 last_frame_.SwapFrame(frame);
123}
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000124webrtc::VideoSendStream::Stats FakeVideoSendStream::GetStats() const {
125 return webrtc::VideoSendStream::Stats();
126}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000127
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000128bool FakeVideoSendStream::ReconfigureVideoEncoder(
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +0000129 const webrtc::VideoEncoderConfig& config) {
130 encoder_config_ = config;
131 if (config.encoder_specific_settings != NULL) {
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +0000132 assert(config_.encoder_settings.payload_name == "VP8");
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +0000133 vp8_settings_ = *reinterpret_cast<const webrtc::VideoCodecVP8*>(
134 config.encoder_specific_settings);
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +0000135 }
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +0000136 codec_settings_set_ = config.encoder_specific_settings != NULL;
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000137 return true;
138}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000139
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000140webrtc::VideoSendStreamInput* FakeVideoSendStream::Input() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000141 return this;
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000142}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000143
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000144void FakeVideoSendStream::Start() {
145 sending_ = true;
146}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000147
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000148void FakeVideoSendStream::Stop() {
149 sending_ = false;
150}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000151
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000152FakeVideoReceiveStream::FakeVideoReceiveStream(
153 const webrtc::VideoReceiveStream::Config& config)
154 : config_(config), receiving_(false) {
155}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000156
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000157webrtc::VideoReceiveStream::Config FakeVideoReceiveStream::GetConfig() {
158 return config_;
159}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000160
pbos@webrtc.org85f42942014-07-22 09:14:58 +0000161bool FakeVideoReceiveStream::IsReceiving() const {
162 return receiving_;
163}
164
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000165webrtc::VideoReceiveStream::Stats FakeVideoReceiveStream::GetStats() const {
166 return webrtc::VideoReceiveStream::Stats();
167}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000168
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000169void FakeVideoReceiveStream::Start() {
170 receiving_ = true;
171}
pbos@webrtc.org85f42942014-07-22 09:14:58 +0000172
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000173void FakeVideoReceiveStream::Stop() {
174 receiving_ = false;
175}
pbos@webrtc.org85f42942014-07-22 09:14:58 +0000176
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000177FakeCall::FakeCall(const webrtc::Call::Config& config)
178 : config_(config), network_state_(kNetworkUp) {
pbos@webrtc.org26c0c412014-09-03 16:17:12 +0000179 SetVideoCodecs(GetDefaultVideoCodecs());
180}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000181
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000182FakeCall::~FakeCall() {
183 EXPECT_EQ(0u, video_send_streams_.size());
184 EXPECT_EQ(0u, video_receive_streams_.size());
185}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000186
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000187void FakeCall::SetVideoCodecs(const std::vector<webrtc::VideoCodec> codecs) {
188 codecs_ = codecs;
189}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000190
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000191webrtc::Call::Config FakeCall::GetConfig() const {
192 return config_;
193}
194
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000195std::vector<FakeVideoSendStream*> FakeCall::GetVideoSendStreams() {
196 return video_send_streams_;
197}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000198
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000199std::vector<FakeVideoReceiveStream*> FakeCall::GetVideoReceiveStreams() {
200 return video_receive_streams_;
201}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000202
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000203webrtc::VideoCodec FakeCall::GetEmptyVideoCodec() {
204 webrtc::VideoCodec codec;
205 codec.minBitrate = 300;
206 codec.startBitrate = 800;
207 codec.maxBitrate = 1500;
208 codec.maxFramerate = 10;
209 codec.width = 640;
210 codec.height = 480;
211 codec.qpMax = 56;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000212
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000213 return codec;
214}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000215
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000216webrtc::VideoCodec FakeCall::GetVideoCodecVp8() {
217 webrtc::VideoCodec vp8_codec = GetEmptyVideoCodec();
218 vp8_codec.codecType = webrtc::kVideoCodecVP8;
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000219 rtc::strcpyn(
220 vp8_codec.plName, ARRAY_SIZE(vp8_codec.plName), kVp8Codec.name.c_str());
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000221 vp8_codec.plType = kVp8Codec.id;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000222
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000223 return vp8_codec;
224}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000225
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000226webrtc::VideoCodec FakeCall::GetVideoCodecVp9() {
227 webrtc::VideoCodec vp9_codec = GetEmptyVideoCodec();
228 // TODO(pbos): Add a correct codecType when webrtc has one.
229 vp9_codec.codecType = webrtc::kVideoCodecVP8;
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000230 rtc::strcpyn(
231 vp9_codec.plName, ARRAY_SIZE(vp9_codec.plName), kVp9Codec.name.c_str());
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000232 vp9_codec.plType = kVp9Codec.id;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000233
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000234 return vp9_codec;
235}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000236
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000237std::vector<webrtc::VideoCodec> FakeCall::GetDefaultVideoCodecs() {
238 std::vector<webrtc::VideoCodec> codecs;
239 codecs.push_back(GetVideoCodecVp8());
240 // codecs.push_back(GetVideoCodecVp9());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000241
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000242 return codecs;
243}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000244
pbos@webrtc.org26c0c412014-09-03 16:17:12 +0000245webrtc::Call::NetworkState FakeCall::GetNetworkState() const {
246 return network_state_;
247}
248
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000249webrtc::VideoSendStream* FakeCall::CreateVideoSendStream(
250 const webrtc::VideoSendStream::Config& config,
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +0000251 const webrtc::VideoEncoderConfig& encoder_config) {
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000252 FakeVideoSendStream* fake_stream =
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +0000253 new FakeVideoSendStream(config, encoder_config);
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000254 video_send_streams_.push_back(fake_stream);
255 return fake_stream;
256}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000257
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000258void FakeCall::DestroyVideoSendStream(webrtc::VideoSendStream* send_stream) {
259 FakeVideoSendStream* fake_stream =
260 static_cast<FakeVideoSendStream*>(send_stream);
261 for (size_t i = 0; i < video_send_streams_.size(); ++i) {
262 if (video_send_streams_[i] == fake_stream) {
263 delete video_send_streams_[i];
264 video_send_streams_.erase(video_send_streams_.begin() + i);
265 return;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000266 }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000267 }
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000268 ADD_FAILURE() << "DestroyVideoSendStream called with unknown paramter.";
269}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000270
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000271webrtc::VideoReceiveStream* FakeCall::CreateVideoReceiveStream(
272 const webrtc::VideoReceiveStream::Config& config) {
273 video_receive_streams_.push_back(new FakeVideoReceiveStream(config));
274 return video_receive_streams_[video_receive_streams_.size() - 1];
275}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000276
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000277void FakeCall::DestroyVideoReceiveStream(
278 webrtc::VideoReceiveStream* receive_stream) {
279 FakeVideoReceiveStream* fake_stream =
280 static_cast<FakeVideoReceiveStream*>(receive_stream);
281 for (size_t i = 0; i < video_receive_streams_.size(); ++i) {
282 if (video_receive_streams_[i] == fake_stream) {
283 delete video_receive_streams_[i];
284 video_receive_streams_.erase(video_receive_streams_.begin() + i);
285 return;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000286 }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000287 }
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000288 ADD_FAILURE() << "DestroyVideoReceiveStream called with unknown paramter.";
289}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000290
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000291webrtc::PacketReceiver* FakeCall::Receiver() {
292 // TODO(pbos): Fix this.
293 return NULL;
294}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000295
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000296uint32_t FakeCall::SendBitrateEstimate() {
297 return 0;
298}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000299
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000300uint32_t FakeCall::ReceiveBitrateEstimate() {
301 return 0;
302}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000303
pbos@webrtc.org26c0c412014-09-03 16:17:12 +0000304void FakeCall::SignalNetworkState(webrtc::Call::NetworkState state) {
305 network_state_ = state;
306}
307
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000308class WebRtcVideoEngine2Test : public ::testing::Test {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000309 public:
pbos@webrtc.orgb648b9d2014-08-26 11:08:06 +0000310 WebRtcVideoEngine2Test() {
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +0000311 std::vector<VideoCodec> engine_codecs = engine_.codecs();
312 assert(!engine_codecs.empty());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000313 bool codec_set = false;
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +0000314 for (size_t i = 0; i < engine_codecs.size(); ++i) {
315 if (engine_codecs[i].name == "red") {
316 default_red_codec_ = engine_codecs[i];
317 } else if (engine_codecs[i].name == "ulpfec") {
318 default_ulpfec_codec_ = engine_codecs[i];
319 } else if (engine_codecs[i].name == "rtx") {
320 default_rtx_codec_ = engine_codecs[i];
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000321 } else if (!codec_set) {
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +0000322 default_codec_ = engine_codecs[i];
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000323 codec_set = true;
324 }
325 }
326
327 assert(codec_set);
328 }
329
330 protected:
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000331 VideoMediaChannel* SetUpForExternalEncoderFactory(
332 cricket::WebRtcVideoEncoderFactory* encoder_factory,
333 const std::vector<VideoCodec>& codecs);
pbos@webrtc.orgfa553ef2014-10-20 11:07:07 +0000334
335 void TestStartBitrate(bool override_start_bitrate, int start_bitrate_bps);
336
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000337 WebRtcVideoEngine2 engine_;
338 VideoCodec default_codec_;
339 VideoCodec default_red_codec_;
340 VideoCodec default_ulpfec_codec_;
341 VideoCodec default_rtx_codec_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000342};
343
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000344// TODO(pbos): Add test that verifies that sync is configured properly.
345TEST_F(WebRtcVideoEngine2Test, DISABLED_CreateChannelWithVoiceEngine) {
346 FAIL() << "Not implemented."; // TODO(pbos): Implement.
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000347}
348
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000349TEST_F(WebRtcVideoEngine2Test, FindCodec) {
350 const std::vector<cricket::VideoCodec>& c = engine_.codecs();
351 EXPECT_EQ(4U, c.size());
352
353 cricket::VideoCodec vp8(104, "VP8", 320, 200, 30, 0);
354 EXPECT_TRUE(engine_.FindCodec(vp8));
355
356 cricket::VideoCodec vp8_ci(104, "vp8", 320, 200, 30, 0);
357 EXPECT_TRUE(engine_.FindCodec(vp8));
358
359 cricket::VideoCodec vp8_diff_fr_diff_pref(104, "VP8", 320, 200, 50, 50);
360 EXPECT_TRUE(engine_.FindCodec(vp8_diff_fr_diff_pref));
361
362 cricket::VideoCodec vp8_diff_id(95, "VP8", 320, 200, 30, 0);
363 EXPECT_FALSE(engine_.FindCodec(vp8_diff_id));
364 vp8_diff_id.id = 97;
365 EXPECT_TRUE(engine_.FindCodec(vp8_diff_id));
366
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000367 // FindCodec ignores the codec size.
368 // Test that FindCodec can accept uncommon codec size.
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000369 cricket::VideoCodec vp8_diff_res(104, "VP8", 320, 111, 30, 0);
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000370 EXPECT_TRUE(engine_.FindCodec(vp8_diff_res));
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000371
372 // PeerConnection doesn't negotiate the resolution at this point.
373 // Test that FindCodec can handle the case when width/height is 0.
374 cricket::VideoCodec vp8_zero_res(104, "VP8", 0, 0, 30, 0);
375 EXPECT_TRUE(engine_.FindCodec(vp8_zero_res));
376
377 cricket::VideoCodec red(101, "RED", 0, 0, 30, 0);
378 EXPECT_TRUE(engine_.FindCodec(red));
379
380 cricket::VideoCodec red_ci(101, "red", 0, 0, 30, 0);
381 EXPECT_TRUE(engine_.FindCodec(red));
382
383 cricket::VideoCodec fec(102, "ULPFEC", 0, 0, 30, 0);
384 EXPECT_TRUE(engine_.FindCodec(fec));
385
386 cricket::VideoCodec fec_ci(102, "ulpfec", 0, 0, 30, 0);
387 EXPECT_TRUE(engine_.FindCodec(fec));
388
389 cricket::VideoCodec rtx(96, "rtx", 0, 0, 30, 0);
390 EXPECT_TRUE(engine_.FindCodec(rtx));
391}
392
393TEST_F(WebRtcVideoEngine2Test, DefaultRtxCodecHasAssociatedPayloadTypeSet) {
394 std::vector<VideoCodec> engine_codecs = engine_.codecs();
395 for (size_t i = 0; i < engine_codecs.size(); ++i) {
396 if (engine_codecs[i].name != kRtxCodecName)
397 continue;
398 int associated_payload_type;
399 EXPECT_TRUE(engine_codecs[i].GetParam(kCodecParamAssociatedPayloadType,
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000400 &associated_payload_type));
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000401 EXPECT_EQ(default_codec_.id, associated_payload_type);
402 return;
403 }
404 FAIL() << "No RTX codec found among default codecs.";
405}
406
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000407TEST_F(WebRtcVideoEngine2Test, SupportsTimestampOffsetHeaderExtension) {
408 std::vector<RtpHeaderExtension> extensions = engine_.rtp_header_extensions();
409 ASSERT_FALSE(extensions.empty());
410 for (size_t i = 0; i < extensions.size(); ++i) {
411 if (extensions[i].uri == kRtpTimestampOffsetHeaderExtension) {
412 EXPECT_EQ(kRtpTimestampOffsetHeaderExtensionDefaultId, extensions[i].id);
413 return;
414 }
415 }
416 FAIL() << "Timestamp offset extension not in header-extension list.";
417}
418
419TEST_F(WebRtcVideoEngine2Test, SupportsAbsoluteSenderTimeHeaderExtension) {
420 std::vector<RtpHeaderExtension> extensions = engine_.rtp_header_extensions();
421 ASSERT_FALSE(extensions.empty());
422 for (size_t i = 0; i < extensions.size(); ++i) {
423 if (extensions[i].uri == kRtpAbsoluteSenderTimeHeaderExtension) {
424 EXPECT_EQ(kRtpAbsoluteSenderTimeHeaderExtensionDefaultId,
425 extensions[i].id);
426 return;
427 }
428 }
429 FAIL() << "Absolute Sender Time extension not in header-extension list.";
430}
431
pbos@webrtc.orgfa553ef2014-10-20 11:07:07 +0000432void WebRtcVideoEngine2Test::TestStartBitrate(bool override_start_bitrate,
433 int start_bitrate_bps) {
434 class FakeCallFactory : public WebRtcCallFactory {
435 public:
436 FakeCallFactory() : fake_call_(NULL) {}
437
438 FakeCall* GetCall() {
439 return fake_call_;
440 }
441
442 private:
443 virtual webrtc::Call* CreateCall(
444 const webrtc::Call::Config& config) OVERRIDE {
445 assert(fake_call_ == NULL);
446 fake_call_ = new FakeCall(config);
447 return fake_call_;
448 }
449
450 FakeCall* fake_call_;
451 };
452
453 FakeCallFactory call_factory;
454 engine_.SetCallFactory(&call_factory);
455
456 engine_.Init(rtc::Thread::Current());
457
458 cricket::VideoOptions options;
459 if (override_start_bitrate) {
460 options.video_start_bitrate.Set(start_bitrate_bps / 1000);
461 }
462
463 rtc::scoped_ptr<VideoMediaChannel> channel(
464 engine_.CreateChannel(options, NULL));
465
466 EXPECT_EQ(override_start_bitrate
467 ? start_bitrate_bps
468 : webrtc::Call::Config::kDefaultStartBitrateBps,
469 call_factory.GetCall()->GetConfig().stream_start_bitrate_bps);
470}
471
472TEST_F(WebRtcVideoEngine2Test, UsesCorrectDefaultStartBitrate) {
473 TestStartBitrate(false, -1);
474}
475
476TEST_F(WebRtcVideoEngine2Test, CreateChannelCanUseIncreasedStartBitrate) {
477 TestStartBitrate(true, 2 * webrtc::Call::Config::kDefaultStartBitrateBps);
478}
479
480TEST_F(WebRtcVideoEngine2Test, CreateChannelCanUseDecreasedStartBitrate) {
481 TestStartBitrate(true, webrtc::Call::Config::kDefaultStartBitrateBps / 2);
482}
483
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +0000484TEST_F(WebRtcVideoEngine2Test, SetSendFailsBeforeSettingCodecs) {
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000485 engine_.Init(rtc::Thread::Current());
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000486 rtc::scoped_ptr<VideoMediaChannel> channel(
487 engine_.CreateChannel(cricket::VideoOptions(), NULL));
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +0000488
489 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
490
491 EXPECT_FALSE(channel->SetSend(true))
492 << "Channel should not start without codecs.";
493 EXPECT_TRUE(channel->SetSend(false))
494 << "Channel should be stoppable even without set codecs.";
495}
496
pbos@webrtc.orgc3d2bd22014-08-12 20:55:10 +0000497TEST_F(WebRtcVideoEngine2Test, GetStatsWithoutSendCodecsSetDoesNotCrash) {
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000498 engine_.Init(rtc::Thread::Current());
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000499 rtc::scoped_ptr<VideoMediaChannel> channel(
500 engine_.CreateChannel(cricket::VideoOptions(), NULL));
pbos@webrtc.orgc3d2bd22014-08-12 20:55:10 +0000501 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
502 VideoMediaInfo info;
503 channel->GetStats(&info);
504}
505
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000506TEST_F(WebRtcVideoEngine2Test, UseExternalFactoryForVp8WhenSupported) {
507 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
508 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
509 std::vector<cricket::VideoCodec> codecs;
510 codecs.push_back(kVp8Codec);
511
512 rtc::scoped_ptr<VideoMediaChannel> channel(
513 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
514
515 EXPECT_TRUE(
516 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
517 ASSERT_EQ(1u, encoder_factory.encoders().size());
518 EXPECT_TRUE(channel->SetSend(true));
519
520 cricket::FakeVideoCapturer capturer;
521 EXPECT_TRUE(channel->SetCapturer(kSsrc, &capturer));
522 EXPECT_EQ(cricket::CS_RUNNING,
523 capturer.Start(capturer.GetSupportedFormats()->front()));
524 EXPECT_TRUE(capturer.CaptureFrame());
525
526 EXPECT_TRUE_WAIT(encoder_factory.encoders()[0]->GetNumEncodedFrames() > 0,
527 kTimeout);
528
529 // Setting codecs of the same type should not reallocate the encoder.
530 EXPECT_TRUE(channel->SetSendCodecs(codecs));
531 EXPECT_EQ(1, encoder_factory.GetNumCreatedEncoders());
532
533 // Remove stream previously added to free the external encoder instance.
534 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
535 EXPECT_EQ(0u, encoder_factory.encoders().size());
536}
537
538VideoMediaChannel* WebRtcVideoEngine2Test::SetUpForExternalEncoderFactory(
539 cricket::WebRtcVideoEncoderFactory* encoder_factory,
540 const std::vector<VideoCodec>& codecs) {
541 engine_.SetExternalEncoderFactory(encoder_factory);
542 engine_.Init(rtc::Thread::Current());
543
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000544 VideoMediaChannel* channel =
545 engine_.CreateChannel(cricket::VideoOptions(), NULL);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000546 EXPECT_TRUE(channel->SetSendCodecs(codecs));
547
548 return channel;
549}
550
551TEST_F(WebRtcVideoEngine2Test, ChannelWithExternalH264CanChangeToInternalVp8) {
552 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
553 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
554 std::vector<cricket::VideoCodec> codecs;
555 codecs.push_back(kH264Codec);
556
557 rtc::scoped_ptr<VideoMediaChannel> channel(
558 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
559
560 EXPECT_TRUE(
561 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
562 ASSERT_EQ(1u, encoder_factory.encoders().size());
563
564 codecs.clear();
565 codecs.push_back(kVp8Codec);
566 EXPECT_TRUE(channel->SetSendCodecs(codecs));
567
568 ASSERT_EQ(0u, encoder_factory.encoders().size());
569}
570
571TEST_F(WebRtcVideoEngine2Test,
572 DontUseExternalEncoderFactoryForUnsupportedCodecs) {
573 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
574 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
575 std::vector<cricket::VideoCodec> codecs;
576 codecs.push_back(kVp8Codec);
577
578 rtc::scoped_ptr<VideoMediaChannel> channel(
579 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
580
581 EXPECT_TRUE(
582 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
583 ASSERT_EQ(0u, encoder_factory.encoders().size());
584}
585
586// Test external codec with be added to the end of the supported codec list.
587TEST_F(WebRtcVideoEngine2Test, ReportSupportedExternalCodecs) {
588 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
589 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
590 engine_.SetExternalEncoderFactory(&encoder_factory);
591
592 engine_.Init(rtc::Thread::Current());
593
594 std::vector<cricket::VideoCodec> codecs(engine_.codecs());
595 ASSERT_GE(codecs.size(), 2u);
596 cricket::VideoCodec internal_codec = codecs.front();
597 cricket::VideoCodec external_codec = codecs.back();
598
599 // The external codec will appear at last.
600 EXPECT_EQ("VP8", internal_codec.name);
601 EXPECT_EQ("H264", external_codec.name);
602}
603
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000604class WebRtcVideoEngine2BaseTest
605 : public VideoEngineTest<cricket::WebRtcVideoEngine2> {
606 protected:
607 typedef VideoEngineTest<cricket::WebRtcVideoEngine2> Base;
608};
609
610#define WEBRTC_ENGINE_BASE_TEST(test) \
611 TEST_F(WebRtcVideoEngine2BaseTest, test) { Base::test##Body(); }
612
613WEBRTC_ENGINE_BASE_TEST(ConstrainNewCodec2);
614
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000615class WebRtcVideoChannel2BaseTest
616 : public VideoMediaChannelTest<WebRtcVideoEngine2, WebRtcVideoChannel2> {
617 protected:
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000618 typedef VideoMediaChannelTest<WebRtcVideoEngine2, WebRtcVideoChannel2> Base;
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000619
620 virtual cricket::VideoCodec DefaultCodec() OVERRIDE { return kVp8Codec; }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000621};
622
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000623#define WEBRTC_BASE_TEST(test) \
624 TEST_F(WebRtcVideoChannel2BaseTest, test) { Base::test(); }
625
626#define WEBRTC_DISABLED_BASE_TEST(test) \
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000627 TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_##test) { Base::test(); }
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000628
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000629// TODO(pbos): Fix WebRtcVideoEngine2BaseTest, where we want CheckCoInitialize.
630#if 0
631// TODO(juberti): Figure out why ViE is munging the COM refcount.
632#ifdef WIN32
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000633WEBRTC_DISABLED_BASE_TEST(CheckCoInitialize) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000634 Base::CheckCoInitialize();
635}
636#endif
637#endif
638
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000639WEBRTC_BASE_TEST(SetSend);
640WEBRTC_BASE_TEST(SetSendWithoutCodecs);
641WEBRTC_BASE_TEST(SetSendSetsTransportBufferSizes);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000642
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000643WEBRTC_BASE_TEST(GetStats);
644WEBRTC_BASE_TEST(GetStatsMultipleRecvStreams);
645WEBRTC_BASE_TEST(GetStatsMultipleSendStreams);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000646
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000647WEBRTC_BASE_TEST(SetSendBandwidth);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000648
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000649WEBRTC_BASE_TEST(SetSendSsrc);
650WEBRTC_BASE_TEST(SetSendSsrcAfterSetCodecs);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000651
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000652WEBRTC_BASE_TEST(SetRenderer);
653WEBRTC_BASE_TEST(AddRemoveRecvStreams);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000654
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000655WEBRTC_DISABLED_BASE_TEST(AddRemoveRecvStreamAndRender);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000656
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000657WEBRTC_BASE_TEST(AddRemoveRecvStreamsNoConference);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000658
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000659WEBRTC_BASE_TEST(AddRemoveSendStreams);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000660
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000661WEBRTC_BASE_TEST(SimulateConference);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000662
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000663WEBRTC_BASE_TEST(AddRemoveCapturer);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000664
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000665WEBRTC_BASE_TEST(RemoveCapturerWithoutAdd);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000666
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000667WEBRTC_BASE_TEST(AddRemoveCapturerMultipleSources);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000668
669// TODO(pbos): Figure out why this fails so often.
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000670WEBRTC_DISABLED_BASE_TEST(HighAspectHighHeightCapturer);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000671
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000672WEBRTC_BASE_TEST(RejectEmptyStreamParams);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000673
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000674WEBRTC_BASE_TEST(AdaptResolution16x10);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000675
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000676WEBRTC_BASE_TEST(AdaptResolution4x3);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000677
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000678// TODO(juberti): Restore this test once we support sending 0 fps.
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000679WEBRTC_DISABLED_BASE_TEST(AdaptDropAllFrames);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000680// TODO(juberti): Understand why we get decode errors on this test.
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000681WEBRTC_DISABLED_BASE_TEST(AdaptFramerate);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000682
pbos@webrtc.orgc4175b92014-09-03 15:25:49 +0000683WEBRTC_BASE_TEST(SendsLowerResolutionOnSmallerFrames);
684
685WEBRTC_BASE_TEST(MuteStream);
686
687WEBRTC_BASE_TEST(MultipleSendStreams);
688
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000689WEBRTC_BASE_TEST(SetSendStreamFormat0x0);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000690
691// TODO(zhurunz): Fix the flakey test.
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000692WEBRTC_DISABLED_BASE_TEST(SetSendStreamFormat);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000693
pbos@webrtc.org9359cb32014-07-23 15:44:48 +0000694TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8Vga) {
695 SendAndReceive(cricket::VideoCodec(100, "VP8", 640, 400, 30, 0));
696}
697
698TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8Qvga) {
699 SendAndReceive(cricket::VideoCodec(100, "VP8", 320, 200, 30, 0));
700}
701
702TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8SvcQqvga) {
703 SendAndReceive(cricket::VideoCodec(100, "VP8", 160, 100, 30, 0));
704}
705
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000706TEST_F(WebRtcVideoChannel2BaseTest, TwoStreamsSendAndReceive) {
707 Base::TwoStreamsSendAndReceive(kVp8Codec);
708}
709
710TEST_F(WebRtcVideoChannel2BaseTest, TwoStreamsReUseFirstStream) {
711 Base::TwoStreamsReUseFirstStream(kVp8Codec);
712}
713
pbos@webrtc.org9359cb32014-07-23 15:44:48 +0000714WEBRTC_BASE_TEST(SendManyResizeOnce);
715
716// TODO(pbos): Enable and figure out why this fails (or should work).
717TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_SendVp8HdAndReceiveAdaptedVp8Vga) {
718 EXPECT_TRUE(channel_->SetCapturer(kSsrc, NULL));
719 EXPECT_TRUE(channel_->SetRenderer(kDefaultReceiveSsrc, &renderer_));
720 channel_->UpdateAspectRatio(1280, 720);
721 video_capturer_.reset(new cricket::FakeVideoCapturer);
722 const std::vector<cricket::VideoFormat>* formats =
723 video_capturer_->GetSupportedFormats();
724 cricket::VideoFormat capture_format_hd = (*formats)[0];
725 EXPECT_EQ(cricket::CS_RUNNING, video_capturer_->Start(capture_format_hd));
726 EXPECT_TRUE(channel_->SetCapturer(kSsrc, video_capturer_.get()));
727
728 // Capture format HD -> adapt (OnOutputFormatRequest VGA) -> VGA.
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +0000729 cricket::VideoCodec codec = kVp8Codec720p;
pbos@webrtc.org9359cb32014-07-23 15:44:48 +0000730 EXPECT_TRUE(SetOneCodec(codec));
731 codec.width /= 2;
732 codec.height /= 2;
733 EXPECT_TRUE(SetSend(true));
734 EXPECT_TRUE(channel_->SetRender(true));
735 EXPECT_EQ(0, renderer_.num_rendered_frames());
736 EXPECT_TRUE(SendFrame());
737 EXPECT_FRAME_WAIT(1, codec.width, codec.height, kTimeout);
738}
739
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000740class WebRtcVideoChannel2Test : public WebRtcVideoEngine2Test,
741 public WebRtcCallFactory {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000742 public:
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000743 WebRtcVideoChannel2Test() : fake_call_(NULL) {}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000744 virtual void SetUp() OVERRIDE {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000745 engine_.SetCallFactory(this);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000746 engine_.Init(rtc::Thread::Current());
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000747 channel_.reset(engine_.CreateChannel(cricket::VideoOptions(), NULL));
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000748 ASSERT_TRUE(fake_call_ != NULL) << "Call not created through factory.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000749 last_ssrc_ = 123;
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000750 ASSERT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000751 }
752
753 protected:
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000754 virtual webrtc::Call* CreateCall(
755 const webrtc::Call::Config& config) OVERRIDE {
756 assert(fake_call_ == NULL);
757 fake_call_ = new FakeCall(config);
758 return fake_call_;
759 }
760
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000761 FakeVideoSendStream* AddSendStream() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000762 return AddSendStream(StreamParams::CreateLegacy(++last_ssrc_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000763 }
764
765 FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000766 size_t num_streams = fake_call_->GetVideoSendStreams().size();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000767 EXPECT_TRUE(channel_->AddSendStream(sp));
768 std::vector<FakeVideoSendStream*> streams =
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000769 fake_call_->GetVideoSendStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000770 EXPECT_EQ(num_streams + 1, streams.size());
771 return streams[streams.size() - 1];
772 }
773
774 std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000775 return fake_call_->GetVideoSendStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000776 }
777
778 FakeVideoReceiveStream* AddRecvStream() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000779 return AddRecvStream(StreamParams::CreateLegacy(++last_ssrc_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000780 }
781
782 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000783 size_t num_streams = fake_call_->GetVideoReceiveStreams().size();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000784 EXPECT_TRUE(channel_->AddRecvStream(sp));
785 std::vector<FakeVideoReceiveStream*> streams =
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000786 fake_call_->GetVideoReceiveStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000787 EXPECT_EQ(num_streams + 1, streams.size());
788 return streams[streams.size() - 1];
789 }
790
791 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate,
792 const char* max_bitrate) {
793 std::vector<VideoCodec> codecs;
794 codecs.push_back(kVp8Codec);
795 codecs[0].params[kCodecParamMinBitrate] = min_bitrate;
796 codecs[0].params[kCodecParamMaxBitrate] = max_bitrate;
797 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
798
799 FakeVideoSendStream* stream = AddSendStream();
800
pbos@webrtc.org6ae48c62014-06-06 10:49:19 +0000801 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
802 ASSERT_EQ(1u, video_streams.size());
803 EXPECT_EQ(atoi(min_bitrate), video_streams.back().min_bitrate_bps / 1000);
804 EXPECT_EQ(atoi(max_bitrate), video_streams.back().max_bitrate_bps / 1000);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000805
806 VideoCodec codec;
807 EXPECT_TRUE(channel_->GetSendCodec(&codec));
808 EXPECT_EQ(min_bitrate, codec.params[kCodecParamMinBitrate]);
809 EXPECT_EQ(max_bitrate, codec.params[kCodecParamMaxBitrate]);
810 }
811
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000812 void TestSetSendRtpHeaderExtensions(const std::string& cricket_ext,
813 const std::string& webrtc_ext) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000814 FakeCall* call = fake_call_;
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000815 // Enable extension.
816 const int id = 1;
817 std::vector<cricket::RtpHeaderExtension> extensions;
818 extensions.push_back(cricket::RtpHeaderExtension(cricket_ext, id));
819 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
820
821 FakeVideoSendStream* send_stream =
822 AddSendStream(cricket::StreamParams::CreateLegacy(123));
823
824 // Verify the send extension id.
825 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
826 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
827 EXPECT_EQ(webrtc_ext, send_stream->GetConfig().rtp.extensions[0].name);
828 // Verify call with same set of extensions returns true.
829 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
830 // Verify that SetSendRtpHeaderExtensions doesn't implicitly add them for
831 // receivers.
832 EXPECT_TRUE(AddRecvStream(cricket::StreamParams::CreateLegacy(123))
833 ->GetConfig()
834 .rtp.extensions.empty());
835
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +0000836 // Verify that existing RTP header extensions can be removed.
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000837 std::vector<cricket::RtpHeaderExtension> empty_extensions;
838 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(empty_extensions));
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +0000839 ASSERT_EQ(1u, call->GetVideoSendStreams().size());
840 send_stream = call->GetVideoSendStreams()[0];
841 EXPECT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
842
843 // Verify that adding receive RTP header extensions adds them for existing
844 // streams.
845 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
846 send_stream = call->GetVideoSendStreams()[0];
847 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
848 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
849 EXPECT_EQ(webrtc_ext, send_stream->GetConfig().rtp.extensions[0].name);
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000850 }
851
852 void TestSetRecvRtpHeaderExtensions(const std::string& cricket_ext,
853 const std::string& webrtc_ext) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000854 FakeCall* call = fake_call_;
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000855 // Enable extension.
856 const int id = 1;
857 std::vector<cricket::RtpHeaderExtension> extensions;
858 extensions.push_back(cricket::RtpHeaderExtension(cricket_ext, id));
859 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
860
861 FakeVideoReceiveStream* recv_stream =
862 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
863
864 // Verify the recv extension id.
865 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
866 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
867 EXPECT_EQ(webrtc_ext, recv_stream->GetConfig().rtp.extensions[0].name);
868 // Verify call with same set of extensions returns true.
869 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +0000870
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000871 // Verify that SetRecvRtpHeaderExtensions doesn't implicitly add them for
872 // senders.
873 EXPECT_TRUE(AddSendStream(cricket::StreamParams::CreateLegacy(123))
874 ->GetConfig()
875 .rtp.extensions.empty());
876
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +0000877 // Verify that existing RTP header extensions can be removed.
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000878 std::vector<cricket::RtpHeaderExtension> empty_extensions;
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +0000879 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(empty_extensions));
880 ASSERT_EQ(1u, call->GetVideoReceiveStreams().size());
881 recv_stream = call->GetVideoReceiveStreams()[0];
882 EXPECT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
883
884 // Verify that adding receive RTP header extensions adds them for existing
885 // streams.
886 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
887 recv_stream = call->GetVideoReceiveStreams()[0];
888 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
889 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
890 EXPECT_EQ(webrtc_ext, recv_stream->GetConfig().rtp.extensions[0].name);
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000891 }
892
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000893 void TestCpuAdaptation(bool enable_overuse);
894
895 FakeCall* fake_call_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000896 rtc::scoped_ptr<VideoMediaChannel> channel_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000897 uint32 last_ssrc_;
898};
899
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000900TEST_F(WebRtcVideoChannel2Test, RecvStreamWithSimAndRtx) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000901 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
902 EXPECT_TRUE(channel_->SetSend(true));
903 cricket::VideoOptions options;
904 options.conference_mode.Set(true);
905 EXPECT_TRUE(channel_->SetOptions(options));
906
907 // Send side.
908 const std::vector<uint32> ssrcs = MAKE_VECTOR(kSsrcs1);
909 const std::vector<uint32> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
910 FakeVideoSendStream* send_stream = AddSendStream(
911 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
912
913 ASSERT_EQ(rtx_ssrcs.size(), send_stream->GetConfig().rtp.rtx.ssrcs.size());
914 for (size_t i = 0; i < rtx_ssrcs.size(); ++i)
915 EXPECT_EQ(rtx_ssrcs[i], send_stream->GetConfig().rtp.rtx.ssrcs[i]);
916
917 // Receiver side.
918 FakeVideoReceiveStream* recv_stream = AddRecvStream(
919 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
920 ASSERT_GT(recv_stream->GetConfig().rtp.rtx.size(), 0u)
921 << "No SSRCs for RTX configured by AddRecvStream.";
922 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.rtx.size())
923 << "This test only works with one receive codec. Please update the test.";
924 EXPECT_EQ(rtx_ssrcs[0],
925 recv_stream->GetConfig().rtp.rtx.begin()->second.ssrc);
926 // TODO(pbos): Make sure we set the RTX for correct payloads etc.
927}
928
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000929TEST_F(WebRtcVideoChannel2Test, RecvStreamWithRtx) {
930 // Setup one channel with an associated RTX stream.
931 cricket::StreamParams params =
932 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
933 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
934 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
935 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.rtx.size());
936 EXPECT_EQ(kRtxSsrcs1[0],
937 recv_stream->GetConfig().rtp.rtx.begin()->second.ssrc);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000938}
939
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000940TEST_F(WebRtcVideoChannel2Test, RecvStreamNoRtx) {
941 // Setup one channel without an associated RTX stream.
942 cricket::StreamParams params =
943 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
944 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
945 ASSERT_TRUE(recv_stream->GetConfig().rtp.rtx.empty());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000946}
947
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000948TEST_F(WebRtcVideoChannel2Test, NoHeaderExtesionsByDefault) {
949 FakeVideoSendStream* send_stream =
950 AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
951 ASSERT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
952
953 FakeVideoReceiveStream* recv_stream =
954 AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
955 ASSERT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000956}
957
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000958// Test support for RTP timestamp offset header extension.
959TEST_F(WebRtcVideoChannel2Test, SendRtpTimestampOffsetHeaderExtensions) {
960 TestSetSendRtpHeaderExtensions(kRtpTimestampOffsetHeaderExtension,
961 webrtc::RtpExtension::kTOffset);
962}
963TEST_F(WebRtcVideoChannel2Test, RecvRtpTimestampOffsetHeaderExtensions) {
964 TestSetRecvRtpHeaderExtensions(kRtpTimestampOffsetHeaderExtension,
965 webrtc::RtpExtension::kTOffset);
966}
967
968// Test support for absolute send time header extension.
969TEST_F(WebRtcVideoChannel2Test, SendAbsoluteSendTimeHeaderExtensions) {
970 TestSetSendRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension,
971 webrtc::RtpExtension::kAbsSendTime);
972}
973TEST_F(WebRtcVideoChannel2Test, RecvAbsoluteSendTimeHeaderExtensions) {
974 TestSetRecvRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension,
975 webrtc::RtpExtension::kAbsSendTime);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000976}
977
pbos@webrtc.org3c107582014-07-20 15:27:35 +0000978TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000979 SetSendRtpHeaderExtensionsExcludeUnsupportedExtensions) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +0000980 const int kUnsupportedId = 1;
981 const int kTOffsetId = 2;
982
983 std::vector<cricket::RtpHeaderExtension> extensions;
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000984 extensions.push_back(
985 cricket::RtpHeaderExtension(kUnsupportedExtensionName, kUnsupportedId));
986 extensions.push_back(
987 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, kTOffsetId));
pbos@webrtc.org3c107582014-07-20 15:27:35 +0000988 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
989 FakeVideoSendStream* send_stream =
990 AddSendStream(cricket::StreamParams::CreateLegacy(123));
991
992 // Only timestamp offset extension is set to send stream,
993 // unsupported rtp extension is ignored.
994 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
995 EXPECT_STREQ(webrtc::RtpExtension::kTOffset,
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000996 send_stream->GetConfig().rtp.extensions[0].name.c_str());
pbos@webrtc.org3c107582014-07-20 15:27:35 +0000997}
998
999TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001000 SetRecvRtpHeaderExtensionsExcludeUnsupportedExtensions) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001001 const int kUnsupportedId = 1;
1002 const int kTOffsetId = 2;
1003
1004 std::vector<cricket::RtpHeaderExtension> extensions;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001005 extensions.push_back(
1006 cricket::RtpHeaderExtension(kUnsupportedExtensionName, kUnsupportedId));
1007 extensions.push_back(
1008 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, kTOffsetId));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001009 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
1010 FakeVideoReceiveStream* recv_stream =
1011 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
1012
1013 // Only timestamp offset extension is set to receive stream,
1014 // unsupported rtp extension is ignored.
1015 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
1016 EXPECT_STREQ(webrtc::RtpExtension::kTOffset,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001017 recv_stream->GetConfig().rtp.extensions[0].name.c_str());
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001018}
1019
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001020TEST_F(WebRtcVideoChannel2Test, SetSendRtpHeaderExtensionsRejectsIncorrectIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001021 const size_t kNumIncorrectIds = 4;
1022 const int kIncorrectIds[kNumIncorrectIds] = {-2, -1, 15, 16};
1023 for (size_t i = 0; i < kNumIncorrectIds; ++i) {
1024 std::vector<cricket::RtpHeaderExtension> extensions;
1025 extensions.push_back(cricket::RtpHeaderExtension(
1026 webrtc::RtpExtension::kTOffset, kIncorrectIds[i]));
1027 EXPECT_FALSE(channel_->SetSendRtpHeaderExtensions(extensions))
1028 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
1029 }
1030}
1031
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001032TEST_F(WebRtcVideoChannel2Test, SetRecvRtpHeaderExtensionsRejectsIncorrectIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001033 const size_t kNumIncorrectIds = 4;
1034 const int kIncorrectIds[kNumIncorrectIds] = {-2, -1, 15, 16};
1035 for (size_t i = 0; i < kNumIncorrectIds; ++i) {
1036 std::vector<cricket::RtpHeaderExtension> extensions;
1037 extensions.push_back(cricket::RtpHeaderExtension(
1038 webrtc::RtpExtension::kTOffset, kIncorrectIds[i]));
1039 EXPECT_FALSE(channel_->SetRecvRtpHeaderExtensions(extensions))
1040 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
1041 }
1042}
1043
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001044TEST_F(WebRtcVideoChannel2Test, SetSendRtpHeaderExtensionsRejectsDuplicateIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001045 const int id = 1;
1046 std::vector<cricket::RtpHeaderExtension> extensions;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001047 extensions.push_back(
1048 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, id));
1049 extensions.push_back(
1050 cricket::RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, id));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001051 EXPECT_FALSE(channel_->SetSendRtpHeaderExtensions(extensions));
1052
1053 // Duplicate entries are also not supported.
1054 extensions.clear();
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001055 extensions.push_back(
1056 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, id));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001057 extensions.push_back(extensions.back());
1058 EXPECT_FALSE(channel_->SetSendRtpHeaderExtensions(extensions));
1059}
1060
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001061TEST_F(WebRtcVideoChannel2Test, SetRecvRtpHeaderExtensionsRejectsDuplicateIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001062 const int id = 1;
1063 std::vector<cricket::RtpHeaderExtension> extensions;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001064 extensions.push_back(
1065 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, id));
1066 extensions.push_back(
1067 cricket::RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, id));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001068 EXPECT_FALSE(channel_->SetRecvRtpHeaderExtensions(extensions));
1069
1070 // Duplicate entries are also not supported.
1071 extensions.clear();
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001072 extensions.push_back(
1073 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, id));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001074 extensions.push_back(extensions.back());
1075 EXPECT_FALSE(channel_->SetRecvRtpHeaderExtensions(extensions));
1076}
1077
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001078TEST_F(WebRtcVideoChannel2Test, DISABLED_LeakyBucketTest) {
1079 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1080}
1081
1082TEST_F(WebRtcVideoChannel2Test, DISABLED_BufferedModeLatency) {
1083 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1084}
1085
1086TEST_F(WebRtcVideoChannel2Test, DISABLED_AdditiveVideoOptions) {
1087 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1088}
1089
1090TEST_F(WebRtcVideoChannel2Test, AddRecvStreamOnlyUsesOneReceiveStream) {
1091 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001092 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001093}
1094
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001095TEST_F(WebRtcVideoChannel2Test, RembIsEnabledByDefault) {
1096 FakeVideoReceiveStream* stream = AddRecvStream();
1097 EXPECT_TRUE(stream->GetConfig().rtp.remb);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001098}
1099
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001100TEST_F(WebRtcVideoChannel2Test, RembCanBeEnabledAndDisabled) {
1101 FakeVideoReceiveStream* stream = AddRecvStream();
1102 EXPECT_TRUE(stream->GetConfig().rtp.remb);
1103
1104 // Verify that REMB is turned off when codecs without REMB are set.
1105 std::vector<VideoCodec> codecs;
1106 codecs.push_back(kVp8Codec);
1107 EXPECT_TRUE(codecs[0].feedback_params.params().empty());
1108 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001109 stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001110 EXPECT_FALSE(stream->GetConfig().rtp.remb);
1111
1112 // Verify that REMB is turned on when setting default codecs since the
1113 // default codecs have REMB enabled.
1114 EXPECT_TRUE(channel_->SetRecvCodecs(engine_.codecs()));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001115 stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001116 EXPECT_TRUE(stream->GetConfig().rtp.remb);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001117}
1118
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00001119TEST_F(WebRtcVideoChannel2Test, NackIsEnabledByDefault) {
1120 VerifyCodecHasDefaultFeedbackParams(default_codec_);
1121
pbos@webrtc.org19864742014-05-30 07:35:47 +00001122 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
1123 EXPECT_TRUE(channel_->SetSend(true));
1124
1125 // Send side.
1126 FakeVideoSendStream* send_stream =
1127 AddSendStream(cricket::StreamParams::CreateLegacy(1));
1128 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1129
1130 // Receiver side.
1131 FakeVideoReceiveStream* recv_stream =
1132 AddRecvStream(cricket::StreamParams::CreateLegacy(1));
1133 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1134
1135 // Nack history size should match between sender and receiver.
1136 EXPECT_EQ(send_stream->GetConfig().rtp.nack.rtp_history_ms,
1137 recv_stream->GetConfig().rtp.nack.rtp_history_ms);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001138}
1139
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00001140TEST_F(WebRtcVideoChannel2Test, NackCanBeDisabled) {
1141 std::vector<VideoCodec> codecs;
1142 codecs.push_back(kVp8Codec);
1143
1144 // Send side.
1145 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
1146 FakeVideoSendStream* send_stream =
1147 AddSendStream(cricket::StreamParams::CreateLegacy(1));
1148 EXPECT_EQ(0, send_stream->GetConfig().rtp.nack.rtp_history_ms);
1149
1150 // Receiver side.
1151 ASSERT_TRUE(channel_->SetRecvCodecs(codecs));
1152 FakeVideoReceiveStream* recv_stream =
1153 AddRecvStream(cricket::StreamParams::CreateLegacy(1));
1154 EXPECT_EQ(0, recv_stream->GetConfig().rtp.nack.rtp_history_ms);
1155}
1156
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001157TEST_F(WebRtcVideoChannel2Test, DISABLED_VideoProtectionInterop) {
1158 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1159}
1160
1161TEST_F(WebRtcVideoChannel2Test, DISABLED_VideoProtectionInteropReversed) {
1162 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1163}
1164
1165TEST_F(WebRtcVideoChannel2Test, DISABLED_HybridNackFecConference) {
1166 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1167}
1168
1169TEST_F(WebRtcVideoChannel2Test, DISABLED_AddRemoveRecvStreamConference) {
1170 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1171}
1172
1173TEST_F(WebRtcVideoChannel2Test, DISABLED_SetRender) {
1174 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1175}
1176
1177TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthAuto) {
1178 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1179}
1180
1181TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthAutoCapped) {
1182 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1183}
1184
1185TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthFixed) {
1186 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1187}
1188
1189TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthInConference) {
1190 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1191}
1192
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001193TEST_F(WebRtcVideoChannel2Test, UsesCorrectSettingsForScreencast) {
1194 static const int kScreenshareMinBitrateKbps = 800;
1195 cricket::VideoCodec codec = kVp8Codec360p;
1196 std::vector<cricket::VideoCodec> codecs;
1197 codecs.push_back(codec);
1198 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1199 VideoOptions options;
1200 options.screencast_min_bitrate.Set(kScreenshareMinBitrateKbps);
1201 channel_->SetOptions(options);
1202
1203 AddSendStream();
1204
1205 cricket::FakeVideoCapturer capturer;
1206 capturer.SetScreencast(false);
1207 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer));
1208 cricket::VideoFormat capture_format_hd =
1209 capturer.GetSupportedFormats()->front();
1210 EXPECT_EQ(1280, capture_format_hd.width);
1211 EXPECT_EQ(720, capture_format_hd.height);
1212 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format_hd));
1213
1214 EXPECT_TRUE(channel_->SetSend(true));
1215
1216 EXPECT_TRUE(capturer.CaptureFrame());
1217 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
1218 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
1219
1220 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
1221
1222 // Verify non-screencast settings.
1223 webrtc::VideoEncoderConfig encoder_config = send_stream->GetEncoderConfig();
1224 EXPECT_EQ(webrtc::VideoEncoderConfig::kRealtimeVideo,
1225 encoder_config.content_type);
1226 EXPECT_EQ(codec.width, encoder_config.streams.front().width);
1227 EXPECT_EQ(codec.height, encoder_config.streams.front().height);
1228 EXPECT_EQ(0, encoder_config.min_transmit_bitrate_bps)
1229 << "Non-screenshare shouldn't use min-transmit bitrate.";
1230
1231 capturer.SetScreencast(true);
1232 EXPECT_TRUE(capturer.CaptureFrame());
1233
1234 EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
1235
1236 // Verify screencast settings.
1237 encoder_config = send_stream->GetEncoderConfig();
1238 EXPECT_EQ(webrtc::VideoEncoderConfig::kScreenshare,
1239 encoder_config.content_type);
1240 EXPECT_EQ(kScreenshareMinBitrateKbps * 1000,
1241 encoder_config.min_transmit_bitrate_bps);
1242
1243 EXPECT_EQ(capture_format_hd.width, encoder_config.streams.front().width);
1244 EXPECT_EQ(capture_format_hd.height, encoder_config.streams.front().height);
1245
1246 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001247}
1248
1249TEST_F(WebRtcVideoChannel2Test, DISABLED_SetSendSsrcAndCname) {
1250 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1251}
1252
1253TEST_F(WebRtcVideoChannel2Test,
1254 DISABLED_SetSendSsrcAfterCreatingReceiveChannel) {
1255 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1256}
1257
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00001258TEST_F(WebRtcVideoChannel2Test, SuspendBelowMinBitrateDisabledByDefault) {
1259 FakeVideoSendStream* stream = AddSendStream();
1260 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
1261}
1262
1263TEST_F(WebRtcVideoChannel2Test, SetOptionsWithSuspendBelowMinBitrate) {
1264 VideoOptions options;
1265 options.suspend_below_min_bitrate.Set(true);
1266 channel_->SetOptions(options);
1267
1268 FakeVideoSendStream* stream = AddSendStream();
1269 EXPECT_TRUE(stream->GetConfig().suspend_below_min_bitrate);
1270
1271 options.suspend_below_min_bitrate.Set(false);
1272 channel_->SetOptions(options);
1273
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001274 stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00001275 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
1276}
1277
pbos@webrtc.org543e5892014-07-23 07:01:31 +00001278TEST_F(WebRtcVideoChannel2Test, RedundantPayloadsDisabledByDefault) {
1279 const std::vector<uint32> ssrcs = MAKE_VECTOR(kSsrcs1);
1280 const std::vector<uint32> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
1281 FakeVideoSendStream* stream = AddSendStream(
1282 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
1283 EXPECT_FALSE(stream->GetConfig().rtp.rtx.pad_with_redundant_payloads);
1284}
1285
1286TEST_F(WebRtcVideoChannel2Test, SetOptionsWithPayloadPadding) {
1287 VideoOptions options;
1288 options.use_payload_padding.Set(true);
1289 channel_->SetOptions(options);
1290
1291 const std::vector<uint32> ssrcs = MAKE_VECTOR(kSsrcs1);
1292 const std::vector<uint32> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
1293 FakeVideoSendStream* stream = AddSendStream(
1294 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
1295 EXPECT_TRUE(stream->GetConfig().rtp.rtx.pad_with_redundant_payloads);
1296
1297 options.use_payload_padding.Set(false);
1298 channel_->SetOptions(options);
1299
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001300 stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.org543e5892014-07-23 07:01:31 +00001301 EXPECT_FALSE(stream->GetConfig().rtp.rtx.pad_with_redundant_payloads);
1302}
1303
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001304TEST_F(WebRtcVideoChannel2Test, Vp8DenoisingEnabledByDefault) {
1305 FakeVideoSendStream* stream = AddSendStream();
1306 webrtc::VideoCodecVP8 vp8_settings;
1307 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1308 EXPECT_TRUE(vp8_settings.denoisingOn);
1309}
1310
1311TEST_F(WebRtcVideoChannel2Test, SetOptionsWithDenoising) {
1312 VideoOptions options;
1313 options.video_noise_reduction.Set(false);
1314 channel_->SetOptions(options);
1315
1316 FakeVideoSendStream* stream = AddSendStream();
1317 webrtc::VideoCodecVP8 vp8_settings;
1318 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1319 EXPECT_FALSE(vp8_settings.denoisingOn);
1320
1321 options.video_noise_reduction.Set(true);
1322 channel_->SetOptions(options);
1323
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001324 stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001325 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1326 EXPECT_TRUE(vp8_settings.denoisingOn);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001327}
1328
1329TEST_F(WebRtcVideoChannel2Test, DISABLED_MultipleSendStreamsWithOneCapturer) {
1330 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1331}
1332
pbos@webrtc.org8aed9452014-07-26 10:16:49 +00001333TEST_F(WebRtcVideoChannel2Test, DISABLED_SendReceiveBitratesStats) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001334 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1335}
1336
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001337TEST_F(WebRtcVideoChannel2Test, AdaptsOnOveruse) {
1338 TestCpuAdaptation(true);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001339}
1340
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001341TEST_F(WebRtcVideoChannel2Test, DoesNotAdaptOnOveruseWhenDisabled) {
1342 TestCpuAdaptation(false);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001343}
1344
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001345void WebRtcVideoChannel2Test::TestCpuAdaptation(bool enable_overuse) {
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001346 cricket::VideoCodec codec = kVp8Codec720p;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001347 std::vector<cricket::VideoCodec> codecs;
1348 codecs.push_back(codec);
1349 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1350
1351 if (enable_overuse) {
1352 VideoOptions options;
1353 options.cpu_overuse_detection.Set(true);
1354 channel_->SetOptions(options);
1355 }
1356
1357 AddSendStream();
1358
1359 cricket::FakeVideoCapturer capturer;
1360 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer));
1361 EXPECT_EQ(cricket::CS_RUNNING,
1362 capturer.Start(capturer.GetSupportedFormats()->front()));
1363
1364 EXPECT_TRUE(channel_->SetSend(true));
1365
1366 // Trigger overuse.
1367 webrtc::LoadObserver* overuse_callback =
1368 fake_call_->GetConfig().overuse_callback;
1369 ASSERT_TRUE(overuse_callback != NULL);
1370 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kOveruse);
1371
1372 EXPECT_TRUE(capturer.CaptureFrame());
1373 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
1374 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
1375
1376 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
1377
1378 if (enable_overuse) {
1379 EXPECT_LT(send_stream->GetLastWidth(), codec.width);
1380 EXPECT_LT(send_stream->GetLastHeight(), codec.height);
1381 } else {
1382 EXPECT_EQ(codec.width, send_stream->GetLastWidth());
1383 EXPECT_EQ(codec.height, send_stream->GetLastHeight());
1384 }
1385
1386 // Trigger underuse which should go back to normal resolution.
1387 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kUnderuse);
1388 EXPECT_TRUE(capturer.CaptureFrame());
1389
1390 EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
1391
1392 EXPECT_EQ(codec.width, send_stream->GetLastWidth());
1393 EXPECT_EQ(codec.height, send_stream->GetLastHeight());
1394
1395 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001396}
1397
1398TEST_F(WebRtcVideoChannel2Test, DISABLED_WebRtcShouldLog) {
1399 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1400}
1401
1402TEST_F(WebRtcVideoChannel2Test, DISABLED_WebRtcShouldNotLog) {
1403 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1404}
1405
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001406TEST_F(WebRtcVideoChannel2Test, SetDefaultSendCodecs) {
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +00001407 ASSERT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001408
1409 VideoCodec codec;
1410 EXPECT_TRUE(channel_->GetSendCodec(&codec));
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +00001411 EXPECT_TRUE(codec.Matches(engine_.codecs()[0]));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001412
1413 // Using a RTX setup to verify that the default RTX payload type is good.
1414 const std::vector<uint32> ssrcs = MAKE_VECTOR(kSsrcs1);
1415 const std::vector<uint32> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
1416 FakeVideoSendStream* stream = AddSendStream(
1417 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
1418 webrtc::VideoSendStream::Config config = stream->GetConfig();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001419
1420 // Make sure NACK and FEC are enabled on the correct payload types.
1421 EXPECT_EQ(1000, config.rtp.nack.rtp_history_ms);
1422 EXPECT_EQ(default_ulpfec_codec_.id, config.rtp.fec.ulpfec_payload_type);
1423 EXPECT_EQ(default_red_codec_.id, config.rtp.fec.red_payload_type);
pbos@webrtc.org269605c2014-06-26 08:49:03 +00001424
1425 EXPECT_EQ(1u, config.rtp.rtx.ssrcs.size());
1426 EXPECT_EQ(kRtxSsrcs1[0], config.rtp.rtx.ssrcs[0]);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001427 EXPECT_EQ(static_cast<int>(default_rtx_codec_.id),
1428 config.rtp.rtx.payload_type);
1429 // TODO(juberti): Check RTCP, PLI, TMMBR.
1430}
1431
1432TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithoutFec) {
1433 std::vector<VideoCodec> codecs;
1434 codecs.push_back(kVp8Codec);
1435 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
1436
1437 FakeVideoSendStream* stream = AddSendStream();
1438 webrtc::VideoSendStream::Config config = stream->GetConfig();
1439
1440 EXPECT_EQ(-1, config.rtp.fec.ulpfec_payload_type);
1441 EXPECT_EQ(-1, config.rtp.fec.red_payload_type);
1442}
1443
1444TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org269605c2014-06-26 08:49:03 +00001445 SetSendCodecRejectsRtxWithoutAssociatedPayloadType) {
1446 std::vector<VideoCodec> codecs;
1447 cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0);
1448 codecs.push_back(rtx_codec);
1449 EXPECT_FALSE(channel_->SetSendCodecs(codecs))
1450 << "RTX codec without associated payload type should be rejected.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001451}
1452
1453TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org269605c2014-06-26 08:49:03 +00001454 SetSendCodecRejectsRtxWithoutMatchingVideoCodec) {
1455 std::vector<VideoCodec> codecs;
1456 cricket::VideoCodec rtx_codec =
1457 cricket::VideoCodec::CreateRtxCodec(96, kVp8Codec.id);
1458 codecs.push_back(kVp8Codec);
1459 codecs.push_back(rtx_codec);
1460 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
1461
1462 cricket::VideoCodec rtx_codec2 =
1463 cricket::VideoCodec::CreateRtxCodec(96, kVp8Codec.id + 1);
1464 codecs.pop_back();
1465 codecs.push_back(rtx_codec2);
1466 EXPECT_FALSE(channel_->SetSendCodecs(codecs))
1467 << "RTX without matching video codec should be rejected.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001468}
1469
pbos@webrtc.org269605c2014-06-26 08:49:03 +00001470TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithoutFecDisablesFec) {
1471 std::vector<VideoCodec> codecs;
1472 codecs.push_back(kVp8Codec);
1473 codecs.push_back(kUlpfecCodec);
1474 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
1475
1476 FakeVideoSendStream* stream = AddSendStream();
1477 webrtc::VideoSendStream::Config config = stream->GetConfig();
1478
1479 EXPECT_EQ(kUlpfecCodec.id, config.rtp.fec.ulpfec_payload_type);
1480
1481 codecs.pop_back();
1482 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001483 stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.org269605c2014-06-26 08:49:03 +00001484 ASSERT_TRUE(stream != NULL);
1485 config = stream->GetConfig();
1486 EXPECT_EQ(-1, config.rtp.fec.ulpfec_payload_type)
1487 << "SetSendCodec without FEC should disable current FEC.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001488}
1489
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00001490TEST_F(WebRtcVideoChannel2Test, SetSendCodecsChangesExistingStreams) {
1491 std::vector<VideoCodec> codecs;
1492 codecs.push_back(kVp8Codec720p);
1493 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
1494
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001495 std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00001496 EXPECT_EQ(kVp8Codec720p.width, streams[0].width);
1497 EXPECT_EQ(kVp8Codec720p.height, streams[0].height);
1498
1499 codecs.clear();
1500 codecs.push_back(kVp8Codec360p);
1501 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001502 streams = fake_call_->GetVideoSendStreams()[0]->GetVideoStreams();
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00001503 EXPECT_EQ(kVp8Codec360p.width, streams[0].width);
1504 EXPECT_EQ(kVp8Codec360p.height, streams[0].height);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001505}
1506
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001507TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithMinMaxBitrate) {
1508 SetSendCodecsShouldWorkForBitrates("10", "20");
1509}
1510
1511TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectsMaxLessThanMinBitrate) {
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +00001512 std::vector<VideoCodec> video_codecs = engine_.codecs();
1513 video_codecs[0].params[kCodecParamMinBitrate] = "30";
1514 video_codecs[0].params[kCodecParamMaxBitrate] = "20";
1515 EXPECT_FALSE(channel_->SetSendCodecs(video_codecs));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001516}
1517
1518TEST_F(WebRtcVideoChannel2Test, SetSendCodecsAcceptLargeMinMaxBitrate) {
1519 SetSendCodecsShouldWorkForBitrates("1000", "2000");
1520}
1521
1522TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithMaxQuantization) {
1523 static const char* kMaxQuantization = "21";
1524 std::vector<VideoCodec> codecs;
1525 codecs.push_back(kVp8Codec);
1526 codecs[0].params[kCodecParamMaxQuantization] = kMaxQuantization;
1527 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
pbos@webrtc.org6ae48c62014-06-06 10:49:19 +00001528 EXPECT_EQ(static_cast<unsigned int>(atoi(kMaxQuantization)),
1529 AddSendStream()->GetVideoStreams().back().max_qp);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001530
1531 VideoCodec codec;
1532 EXPECT_TRUE(channel_->GetSendCodec(&codec));
1533 EXPECT_EQ(kMaxQuantization, codec.params[kCodecParamMaxQuantization]);
1534}
1535
1536TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectBadDimensions) {
1537 std::vector<cricket::VideoCodec> codecs;
1538 codecs.push_back(kVp8Codec);
1539
1540 codecs[0].width = 0;
1541 EXPECT_FALSE(channel_->SetSendCodecs(codecs))
1542 << "Codec set though codec width is zero.";
1543
1544 codecs[0].width = kVp8Codec.width;
1545 codecs[0].height = 0;
1546 EXPECT_FALSE(channel_->SetSendCodecs(codecs))
1547 << "Codec set though codec height is zero.";
1548}
1549
1550TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectBadPayloadTypes) {
1551 // TODO(pbos): Should we only allow the dynamic range?
1552 static const size_t kNumIncorrectPayloads = 4;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001553 static const int kIncorrectPayloads[kNumIncorrectPayloads] = {
1554 -2, -1, 128, 129};
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001555 std::vector<cricket::VideoCodec> codecs;
1556 codecs.push_back(kVp8Codec);
1557 for (size_t i = 0; i < kNumIncorrectPayloads; ++i) {
1558 int payload_type = kIncorrectPayloads[i];
1559 codecs[0].id = payload_type;
1560 EXPECT_FALSE(channel_->SetSendCodecs(codecs))
1561 << "Bad payload type '" << payload_type << "' accepted.";
1562 }
1563}
1564
1565TEST_F(WebRtcVideoChannel2Test, SetSendCodecsAcceptAllValidPayloadTypes) {
1566 std::vector<cricket::VideoCodec> codecs;
1567 codecs.push_back(kVp8Codec);
1568 for (int payload_type = 0; payload_type <= 127; ++payload_type) {
1569 codecs[0].id = payload_type;
1570 EXPECT_TRUE(channel_->SetSendCodecs(codecs))
1571 << "Payload type '" << payload_type << "' rejected.";
1572 }
1573}
1574
1575TEST_F(WebRtcVideoChannel2Test, DISABLED_ResetVieSendCodecOnNewFrameSize) {
1576 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1577}
1578
1579TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithOnlyVp8) {
1580 std::vector<cricket::VideoCodec> codecs;
1581 codecs.push_back(kVp8Codec);
1582 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
1583}
1584
pbos@webrtc.orge322a172014-06-13 11:47:28 +00001585// Test that we set our inbound RTX codecs properly.
1586TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithRtx) {
1587 std::vector<cricket::VideoCodec> codecs;
1588 codecs.push_back(kVp8Codec);
1589 cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0);
1590 codecs.push_back(rtx_codec);
1591 EXPECT_FALSE(channel_->SetRecvCodecs(codecs))
1592 << "RTX codec without associated payload should be rejected.";
1593
1594 codecs[1].SetParam("apt", kVp8Codec.id + 1);
1595 EXPECT_FALSE(channel_->SetRecvCodecs(codecs))
1596 << "RTX codec with invalid associated payload type should be rejected.";
1597
1598 codecs[1].SetParam("apt", kVp8Codec.id);
1599 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
1600
1601 cricket::VideoCodec rtx_codec2(97, "rtx", 0, 0, 0, 0);
1602 rtx_codec2.SetParam("apt", rtx_codec.id);
1603 codecs.push_back(rtx_codec2);
1604
1605 EXPECT_FALSE(channel_->SetRecvCodecs(codecs)) << "RTX codec with another RTX "
1606 "as associated payload type "
1607 "should be rejected.";
1608}
1609
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001610TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsDifferentPayloadType) {
1611 std::vector<cricket::VideoCodec> codecs;
1612 codecs.push_back(kVp8Codec);
1613 codecs[0].id = 99;
1614 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
1615}
1616
pbos@webrtc.orgccbed3b2014-07-11 13:02:54 +00001617TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsAcceptDefaultCodecs) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001618 EXPECT_TRUE(channel_->SetRecvCodecs(engine_.codecs()));
pbos@webrtc.orgccbed3b2014-07-11 13:02:54 +00001619
1620 FakeVideoReceiveStream* stream = AddRecvStream();
1621 webrtc::VideoReceiveStream::Config config = stream->GetConfig();
pbos@webrtc.org776e6f22014-10-29 15:28:39 +00001622 EXPECT_EQ(engine_.codecs()[0].name, config.decoders[0].payload_name);
1623 EXPECT_EQ(engine_.codecs()[0].id, config.decoders[0].payload_type);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001624}
1625
1626TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsRejectUnsupportedCodec) {
1627 std::vector<VideoCodec> codecs;
1628 codecs.push_back(kVp8Codec);
1629 codecs.push_back(VideoCodec(101, "WTF3", 640, 400, 30, 0));
1630 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
1631}
1632
1633// TODO(pbos): Enable VP9 through external codec support
1634TEST_F(WebRtcVideoChannel2Test,
1635 DISABLED_SetRecvCodecsAcceptsMultipleVideoCodecs) {
1636 std::vector<VideoCodec> codecs;
1637 codecs.push_back(kVp8Codec);
1638 codecs.push_back(kVp9Codec);
1639 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
1640}
1641
1642TEST_F(WebRtcVideoChannel2Test,
1643 DISABLED_SetRecvCodecsSetsFecForAllVideoCodecs) {
1644 std::vector<VideoCodec> codecs;
1645 codecs.push_back(kVp8Codec);
1646 codecs.push_back(kVp9Codec);
1647 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
1648 FAIL(); // TODO(pbos): Verify that the FEC parameters are set for all codecs.
1649}
1650
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001651TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithoutFecDisablesFec) {
1652 std::vector<VideoCodec> codecs;
1653 codecs.push_back(kVp8Codec);
1654 codecs.push_back(kUlpfecCodec);
1655 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
1656
1657 FakeVideoReceiveStream* stream = AddRecvStream();
1658 webrtc::VideoReceiveStream::Config config = stream->GetConfig();
1659
1660 EXPECT_EQ(kUlpfecCodec.id, config.rtp.fec.ulpfec_payload_type);
1661
1662 codecs.pop_back();
1663 ASSERT_TRUE(channel_->SetRecvCodecs(codecs));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001664 stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001665 ASSERT_TRUE(stream != NULL);
1666 config = stream->GetConfig();
1667 EXPECT_EQ(-1, config.rtp.fec.ulpfec_payload_type)
1668 << "SetSendCodec without FEC should disable current FEC.";
pbos@webrtc.org269605c2014-06-26 08:49:03 +00001669}
1670
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001671TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectDuplicateFecPayloads) {
1672 std::vector<VideoCodec> codecs;
1673 codecs.push_back(kVp8Codec);
1674 codecs.push_back(kRedCodec);
1675 codecs[1].id = codecs[0].id;
1676 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
1677}
1678
1679TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsRejectDuplicateCodecPayloads) {
1680 std::vector<VideoCodec> codecs;
1681 codecs.push_back(kVp8Codec);
1682 codecs.push_back(kVp9Codec);
1683 codecs[1].id = codecs[0].id;
1684 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
1685}
1686
1687TEST_F(WebRtcVideoChannel2Test,
1688 SetRecvCodecsAcceptSameCodecOnMultiplePayloadTypes) {
1689 std::vector<VideoCodec> codecs;
1690 codecs.push_back(kVp8Codec);
1691 codecs.push_back(kVp8Codec);
1692 codecs[1].id += 1;
1693 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
1694}
1695
1696TEST_F(WebRtcVideoChannel2Test, SendStreamNotSendingByDefault) {
1697 EXPECT_FALSE(AddSendStream()->IsSending());
1698}
1699
pbos@webrtc.org85f42942014-07-22 09:14:58 +00001700TEST_F(WebRtcVideoChannel2Test, ReceiveStreamReceivingByDefault) {
1701 EXPECT_TRUE(AddRecvStream()->IsReceiving());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001702}
1703
1704TEST_F(WebRtcVideoChannel2Test, SetSend) {
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +00001705 FakeVideoSendStream* stream = AddSendStream();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001706 EXPECT_FALSE(stream->IsSending());
1707
1708 // false->true
1709 EXPECT_TRUE(channel_->SetSend(true));
1710 EXPECT_TRUE(stream->IsSending());
1711 // true->true
1712 EXPECT_TRUE(channel_->SetSend(true));
1713 EXPECT_TRUE(stream->IsSending());
1714 // true->false
1715 EXPECT_TRUE(channel_->SetSend(false));
1716 EXPECT_FALSE(stream->IsSending());
1717 // false->false
1718 EXPECT_TRUE(channel_->SetSend(false));
1719 EXPECT_FALSE(stream->IsSending());
1720
1721 EXPECT_TRUE(channel_->SetSend(true));
1722 FakeVideoSendStream* new_stream = AddSendStream();
1723 EXPECT_TRUE(new_stream->IsSending())
1724 << "Send stream created after SetSend(true) not sending initially.";
1725}
1726
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001727TEST_F(WebRtcVideoChannel2Test, DISABLED_TestSetDscpOptions) {
1728 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1729}
1730
1731TEST_F(WebRtcVideoChannel2Test, DISABLED_SetOptionsWithMaxBitrate) {
1732 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1733}
1734
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001735TEST_F(WebRtcVideoChannel2Test, DISABLED_ResetCodecOnScreencast) {
1736 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1737}
1738
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001739TEST_F(WebRtcVideoChannel2Test, DISABLED_RegisterDecoderIfFactoryIsGiven) {
1740 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1741}
1742
1743TEST_F(WebRtcVideoChannel2Test, DISABLED_DontRegisterDecoderMultipleTimes) {
1744 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1745}
1746
1747TEST_F(WebRtcVideoChannel2Test, DISABLED_DontRegisterDecoderForNonVP8) {
1748 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1749}
1750
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001751TEST_F(WebRtcVideoChannel2Test, DISABLED_ExternalCodecIgnored) {
1752 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1753}
1754
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00001755TEST_F(WebRtcVideoChannel2Test, OnReadyToSendSignalsNetworkState) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001756 EXPECT_EQ(webrtc::Call::kNetworkUp, fake_call_->GetNetworkState());
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00001757
1758 channel_->OnReadyToSend(false);
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001759 EXPECT_EQ(webrtc::Call::kNetworkDown, fake_call_->GetNetworkState());
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00001760
1761 channel_->OnReadyToSend(true);
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001762 EXPECT_EQ(webrtc::Call::kNetworkUp, fake_call_->GetNetworkState());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001763}
1764
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001765} // namespace cricket