| /* |
| * libjingle |
| * Copyright 2004 Google Inc. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * |
| * 1. Redistributions of source code must retain the above copyright notice, |
| * this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright notice, |
| * this list of conditions and the following disclaimer in the documentation |
| * and/or other materials provided with the distribution. |
| * 3. The name of the author may not be used to endorse or promote products |
| * derived from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
| * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO |
| * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; |
| * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
| * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
| * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #include "talk/base/fakecpumonitor.h" |
| #include "talk/base/gunit.h" |
| #include "talk/base/logging.h" |
| #include "talk/base/scoped_ptr.h" |
| #include "talk/base/stream.h" |
| #include "talk/media/base/constants.h" |
| #include "talk/media/base/fakemediaprocessor.h" |
| #include "talk/media/base/fakenetworkinterface.h" |
| #include "talk/media/base/fakevideorenderer.h" |
| #include "talk/media/base/mediachannel.h" |
| #include "talk/media/base/testutils.h" |
| #include "talk/media/base/videoengine_unittest.h" |
| #include "talk/media/webrtc/fakewebrtcvideocapturemodule.h" |
| #include "talk/media/webrtc/fakewebrtcvideoengine.h" |
| #include "talk/media/webrtc/fakewebrtcvoiceengine.h" |
| #include "talk/media/webrtc/webrtcvideocapturer.h" |
| #include "talk/media/webrtc/webrtcvideoengine.h" |
| #include "talk/media/webrtc/webrtcvideoframe.h" |
| #include "talk/media/webrtc/webrtcvoiceengine.h" |
| #include "talk/session/media/mediasession.h" |
| #include "webrtc/system_wrappers/interface/trace.h" |
| |
| // Tests for the WebRtcVideoEngine/VideoChannel code. |
| |
| static const cricket::VideoCodec kVP8Codec720p(100, "VP8", 1280, 720, 30, 0); |
| static const cricket::VideoCodec kVP8Codec360p(100, "VP8", 640, 360, 30, 0); |
| static const cricket::VideoCodec kVP8Codec270p(100, "VP8", 480, 270, 30, 0); |
| static const cricket::VideoCodec kVP8Codec180p(100, "VP8", 320, 180, 30, 0); |
| |
| static const cricket::VideoCodec kVP8Codec(100, "VP8", 640, 400, 30, 0); |
| static const cricket::VideoCodec kRedCodec(101, "red", 0, 0, 0, 0); |
| static const cricket::VideoCodec kUlpFecCodec(102, "ulpfec", 0, 0, 0, 0); |
| static const cricket::VideoCodec* const kVideoCodecs[] = { |
| &kVP8Codec, |
| &kRedCodec, |
| &kUlpFecCodec |
| }; |
| |
| static const unsigned int kMinBandwidthKbps = 50; |
| static const unsigned int kStartBandwidthKbps = 300; |
| static const unsigned int kMaxBandwidthKbps = 2000; |
| |
| static const unsigned int kNumberOfTemporalLayers = 1; |
| |
| |
| class FakeViEWrapper : public cricket::ViEWrapper { |
| public: |
| explicit FakeViEWrapper(cricket::FakeWebRtcVideoEngine* engine) |
| : cricket::ViEWrapper(engine, // base |
| engine, // codec |
| engine, // capture |
| engine, // network |
| engine, // render |
| engine, // rtp |
| engine, // image |
| engine) { // external decoder |
| } |
| }; |
| |
| // Test fixture to test WebRtcVideoEngine with a fake webrtc::VideoEngine. |
| // Useful for testing failure paths. |
| class WebRtcVideoEngineTestFake : public testing::Test, |
| public sigslot::has_slots<> { |
| public: |
| WebRtcVideoEngineTestFake() |
| : vie_(kVideoCodecs, ARRAY_SIZE(kVideoCodecs)), |
| cpu_monitor_(new talk_base::FakeCpuMonitor( |
| talk_base::Thread::Current())), |
| engine_(NULL, // cricket::WebRtcVoiceEngine |
| new FakeViEWrapper(&vie_), cpu_monitor_), |
| channel_(NULL), |
| voice_channel_(NULL), |
| last_error_(cricket::VideoMediaChannel::ERROR_NONE) { |
| } |
| bool SetupEngine() { |
| bool result = engine_.Init(talk_base::Thread::Current()); |
| if (result) { |
| channel_ = engine_.CreateChannel(voice_channel_); |
| channel_->SignalMediaError.connect(this, |
| &WebRtcVideoEngineTestFake::OnMediaError); |
| result = (channel_ != NULL); |
| } |
| return result; |
| } |
| void OnMediaError(uint32 ssrc, cricket::VideoMediaChannel::Error error) { |
| last_error_ = error; |
| } |
| bool SendI420Frame(int width, int height) { |
| if (NULL == channel_) { |
| return false; |
| } |
| cricket::WebRtcVideoFrame frame; |
| size_t size = width * height * 3 / 2; // I420 |
| talk_base::scoped_array<uint8> pixel(new uint8[size]); |
| if (!frame.Init(cricket::FOURCC_I420, |
| width, height, width, height, |
| pixel.get(), size, 1, 1, 0, 0, 0)) { |
| return false; |
| } |
| cricket::FakeVideoCapturer capturer; |
| channel_->SendFrame(&capturer, &frame); |
| return true; |
| } |
| bool SendI420ScreencastFrame(int width, int height) { |
| return SendI420ScreencastFrameWithTimestamp(width, height, 0); |
| } |
| bool SendI420ScreencastFrameWithTimestamp( |
| int width, int height, int64 timestamp) { |
| if (NULL == channel_) { |
| return false; |
| } |
| cricket::WebRtcVideoFrame frame; |
| size_t size = width * height * 3 / 2; // I420 |
| talk_base::scoped_array<uint8> pixel(new uint8[size]); |
| if (!frame.Init(cricket::FOURCC_I420, |
| width, height, width, height, |
| pixel.get(), size, 1, 1, 0, timestamp, 0)) { |
| return false; |
| } |
| cricket::FakeVideoCapturer capturer; |
| capturer.SetScreencast(true); |
| channel_->SendFrame(&capturer, &frame); |
| return true; |
| } |
| void VerifyVP8SendCodec(int channel_num, |
| unsigned int width, |
| unsigned int height, |
| unsigned int layers = 0, |
| unsigned int max_bitrate = kMaxBandwidthKbps, |
| unsigned int min_bitrate = kMinBandwidthKbps, |
| unsigned int start_bitrate = kStartBandwidthKbps, |
| unsigned int fps = 30, |
| unsigned int max_quantization = 0 |
| ) { |
| webrtc::VideoCodec gcodec; |
| EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec)); |
| |
| // Video codec properties. |
| EXPECT_EQ(webrtc::kVideoCodecVP8, gcodec.codecType); |
| EXPECT_STREQ("VP8", gcodec.plName); |
| EXPECT_EQ(100, gcodec.plType); |
| EXPECT_EQ(width, gcodec.width); |
| EXPECT_EQ(height, gcodec.height); |
| EXPECT_EQ(talk_base::_min(start_bitrate, max_bitrate), gcodec.startBitrate); |
| EXPECT_EQ(max_bitrate, gcodec.maxBitrate); |
| EXPECT_EQ(min_bitrate, gcodec.minBitrate); |
| EXPECT_EQ(fps, gcodec.maxFramerate); |
| // VP8 specific. |
| EXPECT_FALSE(gcodec.codecSpecific.VP8.pictureLossIndicationOn); |
| EXPECT_FALSE(gcodec.codecSpecific.VP8.feedbackModeOn); |
| EXPECT_EQ(webrtc::kComplexityNormal, gcodec.codecSpecific.VP8.complexity); |
| EXPECT_EQ(webrtc::kResilienceOff, gcodec.codecSpecific.VP8.resilience); |
| EXPECT_EQ(max_quantization, gcodec.qpMax); |
| } |
| virtual void TearDown() { |
| delete channel_; |
| engine_.Terminate(); |
| } |
| |
| protected: |
| cricket::FakeWebRtcVideoEngine vie_; |
| cricket::FakeWebRtcVideoDecoderFactory decoder_factory_; |
| cricket::FakeWebRtcVideoEncoderFactory encoder_factory_; |
| talk_base::FakeCpuMonitor* cpu_monitor_; |
| cricket::WebRtcVideoEngine engine_; |
| cricket::WebRtcVideoMediaChannel* channel_; |
| cricket::WebRtcVoiceMediaChannel* voice_channel_; |
| cricket::VideoMediaChannel::Error last_error_; |
| }; |
| |
| // Test fixtures to test WebRtcVideoEngine with a real webrtc::VideoEngine. |
| class WebRtcVideoEngineTest |
| : public VideoEngineTest<cricket::WebRtcVideoEngine> { |
| protected: |
| typedef VideoEngineTest<cricket::WebRtcVideoEngine> Base; |
| }; |
| class WebRtcVideoMediaChannelTest |
| : public VideoMediaChannelTest< |
| cricket::WebRtcVideoEngine, cricket::WebRtcVideoMediaChannel> { |
| protected: |
| typedef VideoMediaChannelTest<cricket::WebRtcVideoEngine, |
| cricket::WebRtcVideoMediaChannel> Base; |
| virtual cricket::VideoCodec DefaultCodec() { return kVP8Codec; } |
| virtual void SetUp() { |
| Base::SetUp(); |
| } |
| virtual void TearDown() { |
| Base::TearDown(); |
| } |
| }; |
| |
| ///////////////////////// |
| // Tests with fake ViE // |
| ///////////////////////// |
| |
| // Tests that our stub library "works". |
| TEST_F(WebRtcVideoEngineTestFake, StartupShutdown) { |
| EXPECT_FALSE(vie_.IsInited()); |
| EXPECT_TRUE(engine_.Init(talk_base::Thread::Current())); |
| EXPECT_TRUE(vie_.IsInited()); |
| engine_.Terminate(); |
| } |
| |
| // Tests that webrtc logs are logged when they should be. |
| TEST_F(WebRtcVideoEngineTest, WebRtcShouldLog) { |
| const char webrtc_log[] = "WebRtcVideoEngineTest.WebRtcShouldLog"; |
| EXPECT_TRUE(engine_.Init(talk_base::Thread::Current())); |
| engine_.SetLogging(talk_base::LS_INFO, ""); |
| std::string str; |
| talk_base::StringStream stream(str); |
| talk_base::LogMessage::AddLogToStream(&stream, talk_base::LS_INFO); |
| EXPECT_EQ(talk_base::LS_INFO, talk_base::LogMessage::GetLogToStream(&stream)); |
| webrtc::Trace::Add(webrtc::kTraceStateInfo, webrtc::kTraceUndefined, 0, |
| webrtc_log); |
| EXPECT_TRUE_WAIT(std::string::npos != str.find(webrtc_log), 10); |
| talk_base::LogMessage::RemoveLogToStream(&stream); |
| } |
| |
| // Tests that webrtc logs are not logged when they should't be. |
| TEST_F(WebRtcVideoEngineTest, WebRtcShouldNotLog) { |
| const char webrtc_log[] = "WebRtcVideoEngineTest.WebRtcShouldNotLog"; |
| EXPECT_TRUE(engine_.Init(talk_base::Thread::Current())); |
| // WebRTC should never be logged lower than LS_INFO. |
| engine_.SetLogging(talk_base::LS_WARNING, ""); |
| std::string str; |
| talk_base::StringStream stream(str); |
| // Make sure that WebRTC is not logged, even at lowest severity |
| talk_base::LogMessage::AddLogToStream(&stream, talk_base::LS_SENSITIVE); |
| EXPECT_EQ(talk_base::LS_SENSITIVE, |
| talk_base::LogMessage::GetLogToStream(&stream)); |
| webrtc::Trace::Add(webrtc::kTraceStateInfo, webrtc::kTraceUndefined, 0, |
| webrtc_log); |
| talk_base::Thread::Current()->ProcessMessages(10); |
| EXPECT_EQ(std::string::npos, str.find(webrtc_log)); |
| talk_base::LogMessage::RemoveLogToStream(&stream); |
| } |
| |
| // Tests that we can create and destroy a channel. |
| TEST_F(WebRtcVideoEngineTestFake, CreateChannel) { |
| EXPECT_TRUE(engine_.Init(talk_base::Thread::Current())); |
| channel_ = engine_.CreateChannel(voice_channel_); |
| EXPECT_TRUE(channel_ != NULL); |
| EXPECT_EQ(1, engine_.GetNumOfChannels()); |
| delete channel_; |
| channel_ = NULL; |
| EXPECT_EQ(0, engine_.GetNumOfChannels()); |
| } |
| |
| // Tests that we properly handle failures in CreateChannel. |
| TEST_F(WebRtcVideoEngineTestFake, CreateChannelFail) { |
| vie_.set_fail_create_channel(true); |
| EXPECT_TRUE(engine_.Init(talk_base::Thread::Current())); |
| channel_ = engine_.CreateChannel(voice_channel_); |
| EXPECT_TRUE(channel_ == NULL); |
| } |
| |
| // Tests that we properly handle failures in AllocateExternalCaptureDevice. |
| TEST_F(WebRtcVideoEngineTestFake, AllocateExternalCaptureDeviceFail) { |
| vie_.set_fail_alloc_capturer(true); |
| EXPECT_TRUE(engine_.Init(talk_base::Thread::Current())); |
| channel_ = engine_.CreateChannel(voice_channel_); |
| EXPECT_TRUE(channel_ == NULL); |
| } |
| |
| // Test that we apply our default codecs properly. |
| TEST_F(WebRtcVideoEngineTestFake, SetSendCodecs) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| std::vector<cricket::VideoCodec> codecs(engine_.codecs()); |
| EXPECT_TRUE(channel_->SetSendCodecs(codecs)); |
| VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height); |
| EXPECT_TRUE(vie_.GetHybridNackFecStatus(channel_num)); |
| EXPECT_FALSE(vie_.GetNackStatus(channel_num)); |
| // TODO(juberti): Check RTCP, PLI, TMMBR. |
| } |
| |
| TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsWithMinMaxBitrate) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| std::vector<cricket::VideoCodec> codecs(engine_.codecs()); |
| codecs[0].params[cricket::kCodecParamMinBitrate] = "10"; |
| codecs[0].params[cricket::kCodecParamMaxBitrate] = "20"; |
| EXPECT_TRUE(channel_->SetSendCodecs(codecs)); |
| |
| VerifyVP8SendCodec( |
| channel_num, kVP8Codec.width, kVP8Codec.height, 0, 20, 10, 20); |
| |
| cricket::VideoCodec codec; |
| EXPECT_TRUE(channel_->GetSendCodec(&codec)); |
| EXPECT_EQ("10", codec.params[cricket::kCodecParamMinBitrate]); |
| EXPECT_EQ("20", codec.params[cricket::kCodecParamMaxBitrate]); |
| } |
| |
| TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsWithMinMaxBitrateInvalid) { |
| EXPECT_TRUE(SetupEngine()); |
| std::vector<cricket::VideoCodec> codecs(engine_.codecs()); |
| codecs[0].params[cricket::kCodecParamMinBitrate] = "30"; |
| codecs[0].params[cricket::kCodecParamMaxBitrate] = "20"; |
| EXPECT_FALSE(channel_->SetSendCodecs(codecs)); |
| } |
| |
| TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsWithLargeMinMaxBitrate) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| std::vector<cricket::VideoCodec> codecs(engine_.codecs()); |
| codecs[0].params[cricket::kCodecParamMinBitrate] = "1000"; |
| codecs[0].params[cricket::kCodecParamMaxBitrate] = "2000"; |
| EXPECT_TRUE(channel_->SetSendCodecs(codecs)); |
| |
| VerifyVP8SendCodec( |
| channel_num, kVP8Codec.width, kVP8Codec.height, 0, 2000, 1000, |
| 1000); |
| } |
| |
| TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsWithMaxQuantization) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| std::vector<cricket::VideoCodec> codecs(engine_.codecs()); |
| codecs[0].params[cricket::kCodecParamMaxQuantization] = "21"; |
| EXPECT_TRUE(channel_->SetSendCodecs(codecs)); |
| |
| VerifyVP8SendCodec( |
| channel_num, kVP8Codec.width, kVP8Codec.height, 0, 2000, 50, 300, |
| 30, 21); |
| |
| cricket::VideoCodec codec; |
| EXPECT_TRUE(channel_->GetSendCodec(&codec)); |
| EXPECT_EQ("21", codec.params[cricket::kCodecParamMaxQuantization]); |
| } |
| |
| TEST_F(WebRtcVideoEngineTestFake, SetOptionsWithMaxBitrate) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| std::vector<cricket::VideoCodec> codecs(engine_.codecs()); |
| codecs[0].params[cricket::kCodecParamMinBitrate] = "10"; |
| codecs[0].params[cricket::kCodecParamMaxBitrate] = "20"; |
| EXPECT_TRUE(channel_->SetSendCodecs(codecs)); |
| |
| VerifyVP8SendCodec( |
| channel_num, kVP8Codec.width, kVP8Codec.height, 0, 20, 10, 20); |
| |
| // Verify that max bitrate doesn't change after SetOptions(). |
| cricket::VideoOptions options; |
| options.video_noise_reduction.Set(true); |
| EXPECT_TRUE(channel_->SetOptions(options)); |
| VerifyVP8SendCodec( |
| channel_num, kVP8Codec.width, kVP8Codec.height, 0, 20, 10, 20); |
| |
| options.video_noise_reduction.Set(false); |
| options.conference_mode.Set(false); |
| EXPECT_TRUE(channel_->SetOptions(options)); |
| VerifyVP8SendCodec( |
| channel_num, kVP8Codec.width, kVP8Codec.height, 0, 20, 10, 20); |
| } |
| |
| TEST_F(WebRtcVideoEngineTestFake, MaxBitrateResetWithConferenceMode) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| std::vector<cricket::VideoCodec> codecs(engine_.codecs()); |
| codecs[0].params[cricket::kCodecParamMinBitrate] = "10"; |
| codecs[0].params[cricket::kCodecParamMaxBitrate] = "20"; |
| EXPECT_TRUE(channel_->SetSendCodecs(codecs)); |
| |
| VerifyVP8SendCodec( |
| channel_num, kVP8Codec.width, kVP8Codec.height, 0, 20, 10, 20); |
| |
| cricket::VideoOptions options; |
| options.conference_mode.Set(true); |
| EXPECT_TRUE(channel_->SetOptions(options)); |
| options.conference_mode.Set(false); |
| EXPECT_TRUE(channel_->SetOptions(options)); |
| VerifyVP8SendCodec( |
| channel_num, kVP8Codec.width, kVP8Codec.height, 0, |
| kMaxBandwidthKbps, 10, 20); |
| } |
| |
| // Verify the current send bitrate is used as start bitrate when reconfiguring |
| // the send codec. |
| TEST_F(WebRtcVideoEngineTestFake, StartSendBitrate) { |
| EXPECT_TRUE(SetupEngine()); |
| EXPECT_TRUE(channel_->AddSendStream( |
| cricket::StreamParams::CreateLegacy(1))); |
| int send_channel = vie_.GetLastChannel(); |
| cricket::VideoCodec codec(kVP8Codec); |
| std::vector<cricket::VideoCodec> codec_list; |
| codec_list.push_back(codec); |
| EXPECT_TRUE(channel_->SetSendCodecs(codec_list)); |
| const unsigned int kVideoMaxSendBitrateKbps = 2000; |
| const unsigned int kVideoMinSendBitrateKbps = 50; |
| const unsigned int kVideoDefaultStartSendBitrateKbps = 300; |
| VerifyVP8SendCodec(send_channel, kVP8Codec.width, kVP8Codec.height, 0, |
| kVideoMaxSendBitrateKbps, kVideoMinSendBitrateKbps, |
| kVideoDefaultStartSendBitrateKbps); |
| EXPECT_EQ(0, vie_.StartSend(send_channel)); |
| |
| // Increase the send bitrate and verify it is used as start bitrate. |
| const unsigned int kVideoSendBitrateBps = 768000; |
| vie_.SetSendBitrates(send_channel, kVideoSendBitrateBps, 0, 0); |
| EXPECT_TRUE(channel_->SetSendCodecs(codec_list)); |
| VerifyVP8SendCodec(send_channel, kVP8Codec.width, kVP8Codec.height, 0, |
| kVideoMaxSendBitrateKbps, kVideoMinSendBitrateKbps, |
| kVideoSendBitrateBps / 1000); |
| |
| // Never set a start bitrate higher than the max bitrate. |
| vie_.SetSendBitrates(send_channel, kVideoMaxSendBitrateKbps + 500, 0, 0); |
| EXPECT_TRUE(channel_->SetSendCodecs(codec_list)); |
| VerifyVP8SendCodec(send_channel, kVP8Codec.width, kVP8Codec.height, 0, |
| kVideoMaxSendBitrateKbps, kVideoMinSendBitrateKbps, |
| kVideoDefaultStartSendBitrateKbps); |
| |
| // Use the default start bitrate if the send bitrate is lower. |
| vie_.SetSendBitrates(send_channel, kVideoDefaultStartSendBitrateKbps - 50, 0, |
| 0); |
| EXPECT_TRUE(channel_->SetSendCodecs(codec_list)); |
| VerifyVP8SendCodec(send_channel, kVP8Codec.width, kVP8Codec.height, 0, |
| kVideoMaxSendBitrateKbps, kVideoMinSendBitrateKbps, |
| kVideoDefaultStartSendBitrateKbps); |
| } |
| |
| |
| // Test that we constrain send codecs properly. |
| TEST_F(WebRtcVideoEngineTestFake, ConstrainSendCodecs) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| |
| // Set max settings of 640x400x30. |
| EXPECT_TRUE(engine_.SetDefaultEncoderConfig( |
| cricket::VideoEncoderConfig(kVP8Codec))); |
| |
| // Send codec format bigger than max setting. |
| cricket::VideoCodec codec(kVP8Codec); |
| codec.width = 1280; |
| codec.height = 800; |
| codec.framerate = 60; |
| std::vector<cricket::VideoCodec> codec_list; |
| codec_list.push_back(codec); |
| |
| // Set send codec and verify codec has been constrained. |
| EXPECT_TRUE(channel_->SetSendCodecs(codec_list)); |
| VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height); |
| } |
| |
| // Test that SetSendCodecs rejects bad format. |
| TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsRejectBadFormat) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| |
| // Set w = 0. |
| cricket::VideoCodec codec(kVP8Codec); |
| codec.width = 0; |
| std::vector<cricket::VideoCodec> codec_list; |
| codec_list.push_back(codec); |
| |
| // Verify SetSendCodecs failed and send codec is not changed on engine. |
| EXPECT_FALSE(channel_->SetSendCodecs(codec_list)); |
| webrtc::VideoCodec gcodec; |
| // Set plType to something other than the value to test against ensuring |
| // that failure will happen if it is not changed. |
| gcodec.plType = 1; |
| EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec)); |
| EXPECT_EQ(0, gcodec.plType); |
| |
| // Set h = 0. |
| codec_list[0].width = 640; |
| codec_list[0].height = 0; |
| |
| // Verify SetSendCodecs failed and send codec is not changed on engine. |
| EXPECT_FALSE(channel_->SetSendCodecs(codec_list)); |
| // Set plType to something other than the value to test against ensuring |
| // that failure will happen if it is not changed. |
| gcodec.plType = 1; |
| EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec)); |
| EXPECT_EQ(0, gcodec.plType); |
| } |
| |
| // Test that SetSendCodecs rejects bad codec. |
| TEST_F(WebRtcVideoEngineTestFake, SetSendCodecsRejectBadCodec) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| |
| // Set bad codec name. |
| cricket::VideoCodec codec(kVP8Codec); |
| codec.name = "bad"; |
| std::vector<cricket::VideoCodec> codec_list; |
| codec_list.push_back(codec); |
| |
| // Verify SetSendCodecs failed and send codec is not changed on engine. |
| EXPECT_FALSE(channel_->SetSendCodecs(codec_list)); |
| webrtc::VideoCodec gcodec; |
| // Set plType to something other than the value to test against ensuring |
| // that failure will happen if it is not changed. |
| gcodec.plType = 1; |
| EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec)); |
| EXPECT_EQ(0, gcodec.plType); |
| } |
| |
| // Test that vie send codec is reset on new video frame size. |
| TEST_F(WebRtcVideoEngineTestFake, ResetVieSendCodecOnNewFrameSize) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| |
| // Set send codec. |
| std::vector<cricket::VideoCodec> codec_list; |
| codec_list.push_back(kVP8Codec); |
| EXPECT_TRUE(channel_->SetSendCodecs(codec_list)); |
| EXPECT_TRUE(channel_->AddSendStream( |
| cricket::StreamParams::CreateLegacy(123))); |
| EXPECT_TRUE(channel_->SetSend(true)); |
| |
| // Capture a smaller frame and verify vie send codec has been reset to |
| // the new size. |
| SendI420Frame(kVP8Codec.width / 2, kVP8Codec.height / 2); |
| VerifyVP8SendCodec(channel_num, kVP8Codec.width / 2, kVP8Codec.height / 2); |
| |
| // Capture a frame bigger than send_codec_ and verify vie send codec has been |
| // reset (and clipped) to send_codec_. |
| SendI420Frame(kVP8Codec.width * 2, kVP8Codec.height * 2); |
| VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height); |
| } |
| |
| // Test that we set our inbound codecs properly. |
| TEST_F(WebRtcVideoEngineTestFake, SetRecvCodecs) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| |
| std::vector<cricket::VideoCodec> codecs; |
| codecs.push_back(kVP8Codec); |
| EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); |
| |
| webrtc::VideoCodec wcodec; |
| EXPECT_TRUE(engine_.ConvertFromCricketVideoCodec(kVP8Codec, &wcodec)); |
| EXPECT_TRUE(vie_.ReceiveCodecRegistered(channel_num, wcodec)); |
| } |
| |
| // Test that channel connects and disconnects external capturer correctly. |
| TEST_F(WebRtcVideoEngineTestFake, HasExternalCapturer) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| |
| EXPECT_EQ(1, vie_.GetNumCapturers()); |
| int capture_id = vie_.GetCaptureId(channel_num); |
| EXPECT_EQ(channel_num, vie_.GetCaptureChannelId(capture_id)); |
| |
| // Delete the channel should disconnect the capturer. |
| delete channel_; |
| channel_ = NULL; |
| EXPECT_EQ(0, vie_.GetNumCapturers()); |
| } |
| |
| // Test that channel adds and removes renderer correctly. |
| TEST_F(WebRtcVideoEngineTestFake, HasRenderer) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| |
| EXPECT_TRUE(vie_.GetHasRenderer(channel_num)); |
| EXPECT_FALSE(vie_.GetRenderStarted(channel_num)); |
| } |
| |
| // Test that rtcp is enabled on the channel. |
| TEST_F(WebRtcVideoEngineTestFake, RtcpEnabled) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| EXPECT_EQ(webrtc::kRtcpCompound_RFC4585, vie_.GetRtcpStatus(channel_num)); |
| } |
| |
| // Test that key frame request method is set on the channel. |
| TEST_F(WebRtcVideoEngineTestFake, KeyFrameRequestEnabled) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| EXPECT_EQ(webrtc::kViEKeyFrameRequestPliRtcp, |
| vie_.GetKeyFrameRequestMethod(channel_num)); |
| } |
| |
| // Test that remb receive and send is enabled for the default channel in a 1:1 |
| // call. |
| TEST_F(WebRtcVideoEngineTestFake, RembEnabled) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| EXPECT_TRUE(channel_->AddSendStream( |
| cricket::StreamParams::CreateLegacy(1))); |
| EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs())); |
| EXPECT_TRUE(vie_.GetRembStatusBwPartition(channel_num)); |
| EXPECT_TRUE(channel_->SetSend(true)); |
| EXPECT_TRUE(vie_.GetRembStatusBwPartition(channel_num)); |
| EXPECT_TRUE(vie_.GetRembStatusContribute(channel_num)); |
| } |
| |
| // When in conference mode, test that remb is enabled on a receive channel but |
| // not for the default channel and that it uses the default channel for sending |
| // remb packets. |
| TEST_F(WebRtcVideoEngineTestFake, RembEnabledOnReceiveChannels) { |
| EXPECT_TRUE(SetupEngine()); |
| int default_channel = vie_.GetLastChannel(); |
| cricket::VideoOptions options; |
| options.conference_mode.Set(true); |
| EXPECT_TRUE(channel_->SetOptions(options)); |
| EXPECT_TRUE(channel_->AddSendStream( |
| cricket::StreamParams::CreateLegacy(1))); |
| EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs())); |
| EXPECT_TRUE(vie_.GetRembStatusBwPartition(default_channel)); |
| EXPECT_TRUE(vie_.GetRembStatusContribute(default_channel)); |
| EXPECT_TRUE(channel_->SetSend(true)); |
| EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1))); |
| int new_channel_num = vie_.GetLastChannel(); |
| EXPECT_NE(default_channel, new_channel_num); |
| |
| EXPECT_TRUE(vie_.GetRembStatusBwPartition(default_channel)); |
| EXPECT_TRUE(vie_.GetRembStatusContribute(default_channel)); |
| EXPECT_FALSE(vie_.GetRembStatusBwPartition(new_channel_num)); |
| EXPECT_TRUE(vie_.GetRembStatusContribute(new_channel_num)); |
| } |
| |
| // Test support for RTP timestamp offset header extension. |
| TEST_F(WebRtcVideoEngineTestFake, RtpTimestampOffsetHeaderExtensions) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| cricket::VideoOptions options; |
| options.conference_mode.Set(true); |
| EXPECT_TRUE(channel_->SetOptions(options)); |
| |
| // Verify extensions are off by default. |
| EXPECT_EQ(0, vie_.GetSendRtpTimestampOffsetExtensionId(channel_num)); |
| EXPECT_EQ(0, vie_.GetReceiveRtpTimestampOffsetExtensionId(channel_num)); |
| |
| // Enable RTP timestamp extension. |
| const int id = 14; |
| std::vector<cricket::RtpHeaderExtension> extensions; |
| extensions.push_back(cricket::RtpHeaderExtension( |
| "urn:ietf:params:rtp-hdrext:toffset", id)); |
| |
| // Verify the send extension id. |
| EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions)); |
| EXPECT_EQ(id, vie_.GetSendRtpTimestampOffsetExtensionId(channel_num)); |
| |
| // Remove the extension id. |
| std::vector<cricket::RtpHeaderExtension> empty_extensions; |
| EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(empty_extensions)); |
| EXPECT_EQ(0, vie_.GetSendRtpTimestampOffsetExtensionId(channel_num)); |
| |
| // Verify receive extension id. |
| EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions)); |
| EXPECT_EQ(id, vie_.GetReceiveRtpTimestampOffsetExtensionId(channel_num)); |
| |
| // Add a new receive stream and verify the extension is set. |
| EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2))); |
| int new_channel_num = vie_.GetLastChannel(); |
| EXPECT_NE(channel_num, new_channel_num); |
| EXPECT_EQ(id, vie_.GetReceiveRtpTimestampOffsetExtensionId(new_channel_num)); |
| |
| // Remove the extension id. |
| EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(empty_extensions)); |
| EXPECT_EQ(0, vie_.GetReceiveRtpTimestampOffsetExtensionId(channel_num)); |
| EXPECT_EQ(0, vie_.GetReceiveRtpTimestampOffsetExtensionId(new_channel_num)); |
| } |
| |
| // Test support for absolute send time header extension. |
| TEST_F(WebRtcVideoEngineTestFake, AbsoluteSendTimeHeaderExtensions) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| cricket::VideoOptions options; |
| options.conference_mode.Set(true); |
| EXPECT_TRUE(channel_->SetOptions(options)); |
| |
| // Verify extensions are off by default. |
| EXPECT_EQ(0, vie_.GetSendAbsoluteSendTimeExtensionId(channel_num)); |
| EXPECT_EQ(0, vie_.GetReceiveAbsoluteSendTimeExtensionId(channel_num)); |
| |
| // Enable RTP timestamp extension. |
| const int id = 12; |
| std::vector<cricket::RtpHeaderExtension> extensions; |
| extensions.push_back(cricket::RtpHeaderExtension( |
| "http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time", id)); |
| |
| // Verify the send extension id. |
| EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions)); |
| EXPECT_EQ(id, vie_.GetSendAbsoluteSendTimeExtensionId(channel_num)); |
| |
| // Remove the extension id. |
| std::vector<cricket::RtpHeaderExtension> empty_extensions; |
| EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(empty_extensions)); |
| EXPECT_EQ(0, vie_.GetSendAbsoluteSendTimeExtensionId(channel_num)); |
| |
| // Verify receive extension id. |
| EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions)); |
| EXPECT_EQ(id, vie_.GetReceiveAbsoluteSendTimeExtensionId(channel_num)); |
| |
| // Add a new receive stream and verify the extension is set. |
| EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2))); |
| int new_channel_num = vie_.GetLastChannel(); |
| EXPECT_NE(channel_num, new_channel_num); |
| EXPECT_EQ(id, vie_.GetReceiveAbsoluteSendTimeExtensionId(new_channel_num)); |
| |
| // Remove the extension id. |
| EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(empty_extensions)); |
| EXPECT_EQ(0, vie_.GetReceiveAbsoluteSendTimeExtensionId(channel_num)); |
| EXPECT_EQ(0, vie_.GetReceiveAbsoluteSendTimeExtensionId(new_channel_num)); |
| } |
| |
| TEST_F(WebRtcVideoEngineTestFake, LeakyBucketTest) { |
| EXPECT_TRUE(SetupEngine()); |
| |
| // Verify this is off by default. |
| EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1))); |
| int first_send_channel = vie_.GetLastChannel(); |
| EXPECT_FALSE(vie_.GetTransmissionSmoothingStatus(first_send_channel)); |
| |
| // Enable the experiment and verify. |
| cricket::VideoOptions options; |
| options.conference_mode.Set(true); |
| options.video_leaky_bucket.Set(true); |
| EXPECT_TRUE(channel_->SetOptions(options)); |
| EXPECT_TRUE(vie_.GetTransmissionSmoothingStatus(first_send_channel)); |
| |
| // Add a receive channel and verify leaky bucket isn't enabled. |
| EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2))); |
| int recv_channel_num = vie_.GetLastChannel(); |
| EXPECT_NE(first_send_channel, recv_channel_num); |
| EXPECT_FALSE(vie_.GetTransmissionSmoothingStatus(recv_channel_num)); |
| |
| // Add a new send stream and verify leaky bucket is enabled from start. |
| EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(3))); |
| int second_send_channel = vie_.GetLastChannel(); |
| EXPECT_NE(first_send_channel, second_send_channel); |
| EXPECT_TRUE(vie_.GetTransmissionSmoothingStatus(second_send_channel)); |
| } |
| |
| TEST_F(WebRtcVideoEngineTestFake, BufferedModeLatency) { |
| EXPECT_TRUE(SetupEngine()); |
| |
| // Verify this is off by default. |
| EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1))); |
| int first_send_channel = vie_.GetLastChannel(); |
| EXPECT_EQ(0, vie_.GetSenderTargetDelay(first_send_channel)); |
| EXPECT_EQ(0, vie_.GetReceiverTargetDelay(first_send_channel)); |
| |
| // Enable the experiment and verify. The default channel will have both |
| // sender and receiver buffered mode enabled. |
| cricket::VideoOptions options; |
| options.conference_mode.Set(true); |
| options.buffered_mode_latency.Set(100); |
| EXPECT_TRUE(channel_->SetOptions(options)); |
| EXPECT_EQ(100, vie_.GetSenderTargetDelay(first_send_channel)); |
| EXPECT_EQ(100, vie_.GetReceiverTargetDelay(first_send_channel)); |
| |
| // Add a receive channel and verify sender buffered mode isn't enabled. |
| EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2))); |
| int recv_channel_num = vie_.GetLastChannel(); |
| EXPECT_NE(first_send_channel, recv_channel_num); |
| EXPECT_EQ(0, vie_.GetSenderTargetDelay(recv_channel_num)); |
| EXPECT_EQ(100, vie_.GetReceiverTargetDelay(recv_channel_num)); |
| |
| // Add a new send stream and verify sender buffered mode is enabled. |
| EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(3))); |
| int second_send_channel = vie_.GetLastChannel(); |
| EXPECT_NE(first_send_channel, second_send_channel); |
| EXPECT_EQ(100, vie_.GetSenderTargetDelay(second_send_channel)); |
| EXPECT_EQ(0, vie_.GetReceiverTargetDelay(second_send_channel)); |
| |
| // Disable sender buffered mode and verify. |
| options.buffered_mode_latency.Set(cricket::kBufferedModeDisabled); |
| EXPECT_TRUE(channel_->SetOptions(options)); |
| EXPECT_EQ(0, vie_.GetSenderTargetDelay(first_send_channel)); |
| EXPECT_EQ(0, vie_.GetReceiverTargetDelay(first_send_channel)); |
| EXPECT_EQ(0, vie_.GetSenderTargetDelay(second_send_channel)); |
| EXPECT_EQ(0, vie_.GetReceiverTargetDelay(second_send_channel)); |
| EXPECT_EQ(0, vie_.GetSenderTargetDelay(recv_channel_num)); |
| EXPECT_EQ(0, vie_.GetReceiverTargetDelay(recv_channel_num)); |
| } |
| |
| TEST_F(WebRtcVideoEngineTestFake, AdditiveVideoOptions) { |
| EXPECT_TRUE(SetupEngine()); |
| |
| EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1))); |
| int first_send_channel = vie_.GetLastChannel(); |
| EXPECT_EQ(0, vie_.GetSenderTargetDelay(first_send_channel)); |
| EXPECT_EQ(0, vie_.GetReceiverTargetDelay(first_send_channel)); |
| |
| cricket::VideoOptions options1; |
| options1.buffered_mode_latency.Set(100); |
| EXPECT_TRUE(channel_->SetOptions(options1)); |
| EXPECT_EQ(100, vie_.GetSenderTargetDelay(first_send_channel)); |
| EXPECT_EQ(100, vie_.GetReceiverTargetDelay(first_send_channel)); |
| EXPECT_FALSE(vie_.GetTransmissionSmoothingStatus(first_send_channel)); |
| |
| cricket::VideoOptions options2; |
| options2.video_leaky_bucket.Set(true); |
| EXPECT_TRUE(channel_->SetOptions(options2)); |
| EXPECT_TRUE(vie_.GetTransmissionSmoothingStatus(first_send_channel)); |
| // The buffered_mode_latency still takes effect. |
| EXPECT_EQ(100, vie_.GetSenderTargetDelay(first_send_channel)); |
| EXPECT_EQ(100, vie_.GetReceiverTargetDelay(first_send_channel)); |
| |
| options1.buffered_mode_latency.Set(50); |
| EXPECT_TRUE(channel_->SetOptions(options1)); |
| EXPECT_EQ(50, vie_.GetSenderTargetDelay(first_send_channel)); |
| EXPECT_EQ(50, vie_.GetReceiverTargetDelay(first_send_channel)); |
| // The video_leaky_bucket still takes effect. |
| EXPECT_TRUE(vie_.GetTransmissionSmoothingStatus(first_send_channel)); |
| } |
| |
| // Test that AddRecvStream doesn't create new channel for 1:1 call. |
| TEST_F(WebRtcVideoEngineTestFake, AddRecvStream1On1) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1))); |
| EXPECT_EQ(channel_num, vie_.GetLastChannel()); |
| } |
| |
| // Test that AddRecvStream doesn't change remb for 1:1 call. |
| TEST_F(WebRtcVideoEngineTestFake, NoRembChangeAfterAddRecvStream) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| EXPECT_TRUE(channel_->AddSendStream( |
| cricket::StreamParams::CreateLegacy(1))); |
| EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs())); |
| EXPECT_TRUE(vie_.GetRembStatusBwPartition(channel_num)); |
| EXPECT_TRUE(vie_.GetRembStatusContribute(channel_num)); |
| EXPECT_TRUE(channel_->SetSend(true)); |
| EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1))); |
| EXPECT_TRUE(vie_.GetRembStatusBwPartition(channel_num)); |
| EXPECT_TRUE(vie_.GetRembStatusContribute(channel_num)); |
| } |
| |
| // Verify default REMB setting and that it can be turned on and off. |
| TEST_F(WebRtcVideoEngineTestFake, RembOnOff) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| // Verify REMB sending is always off by default. |
| EXPECT_FALSE(vie_.GetRembStatusBwPartition(channel_num)); |
| |
| // Verify that REMB is turned on when setting default codecs since the |
| // default codecs have REMB enabled. |
| EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs())); |
| EXPECT_TRUE(vie_.GetRembStatusBwPartition(channel_num)); |
| |
| // Verify that REMB is turned off when codecs without REMB are set. |
| std::vector<cricket::VideoCodec> codecs = engine_.codecs(); |
| // Clearing the codecs' FeedbackParams and setting send codecs should disable |
| // REMB. |
| for (std::vector<cricket::VideoCodec>::iterator iter = codecs.begin(); |
| iter != codecs.end(); ++iter) { |
| // Intersecting with empty will clear the FeedbackParams. |
| cricket::FeedbackParams empty_params; |
| iter->feedback_params.Intersect(empty_params); |
| EXPECT_TRUE(iter->feedback_params.params().empty()); |
| } |
| EXPECT_TRUE(channel_->SetSendCodecs(codecs)); |
| EXPECT_FALSE(vie_.GetRembStatusBwPartition(channel_num)); |
| } |
| |
| // Test that nack is enabled on the channel if we don't offer red/fec. |
| TEST_F(WebRtcVideoEngineTestFake, NackEnabled) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| std::vector<cricket::VideoCodec> codecs(engine_.codecs()); |
| codecs.resize(1); // toss out red and ulpfec |
| EXPECT_TRUE(channel_->SetSendCodecs(codecs)); |
| EXPECT_TRUE(vie_.GetNackStatus(channel_num)); |
| } |
| |
| // Test that we enable hybrid NACK FEC mode. |
| TEST_F(WebRtcVideoEngineTestFake, HybridNackFec) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| EXPECT_TRUE(channel_->SetRecvCodecs(engine_.codecs())); |
| EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs())); |
| EXPECT_TRUE(vie_.GetHybridNackFecStatus(channel_num)); |
| EXPECT_FALSE(vie_.GetNackStatus(channel_num)); |
| } |
| |
| // Test that we enable hybrid NACK FEC mode when calling SetSendCodecs and |
| // SetReceiveCodecs in reversed order. |
| TEST_F(WebRtcVideoEngineTestFake, HybridNackFecReversedOrder) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs())); |
| EXPECT_TRUE(channel_->SetRecvCodecs(engine_.codecs())); |
| EXPECT_TRUE(vie_.GetHybridNackFecStatus(channel_num)); |
| EXPECT_FALSE(vie_.GetNackStatus(channel_num)); |
| } |
| |
| // Test NACK vs Hybrid NACK/FEC interop call setup, i.e. only use NACK even if |
| // red/fec is offered as receive codec. |
| TEST_F(WebRtcVideoEngineTestFake, VideoProtectionInterop) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| std::vector<cricket::VideoCodec> recv_codecs(engine_.codecs()); |
| std::vector<cricket::VideoCodec> send_codecs(engine_.codecs()); |
| // Only add VP8 as send codec. |
| send_codecs.resize(1); |
| EXPECT_TRUE(channel_->SetRecvCodecs(recv_codecs)); |
| EXPECT_TRUE(channel_->SetSendCodecs(send_codecs)); |
| EXPECT_FALSE(vie_.GetHybridNackFecStatus(channel_num)); |
| EXPECT_TRUE(vie_.GetNackStatus(channel_num)); |
| } |
| |
| // Test NACK vs Hybrid NACK/FEC interop call setup, i.e. only use NACK even if |
| // red/fec is offered as receive codec. Call order reversed compared to |
| // VideoProtectionInterop. |
| TEST_F(WebRtcVideoEngineTestFake, VideoProtectionInteropReversed) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| std::vector<cricket::VideoCodec> recv_codecs(engine_.codecs()); |
| std::vector<cricket::VideoCodec> send_codecs(engine_.codecs()); |
| // Only add VP8 as send codec. |
| send_codecs.resize(1); |
| EXPECT_TRUE(channel_->SetSendCodecs(send_codecs)); |
| EXPECT_TRUE(channel_->SetRecvCodecs(recv_codecs)); |
| EXPECT_FALSE(vie_.GetHybridNackFecStatus(channel_num)); |
| EXPECT_TRUE(vie_.GetNackStatus(channel_num)); |
| } |
| |
| // Test that NACK, not hybrid mode, is enabled in conference mode. |
| TEST_F(WebRtcVideoEngineTestFake, HybridNackFecConference) { |
| EXPECT_TRUE(SetupEngine()); |
| // Setup the send channel. |
| int send_channel_num = vie_.GetLastChannel(); |
| cricket::VideoOptions options; |
| options.conference_mode.Set(true); |
| EXPECT_TRUE(channel_->SetOptions(options)); |
| EXPECT_TRUE(channel_->SetRecvCodecs(engine_.codecs())); |
| EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs())); |
| EXPECT_FALSE(vie_.GetHybridNackFecStatus(send_channel_num)); |
| EXPECT_TRUE(vie_.GetNackStatus(send_channel_num)); |
| // Add a receive stream. |
| EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1))); |
| int receive_channel_num = vie_.GetLastChannel(); |
| EXPECT_FALSE(vie_.GetHybridNackFecStatus(receive_channel_num)); |
| EXPECT_TRUE(vie_.GetNackStatus(receive_channel_num)); |
| } |
| |
| // Test that when AddRecvStream in conference mode, a new channel is created |
| // for receiving. And the new channel's "original channel" is the send channel. |
| TEST_F(WebRtcVideoEngineTestFake, AddRemoveRecvStreamConference) { |
| EXPECT_TRUE(SetupEngine()); |
| // Setup the send channel. |
| int send_channel_num = vie_.GetLastChannel(); |
| cricket::VideoOptions options; |
| options.conference_mode.Set(true); |
| EXPECT_TRUE(channel_->SetOptions(options)); |
| // Add a receive stream. |
| EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1))); |
| int receive_channel_num = vie_.GetLastChannel(); |
| EXPECT_EQ(send_channel_num, vie_.GetOriginalChannelId(receive_channel_num)); |
| EXPECT_TRUE(channel_->RemoveRecvStream(1)); |
| EXPECT_FALSE(vie_.IsChannel(receive_channel_num)); |
| } |
| |
| // Test that we can create a channel and start/stop rendering out on it. |
| TEST_F(WebRtcVideoEngineTestFake, SetRender) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| |
| // Verify we can start/stop/start/stop rendering. |
| EXPECT_TRUE(channel_->SetRender(true)); |
| EXPECT_TRUE(vie_.GetRenderStarted(channel_num)); |
| EXPECT_TRUE(channel_->SetRender(false)); |
| EXPECT_FALSE(vie_.GetRenderStarted(channel_num)); |
| EXPECT_TRUE(channel_->SetRender(true)); |
| EXPECT_TRUE(vie_.GetRenderStarted(channel_num)); |
| EXPECT_TRUE(channel_->SetRender(false)); |
| EXPECT_FALSE(vie_.GetRenderStarted(channel_num)); |
| } |
| |
| // Test that we can create a channel and start/stop sending out on it. |
| TEST_F(WebRtcVideoEngineTestFake, SetSend) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| |
| // Set send codecs on the channel. |
| std::vector<cricket::VideoCodec> codecs; |
| codecs.push_back(kVP8Codec); |
| EXPECT_TRUE(channel_->SetSendCodecs(codecs)); |
| EXPECT_TRUE(channel_->AddSendStream( |
| cricket::StreamParams::CreateLegacy(123))); |
| |
| // Verify we can start/stop/start/stop sending. |
| EXPECT_TRUE(channel_->SetSend(true)); |
| EXPECT_TRUE(vie_.GetSend(channel_num)); |
| EXPECT_TRUE(channel_->SetSend(false)); |
| EXPECT_FALSE(vie_.GetSend(channel_num)); |
| EXPECT_TRUE(channel_->SetSend(true)); |
| EXPECT_TRUE(vie_.GetSend(channel_num)); |
| EXPECT_TRUE(channel_->SetSend(false)); |
| EXPECT_FALSE(vie_.GetSend(channel_num)); |
| } |
| |
| // Test that we set bandwidth properly when using full auto bandwidth mode. |
| TEST_F(WebRtcVideoEngineTestFake, SetBandwidthAuto) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs())); |
| EXPECT_TRUE(channel_->SetSendBandwidth(true, cricket::kAutoBandwidth)); |
| VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height); |
| } |
| |
| // Test that we set bandwidth properly when using auto with upper bound. |
| TEST_F(WebRtcVideoEngineTestFake, SetBandwidthAutoCapped) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs())); |
| EXPECT_TRUE(channel_->SetSendBandwidth(true, 768000)); |
| VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height, 0, 768U); |
| } |
| |
| // Test that we set bandwidth properly when using a fixed bandwidth. |
| TEST_F(WebRtcVideoEngineTestFake, SetBandwidthFixed) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs())); |
| EXPECT_TRUE(channel_->SetSendBandwidth(false, 768000)); |
| VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height, 0, |
| 768U, 768U, 768U); |
| } |
| |
| // Test that SetSendBandwidth is ignored in conference mode. |
| TEST_F(WebRtcVideoEngineTestFake, SetBandwidthInConference) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| cricket::VideoOptions options; |
| options.conference_mode.Set(true); |
| EXPECT_TRUE(channel_->SetOptions(options)); |
| EXPECT_TRUE(channel_->SetSendCodecs(engine_.codecs())); |
| VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height); |
| |
| // Set send bandwidth. |
| EXPECT_TRUE(channel_->SetSendBandwidth(false, 768000)); |
| |
| // Verify bitrate not changed. |
| webrtc::VideoCodec gcodec; |
| EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec)); |
| EXPECT_EQ(kMinBandwidthKbps, gcodec.minBitrate); |
| EXPECT_EQ(kStartBandwidthKbps, gcodec.startBitrate); |
| EXPECT_EQ(kMaxBandwidthKbps, gcodec.maxBitrate); |
| EXPECT_NE(768U, gcodec.minBitrate); |
| EXPECT_NE(768U, gcodec.startBitrate); |
| EXPECT_NE(768U, gcodec.maxBitrate); |
| } |
| |
| // Test that sending screencast frames doesn't change bitrate. |
| TEST_F(WebRtcVideoEngineTestFake, SetBandwidthScreencast) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| |
| // Set send codec. |
| cricket::VideoCodec codec(kVP8Codec); |
| std::vector<cricket::VideoCodec> codec_list; |
| codec_list.push_back(codec); |
| EXPECT_TRUE(channel_->AddSendStream( |
| cricket::StreamParams::CreateLegacy(123))); |
| EXPECT_TRUE(channel_->SetSendCodecs(codec_list)); |
| EXPECT_TRUE(channel_->SetSendBandwidth(false, 111000)); |
| EXPECT_TRUE(channel_->SetSend(true)); |
| |
| SendI420ScreencastFrame(kVP8Codec.width, kVP8Codec.height); |
| VerifyVP8SendCodec(channel_num, kVP8Codec.width, kVP8Codec.height, 0, |
| 111, 111, 111); |
| } |
| |
| |
| // Test SetSendSsrc. |
| TEST_F(WebRtcVideoEngineTestFake, SetSendSsrcAndCname) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| |
| cricket::StreamParams stream; |
| stream.ssrcs.push_back(1234); |
| stream.cname = "cname"; |
| channel_->AddSendStream(stream); |
| |
| unsigned int ssrc = 0; |
| EXPECT_EQ(0, vie_.GetLocalSSRC(channel_num, ssrc)); |
| EXPECT_EQ(1234U, ssrc); |
| EXPECT_EQ(1, vie_.GetNumSsrcs(channel_num)); |
| |
| char rtcp_cname[256]; |
| EXPECT_EQ(0, vie_.GetRTCPCName(channel_num, rtcp_cname)); |
| EXPECT_STREQ("cname", rtcp_cname); |
| } |
| |
| |
| // Test that the local SSRC is the same on sending and receiving channels if the |
| // receive channel is created before the send channel. |
| TEST_F(WebRtcVideoEngineTestFake, SetSendSsrcAfterCreatingReceiveChannel) { |
| EXPECT_TRUE(SetupEngine()); |
| |
| EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1))); |
| int receive_channel_num = vie_.GetLastChannel(); |
| cricket::StreamParams stream = cricket::StreamParams::CreateLegacy(1234); |
| EXPECT_TRUE(channel_->AddSendStream(stream)); |
| int send_channel_num = vie_.GetLastChannel(); |
| unsigned int ssrc = 0; |
| EXPECT_EQ(0, vie_.GetLocalSSRC(send_channel_num, ssrc)); |
| EXPECT_EQ(1234U, ssrc); |
| EXPECT_EQ(1, vie_.GetNumSsrcs(send_channel_num)); |
| ssrc = 0; |
| EXPECT_EQ(0, vie_.GetLocalSSRC(receive_channel_num, ssrc)); |
| EXPECT_EQ(1234U, ssrc); |
| EXPECT_EQ(1, vie_.GetNumSsrcs(receive_channel_num)); |
| } |
| |
| |
| // Test SetOptions with denoising flag. |
| TEST_F(WebRtcVideoEngineTestFake, SetOptionsWithDenoising) { |
| EXPECT_TRUE(SetupEngine()); |
| EXPECT_EQ(1, vie_.GetNumCapturers()); |
| int channel_num = vie_.GetLastChannel(); |
| int capture_id = vie_.GetCaptureId(channel_num); |
| // Set send codecs on the channel. |
| std::vector<cricket::VideoCodec> codecs; |
| codecs.push_back(kVP8Codec); |
| EXPECT_TRUE(channel_->SetSendCodecs(codecs)); |
| |
| // Set options with OPT_VIDEO_NOISE_REDUCTION flag. |
| cricket::VideoOptions options; |
| options.video_noise_reduction.Set(true); |
| EXPECT_TRUE(channel_->SetOptions(options)); |
| |
| // Verify capture has denoising turned on. |
| webrtc::VideoCodec send_codec; |
| memset(&send_codec, 0, sizeof(send_codec)); // avoid uninitialized warning |
| EXPECT_EQ(0, vie_.GetSendCodec(channel_num, send_codec)); |
| EXPECT_TRUE(send_codec.codecSpecific.VP8.denoisingOn); |
| EXPECT_FALSE(vie_.GetCaptureDenoising(capture_id)); |
| |
| // Set options back to zero. |
| options.video_noise_reduction.Set(false); |
| EXPECT_TRUE(channel_->SetOptions(options)); |
| |
| // Verify capture has denoising turned off. |
| EXPECT_EQ(0, vie_.GetSendCodec(channel_num, send_codec)); |
| EXPECT_FALSE(send_codec.codecSpecific.VP8.denoisingOn); |
| EXPECT_FALSE(vie_.GetCaptureDenoising(capture_id)); |
| } |
| |
| |
| TEST_F(WebRtcVideoEngineTestFake, SendReceiveBitratesStats) { |
| EXPECT_TRUE(SetupEngine()); |
| cricket::VideoOptions options; |
| options.conference_mode.Set(true); |
| EXPECT_TRUE(channel_->SetOptions(options)); |
| EXPECT_TRUE(channel_->AddSendStream( |
| cricket::StreamParams::CreateLegacy(1))); |
| int send_channel = vie_.GetLastChannel(); |
| cricket::VideoCodec codec(kVP8Codec720p); |
| std::vector<cricket::VideoCodec> codec_list; |
| codec_list.push_back(codec); |
| EXPECT_TRUE(channel_->SetSendCodecs(codec_list)); |
| |
| EXPECT_TRUE(channel_->AddRecvStream( |
| cricket::StreamParams::CreateLegacy(2))); |
| int first_receive_channel = vie_.GetLastChannel(); |
| EXPECT_NE(send_channel, first_receive_channel); |
| EXPECT_TRUE(channel_->AddRecvStream( |
| cricket::StreamParams::CreateLegacy(3))); |
| int second_receive_channel = vie_.GetLastChannel(); |
| EXPECT_NE(first_receive_channel, second_receive_channel); |
| |
| cricket::VideoMediaInfo info; |
| EXPECT_TRUE(channel_->GetStats(&info)); |
| ASSERT_EQ(1U, info.bw_estimations.size()); |
| ASSERT_EQ(0, info.bw_estimations[0].actual_enc_bitrate); |
| ASSERT_EQ(0, info.bw_estimations[0].transmit_bitrate); |
| ASSERT_EQ(0, info.bw_estimations[0].retransmit_bitrate); |
| ASSERT_EQ(0, info.bw_estimations[0].available_send_bandwidth); |
| ASSERT_EQ(0, info.bw_estimations[0].available_recv_bandwidth); |
| ASSERT_EQ(0, info.bw_estimations[0].target_enc_bitrate); |
| |
| // Start sending and receiving on one of the channels and verify bitrates. |
| EXPECT_EQ(0, vie_.StartSend(send_channel)); |
| int send_video_bitrate = 800; |
| int send_fec_bitrate = 100; |
| int send_nack_bitrate = 20; |
| int send_total_bitrate = send_video_bitrate + send_fec_bitrate + |
| send_nack_bitrate; |
| int send_bandwidth = 950; |
| vie_.SetSendBitrates(send_channel, send_video_bitrate, send_fec_bitrate, |
| send_nack_bitrate); |
| vie_.SetSendBandwidthEstimate(send_channel, send_bandwidth); |
| |
| EXPECT_EQ(0, vie_.StartReceive(first_receive_channel)); |
| int first_channel_receive_bandwidth = 600; |
| vie_.SetReceiveBandwidthEstimate(first_receive_channel, |
| first_channel_receive_bandwidth); |
| |
| info.Clear(); |
| EXPECT_TRUE(channel_->GetStats(&info)); |
| ASSERT_EQ(1U, info.bw_estimations.size()); |
| ASSERT_EQ(send_video_bitrate, info.bw_estimations[0].actual_enc_bitrate); |
| ASSERT_EQ(send_total_bitrate, info.bw_estimations[0].transmit_bitrate); |
| ASSERT_EQ(send_nack_bitrate, info.bw_estimations[0].retransmit_bitrate); |
| ASSERT_EQ(send_bandwidth, info.bw_estimations[0].available_send_bandwidth); |
| ASSERT_EQ(first_channel_receive_bandwidth, |
| info.bw_estimations[0].available_recv_bandwidth); |
| ASSERT_EQ(send_video_bitrate, info.bw_estimations[0].target_enc_bitrate); |
| |
| // Start receiving on the second channel and verify received rate. |
| EXPECT_EQ(0, vie_.StartReceive(second_receive_channel)); |
| int second_channel_receive_bandwidth = 100; |
| vie_.SetReceiveBandwidthEstimate(second_receive_channel, |
| second_channel_receive_bandwidth); |
| |
| info.Clear(); |
| EXPECT_TRUE(channel_->GetStats(&info)); |
| ASSERT_EQ(1U, info.bw_estimations.size()); |
| ASSERT_EQ(send_video_bitrate, info.bw_estimations[0].actual_enc_bitrate); |
| ASSERT_EQ(send_total_bitrate, info.bw_estimations[0].transmit_bitrate); |
| ASSERT_EQ(send_nack_bitrate, info.bw_estimations[0].retransmit_bitrate); |
| ASSERT_EQ(send_bandwidth, info.bw_estimations[0].available_send_bandwidth); |
| ASSERT_EQ(first_channel_receive_bandwidth + second_channel_receive_bandwidth, |
| info.bw_estimations[0].available_recv_bandwidth); |
| ASSERT_EQ(send_video_bitrate, info.bw_estimations[0].target_enc_bitrate); |
| } |
| |
| TEST_F(WebRtcVideoEngineTestFake, TestSetAdaptInputToCpuUsage) { |
| EXPECT_TRUE(SetupEngine()); |
| cricket::VideoOptions options_in, options_out; |
| bool cpu_adapt = false; |
| channel_->SetOptions(options_in); |
| EXPECT_TRUE(channel_->GetOptions(&options_out)); |
| EXPECT_FALSE(options_out.adapt_input_to_cpu_usage.Get(&cpu_adapt)); |
| // Set adapt input CPU usage option. |
| options_in.adapt_input_to_cpu_usage.Set(true); |
| EXPECT_TRUE(channel_->SetOptions(options_in)); |
| EXPECT_TRUE(channel_->GetOptions(&options_out)); |
| EXPECT_TRUE(options_out.adapt_input_to_cpu_usage.Get(&cpu_adapt)); |
| EXPECT_TRUE(cpu_adapt); |
| } |
| |
| TEST_F(WebRtcVideoEngineTestFake, TestSetCpuThreshold) { |
| EXPECT_TRUE(SetupEngine()); |
| float low, high; |
| cricket::VideoOptions options_in, options_out; |
| // Verify that initial values are set. |
| EXPECT_TRUE(channel_->GetOptions(&options_out)); |
| EXPECT_TRUE(options_out.system_low_adaptation_threshhold.Get(&low)); |
| EXPECT_EQ(low, 0.65f); |
| EXPECT_TRUE(options_out.system_high_adaptation_threshhold.Get(&high)); |
| EXPECT_EQ(high, 0.85f); |
| // Set new CPU threshold values. |
| options_in.system_low_adaptation_threshhold.Set(0.45f); |
| options_in.system_high_adaptation_threshhold.Set(0.95f); |
| EXPECT_TRUE(channel_->SetOptions(options_in)); |
| EXPECT_TRUE(channel_->GetOptions(&options_out)); |
| EXPECT_TRUE(options_out.system_low_adaptation_threshhold.Get(&low)); |
| EXPECT_EQ(low, 0.45f); |
| EXPECT_TRUE(options_out.system_high_adaptation_threshhold.Get(&high)); |
| EXPECT_EQ(high, 0.95f); |
| } |
| |
| TEST_F(WebRtcVideoEngineTestFake, TestSetInvalidCpuThreshold) { |
| EXPECT_TRUE(SetupEngine()); |
| float low, high; |
| cricket::VideoOptions options_in, options_out; |
| // Valid range is [0, 1]. |
| options_in.system_low_adaptation_threshhold.Set(-1.5f); |
| options_in.system_high_adaptation_threshhold.Set(1.5f); |
| EXPECT_TRUE(channel_->SetOptions(options_in)); |
| EXPECT_TRUE(channel_->GetOptions(&options_out)); |
| EXPECT_TRUE(options_out.system_low_adaptation_threshhold.Get(&low)); |
| EXPECT_EQ(low, 0.0f); |
| EXPECT_TRUE(options_out.system_high_adaptation_threshhold.Get(&high)); |
| EXPECT_EQ(high, 1.0f); |
| } |
| |
| |
| ///////////////////////// |
| // Tests with real ViE // |
| ///////////////////////// |
| |
| // Tests that we can find codecs by name or id. |
| TEST_F(WebRtcVideoEngineTest, FindCodec) { |
| // We should not need to init engine in order to get codecs. |
| const std::vector<cricket::VideoCodec>& c = engine_.codecs(); |
| EXPECT_EQ(3U, c.size()); |
| |
| cricket::VideoCodec vp8(104, "VP8", 320, 200, 30, 0); |
| EXPECT_TRUE(engine_.FindCodec(vp8)); |
| |
| cricket::VideoCodec vp8_ci(104, "vp8", 320, 200, 30, 0); |
| EXPECT_TRUE(engine_.FindCodec(vp8)); |
| |
| cricket::VideoCodec vp8_diff_fr_diff_pref(104, "VP8", 320, 200, 50, 50); |
| EXPECT_TRUE(engine_.FindCodec(vp8_diff_fr_diff_pref)); |
| |
| cricket::VideoCodec vp8_diff_id(95, "VP8", 320, 200, 30, 0); |
| EXPECT_FALSE(engine_.FindCodec(vp8_diff_id)); |
| vp8_diff_id.id = 97; |
| EXPECT_TRUE(engine_.FindCodec(vp8_diff_id)); |
| |
| cricket::VideoCodec vp8_diff_res(104, "VP8", 320, 111, 30, 0); |
| EXPECT_FALSE(engine_.FindCodec(vp8_diff_res)); |
| |
| // PeerConnection doesn't negotiate the resolution at this point. |
| // Test that FindCodec can handle the case when width/height is 0. |
| cricket::VideoCodec vp8_zero_res(104, "VP8", 0, 0, 30, 0); |
| EXPECT_TRUE(engine_.FindCodec(vp8_zero_res)); |
| |
| cricket::VideoCodec red(101, "RED", 0, 0, 30, 0); |
| EXPECT_TRUE(engine_.FindCodec(red)); |
| |
| cricket::VideoCodec red_ci(101, "red", 0, 0, 30, 0); |
| EXPECT_TRUE(engine_.FindCodec(red)); |
| |
| cricket::VideoCodec fec(102, "ULPFEC", 0, 0, 30, 0); |
| EXPECT_TRUE(engine_.FindCodec(fec)); |
| |
| cricket::VideoCodec fec_ci(102, "ulpfec", 0, 0, 30, 0); |
| EXPECT_TRUE(engine_.FindCodec(fec)); |
| } |
| |
| TEST_F(WebRtcVideoEngineTest, StartupShutdown) { |
| EXPECT_TRUE(engine_.Init(talk_base::Thread::Current())); |
| engine_.Terminate(); |
| } |
| |
| TEST_PRE_VIDEOENGINE_INIT(WebRtcVideoEngineTest, ConstrainNewCodec) |
| TEST_POST_VIDEOENGINE_INIT(WebRtcVideoEngineTest, ConstrainNewCodec) |
| |
| TEST_PRE_VIDEOENGINE_INIT(WebRtcVideoEngineTest, ConstrainRunningCodec) |
| TEST_POST_VIDEOENGINE_INIT(WebRtcVideoEngineTest, ConstrainRunningCodec) |
| |
| // TODO(juberti): Figure out why ViE is munging the COM refcount. |
| #ifdef WIN32 |
| TEST_F(WebRtcVideoEngineTest, DISABLED_CheckCoInitialize) { |
| Base::CheckCoInitialize(); |
| } |
| #endif |
| |
| TEST_F(WebRtcVideoEngineTest, CreateChannel) { |
| EXPECT_TRUE(engine_.Init(talk_base::Thread::Current())); |
| cricket::VideoMediaChannel* channel = engine_.CreateChannel(NULL); |
| EXPECT_TRUE(channel != NULL); |
| delete channel; |
| } |
| |
| TEST_F(WebRtcVideoMediaChannelTest, SetRecvCodecs) { |
| std::vector<cricket::VideoCodec> codecs; |
| codecs.push_back(kVP8Codec); |
| EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); |
| } |
| TEST_F(WebRtcVideoMediaChannelTest, SetRecvCodecsWrongPayloadType) { |
| std::vector<cricket::VideoCodec> codecs; |
| codecs.push_back(kVP8Codec); |
| codecs[0].id = 99; |
| EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); |
| } |
| TEST_F(WebRtcVideoMediaChannelTest, SetRecvCodecsUnsupportedCodec) { |
| std::vector<cricket::VideoCodec> codecs; |
| codecs.push_back(kVP8Codec); |
| codecs.push_back(cricket::VideoCodec(101, "VP1", 640, 400, 30, 0)); |
| EXPECT_FALSE(channel_->SetRecvCodecs(codecs)); |
| } |
| |
| TEST_F(WebRtcVideoMediaChannelTest, SetSend) { |
| Base::SetSend(); |
| } |
| TEST_F(WebRtcVideoMediaChannelTest, SetSendWithoutCodecs) { |
| Base::SetSendWithoutCodecs(); |
| } |
| TEST_F(WebRtcVideoMediaChannelTest, SetSendSetsTransportBufferSizes) { |
| Base::SetSendSetsTransportBufferSizes(); |
| } |
| |
| TEST_F(WebRtcVideoMediaChannelTest, SendAndReceiveVp8Vga) { |
| SendAndReceive(cricket::VideoCodec(100, "VP8", 640, 400, 30, 0)); |
| } |
| TEST_F(WebRtcVideoMediaChannelTest, SendAndReceiveVp8Qvga) { |
| SendAndReceive(cricket::VideoCodec(100, "VP8", 320, 200, 30, 0)); |
| } |
| TEST_F(WebRtcVideoMediaChannelTest, SendAndReceiveH264SvcQqvga) { |
| SendAndReceive(cricket::VideoCodec(100, "VP8", 160, 100, 30, 0)); |
| } |
| TEST_F(WebRtcVideoMediaChannelTest, SendManyResizeOnce) { |
| SendManyResizeOnce(); |
| } |
| |
| TEST_F(WebRtcVideoMediaChannelTest, SendVp8HdAndReceiveAdaptedVp8Vga) { |
| EXPECT_TRUE(channel_->SetCapturer(kSsrc, NULL)); |
| channel_->UpdateAspectRatio(1280, 720); |
| video_capturer_.reset(new cricket::FakeVideoCapturer); |
| const std::vector<cricket::VideoFormat>* formats = |
| video_capturer_->GetSupportedFormats(); |
| cricket::VideoFormat capture_format_hd = (*formats)[0]; |
| EXPECT_EQ(cricket::CS_RUNNING, video_capturer_->Start(capture_format_hd)); |
| EXPECT_TRUE(channel_->SetCapturer(kSsrc, video_capturer_.get())); |
| |
| // Capture format HD -> adapt (OnOutputFormatRequest VGA) -> VGA. |
| cricket::VideoCodec codec(100, "VP8", 1280, 720, 30, 0); |
| EXPECT_TRUE(SetOneCodec(codec)); |
| codec.width /= 2; |
| codec.height /= 2; |
| EXPECT_TRUE(channel_->SetSendStreamFormat(kSsrc, cricket::VideoFormat( |
| codec.width, codec.height, |
| cricket::VideoFormat::FpsToInterval(codec.framerate), |
| cricket::FOURCC_ANY))); |
| EXPECT_TRUE(SetSend(true)); |
| EXPECT_TRUE(channel_->SetRender(true)); |
| EXPECT_EQ(0, renderer_.num_rendered_frames()); |
| EXPECT_TRUE(SendFrame()); |
| EXPECT_FRAME_WAIT(1, codec.width, codec.height, kTimeout); |
| } |
| |
| // TODO(juberti): Fix this test to tolerate missing stats. |
| TEST_F(WebRtcVideoMediaChannelTest, DISABLED_GetStats) { |
| Base::GetStats(); |
| } |
| |
| // TODO(juberti): Fix this test to tolerate missing stats. |
| TEST_F(WebRtcVideoMediaChannelTest, DISABLED_GetStatsMultipleRecvStreams) { |
| Base::GetStatsMultipleRecvStreams(); |
| } |
| |
| TEST_F(WebRtcVideoMediaChannelTest, GetStatsMultipleSendStreams) { |
| Base::GetStatsMultipleSendStreams(); |
| } |
| |
| TEST_F(WebRtcVideoMediaChannelTest, SetSendBandwidth) { |
| Base::SetSendBandwidth(); |
| } |
| TEST_F(WebRtcVideoMediaChannelTest, SetSendSsrc) { |
| Base::SetSendSsrc(); |
| } |
| TEST_F(WebRtcVideoMediaChannelTest, SetSendSsrcAfterSetCodecs) { |
| Base::SetSendSsrcAfterSetCodecs(); |
| } |
| |
| TEST_F(WebRtcVideoMediaChannelTest, SetRenderer) { |
| Base::SetRenderer(); |
| } |
| |
| TEST_F(WebRtcVideoMediaChannelTest, AddRemoveRecvStreams) { |
| Base::AddRemoveRecvStreams(); |
| } |
| |
| TEST_F(WebRtcVideoMediaChannelTest, AddRemoveRecvStreamAndRender) { |
| Base::AddRemoveRecvStreamAndRender(); |
| } |
| |
| TEST_F(WebRtcVideoMediaChannelTest, AddRemoveRecvStreamsNoConference) { |
| Base::AddRemoveRecvStreamsNoConference(); |
| } |
| |
| TEST_F(WebRtcVideoMediaChannelTest, AddRemoveSendStreams) { |
| Base::AddRemoveSendStreams(); |
| } |
| |
| TEST_F(WebRtcVideoMediaChannelTest, SimulateConference) { |
| Base::SimulateConference(); |
| } |
| |
| TEST_F(WebRtcVideoMediaChannelTest, AddRemoveCapturer) { |
| Base::AddRemoveCapturer(); |
| } |
| |
| TEST_F(WebRtcVideoMediaChannelTest, RemoveCapturerWithoutAdd) { |
| Base::RemoveCapturerWithoutAdd(); |
| } |
| |
| TEST_F(WebRtcVideoMediaChannelTest, AddRemoveCapturerMultipleSources) { |
| Base::AddRemoveCapturerMultipleSources(); |
| } |
| |
| |
| TEST_F(WebRtcVideoMediaChannelTest, SetOptionsSucceedsWhenSending) { |
| cricket::VideoOptions options; |
| options.conference_mode.Set(true); |
| EXPECT_TRUE(channel_->SetOptions(options)); |
| |
| // Verify SetOptions returns true on a different options. |
| cricket::VideoOptions options2; |
| options2.adapt_input_to_cpu_usage.Set(true); |
| EXPECT_TRUE(channel_->SetOptions(options2)); |
| |
| // Set send codecs on the channel and start sending. |
| std::vector<cricket::VideoCodec> codecs; |
| codecs.push_back(kVP8Codec); |
| EXPECT_TRUE(channel_->SetSendCodecs(codecs)); |
| EXPECT_TRUE(channel_->SetSend(true)); |
| |
| // Verify SetOptions returns true if channel is already sending. |
| cricket::VideoOptions options3; |
| options3.conference_mode.Set(true); |
| EXPECT_TRUE(channel_->SetOptions(options3)); |
| } |
| |
| // Tests empty StreamParams is rejected. |
| TEST_F(WebRtcVideoMediaChannelTest, RejectEmptyStreamParams) { |
| Base::RejectEmptyStreamParams(); |
| } |
| |
| |
| TEST_F(WebRtcVideoMediaChannelTest, AdaptResolution16x10) { |
| Base::AdaptResolution16x10(); |
| } |
| |
| TEST_F(WebRtcVideoMediaChannelTest, AdaptResolution4x3) { |
| Base::AdaptResolution4x3(); |
| } |
| |
| TEST_F(WebRtcVideoMediaChannelTest, MuteStream) { |
| Base::MuteStream(); |
| } |
| |
| TEST_F(WebRtcVideoMediaChannelTest, MultipleSendStreams) { |
| Base::MultipleSendStreams(); |
| } |
| |
| // TODO(juberti): Restore this test once we support sending 0 fps. |
| TEST_F(WebRtcVideoMediaChannelTest, DISABLED_AdaptDropAllFrames) { |
| Base::AdaptDropAllFrames(); |
| } |
| // TODO(juberti): Understand why we get decode errors on this test. |
| TEST_F(WebRtcVideoMediaChannelTest, DISABLED_AdaptFramerate) { |
| Base::AdaptFramerate(); |
| } |
| |
| TEST_F(WebRtcVideoMediaChannelTest, SetSendStreamFormat0x0) { |
| Base::SetSendStreamFormat0x0(); |
| } |
| |
| // TODO(zhurunz): Fix the flakey test. |
| TEST_F(WebRtcVideoMediaChannelTest, DISABLED_SetSendStreamFormat) { |
| Base::SetSendStreamFormat(); |
| } |
| |
| TEST_F(WebRtcVideoMediaChannelTest, TwoStreamsSendAndReceive) { |
| Base::TwoStreamsSendAndReceive(cricket::VideoCodec(100, "VP8", 640, 400, 30, |
| 0)); |
| } |
| |
| TEST_F(WebRtcVideoMediaChannelTest, TwoStreamsReUseFirstStream) { |
| Base::TwoStreamsReUseFirstStream(cricket::VideoCodec(100, "VP8", 640, 400, 30, |
| 0)); |
| } |
| |
| TEST_F(WebRtcVideoEngineTestFake, ResetCodecOnScreencast) { |
| EXPECT_TRUE(SetupEngine()); |
| cricket::VideoOptions options; |
| options.video_noise_reduction.Set(true); |
| EXPECT_TRUE(channel_->SetOptions(options)); |
| |
| // Set send codec. |
| cricket::VideoCodec codec(kVP8Codec); |
| std::vector<cricket::VideoCodec> codec_list; |
| codec_list.push_back(codec); |
| EXPECT_TRUE(channel_->AddSendStream( |
| cricket::StreamParams::CreateLegacy(123))); |
| EXPECT_TRUE(channel_->SetSendCodecs(codec_list)); |
| EXPECT_TRUE(channel_->SetSend(true)); |
| EXPECT_EQ(1, vie_.num_set_send_codecs()); |
| |
| webrtc::VideoCodec gcodec; |
| memset(&gcodec, 0, sizeof(gcodec)); |
| int channel_num = vie_.GetLastChannel(); |
| EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec)); |
| EXPECT_TRUE(gcodec.codecSpecific.VP8.denoisingOn); |
| |
| // Send a screencast frame with the same size. |
| // Verify that denoising is turned off. |
| SendI420ScreencastFrame(kVP8Codec.width, kVP8Codec.height); |
| EXPECT_EQ(2, vie_.num_set_send_codecs()); |
| EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec)); |
| EXPECT_FALSE(gcodec.codecSpecific.VP8.denoisingOn); |
| } |
| |
| |
| TEST_F(WebRtcVideoEngineTestFake, DontRegisterDecoderIfFactoryIsNotGiven) { |
| engine_.SetExternalDecoderFactory(NULL); |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| |
| std::vector<cricket::VideoCodec> codecs; |
| codecs.push_back(kVP8Codec); |
| EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); |
| |
| EXPECT_EQ(0, vie_.GetNumExternalDecoderRegistered(channel_num)); |
| } |
| |
| TEST_F(WebRtcVideoEngineTestFake, RegisterDecoderIfFactoryIsGiven) { |
| decoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8); |
| engine_.SetExternalDecoderFactory(&decoder_factory_); |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| |
| std::vector<cricket::VideoCodec> codecs; |
| codecs.push_back(kVP8Codec); |
| EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); |
| |
| EXPECT_TRUE(vie_.ExternalDecoderRegistered(channel_num, 100)); |
| EXPECT_EQ(1, vie_.GetNumExternalDecoderRegistered(channel_num)); |
| } |
| |
| TEST_F(WebRtcVideoEngineTestFake, DontRegisterDecoderMultipleTimes) { |
| decoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8); |
| engine_.SetExternalDecoderFactory(&decoder_factory_); |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| |
| std::vector<cricket::VideoCodec> codecs; |
| codecs.push_back(kVP8Codec); |
| EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); |
| |
| EXPECT_TRUE(vie_.ExternalDecoderRegistered(channel_num, 100)); |
| EXPECT_EQ(1, vie_.GetNumExternalDecoderRegistered(channel_num)); |
| EXPECT_EQ(1, decoder_factory_.GetNumCreatedDecoders()); |
| |
| EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); |
| EXPECT_EQ(1, vie_.GetNumExternalDecoderRegistered(channel_num)); |
| EXPECT_EQ(1, decoder_factory_.GetNumCreatedDecoders()); |
| } |
| |
| TEST_F(WebRtcVideoEngineTestFake, DontRegisterDecoderForNonVP8) { |
| decoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8); |
| engine_.SetExternalDecoderFactory(&decoder_factory_); |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| |
| std::vector<cricket::VideoCodec> codecs; |
| codecs.push_back(kRedCodec); |
| EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); |
| |
| EXPECT_EQ(0, vie_.GetNumExternalDecoderRegistered(channel_num)); |
| } |
| |
| TEST_F(WebRtcVideoEngineTestFake, DontRegisterEncoderIfFactoryIsNotGiven) { |
| engine_.SetExternalEncoderFactory(NULL); |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| |
| std::vector<cricket::VideoCodec> codecs; |
| codecs.push_back(kVP8Codec); |
| EXPECT_TRUE(channel_->SetSendCodecs(codecs)); |
| |
| EXPECT_EQ(0, vie_.GetNumExternalEncoderRegistered(channel_num)); |
| } |
| |
| TEST_F(WebRtcVideoEngineTestFake, RegisterEncoderIfFactoryIsGiven) { |
| encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8"); |
| engine_.SetExternalEncoderFactory(&encoder_factory_); |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| |
| std::vector<cricket::VideoCodec> codecs; |
| codecs.push_back(kVP8Codec); |
| EXPECT_TRUE(channel_->SetSendCodecs(codecs)); |
| |
| EXPECT_TRUE(vie_.ExternalEncoderRegistered(channel_num, 100)); |
| EXPECT_EQ(1, vie_.GetNumExternalEncoderRegistered(channel_num)); |
| } |
| |
| TEST_F(WebRtcVideoEngineTestFake, DontRegisterEncoderMultipleTimes) { |
| encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8"); |
| engine_.SetExternalEncoderFactory(&encoder_factory_); |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| |
| std::vector<cricket::VideoCodec> codecs; |
| codecs.push_back(kVP8Codec); |
| EXPECT_TRUE(channel_->SetSendCodecs(codecs)); |
| |
| EXPECT_TRUE(vie_.ExternalEncoderRegistered(channel_num, 100)); |
| EXPECT_EQ(1, vie_.GetNumExternalEncoderRegistered(channel_num)); |
| EXPECT_EQ(1, encoder_factory_.GetNumCreatedEncoders()); |
| |
| EXPECT_TRUE(channel_->SetSendCodecs(codecs)); |
| EXPECT_EQ(1, vie_.GetNumExternalEncoderRegistered(channel_num)); |
| EXPECT_EQ(1, encoder_factory_.GetNumCreatedEncoders()); |
| } |
| |
| TEST_F(WebRtcVideoEngineTestFake, RegisterEncoderWithMultipleSendStreams) { |
| encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8"); |
| engine_.SetExternalEncoderFactory(&encoder_factory_); |
| EXPECT_TRUE(SetupEngine()); |
| |
| std::vector<cricket::VideoCodec> codecs; |
| codecs.push_back(kVP8Codec); |
| EXPECT_TRUE(channel_->SetSendCodecs(codecs)); |
| EXPECT_EQ(1, vie_.GetTotalNumExternalEncoderRegistered()); |
| |
| // When we add the first stream (1234), it reuses the default send channel, |
| // so it doesn't increase the registration count of external encoders. |
| EXPECT_TRUE(channel_->AddSendStream( |
| cricket::StreamParams::CreateLegacy(1234))); |
| EXPECT_EQ(1, vie_.GetTotalNumExternalEncoderRegistered()); |
| |
| // When we add the second stream (2345), it creates a new channel and |
| // increments the registration count. |
| EXPECT_TRUE(channel_->AddSendStream( |
| cricket::StreamParams::CreateLegacy(2345))); |
| EXPECT_EQ(2, vie_.GetTotalNumExternalEncoderRegistered()); |
| |
| // At this moment the total registration count is two, but only one encoder |
| // is registered per channel. |
| int channel_num = vie_.GetLastChannel(); |
| EXPECT_EQ(1, vie_.GetNumExternalEncoderRegistered(channel_num)); |
| |
| // Removing send streams decrements the registration count. |
| EXPECT_TRUE(channel_->RemoveSendStream(1234)); |
| EXPECT_EQ(1, vie_.GetTotalNumExternalEncoderRegistered()); |
| |
| // When we remove the last send stream, it also destroys the last send |
| // channel and causes the registration count to drop to zero. It is a little |
| // weird, but not a bug. |
| EXPECT_TRUE(channel_->RemoveSendStream(2345)); |
| EXPECT_EQ(0, vie_.GetTotalNumExternalEncoderRegistered()); |
| } |
| |
| TEST_F(WebRtcVideoEngineTestFake, DontRegisterEncoderForNonVP8) { |
| encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecGeneric, |
| "GENERIC"); |
| engine_.SetExternalEncoderFactory(&encoder_factory_); |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| |
| // Note: unlike the SetRecvCodecs, we must set a valid video codec for |
| // channel_->SetSendCodecs() to succeed. |
| std::vector<cricket::VideoCodec> codecs; |
| codecs.push_back(kVP8Codec); |
| EXPECT_TRUE(channel_->SetSendCodecs(codecs)); |
| |
| EXPECT_EQ(0, vie_.GetNumExternalEncoderRegistered(channel_num)); |
| } |
| |
| // Test that NACK and REMB are enabled for external codec. |
| TEST_F(WebRtcVideoEngineTestFake, FeedbackParamsForNonVP8) { |
| encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecGeneric, |
| "GENERIC"); |
| engine_.SetExternalEncoderFactory(&encoder_factory_); |
| encoder_factory_.NotifyCodecsAvailable(); |
| EXPECT_TRUE(SetupEngine()); |
| |
| std::vector<cricket::VideoCodec> codecs(engine_.codecs()); |
| // The external codec will appear at last. |
| size_t pos = codecs.size() - 1; |
| EXPECT_EQ("GENERIC", codecs[pos].name); |
| EXPECT_TRUE(codecs[pos].HasFeedbackParam( |
| cricket::FeedbackParam(cricket::kRtcpFbParamNack, |
| cricket::kParamValueEmpty))); |
| EXPECT_TRUE(codecs[pos].HasFeedbackParam( |
| cricket::FeedbackParam(cricket::kRtcpFbParamRemb, |
| cricket::kParamValueEmpty))); |
| EXPECT_TRUE(codecs[pos].HasFeedbackParam( |
| cricket::FeedbackParam(cricket::kRtcpFbParamCcm, |
| cricket::kRtcpFbCcmParamFir))); |
| } |
| |
| // Test external codec with be added to the end of the supported codec list. |
| TEST_F(WebRtcVideoEngineTestFake, ExternalCodecAddedToTheEnd) { |
| EXPECT_TRUE(SetupEngine()); |
| |
| std::vector<cricket::VideoCodec> codecs(engine_.codecs()); |
| EXPECT_EQ("VP8", codecs[0].name); |
| |
| encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecGeneric, |
| "GENERIC"); |
| engine_.SetExternalEncoderFactory(&encoder_factory_); |
| encoder_factory_.NotifyCodecsAvailable(); |
| |
| codecs = engine_.codecs(); |
| cricket::VideoCodec internal_codec = codecs[0]; |
| cricket::VideoCodec external_codec = codecs[codecs.size() - 1]; |
| // The external codec will appear at last. |
| EXPECT_EQ("GENERIC", external_codec.name); |
| // The internal codec is preferred. |
| EXPECT_GE(internal_codec.preference, external_codec.preference); |
| } |
| |
| // Test that external codec with be ignored if it has the same name as one of |
| // the internal codecs. |
| TEST_F(WebRtcVideoEngineTestFake, ExternalCodecIgnored) { |
| EXPECT_TRUE(SetupEngine()); |
| |
| std::vector<cricket::VideoCodec> internal_codecs(engine_.codecs()); |
| EXPECT_EQ("VP8", internal_codecs[0].name); |
| |
| encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8"); |
| engine_.SetExternalEncoderFactory(&encoder_factory_); |
| encoder_factory_.NotifyCodecsAvailable(); |
| |
| std::vector<cricket::VideoCodec> codecs = engine_.codecs(); |
| EXPECT_EQ("VP8", codecs[0].name); |
| EXPECT_EQ(internal_codecs[0].height, codecs[0].height); |
| EXPECT_EQ(internal_codecs[0].width, codecs[0].width); |
| // Verify the last codec is not the external codec. |
| EXPECT_NE("VP8", codecs[codecs.size() - 1].name); |
| } |
| |
| TEST_F(WebRtcVideoEngineTestFake, UpdateEncoderCodecsAfterSetFactory) { |
| engine_.SetExternalEncoderFactory(&encoder_factory_); |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| |
| encoder_factory_.AddSupportedVideoCodecType(webrtc::kVideoCodecVP8, "VP8"); |
| encoder_factory_.NotifyCodecsAvailable(); |
| std::vector<cricket::VideoCodec> codecs; |
| codecs.push_back(kVP8Codec); |
| EXPECT_TRUE(channel_->SetSendCodecs(codecs)); |
| |
| EXPECT_TRUE(vie_.ExternalEncoderRegistered(channel_num, 100)); |
| EXPECT_EQ(1, vie_.GetNumExternalEncoderRegistered(channel_num)); |
| EXPECT_EQ(1, encoder_factory_.GetNumCreatedEncoders()); |
| } |
| |
| // Tests that OnReadyToSend will be propagated into ViE. |
| TEST_F(WebRtcVideoEngineTestFake, OnReadyToSend) { |
| EXPECT_TRUE(SetupEngine()); |
| int channel_num = vie_.GetLastChannel(); |
| EXPECT_TRUE(vie_.GetIsTransmitting(channel_num)); |
| |
| channel_->OnReadyToSend(false); |
| EXPECT_FALSE(vie_.GetIsTransmitting(channel_num)); |
| |
| channel_->OnReadyToSend(true); |
| EXPECT_TRUE(vie_.GetIsTransmitting(channel_num)); |
| } |
| |
| #if 0 |
| TEST_F(WebRtcVideoEngineTestFake, CaptureFrameTimestampToNtpTimestamp) { |
| EXPECT_TRUE(SetupEngine()); |
| int capture_id = vie_.GetCaptureId(vie_.GetLastChannel()); |
| |
| // Set send codec. |
| cricket::VideoCodec codec(kVP8Codec); |
| std::vector<cricket::VideoCodec> codec_list; |
| codec_list.push_back(codec); |
| EXPECT_TRUE(channel_->AddSendStream( |
| cricket::StreamParams::CreateLegacy(123))); |
| EXPECT_TRUE(channel_->SetSendCodecs(codec_list)); |
| EXPECT_TRUE(channel_->SetSend(true)); |
| |
| int64 timestamp = time(NULL) * talk_base::kNumNanosecsPerSec; |
| SendI420ScreencastFrameWithTimestamp( |
| kVP8Codec.width, kVP8Codec.height, timestamp); |
| EXPECT_EQ(talk_base::UnixTimestampNanosecsToNtpMillisecs(timestamp), |
| vie_.GetCaptureLastTimestamp(capture_id)); |
| |
| SendI420ScreencastFrameWithTimestamp(kVP8Codec.width, kVP8Codec.height, 0); |
| EXPECT_EQ(0, vie_.GetCaptureLastTimestamp(capture_id)); |
| } |
| #endif |