blob: 29c7dd57f82d564d2708fcfdac502736daa629a6 [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.org86f613d2014-06-10 08:53:05 +0000177void FakeVideoReceiveStream::GetCurrentReceiveCodec(webrtc::VideoCodec* codec) {
178}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000179
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000180FakeCall::FakeCall(const webrtc::Call::Config& config)
181 : config_(config), network_state_(kNetworkUp) {
pbos@webrtc.org26c0c412014-09-03 16:17:12 +0000182 SetVideoCodecs(GetDefaultVideoCodecs());
183}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000184
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000185FakeCall::~FakeCall() {
186 EXPECT_EQ(0u, video_send_streams_.size());
187 EXPECT_EQ(0u, video_receive_streams_.size());
188}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000189
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000190void FakeCall::SetVideoCodecs(const std::vector<webrtc::VideoCodec> codecs) {
191 codecs_ = codecs;
192}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000193
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000194webrtc::Call::Config FakeCall::GetConfig() const {
195 return config_;
196}
197
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000198std::vector<FakeVideoSendStream*> FakeCall::GetVideoSendStreams() {
199 return video_send_streams_;
200}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000201
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000202std::vector<FakeVideoReceiveStream*> FakeCall::GetVideoReceiveStreams() {
203 return video_receive_streams_;
204}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000205
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000206webrtc::VideoCodec FakeCall::GetEmptyVideoCodec() {
207 webrtc::VideoCodec codec;
208 codec.minBitrate = 300;
209 codec.startBitrate = 800;
210 codec.maxBitrate = 1500;
211 codec.maxFramerate = 10;
212 codec.width = 640;
213 codec.height = 480;
214 codec.qpMax = 56;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000215
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000216 return codec;
217}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000218
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000219webrtc::VideoCodec FakeCall::GetVideoCodecVp8() {
220 webrtc::VideoCodec vp8_codec = GetEmptyVideoCodec();
221 vp8_codec.codecType = webrtc::kVideoCodecVP8;
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000222 rtc::strcpyn(
223 vp8_codec.plName, ARRAY_SIZE(vp8_codec.plName), kVp8Codec.name.c_str());
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000224 vp8_codec.plType = kVp8Codec.id;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000225
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000226 return vp8_codec;
227}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000228
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000229webrtc::VideoCodec FakeCall::GetVideoCodecVp9() {
230 webrtc::VideoCodec vp9_codec = GetEmptyVideoCodec();
231 // TODO(pbos): Add a correct codecType when webrtc has one.
232 vp9_codec.codecType = webrtc::kVideoCodecVP8;
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000233 rtc::strcpyn(
234 vp9_codec.plName, ARRAY_SIZE(vp9_codec.plName), kVp9Codec.name.c_str());
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000235 vp9_codec.plType = kVp9Codec.id;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000236
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000237 return vp9_codec;
238}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000239
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000240std::vector<webrtc::VideoCodec> FakeCall::GetDefaultVideoCodecs() {
241 std::vector<webrtc::VideoCodec> codecs;
242 codecs.push_back(GetVideoCodecVp8());
243 // codecs.push_back(GetVideoCodecVp9());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000244
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000245 return codecs;
246}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000247
pbos@webrtc.org26c0c412014-09-03 16:17:12 +0000248webrtc::Call::NetworkState FakeCall::GetNetworkState() const {
249 return network_state_;
250}
251
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000252webrtc::VideoSendStream* FakeCall::CreateVideoSendStream(
253 const webrtc::VideoSendStream::Config& config,
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +0000254 const webrtc::VideoEncoderConfig& encoder_config) {
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000255 FakeVideoSendStream* fake_stream =
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +0000256 new FakeVideoSendStream(config, encoder_config);
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000257 video_send_streams_.push_back(fake_stream);
258 return fake_stream;
259}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000260
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000261void FakeCall::DestroyVideoSendStream(webrtc::VideoSendStream* send_stream) {
262 FakeVideoSendStream* fake_stream =
263 static_cast<FakeVideoSendStream*>(send_stream);
264 for (size_t i = 0; i < video_send_streams_.size(); ++i) {
265 if (video_send_streams_[i] == fake_stream) {
266 delete video_send_streams_[i];
267 video_send_streams_.erase(video_send_streams_.begin() + i);
268 return;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000269 }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000270 }
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000271 ADD_FAILURE() << "DestroyVideoSendStream called with unknown paramter.";
272}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000273
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000274webrtc::VideoReceiveStream* FakeCall::CreateVideoReceiveStream(
275 const webrtc::VideoReceiveStream::Config& config) {
276 video_receive_streams_.push_back(new FakeVideoReceiveStream(config));
277 return video_receive_streams_[video_receive_streams_.size() - 1];
278}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000279
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000280void FakeCall::DestroyVideoReceiveStream(
281 webrtc::VideoReceiveStream* receive_stream) {
282 FakeVideoReceiveStream* fake_stream =
283 static_cast<FakeVideoReceiveStream*>(receive_stream);
284 for (size_t i = 0; i < video_receive_streams_.size(); ++i) {
285 if (video_receive_streams_[i] == fake_stream) {
286 delete video_receive_streams_[i];
287 video_receive_streams_.erase(video_receive_streams_.begin() + i);
288 return;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000289 }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000290 }
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000291 ADD_FAILURE() << "DestroyVideoReceiveStream called with unknown paramter.";
292}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000293
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000294webrtc::PacketReceiver* FakeCall::Receiver() {
295 // TODO(pbos): Fix this.
296 return NULL;
297}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000298
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000299uint32_t FakeCall::SendBitrateEstimate() {
300 return 0;
301}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000302
pbos@webrtc.org86f613d2014-06-10 08:53:05 +0000303uint32_t FakeCall::ReceiveBitrateEstimate() {
304 return 0;
305}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000306
pbos@webrtc.org26c0c412014-09-03 16:17:12 +0000307void FakeCall::SignalNetworkState(webrtc::Call::NetworkState state) {
308 network_state_ = state;
309}
310
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000311class WebRtcVideoEngine2Test : public ::testing::Test {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000312 public:
pbos@webrtc.orgb648b9d2014-08-26 11:08:06 +0000313 WebRtcVideoEngine2Test() {
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +0000314 std::vector<VideoCodec> engine_codecs = engine_.codecs();
315 assert(!engine_codecs.empty());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000316 bool codec_set = false;
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +0000317 for (size_t i = 0; i < engine_codecs.size(); ++i) {
318 if (engine_codecs[i].name == "red") {
319 default_red_codec_ = engine_codecs[i];
320 } else if (engine_codecs[i].name == "ulpfec") {
321 default_ulpfec_codec_ = engine_codecs[i];
322 } else if (engine_codecs[i].name == "rtx") {
323 default_rtx_codec_ = engine_codecs[i];
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000324 } else if (!codec_set) {
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +0000325 default_codec_ = engine_codecs[i];
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000326 codec_set = true;
327 }
328 }
329
330 assert(codec_set);
331 }
332
333 protected:
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000334 VideoMediaChannel* SetUpForExternalEncoderFactory(
335 cricket::WebRtcVideoEncoderFactory* encoder_factory,
336 const std::vector<VideoCodec>& codecs);
pbos@webrtc.orgfa553ef2014-10-20 11:07:07 +0000337
338 void TestStartBitrate(bool override_start_bitrate, int start_bitrate_bps);
339
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000340 WebRtcVideoEngine2 engine_;
341 VideoCodec default_codec_;
342 VideoCodec default_red_codec_;
343 VideoCodec default_ulpfec_codec_;
344 VideoCodec default_rtx_codec_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000345};
346
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000347// TODO(pbos): Add test that verifies that sync is configured properly.
348TEST_F(WebRtcVideoEngine2Test, DISABLED_CreateChannelWithVoiceEngine) {
349 FAIL() << "Not implemented."; // TODO(pbos): Implement.
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000350}
351
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000352TEST_F(WebRtcVideoEngine2Test, FindCodec) {
353 const std::vector<cricket::VideoCodec>& c = engine_.codecs();
354 EXPECT_EQ(4U, c.size());
355
356 cricket::VideoCodec vp8(104, "VP8", 320, 200, 30, 0);
357 EXPECT_TRUE(engine_.FindCodec(vp8));
358
359 cricket::VideoCodec vp8_ci(104, "vp8", 320, 200, 30, 0);
360 EXPECT_TRUE(engine_.FindCodec(vp8));
361
362 cricket::VideoCodec vp8_diff_fr_diff_pref(104, "VP8", 320, 200, 50, 50);
363 EXPECT_TRUE(engine_.FindCodec(vp8_diff_fr_diff_pref));
364
365 cricket::VideoCodec vp8_diff_id(95, "VP8", 320, 200, 30, 0);
366 EXPECT_FALSE(engine_.FindCodec(vp8_diff_id));
367 vp8_diff_id.id = 97;
368 EXPECT_TRUE(engine_.FindCodec(vp8_diff_id));
369
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000370 // FindCodec ignores the codec size.
371 // Test that FindCodec can accept uncommon codec size.
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000372 cricket::VideoCodec vp8_diff_res(104, "VP8", 320, 111, 30, 0);
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000373 EXPECT_TRUE(engine_.FindCodec(vp8_diff_res));
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000374
375 // PeerConnection doesn't negotiate the resolution at this point.
376 // Test that FindCodec can handle the case when width/height is 0.
377 cricket::VideoCodec vp8_zero_res(104, "VP8", 0, 0, 30, 0);
378 EXPECT_TRUE(engine_.FindCodec(vp8_zero_res));
379
380 cricket::VideoCodec red(101, "RED", 0, 0, 30, 0);
381 EXPECT_TRUE(engine_.FindCodec(red));
382
383 cricket::VideoCodec red_ci(101, "red", 0, 0, 30, 0);
384 EXPECT_TRUE(engine_.FindCodec(red));
385
386 cricket::VideoCodec fec(102, "ULPFEC", 0, 0, 30, 0);
387 EXPECT_TRUE(engine_.FindCodec(fec));
388
389 cricket::VideoCodec fec_ci(102, "ulpfec", 0, 0, 30, 0);
390 EXPECT_TRUE(engine_.FindCodec(fec));
391
392 cricket::VideoCodec rtx(96, "rtx", 0, 0, 30, 0);
393 EXPECT_TRUE(engine_.FindCodec(rtx));
394}
395
396TEST_F(WebRtcVideoEngine2Test, DefaultRtxCodecHasAssociatedPayloadTypeSet) {
397 std::vector<VideoCodec> engine_codecs = engine_.codecs();
398 for (size_t i = 0; i < engine_codecs.size(); ++i) {
399 if (engine_codecs[i].name != kRtxCodecName)
400 continue;
401 int associated_payload_type;
402 EXPECT_TRUE(engine_codecs[i].GetParam(kCodecParamAssociatedPayloadType,
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000403 &associated_payload_type));
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000404 EXPECT_EQ(default_codec_.id, associated_payload_type);
405 return;
406 }
407 FAIL() << "No RTX codec found among default codecs.";
408}
409
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000410TEST_F(WebRtcVideoEngine2Test, SupportsTimestampOffsetHeaderExtension) {
411 std::vector<RtpHeaderExtension> extensions = engine_.rtp_header_extensions();
412 ASSERT_FALSE(extensions.empty());
413 for (size_t i = 0; i < extensions.size(); ++i) {
414 if (extensions[i].uri == kRtpTimestampOffsetHeaderExtension) {
415 EXPECT_EQ(kRtpTimestampOffsetHeaderExtensionDefaultId, extensions[i].id);
416 return;
417 }
418 }
419 FAIL() << "Timestamp offset extension not in header-extension list.";
420}
421
422TEST_F(WebRtcVideoEngine2Test, SupportsAbsoluteSenderTimeHeaderExtension) {
423 std::vector<RtpHeaderExtension> extensions = engine_.rtp_header_extensions();
424 ASSERT_FALSE(extensions.empty());
425 for (size_t i = 0; i < extensions.size(); ++i) {
426 if (extensions[i].uri == kRtpAbsoluteSenderTimeHeaderExtension) {
427 EXPECT_EQ(kRtpAbsoluteSenderTimeHeaderExtensionDefaultId,
428 extensions[i].id);
429 return;
430 }
431 }
432 FAIL() << "Absolute Sender Time extension not in header-extension list.";
433}
434
pbos@webrtc.orgfa553ef2014-10-20 11:07:07 +0000435void WebRtcVideoEngine2Test::TestStartBitrate(bool override_start_bitrate,
436 int start_bitrate_bps) {
437 class FakeCallFactory : public WebRtcCallFactory {
438 public:
439 FakeCallFactory() : fake_call_(NULL) {}
440
441 FakeCall* GetCall() {
442 return fake_call_;
443 }
444
445 private:
446 virtual webrtc::Call* CreateCall(
447 const webrtc::Call::Config& config) OVERRIDE {
448 assert(fake_call_ == NULL);
449 fake_call_ = new FakeCall(config);
450 return fake_call_;
451 }
452
453 FakeCall* fake_call_;
454 };
455
456 FakeCallFactory call_factory;
457 engine_.SetCallFactory(&call_factory);
458
459 engine_.Init(rtc::Thread::Current());
460
461 cricket::VideoOptions options;
462 if (override_start_bitrate) {
463 options.video_start_bitrate.Set(start_bitrate_bps / 1000);
464 }
465
466 rtc::scoped_ptr<VideoMediaChannel> channel(
467 engine_.CreateChannel(options, NULL));
468
469 EXPECT_EQ(override_start_bitrate
470 ? start_bitrate_bps
471 : webrtc::Call::Config::kDefaultStartBitrateBps,
472 call_factory.GetCall()->GetConfig().stream_start_bitrate_bps);
473}
474
475TEST_F(WebRtcVideoEngine2Test, UsesCorrectDefaultStartBitrate) {
476 TestStartBitrate(false, -1);
477}
478
479TEST_F(WebRtcVideoEngine2Test, CreateChannelCanUseIncreasedStartBitrate) {
480 TestStartBitrate(true, 2 * webrtc::Call::Config::kDefaultStartBitrateBps);
481}
482
483TEST_F(WebRtcVideoEngine2Test, CreateChannelCanUseDecreasedStartBitrate) {
484 TestStartBitrate(true, webrtc::Call::Config::kDefaultStartBitrateBps / 2);
485}
486
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +0000487TEST_F(WebRtcVideoEngine2Test, SetSendFailsBeforeSettingCodecs) {
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000488 engine_.Init(rtc::Thread::Current());
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000489 rtc::scoped_ptr<VideoMediaChannel> channel(
490 engine_.CreateChannel(cricket::VideoOptions(), NULL));
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +0000491
492 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
493
494 EXPECT_FALSE(channel->SetSend(true))
495 << "Channel should not start without codecs.";
496 EXPECT_TRUE(channel->SetSend(false))
497 << "Channel should be stoppable even without set codecs.";
498}
499
pbos@webrtc.orgc3d2bd22014-08-12 20:55:10 +0000500TEST_F(WebRtcVideoEngine2Test, GetStatsWithoutSendCodecsSetDoesNotCrash) {
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000501 engine_.Init(rtc::Thread::Current());
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000502 rtc::scoped_ptr<VideoMediaChannel> channel(
503 engine_.CreateChannel(cricket::VideoOptions(), NULL));
pbos@webrtc.orgc3d2bd22014-08-12 20:55:10 +0000504 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
505 VideoMediaInfo info;
506 channel->GetStats(&info);
507}
508
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000509TEST_F(WebRtcVideoEngine2Test, UseExternalFactoryForVp8WhenSupported) {
510 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
511 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8");
512 std::vector<cricket::VideoCodec> codecs;
513 codecs.push_back(kVp8Codec);
514
515 rtc::scoped_ptr<VideoMediaChannel> channel(
516 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
517
518 EXPECT_TRUE(
519 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
520 ASSERT_EQ(1u, encoder_factory.encoders().size());
521 EXPECT_TRUE(channel->SetSend(true));
522
523 cricket::FakeVideoCapturer capturer;
524 EXPECT_TRUE(channel->SetCapturer(kSsrc, &capturer));
525 EXPECT_EQ(cricket::CS_RUNNING,
526 capturer.Start(capturer.GetSupportedFormats()->front()));
527 EXPECT_TRUE(capturer.CaptureFrame());
528
529 EXPECT_TRUE_WAIT(encoder_factory.encoders()[0]->GetNumEncodedFrames() > 0,
530 kTimeout);
531
532 // Setting codecs of the same type should not reallocate the encoder.
533 EXPECT_TRUE(channel->SetSendCodecs(codecs));
534 EXPECT_EQ(1, encoder_factory.GetNumCreatedEncoders());
535
536 // Remove stream previously added to free the external encoder instance.
537 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
538 EXPECT_EQ(0u, encoder_factory.encoders().size());
539}
540
541VideoMediaChannel* WebRtcVideoEngine2Test::SetUpForExternalEncoderFactory(
542 cricket::WebRtcVideoEncoderFactory* encoder_factory,
543 const std::vector<VideoCodec>& codecs) {
544 engine_.SetExternalEncoderFactory(encoder_factory);
545 engine_.Init(rtc::Thread::Current());
546
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000547 VideoMediaChannel* channel =
548 engine_.CreateChannel(cricket::VideoOptions(), NULL);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000549 EXPECT_TRUE(channel->SetSendCodecs(codecs));
550
551 return channel;
552}
553
554TEST_F(WebRtcVideoEngine2Test, ChannelWithExternalH264CanChangeToInternalVp8) {
555 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
556 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
557 std::vector<cricket::VideoCodec> codecs;
558 codecs.push_back(kH264Codec);
559
560 rtc::scoped_ptr<VideoMediaChannel> channel(
561 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
562
563 EXPECT_TRUE(
564 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
565 ASSERT_EQ(1u, encoder_factory.encoders().size());
566
567 codecs.clear();
568 codecs.push_back(kVp8Codec);
569 EXPECT_TRUE(channel->SetSendCodecs(codecs));
570
571 ASSERT_EQ(0u, encoder_factory.encoders().size());
572}
573
574TEST_F(WebRtcVideoEngine2Test,
575 DontUseExternalEncoderFactoryForUnsupportedCodecs) {
576 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
577 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
578 std::vector<cricket::VideoCodec> codecs;
579 codecs.push_back(kVp8Codec);
580
581 rtc::scoped_ptr<VideoMediaChannel> channel(
582 SetUpForExternalEncoderFactory(&encoder_factory, codecs));
583
584 EXPECT_TRUE(
585 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
586 ASSERT_EQ(0u, encoder_factory.encoders().size());
587}
588
589// Test external codec with be added to the end of the supported codec list.
590TEST_F(WebRtcVideoEngine2Test, ReportSupportedExternalCodecs) {
591 cricket::FakeWebRtcVideoEncoderFactory encoder_factory;
592 encoder_factory.AddSupportedVideoCodecType(webrtc::kVideoCodecH264, "H264");
593 engine_.SetExternalEncoderFactory(&encoder_factory);
594
595 engine_.Init(rtc::Thread::Current());
596
597 std::vector<cricket::VideoCodec> codecs(engine_.codecs());
598 ASSERT_GE(codecs.size(), 2u);
599 cricket::VideoCodec internal_codec = codecs.front();
600 cricket::VideoCodec external_codec = codecs.back();
601
602 // The external codec will appear at last.
603 EXPECT_EQ("VP8", internal_codec.name);
604 EXPECT_EQ("H264", external_codec.name);
605}
606
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000607class WebRtcVideoEngine2BaseTest
608 : public VideoEngineTest<cricket::WebRtcVideoEngine2> {
609 protected:
610 typedef VideoEngineTest<cricket::WebRtcVideoEngine2> Base;
611};
612
613#define WEBRTC_ENGINE_BASE_TEST(test) \
614 TEST_F(WebRtcVideoEngine2BaseTest, test) { Base::test##Body(); }
615
616WEBRTC_ENGINE_BASE_TEST(ConstrainNewCodec2);
617
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000618class WebRtcVideoChannel2BaseTest
619 : public VideoMediaChannelTest<WebRtcVideoEngine2, WebRtcVideoChannel2> {
620 protected:
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000621 typedef VideoMediaChannelTest<WebRtcVideoEngine2, WebRtcVideoChannel2> Base;
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000622
623 virtual cricket::VideoCodec DefaultCodec() OVERRIDE { return kVp8Codec; }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000624};
625
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000626#define WEBRTC_BASE_TEST(test) \
627 TEST_F(WebRtcVideoChannel2BaseTest, test) { Base::test(); }
628
629#define WEBRTC_DISABLED_BASE_TEST(test) \
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000630 TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_##test) { Base::test(); }
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000631
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000632// TODO(pbos): Fix WebRtcVideoEngine2BaseTest, where we want CheckCoInitialize.
633#if 0
634// TODO(juberti): Figure out why ViE is munging the COM refcount.
635#ifdef WIN32
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000636WEBRTC_DISABLED_BASE_TEST(CheckCoInitialize) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000637 Base::CheckCoInitialize();
638}
639#endif
640#endif
641
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000642WEBRTC_BASE_TEST(SetSend);
643WEBRTC_BASE_TEST(SetSendWithoutCodecs);
644WEBRTC_BASE_TEST(SetSendSetsTransportBufferSizes);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000645
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000646WEBRTC_BASE_TEST(GetStats);
647WEBRTC_BASE_TEST(GetStatsMultipleRecvStreams);
648WEBRTC_BASE_TEST(GetStatsMultipleSendStreams);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000649
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000650WEBRTC_BASE_TEST(SetSendBandwidth);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000651
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000652WEBRTC_BASE_TEST(SetSendSsrc);
653WEBRTC_BASE_TEST(SetSendSsrcAfterSetCodecs);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000654
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000655WEBRTC_BASE_TEST(SetRenderer);
656WEBRTC_BASE_TEST(AddRemoveRecvStreams);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000657
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000658WEBRTC_DISABLED_BASE_TEST(AddRemoveRecvStreamAndRender);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000659
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000660WEBRTC_BASE_TEST(AddRemoveRecvStreamsNoConference);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000661
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000662WEBRTC_BASE_TEST(AddRemoveSendStreams);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000663
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000664WEBRTC_BASE_TEST(SimulateConference);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000665
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000666WEBRTC_BASE_TEST(AddRemoveCapturer);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000667
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000668WEBRTC_BASE_TEST(RemoveCapturerWithoutAdd);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000669
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000670WEBRTC_BASE_TEST(AddRemoveCapturerMultipleSources);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000671
672// TODO(pbos): Figure out why this fails so often.
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000673WEBRTC_DISABLED_BASE_TEST(HighAspectHighHeightCapturer);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000674
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000675WEBRTC_BASE_TEST(RejectEmptyStreamParams);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000676
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000677WEBRTC_BASE_TEST(AdaptResolution16x10);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000678
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000679WEBRTC_BASE_TEST(AdaptResolution4x3);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000680
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000681// TODO(juberti): Restore this test once we support sending 0 fps.
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000682WEBRTC_DISABLED_BASE_TEST(AdaptDropAllFrames);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000683// TODO(juberti): Understand why we get decode errors on this test.
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000684WEBRTC_DISABLED_BASE_TEST(AdaptFramerate);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000685
pbos@webrtc.orgc4175b92014-09-03 15:25:49 +0000686WEBRTC_BASE_TEST(SendsLowerResolutionOnSmallerFrames);
687
688WEBRTC_BASE_TEST(MuteStream);
689
690WEBRTC_BASE_TEST(MultipleSendStreams);
691
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000692WEBRTC_BASE_TEST(SetSendStreamFormat0x0);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000693
694// TODO(zhurunz): Fix the flakey test.
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +0000695WEBRTC_DISABLED_BASE_TEST(SetSendStreamFormat);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000696
pbos@webrtc.org9359cb32014-07-23 15:44:48 +0000697TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8Vga) {
698 SendAndReceive(cricket::VideoCodec(100, "VP8", 640, 400, 30, 0));
699}
700
701TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8Qvga) {
702 SendAndReceive(cricket::VideoCodec(100, "VP8", 320, 200, 30, 0));
703}
704
705TEST_F(WebRtcVideoChannel2BaseTest, SendAndReceiveVp8SvcQqvga) {
706 SendAndReceive(cricket::VideoCodec(100, "VP8", 160, 100, 30, 0));
707}
708
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000709TEST_F(WebRtcVideoChannel2BaseTest, TwoStreamsSendAndReceive) {
710 Base::TwoStreamsSendAndReceive(kVp8Codec);
711}
712
713TEST_F(WebRtcVideoChannel2BaseTest, TwoStreamsReUseFirstStream) {
714 Base::TwoStreamsReUseFirstStream(kVp8Codec);
715}
716
pbos@webrtc.org9359cb32014-07-23 15:44:48 +0000717WEBRTC_BASE_TEST(SendManyResizeOnce);
718
719// TODO(pbos): Enable and figure out why this fails (or should work).
720TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_SendVp8HdAndReceiveAdaptedVp8Vga) {
721 EXPECT_TRUE(channel_->SetCapturer(kSsrc, NULL));
722 EXPECT_TRUE(channel_->SetRenderer(kDefaultReceiveSsrc, &renderer_));
723 channel_->UpdateAspectRatio(1280, 720);
724 video_capturer_.reset(new cricket::FakeVideoCapturer);
725 const std::vector<cricket::VideoFormat>* formats =
726 video_capturer_->GetSupportedFormats();
727 cricket::VideoFormat capture_format_hd = (*formats)[0];
728 EXPECT_EQ(cricket::CS_RUNNING, video_capturer_->Start(capture_format_hd));
729 EXPECT_TRUE(channel_->SetCapturer(kSsrc, video_capturer_.get()));
730
731 // Capture format HD -> adapt (OnOutputFormatRequest VGA) -> VGA.
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +0000732 cricket::VideoCodec codec = kVp8Codec720p;
pbos@webrtc.org9359cb32014-07-23 15:44:48 +0000733 EXPECT_TRUE(SetOneCodec(codec));
734 codec.width /= 2;
735 codec.height /= 2;
736 EXPECT_TRUE(SetSend(true));
737 EXPECT_TRUE(channel_->SetRender(true));
738 EXPECT_EQ(0, renderer_.num_rendered_frames());
739 EXPECT_TRUE(SendFrame());
740 EXPECT_FRAME_WAIT(1, codec.width, codec.height, kTimeout);
741}
742
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000743class WebRtcVideoChannel2Test : public WebRtcVideoEngine2Test,
744 public WebRtcCallFactory {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000745 public:
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000746 WebRtcVideoChannel2Test() : fake_call_(NULL) {}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000747 virtual void SetUp() OVERRIDE {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000748 engine_.SetCallFactory(this);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000749 engine_.Init(rtc::Thread::Current());
buildbot@webrtc.org1ecbe452014-10-14 20:29:28 +0000750 channel_.reset(engine_.CreateChannel(cricket::VideoOptions(), NULL));
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000751 ASSERT_TRUE(fake_call_ != NULL) << "Call not created through factory.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000752 last_ssrc_ = 123;
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000753 ASSERT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000754 }
755
756 protected:
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000757 virtual webrtc::Call* CreateCall(
758 const webrtc::Call::Config& config) OVERRIDE {
759 assert(fake_call_ == NULL);
760 fake_call_ = new FakeCall(config);
761 return fake_call_;
762 }
763
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000764 FakeVideoSendStream* AddSendStream() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000765 return AddSendStream(StreamParams::CreateLegacy(++last_ssrc_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000766 }
767
768 FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000769 size_t num_streams = fake_call_->GetVideoSendStreams().size();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000770 EXPECT_TRUE(channel_->AddSendStream(sp));
771 std::vector<FakeVideoSendStream*> streams =
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000772 fake_call_->GetVideoSendStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000773 EXPECT_EQ(num_streams + 1, streams.size());
774 return streams[streams.size() - 1];
775 }
776
777 std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000778 return fake_call_->GetVideoSendStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000779 }
780
781 FakeVideoReceiveStream* AddRecvStream() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000782 return AddRecvStream(StreamParams::CreateLegacy(++last_ssrc_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000783 }
784
785 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000786 size_t num_streams = fake_call_->GetVideoReceiveStreams().size();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000787 EXPECT_TRUE(channel_->AddRecvStream(sp));
788 std::vector<FakeVideoReceiveStream*> streams =
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000789 fake_call_->GetVideoReceiveStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000790 EXPECT_EQ(num_streams + 1, streams.size());
791 return streams[streams.size() - 1];
792 }
793
794 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate,
795 const char* max_bitrate) {
796 std::vector<VideoCodec> codecs;
797 codecs.push_back(kVp8Codec);
798 codecs[0].params[kCodecParamMinBitrate] = min_bitrate;
799 codecs[0].params[kCodecParamMaxBitrate] = max_bitrate;
800 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
801
802 FakeVideoSendStream* stream = AddSendStream();
803
pbos@webrtc.org6ae48c62014-06-06 10:49:19 +0000804 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
805 ASSERT_EQ(1u, video_streams.size());
806 EXPECT_EQ(atoi(min_bitrate), video_streams.back().min_bitrate_bps / 1000);
807 EXPECT_EQ(atoi(max_bitrate), video_streams.back().max_bitrate_bps / 1000);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000808
809 VideoCodec codec;
810 EXPECT_TRUE(channel_->GetSendCodec(&codec));
811 EXPECT_EQ(min_bitrate, codec.params[kCodecParamMinBitrate]);
812 EXPECT_EQ(max_bitrate, codec.params[kCodecParamMaxBitrate]);
813 }
814
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000815 void TestSetSendRtpHeaderExtensions(const std::string& cricket_ext,
816 const std::string& webrtc_ext) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000817 FakeCall* call = fake_call_;
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000818 // Enable extension.
819 const int id = 1;
820 std::vector<cricket::RtpHeaderExtension> extensions;
821 extensions.push_back(cricket::RtpHeaderExtension(cricket_ext, id));
822 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
823
824 FakeVideoSendStream* send_stream =
825 AddSendStream(cricket::StreamParams::CreateLegacy(123));
826
827 // Verify the send extension id.
828 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
829 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
830 EXPECT_EQ(webrtc_ext, send_stream->GetConfig().rtp.extensions[0].name);
831 // Verify call with same set of extensions returns true.
832 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
833 // Verify that SetSendRtpHeaderExtensions doesn't implicitly add them for
834 // receivers.
835 EXPECT_TRUE(AddRecvStream(cricket::StreamParams::CreateLegacy(123))
836 ->GetConfig()
837 .rtp.extensions.empty());
838
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +0000839 // Verify that existing RTP header extensions can be removed.
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000840 std::vector<cricket::RtpHeaderExtension> empty_extensions;
841 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(empty_extensions));
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +0000842 ASSERT_EQ(1u, call->GetVideoSendStreams().size());
843 send_stream = call->GetVideoSendStreams()[0];
844 EXPECT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
845
846 // Verify that adding receive RTP header extensions adds them for existing
847 // streams.
848 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
849 send_stream = call->GetVideoSendStreams()[0];
850 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
851 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
852 EXPECT_EQ(webrtc_ext, send_stream->GetConfig().rtp.extensions[0].name);
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000853 }
854
855 void TestSetRecvRtpHeaderExtensions(const std::string& cricket_ext,
856 const std::string& webrtc_ext) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000857 FakeCall* call = fake_call_;
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000858 // Enable extension.
859 const int id = 1;
860 std::vector<cricket::RtpHeaderExtension> extensions;
861 extensions.push_back(cricket::RtpHeaderExtension(cricket_ext, id));
862 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
863
864 FakeVideoReceiveStream* recv_stream =
865 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
866
867 // Verify the recv extension id.
868 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
869 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
870 EXPECT_EQ(webrtc_ext, recv_stream->GetConfig().rtp.extensions[0].name);
871 // Verify call with same set of extensions returns true.
872 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +0000873
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000874 // Verify that SetRecvRtpHeaderExtensions doesn't implicitly add them for
875 // senders.
876 EXPECT_TRUE(AddSendStream(cricket::StreamParams::CreateLegacy(123))
877 ->GetConfig()
878 .rtp.extensions.empty());
879
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +0000880 // Verify that existing RTP header extensions can be removed.
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000881 std::vector<cricket::RtpHeaderExtension> empty_extensions;
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +0000882 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(empty_extensions));
883 ASSERT_EQ(1u, call->GetVideoReceiveStreams().size());
884 recv_stream = call->GetVideoReceiveStreams()[0];
885 EXPECT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
886
887 // Verify that adding receive RTP header extensions adds them for existing
888 // streams.
889 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
890 recv_stream = call->GetVideoReceiveStreams()[0];
891 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
892 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
893 EXPECT_EQ(webrtc_ext, recv_stream->GetConfig().rtp.extensions[0].name);
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000894 }
895
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000896 void TestCpuAdaptation(bool enable_overuse);
897
898 FakeCall* fake_call_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000899 rtc::scoped_ptr<VideoMediaChannel> channel_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000900 uint32 last_ssrc_;
901};
902
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000903TEST_F(WebRtcVideoChannel2Test, RecvStreamWithSimAndRtx) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000904 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
905 EXPECT_TRUE(channel_->SetSend(true));
906 cricket::VideoOptions options;
907 options.conference_mode.Set(true);
908 EXPECT_TRUE(channel_->SetOptions(options));
909
910 // Send side.
911 const std::vector<uint32> ssrcs = MAKE_VECTOR(kSsrcs1);
912 const std::vector<uint32> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
913 FakeVideoSendStream* send_stream = AddSendStream(
914 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
915
916 ASSERT_EQ(rtx_ssrcs.size(), send_stream->GetConfig().rtp.rtx.ssrcs.size());
917 for (size_t i = 0; i < rtx_ssrcs.size(); ++i)
918 EXPECT_EQ(rtx_ssrcs[i], send_stream->GetConfig().rtp.rtx.ssrcs[i]);
919
920 // Receiver side.
921 FakeVideoReceiveStream* recv_stream = AddRecvStream(
922 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
923 ASSERT_GT(recv_stream->GetConfig().rtp.rtx.size(), 0u)
924 << "No SSRCs for RTX configured by AddRecvStream.";
925 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.rtx.size())
926 << "This test only works with one receive codec. Please update the test.";
927 EXPECT_EQ(rtx_ssrcs[0],
928 recv_stream->GetConfig().rtp.rtx.begin()->second.ssrc);
929 // TODO(pbos): Make sure we set the RTX for correct payloads etc.
930}
931
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000932TEST_F(WebRtcVideoChannel2Test, RecvStreamWithRtx) {
933 // Setup one channel with an associated RTX stream.
934 cricket::StreamParams params =
935 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
936 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
937 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
938 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.rtx.size());
939 EXPECT_EQ(kRtxSsrcs1[0],
940 recv_stream->GetConfig().rtp.rtx.begin()->second.ssrc);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000941}
942
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000943TEST_F(WebRtcVideoChannel2Test, RecvStreamNoRtx) {
944 // Setup one channel without an associated RTX stream.
945 cricket::StreamParams params =
946 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
947 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
948 ASSERT_TRUE(recv_stream->GetConfig().rtp.rtx.empty());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000949}
950
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000951TEST_F(WebRtcVideoChannel2Test, NoHeaderExtesionsByDefault) {
952 FakeVideoSendStream* send_stream =
953 AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
954 ASSERT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
955
956 FakeVideoReceiveStream* recv_stream =
957 AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
958 ASSERT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000959}
960
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000961// Test support for RTP timestamp offset header extension.
962TEST_F(WebRtcVideoChannel2Test, SendRtpTimestampOffsetHeaderExtensions) {
963 TestSetSendRtpHeaderExtensions(kRtpTimestampOffsetHeaderExtension,
964 webrtc::RtpExtension::kTOffset);
965}
966TEST_F(WebRtcVideoChannel2Test, RecvRtpTimestampOffsetHeaderExtensions) {
967 TestSetRecvRtpHeaderExtensions(kRtpTimestampOffsetHeaderExtension,
968 webrtc::RtpExtension::kTOffset);
969}
970
971// Test support for absolute send time header extension.
972TEST_F(WebRtcVideoChannel2Test, SendAbsoluteSendTimeHeaderExtensions) {
973 TestSetSendRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension,
974 webrtc::RtpExtension::kAbsSendTime);
975}
976TEST_F(WebRtcVideoChannel2Test, RecvAbsoluteSendTimeHeaderExtensions) {
977 TestSetRecvRtpHeaderExtensions(kRtpAbsoluteSenderTimeHeaderExtension,
978 webrtc::RtpExtension::kAbsSendTime);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000979}
980
pbos@webrtc.org3c107582014-07-20 15:27:35 +0000981TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000982 SetSendRtpHeaderExtensionsExcludeUnsupportedExtensions) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +0000983 const int kUnsupportedId = 1;
984 const int kTOffsetId = 2;
985
986 std::vector<cricket::RtpHeaderExtension> extensions;
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000987 extensions.push_back(
988 cricket::RtpHeaderExtension(kUnsupportedExtensionName, kUnsupportedId));
989 extensions.push_back(
990 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, kTOffsetId));
pbos@webrtc.org3c107582014-07-20 15:27:35 +0000991 EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
992 FakeVideoSendStream* send_stream =
993 AddSendStream(cricket::StreamParams::CreateLegacy(123));
994
995 // Only timestamp offset extension is set to send stream,
996 // unsupported rtp extension is ignored.
997 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
998 EXPECT_STREQ(webrtc::RtpExtension::kTOffset,
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000999 send_stream->GetConfig().rtp.extensions[0].name.c_str());
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001000}
1001
1002TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001003 SetRecvRtpHeaderExtensionsExcludeUnsupportedExtensions) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001004 const int kUnsupportedId = 1;
1005 const int kTOffsetId = 2;
1006
1007 std::vector<cricket::RtpHeaderExtension> extensions;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001008 extensions.push_back(
1009 cricket::RtpHeaderExtension(kUnsupportedExtensionName, kUnsupportedId));
1010 extensions.push_back(
1011 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, kTOffsetId));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001012 EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
1013 FakeVideoReceiveStream* recv_stream =
1014 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
1015
1016 // Only timestamp offset extension is set to receive stream,
1017 // unsupported rtp extension is ignored.
1018 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
1019 EXPECT_STREQ(webrtc::RtpExtension::kTOffset,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001020 recv_stream->GetConfig().rtp.extensions[0].name.c_str());
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001021}
1022
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001023TEST_F(WebRtcVideoChannel2Test, SetSendRtpHeaderExtensionsRejectsIncorrectIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001024 const size_t kNumIncorrectIds = 4;
1025 const int kIncorrectIds[kNumIncorrectIds] = {-2, -1, 15, 16};
1026 for (size_t i = 0; i < kNumIncorrectIds; ++i) {
1027 std::vector<cricket::RtpHeaderExtension> extensions;
1028 extensions.push_back(cricket::RtpHeaderExtension(
1029 webrtc::RtpExtension::kTOffset, kIncorrectIds[i]));
1030 EXPECT_FALSE(channel_->SetSendRtpHeaderExtensions(extensions))
1031 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
1032 }
1033}
1034
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001035TEST_F(WebRtcVideoChannel2Test, SetRecvRtpHeaderExtensionsRejectsIncorrectIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001036 const size_t kNumIncorrectIds = 4;
1037 const int kIncorrectIds[kNumIncorrectIds] = {-2, -1, 15, 16};
1038 for (size_t i = 0; i < kNumIncorrectIds; ++i) {
1039 std::vector<cricket::RtpHeaderExtension> extensions;
1040 extensions.push_back(cricket::RtpHeaderExtension(
1041 webrtc::RtpExtension::kTOffset, kIncorrectIds[i]));
1042 EXPECT_FALSE(channel_->SetRecvRtpHeaderExtensions(extensions))
1043 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
1044 }
1045}
1046
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001047TEST_F(WebRtcVideoChannel2Test, SetSendRtpHeaderExtensionsRejectsDuplicateIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001048 const int id = 1;
1049 std::vector<cricket::RtpHeaderExtension> extensions;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001050 extensions.push_back(
1051 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, id));
1052 extensions.push_back(
1053 cricket::RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, id));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001054 EXPECT_FALSE(channel_->SetSendRtpHeaderExtensions(extensions));
1055
1056 // Duplicate entries are also not supported.
1057 extensions.clear();
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001058 extensions.push_back(
1059 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, id));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001060 extensions.push_back(extensions.back());
1061 EXPECT_FALSE(channel_->SetSendRtpHeaderExtensions(extensions));
1062}
1063
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001064TEST_F(WebRtcVideoChannel2Test, SetRecvRtpHeaderExtensionsRejectsDuplicateIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001065 const int id = 1;
1066 std::vector<cricket::RtpHeaderExtension> extensions;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001067 extensions.push_back(
1068 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, id));
1069 extensions.push_back(
1070 cricket::RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, id));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001071 EXPECT_FALSE(channel_->SetRecvRtpHeaderExtensions(extensions));
1072
1073 // Duplicate entries are also not supported.
1074 extensions.clear();
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001075 extensions.push_back(
1076 cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, id));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00001077 extensions.push_back(extensions.back());
1078 EXPECT_FALSE(channel_->SetRecvRtpHeaderExtensions(extensions));
1079}
1080
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001081TEST_F(WebRtcVideoChannel2Test, DISABLED_LeakyBucketTest) {
1082 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1083}
1084
1085TEST_F(WebRtcVideoChannel2Test, DISABLED_BufferedModeLatency) {
1086 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1087}
1088
1089TEST_F(WebRtcVideoChannel2Test, DISABLED_AdditiveVideoOptions) {
1090 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1091}
1092
1093TEST_F(WebRtcVideoChannel2Test, AddRecvStreamOnlyUsesOneReceiveStream) {
1094 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001095 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001096}
1097
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001098TEST_F(WebRtcVideoChannel2Test, RembIsEnabledByDefault) {
1099 FakeVideoReceiveStream* stream = AddRecvStream();
1100 EXPECT_TRUE(stream->GetConfig().rtp.remb);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001101}
1102
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001103TEST_F(WebRtcVideoChannel2Test, RembCanBeEnabledAndDisabled) {
1104 FakeVideoReceiveStream* stream = AddRecvStream();
1105 EXPECT_TRUE(stream->GetConfig().rtp.remb);
1106
1107 // Verify that REMB is turned off when codecs without REMB are set.
1108 std::vector<VideoCodec> codecs;
1109 codecs.push_back(kVp8Codec);
1110 EXPECT_TRUE(codecs[0].feedback_params.params().empty());
1111 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001112 stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001113 EXPECT_FALSE(stream->GetConfig().rtp.remb);
1114
1115 // Verify that REMB is turned on when setting default codecs since the
1116 // default codecs have REMB enabled.
1117 EXPECT_TRUE(channel_->SetRecvCodecs(engine_.codecs()));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001118 stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.org257e1302014-07-25 19:01:32 +00001119 EXPECT_TRUE(stream->GetConfig().rtp.remb);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001120}
1121
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00001122TEST_F(WebRtcVideoChannel2Test, NackIsEnabledByDefault) {
1123 VerifyCodecHasDefaultFeedbackParams(default_codec_);
1124
pbos@webrtc.org19864742014-05-30 07:35:47 +00001125 EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
1126 EXPECT_TRUE(channel_->SetSend(true));
1127
1128 // Send side.
1129 FakeVideoSendStream* send_stream =
1130 AddSendStream(cricket::StreamParams::CreateLegacy(1));
1131 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1132
1133 // Receiver side.
1134 FakeVideoReceiveStream* recv_stream =
1135 AddRecvStream(cricket::StreamParams::CreateLegacy(1));
1136 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
1137
1138 // Nack history size should match between sender and receiver.
1139 EXPECT_EQ(send_stream->GetConfig().rtp.nack.rtp_history_ms,
1140 recv_stream->GetConfig().rtp.nack.rtp_history_ms);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001141}
1142
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00001143TEST_F(WebRtcVideoChannel2Test, NackCanBeDisabled) {
1144 std::vector<VideoCodec> codecs;
1145 codecs.push_back(kVp8Codec);
1146
1147 // Send side.
1148 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
1149 FakeVideoSendStream* send_stream =
1150 AddSendStream(cricket::StreamParams::CreateLegacy(1));
1151 EXPECT_EQ(0, send_stream->GetConfig().rtp.nack.rtp_history_ms);
1152
1153 // Receiver side.
1154 ASSERT_TRUE(channel_->SetRecvCodecs(codecs));
1155 FakeVideoReceiveStream* recv_stream =
1156 AddRecvStream(cricket::StreamParams::CreateLegacy(1));
1157 EXPECT_EQ(0, recv_stream->GetConfig().rtp.nack.rtp_history_ms);
1158}
1159
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001160TEST_F(WebRtcVideoChannel2Test, DISABLED_VideoProtectionInterop) {
1161 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1162}
1163
1164TEST_F(WebRtcVideoChannel2Test, DISABLED_VideoProtectionInteropReversed) {
1165 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1166}
1167
1168TEST_F(WebRtcVideoChannel2Test, DISABLED_HybridNackFecConference) {
1169 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1170}
1171
1172TEST_F(WebRtcVideoChannel2Test, DISABLED_AddRemoveRecvStreamConference) {
1173 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1174}
1175
1176TEST_F(WebRtcVideoChannel2Test, DISABLED_SetRender) {
1177 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1178}
1179
1180TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthAuto) {
1181 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1182}
1183
1184TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthAutoCapped) {
1185 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1186}
1187
1188TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthFixed) {
1189 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1190}
1191
1192TEST_F(WebRtcVideoChannel2Test, DISABLED_SetBandwidthInConference) {
1193 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1194}
1195
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001196TEST_F(WebRtcVideoChannel2Test, UsesCorrectSettingsForScreencast) {
1197 static const int kScreenshareMinBitrateKbps = 800;
1198 cricket::VideoCodec codec = kVp8Codec360p;
1199 std::vector<cricket::VideoCodec> codecs;
1200 codecs.push_back(codec);
1201 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1202 VideoOptions options;
1203 options.screencast_min_bitrate.Set(kScreenshareMinBitrateKbps);
1204 channel_->SetOptions(options);
1205
1206 AddSendStream();
1207
1208 cricket::FakeVideoCapturer capturer;
1209 capturer.SetScreencast(false);
1210 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer));
1211 cricket::VideoFormat capture_format_hd =
1212 capturer.GetSupportedFormats()->front();
1213 EXPECT_EQ(1280, capture_format_hd.width);
1214 EXPECT_EQ(720, capture_format_hd.height);
1215 EXPECT_EQ(cricket::CS_RUNNING, capturer.Start(capture_format_hd));
1216
1217 EXPECT_TRUE(channel_->SetSend(true));
1218
1219 EXPECT_TRUE(capturer.CaptureFrame());
1220 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
1221 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
1222
1223 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
1224
1225 // Verify non-screencast settings.
1226 webrtc::VideoEncoderConfig encoder_config = send_stream->GetEncoderConfig();
1227 EXPECT_EQ(webrtc::VideoEncoderConfig::kRealtimeVideo,
1228 encoder_config.content_type);
1229 EXPECT_EQ(codec.width, encoder_config.streams.front().width);
1230 EXPECT_EQ(codec.height, encoder_config.streams.front().height);
1231 EXPECT_EQ(0, encoder_config.min_transmit_bitrate_bps)
1232 << "Non-screenshare shouldn't use min-transmit bitrate.";
1233
1234 capturer.SetScreencast(true);
1235 EXPECT_TRUE(capturer.CaptureFrame());
1236
1237 EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
1238
1239 // Verify screencast settings.
1240 encoder_config = send_stream->GetEncoderConfig();
1241 EXPECT_EQ(webrtc::VideoEncoderConfig::kScreenshare,
1242 encoder_config.content_type);
1243 EXPECT_EQ(kScreenshareMinBitrateKbps * 1000,
1244 encoder_config.min_transmit_bitrate_bps);
1245
1246 EXPECT_EQ(capture_format_hd.width, encoder_config.streams.front().width);
1247 EXPECT_EQ(capture_format_hd.height, encoder_config.streams.front().height);
1248
1249 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001250}
1251
1252TEST_F(WebRtcVideoChannel2Test, DISABLED_SetSendSsrcAndCname) {
1253 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1254}
1255
1256TEST_F(WebRtcVideoChannel2Test,
1257 DISABLED_SetSendSsrcAfterCreatingReceiveChannel) {
1258 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1259}
1260
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00001261TEST_F(WebRtcVideoChannel2Test, SuspendBelowMinBitrateDisabledByDefault) {
1262 FakeVideoSendStream* stream = AddSendStream();
1263 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
1264}
1265
1266TEST_F(WebRtcVideoChannel2Test, SetOptionsWithSuspendBelowMinBitrate) {
1267 VideoOptions options;
1268 options.suspend_below_min_bitrate.Set(true);
1269 channel_->SetOptions(options);
1270
1271 FakeVideoSendStream* stream = AddSendStream();
1272 EXPECT_TRUE(stream->GetConfig().suspend_below_min_bitrate);
1273
1274 options.suspend_below_min_bitrate.Set(false);
1275 channel_->SetOptions(options);
1276
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001277 stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00001278 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
1279}
1280
pbos@webrtc.org543e5892014-07-23 07:01:31 +00001281TEST_F(WebRtcVideoChannel2Test, RedundantPayloadsDisabledByDefault) {
1282 const std::vector<uint32> ssrcs = MAKE_VECTOR(kSsrcs1);
1283 const std::vector<uint32> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
1284 FakeVideoSendStream* stream = AddSendStream(
1285 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
1286 EXPECT_FALSE(stream->GetConfig().rtp.rtx.pad_with_redundant_payloads);
1287}
1288
1289TEST_F(WebRtcVideoChannel2Test, SetOptionsWithPayloadPadding) {
1290 VideoOptions options;
1291 options.use_payload_padding.Set(true);
1292 channel_->SetOptions(options);
1293
1294 const std::vector<uint32> ssrcs = MAKE_VECTOR(kSsrcs1);
1295 const std::vector<uint32> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
1296 FakeVideoSendStream* stream = AddSendStream(
1297 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
1298 EXPECT_TRUE(stream->GetConfig().rtp.rtx.pad_with_redundant_payloads);
1299
1300 options.use_payload_padding.Set(false);
1301 channel_->SetOptions(options);
1302
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001303 stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.org543e5892014-07-23 07:01:31 +00001304 EXPECT_FALSE(stream->GetConfig().rtp.rtx.pad_with_redundant_payloads);
1305}
1306
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001307TEST_F(WebRtcVideoChannel2Test, Vp8DenoisingEnabledByDefault) {
1308 FakeVideoSendStream* stream = AddSendStream();
1309 webrtc::VideoCodecVP8 vp8_settings;
1310 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1311 EXPECT_TRUE(vp8_settings.denoisingOn);
1312}
1313
1314TEST_F(WebRtcVideoChannel2Test, SetOptionsWithDenoising) {
1315 VideoOptions options;
1316 options.video_noise_reduction.Set(false);
1317 channel_->SetOptions(options);
1318
1319 FakeVideoSendStream* stream = AddSendStream();
1320 webrtc::VideoCodecVP8 vp8_settings;
1321 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1322 EXPECT_FALSE(vp8_settings.denoisingOn);
1323
1324 options.video_noise_reduction.Set(true);
1325 channel_->SetOptions(options);
1326
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001327 stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00001328 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
1329 EXPECT_TRUE(vp8_settings.denoisingOn);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001330}
1331
1332TEST_F(WebRtcVideoChannel2Test, DISABLED_MultipleSendStreamsWithOneCapturer) {
1333 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1334}
1335
pbos@webrtc.org8aed9452014-07-26 10:16:49 +00001336TEST_F(WebRtcVideoChannel2Test, DISABLED_SendReceiveBitratesStats) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001337 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1338}
1339
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001340TEST_F(WebRtcVideoChannel2Test, AdaptsOnOveruse) {
1341 TestCpuAdaptation(true);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001342}
1343
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001344TEST_F(WebRtcVideoChannel2Test, DoesNotAdaptOnOveruseWhenDisabled) {
1345 TestCpuAdaptation(false);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001346}
1347
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001348void WebRtcVideoChannel2Test::TestCpuAdaptation(bool enable_overuse) {
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00001349 cricket::VideoCodec codec = kVp8Codec720p;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001350 std::vector<cricket::VideoCodec> codecs;
1351 codecs.push_back(codec);
1352 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
1353
1354 if (enable_overuse) {
1355 VideoOptions options;
1356 options.cpu_overuse_detection.Set(true);
1357 channel_->SetOptions(options);
1358 }
1359
1360 AddSendStream();
1361
1362 cricket::FakeVideoCapturer capturer;
1363 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer));
1364 EXPECT_EQ(cricket::CS_RUNNING,
1365 capturer.Start(capturer.GetSupportedFormats()->front()));
1366
1367 EXPECT_TRUE(channel_->SetSend(true));
1368
1369 // Trigger overuse.
1370 webrtc::LoadObserver* overuse_callback =
1371 fake_call_->GetConfig().overuse_callback;
1372 ASSERT_TRUE(overuse_callback != NULL);
1373 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kOveruse);
1374
1375 EXPECT_TRUE(capturer.CaptureFrame());
1376 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
1377 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
1378
1379 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
1380
1381 if (enable_overuse) {
1382 EXPECT_LT(send_stream->GetLastWidth(), codec.width);
1383 EXPECT_LT(send_stream->GetLastHeight(), codec.height);
1384 } else {
1385 EXPECT_EQ(codec.width, send_stream->GetLastWidth());
1386 EXPECT_EQ(codec.height, send_stream->GetLastHeight());
1387 }
1388
1389 // Trigger underuse which should go back to normal resolution.
1390 overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kUnderuse);
1391 EXPECT_TRUE(capturer.CaptureFrame());
1392
1393 EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
1394
1395 EXPECT_EQ(codec.width, send_stream->GetLastWidth());
1396 EXPECT_EQ(codec.height, send_stream->GetLastHeight());
1397
1398 EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001399}
1400
1401TEST_F(WebRtcVideoChannel2Test, DISABLED_WebRtcShouldLog) {
1402 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1403}
1404
1405TEST_F(WebRtcVideoChannel2Test, DISABLED_WebRtcShouldNotLog) {
1406 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1407}
1408
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001409TEST_F(WebRtcVideoChannel2Test, SetDefaultSendCodecs) {
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +00001410 ASSERT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001411
1412 VideoCodec codec;
1413 EXPECT_TRUE(channel_->GetSendCodec(&codec));
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +00001414 EXPECT_TRUE(codec.Matches(engine_.codecs()[0]));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001415
1416 // Using a RTX setup to verify that the default RTX payload type is good.
1417 const std::vector<uint32> ssrcs = MAKE_VECTOR(kSsrcs1);
1418 const std::vector<uint32> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
1419 FakeVideoSendStream* stream = AddSendStream(
1420 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
1421 webrtc::VideoSendStream::Config config = stream->GetConfig();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001422
1423 // Make sure NACK and FEC are enabled on the correct payload types.
1424 EXPECT_EQ(1000, config.rtp.nack.rtp_history_ms);
1425 EXPECT_EQ(default_ulpfec_codec_.id, config.rtp.fec.ulpfec_payload_type);
1426 EXPECT_EQ(default_red_codec_.id, config.rtp.fec.red_payload_type);
pbos@webrtc.org269605c2014-06-26 08:49:03 +00001427
1428 EXPECT_EQ(1u, config.rtp.rtx.ssrcs.size());
1429 EXPECT_EQ(kRtxSsrcs1[0], config.rtp.rtx.ssrcs[0]);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001430 EXPECT_EQ(static_cast<int>(default_rtx_codec_.id),
1431 config.rtp.rtx.payload_type);
1432 // TODO(juberti): Check RTCP, PLI, TMMBR.
1433}
1434
1435TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithoutFec) {
1436 std::vector<VideoCodec> codecs;
1437 codecs.push_back(kVp8Codec);
1438 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
1439
1440 FakeVideoSendStream* stream = AddSendStream();
1441 webrtc::VideoSendStream::Config config = stream->GetConfig();
1442
1443 EXPECT_EQ(-1, config.rtp.fec.ulpfec_payload_type);
1444 EXPECT_EQ(-1, config.rtp.fec.red_payload_type);
1445}
1446
1447TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org269605c2014-06-26 08:49:03 +00001448 SetSendCodecRejectsRtxWithoutAssociatedPayloadType) {
1449 std::vector<VideoCodec> codecs;
1450 cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0);
1451 codecs.push_back(rtx_codec);
1452 EXPECT_FALSE(channel_->SetSendCodecs(codecs))
1453 << "RTX codec without associated payload type should be rejected.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001454}
1455
1456TEST_F(WebRtcVideoChannel2Test,
pbos@webrtc.org269605c2014-06-26 08:49:03 +00001457 SetSendCodecRejectsRtxWithoutMatchingVideoCodec) {
1458 std::vector<VideoCodec> codecs;
1459 cricket::VideoCodec rtx_codec =
1460 cricket::VideoCodec::CreateRtxCodec(96, kVp8Codec.id);
1461 codecs.push_back(kVp8Codec);
1462 codecs.push_back(rtx_codec);
1463 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
1464
1465 cricket::VideoCodec rtx_codec2 =
1466 cricket::VideoCodec::CreateRtxCodec(96, kVp8Codec.id + 1);
1467 codecs.pop_back();
1468 codecs.push_back(rtx_codec2);
1469 EXPECT_FALSE(channel_->SetSendCodecs(codecs))
1470 << "RTX without matching video codec should be rejected.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001471}
1472
pbos@webrtc.org269605c2014-06-26 08:49:03 +00001473TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithoutFecDisablesFec) {
1474 std::vector<VideoCodec> codecs;
1475 codecs.push_back(kVp8Codec);
1476 codecs.push_back(kUlpfecCodec);
1477 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
1478
1479 FakeVideoSendStream* stream = AddSendStream();
1480 webrtc::VideoSendStream::Config config = stream->GetConfig();
1481
1482 EXPECT_EQ(kUlpfecCodec.id, config.rtp.fec.ulpfec_payload_type);
1483
1484 codecs.pop_back();
1485 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001486 stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.org269605c2014-06-26 08:49:03 +00001487 ASSERT_TRUE(stream != NULL);
1488 config = stream->GetConfig();
1489 EXPECT_EQ(-1, config.rtp.fec.ulpfec_payload_type)
1490 << "SetSendCodec without FEC should disable current FEC.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001491}
1492
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00001493TEST_F(WebRtcVideoChannel2Test, SetSendCodecsChangesExistingStreams) {
1494 std::vector<VideoCodec> codecs;
1495 codecs.push_back(kVp8Codec720p);
1496 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
1497
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001498 std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00001499 EXPECT_EQ(kVp8Codec720p.width, streams[0].width);
1500 EXPECT_EQ(kVp8Codec720p.height, streams[0].height);
1501
1502 codecs.clear();
1503 codecs.push_back(kVp8Codec360p);
1504 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001505 streams = fake_call_->GetVideoSendStreams()[0]->GetVideoStreams();
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00001506 EXPECT_EQ(kVp8Codec360p.width, streams[0].width);
1507 EXPECT_EQ(kVp8Codec360p.height, streams[0].height);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001508}
1509
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001510TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithMinMaxBitrate) {
1511 SetSendCodecsShouldWorkForBitrates("10", "20");
1512}
1513
1514TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectsMaxLessThanMinBitrate) {
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +00001515 std::vector<VideoCodec> video_codecs = engine_.codecs();
1516 video_codecs[0].params[kCodecParamMinBitrate] = "30";
1517 video_codecs[0].params[kCodecParamMaxBitrate] = "20";
1518 EXPECT_FALSE(channel_->SetSendCodecs(video_codecs));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001519}
1520
1521TEST_F(WebRtcVideoChannel2Test, SetSendCodecsAcceptLargeMinMaxBitrate) {
1522 SetSendCodecsShouldWorkForBitrates("1000", "2000");
1523}
1524
1525TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithMaxQuantization) {
1526 static const char* kMaxQuantization = "21";
1527 std::vector<VideoCodec> codecs;
1528 codecs.push_back(kVp8Codec);
1529 codecs[0].params[kCodecParamMaxQuantization] = kMaxQuantization;
1530 EXPECT_TRUE(channel_->SetSendCodecs(codecs));
pbos@webrtc.org6ae48c62014-06-06 10:49:19 +00001531 EXPECT_EQ(static_cast<unsigned int>(atoi(kMaxQuantization)),
1532 AddSendStream()->GetVideoStreams().back().max_qp);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001533
1534 VideoCodec codec;
1535 EXPECT_TRUE(channel_->GetSendCodec(&codec));
1536 EXPECT_EQ(kMaxQuantization, codec.params[kCodecParamMaxQuantization]);
1537}
1538
1539TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectBadDimensions) {
1540 std::vector<cricket::VideoCodec> codecs;
1541 codecs.push_back(kVp8Codec);
1542
1543 codecs[0].width = 0;
1544 EXPECT_FALSE(channel_->SetSendCodecs(codecs))
1545 << "Codec set though codec width is zero.";
1546
1547 codecs[0].width = kVp8Codec.width;
1548 codecs[0].height = 0;
1549 EXPECT_FALSE(channel_->SetSendCodecs(codecs))
1550 << "Codec set though codec height is zero.";
1551}
1552
1553TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectBadPayloadTypes) {
1554 // TODO(pbos): Should we only allow the dynamic range?
1555 static const size_t kNumIncorrectPayloads = 4;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001556 static const int kIncorrectPayloads[kNumIncorrectPayloads] = {
1557 -2, -1, 128, 129};
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001558 std::vector<cricket::VideoCodec> codecs;
1559 codecs.push_back(kVp8Codec);
1560 for (size_t i = 0; i < kNumIncorrectPayloads; ++i) {
1561 int payload_type = kIncorrectPayloads[i];
1562 codecs[0].id = payload_type;
1563 EXPECT_FALSE(channel_->SetSendCodecs(codecs))
1564 << "Bad payload type '" << payload_type << "' accepted.";
1565 }
1566}
1567
1568TEST_F(WebRtcVideoChannel2Test, SetSendCodecsAcceptAllValidPayloadTypes) {
1569 std::vector<cricket::VideoCodec> codecs;
1570 codecs.push_back(kVp8Codec);
1571 for (int payload_type = 0; payload_type <= 127; ++payload_type) {
1572 codecs[0].id = payload_type;
1573 EXPECT_TRUE(channel_->SetSendCodecs(codecs))
1574 << "Payload type '" << payload_type << "' rejected.";
1575 }
1576}
1577
1578TEST_F(WebRtcVideoChannel2Test, DISABLED_ResetVieSendCodecOnNewFrameSize) {
1579 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1580}
1581
1582TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithOnlyVp8) {
1583 std::vector<cricket::VideoCodec> codecs;
1584 codecs.push_back(kVp8Codec);
1585 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
1586}
1587
pbos@webrtc.orge322a172014-06-13 11:47:28 +00001588// Test that we set our inbound RTX codecs properly.
1589TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithRtx) {
1590 std::vector<cricket::VideoCodec> codecs;
1591 codecs.push_back(kVp8Codec);
1592 cricket::VideoCodec rtx_codec(96, "rtx", 0, 0, 0, 0);
1593 codecs.push_back(rtx_codec);
1594 EXPECT_FALSE(channel_->SetRecvCodecs(codecs))
1595 << "RTX codec without associated payload should be rejected.";
1596
1597 codecs[1].SetParam("apt", kVp8Codec.id + 1);
1598 EXPECT_FALSE(channel_->SetRecvCodecs(codecs))
1599 << "RTX codec with invalid associated payload type should be rejected.";
1600
1601 codecs[1].SetParam("apt", kVp8Codec.id);
1602 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
1603
1604 cricket::VideoCodec rtx_codec2(97, "rtx", 0, 0, 0, 0);
1605 rtx_codec2.SetParam("apt", rtx_codec.id);
1606 codecs.push_back(rtx_codec2);
1607
1608 EXPECT_FALSE(channel_->SetRecvCodecs(codecs)) << "RTX codec with another RTX "
1609 "as associated payload type "
1610 "should be rejected.";
1611}
1612
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001613TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsDifferentPayloadType) {
1614 std::vector<cricket::VideoCodec> codecs;
1615 codecs.push_back(kVp8Codec);
1616 codecs[0].id = 99;
1617 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
1618}
1619
pbos@webrtc.orgccbed3b2014-07-11 13:02:54 +00001620TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsAcceptDefaultCodecs) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001621 EXPECT_TRUE(channel_->SetRecvCodecs(engine_.codecs()));
pbos@webrtc.orgccbed3b2014-07-11 13:02:54 +00001622
1623 FakeVideoReceiveStream* stream = AddRecvStream();
1624 webrtc::VideoReceiveStream::Config config = stream->GetConfig();
1625 EXPECT_STREQ(engine_.codecs()[0].name.c_str(), config.codecs[0].plName);
1626 EXPECT_EQ(engine_.codecs()[0].id, config.codecs[0].plType);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001627}
1628
1629TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsRejectUnsupportedCodec) {
1630 std::vector<VideoCodec> codecs;
1631 codecs.push_back(kVp8Codec);
1632 codecs.push_back(VideoCodec(101, "WTF3", 640, 400, 30, 0));
1633 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
1634}
1635
1636// TODO(pbos): Enable VP9 through external codec support
1637TEST_F(WebRtcVideoChannel2Test,
1638 DISABLED_SetRecvCodecsAcceptsMultipleVideoCodecs) {
1639 std::vector<VideoCodec> codecs;
1640 codecs.push_back(kVp8Codec);
1641 codecs.push_back(kVp9Codec);
1642 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
1643}
1644
1645TEST_F(WebRtcVideoChannel2Test,
1646 DISABLED_SetRecvCodecsSetsFecForAllVideoCodecs) {
1647 std::vector<VideoCodec> codecs;
1648 codecs.push_back(kVp8Codec);
1649 codecs.push_back(kVp9Codec);
1650 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
1651 FAIL(); // TODO(pbos): Verify that the FEC parameters are set for all codecs.
1652}
1653
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001654TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithoutFecDisablesFec) {
1655 std::vector<VideoCodec> codecs;
1656 codecs.push_back(kVp8Codec);
1657 codecs.push_back(kUlpfecCodec);
1658 ASSERT_TRUE(channel_->SetSendCodecs(codecs));
1659
1660 FakeVideoReceiveStream* stream = AddRecvStream();
1661 webrtc::VideoReceiveStream::Config config = stream->GetConfig();
1662
1663 EXPECT_EQ(kUlpfecCodec.id, config.rtp.fec.ulpfec_payload_type);
1664
1665 codecs.pop_back();
1666 ASSERT_TRUE(channel_->SetRecvCodecs(codecs));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001667 stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00001668 ASSERT_TRUE(stream != NULL);
1669 config = stream->GetConfig();
1670 EXPECT_EQ(-1, config.rtp.fec.ulpfec_payload_type)
1671 << "SetSendCodec without FEC should disable current FEC.";
pbos@webrtc.org269605c2014-06-26 08:49:03 +00001672}
1673
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001674TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectDuplicateFecPayloads) {
1675 std::vector<VideoCodec> codecs;
1676 codecs.push_back(kVp8Codec);
1677 codecs.push_back(kRedCodec);
1678 codecs[1].id = codecs[0].id;
1679 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
1680}
1681
1682TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsRejectDuplicateCodecPayloads) {
1683 std::vector<VideoCodec> codecs;
1684 codecs.push_back(kVp8Codec);
1685 codecs.push_back(kVp9Codec);
1686 codecs[1].id = codecs[0].id;
1687 EXPECT_FALSE(channel_->SetRecvCodecs(codecs));
1688}
1689
1690TEST_F(WebRtcVideoChannel2Test,
1691 SetRecvCodecsAcceptSameCodecOnMultiplePayloadTypes) {
1692 std::vector<VideoCodec> codecs;
1693 codecs.push_back(kVp8Codec);
1694 codecs.push_back(kVp8Codec);
1695 codecs[1].id += 1;
1696 EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
1697}
1698
1699TEST_F(WebRtcVideoChannel2Test, SendStreamNotSendingByDefault) {
1700 EXPECT_FALSE(AddSendStream()->IsSending());
1701}
1702
pbos@webrtc.org85f42942014-07-22 09:14:58 +00001703TEST_F(WebRtcVideoChannel2Test, ReceiveStreamReceivingByDefault) {
1704 EXPECT_TRUE(AddRecvStream()->IsReceiving());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001705}
1706
1707TEST_F(WebRtcVideoChannel2Test, SetSend) {
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +00001708 FakeVideoSendStream* stream = AddSendStream();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001709 EXPECT_FALSE(stream->IsSending());
1710
1711 // false->true
1712 EXPECT_TRUE(channel_->SetSend(true));
1713 EXPECT_TRUE(stream->IsSending());
1714 // true->true
1715 EXPECT_TRUE(channel_->SetSend(true));
1716 EXPECT_TRUE(stream->IsSending());
1717 // true->false
1718 EXPECT_TRUE(channel_->SetSend(false));
1719 EXPECT_FALSE(stream->IsSending());
1720 // false->false
1721 EXPECT_TRUE(channel_->SetSend(false));
1722 EXPECT_FALSE(stream->IsSending());
1723
1724 EXPECT_TRUE(channel_->SetSend(true));
1725 FakeVideoSendStream* new_stream = AddSendStream();
1726 EXPECT_TRUE(new_stream->IsSending())
1727 << "Send stream created after SetSend(true) not sending initially.";
1728}
1729
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001730TEST_F(WebRtcVideoChannel2Test, DISABLED_TestSetDscpOptions) {
1731 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1732}
1733
1734TEST_F(WebRtcVideoChannel2Test, DISABLED_SetOptionsWithMaxBitrate) {
1735 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1736}
1737
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001738TEST_F(WebRtcVideoChannel2Test, DISABLED_ResetCodecOnScreencast) {
1739 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1740}
1741
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001742TEST_F(WebRtcVideoChannel2Test, DISABLED_RegisterDecoderIfFactoryIsGiven) {
1743 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1744}
1745
1746TEST_F(WebRtcVideoChannel2Test, DISABLED_DontRegisterDecoderMultipleTimes) {
1747 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1748}
1749
1750TEST_F(WebRtcVideoChannel2Test, DISABLED_DontRegisterDecoderForNonVP8) {
1751 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1752}
1753
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001754TEST_F(WebRtcVideoChannel2Test, DISABLED_ExternalCodecIgnored) {
1755 FAIL() << "Not implemented."; // TODO(pbos): Implement.
1756}
1757
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00001758TEST_F(WebRtcVideoChannel2Test, OnReadyToSendSignalsNetworkState) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001759 EXPECT_EQ(webrtc::Call::kNetworkUp, fake_call_->GetNetworkState());
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00001760
1761 channel_->OnReadyToSend(false);
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001762 EXPECT_EQ(webrtc::Call::kNetworkDown, fake_call_->GetNetworkState());
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00001763
1764 channel_->OnReadyToSend(true);
pbos@webrtc.org42684be2014-10-03 11:25:45 +00001765 EXPECT_EQ(webrtc::Call::kNetworkUp, fake_call_->GetNetworkState());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001766}
1767
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001768} // namespace cricket