Wire up CPU adaptation in WebRtcVideoEngine2.

Includes clean-up work to be able to use the webrtc::Call::Config that's
set up. This introduced a CallFactory to spawn a FakeCall with the
config used and allowed removal of FakeWebRtcVideoChannel2.

BUG=1788
R=mflodman@webrtc.org, pthatcher@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/24779004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@7370 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
pbos@webrtc.org 2014-10-03 11:25:45 +00:00
parent 31b75eae05
commit 42684be21b
7 changed files with 259 additions and 237 deletions

View File

@ -261,6 +261,13 @@ UnsignalledSsrcHandler::Action DefaultUnsignalledSsrcHandler::OnUnsignalledSsrc(
return kDeliverPacket; return kDeliverPacket;
} }
WebRtcCallFactory::~WebRtcCallFactory() {
}
webrtc::Call* WebRtcCallFactory::CreateCall(
const webrtc::Call::Config& config) {
return webrtc::Call::Create(config);
}
VideoRenderer* DefaultUnsignalledSsrcHandler::GetDefaultRenderer() const { VideoRenderer* DefaultUnsignalledSsrcHandler::GetDefaultRenderer() const {
return default_renderer_; return default_renderer_;
} }
@ -284,7 +291,7 @@ WebRtcVideoEngine2::WebRtcVideoEngine2()
FOURCC_ANY), FOURCC_ANY),
initialized_(false), initialized_(false),
cpu_monitor_(new rtc::CpuMonitor(NULL)), cpu_monitor_(new rtc::CpuMonitor(NULL)),
channel_factory_(NULL), call_factory_(&default_call_factory_),
external_decoder_factory_(NULL), external_decoder_factory_(NULL),
external_encoder_factory_(NULL) { external_encoder_factory_(NULL) {
LOG(LS_INFO) << "WebRtcVideoEngine2::WebRtcVideoEngine2()"; LOG(LS_INFO) << "WebRtcVideoEngine2::WebRtcVideoEngine2()";
@ -296,11 +303,6 @@ WebRtcVideoEngine2::WebRtcVideoEngine2()
kRtpAbsoluteSenderTimeHeaderExtensionDefaultId)); kRtpAbsoluteSenderTimeHeaderExtensionDefaultId));
} }
void WebRtcVideoEngine2::SetChannelFactory(
WebRtcVideoChannelFactory* channel_factory) {
channel_factory_ = channel_factory;
}
WebRtcVideoEngine2::~WebRtcVideoEngine2() { WebRtcVideoEngine2::~WebRtcVideoEngine2() {
LOG(LS_INFO) << "WebRtcVideoEngine2::~WebRtcVideoEngine2"; LOG(LS_INFO) << "WebRtcVideoEngine2::~WebRtcVideoEngine2";
@ -309,6 +311,10 @@ WebRtcVideoEngine2::~WebRtcVideoEngine2() {
} }
} }
void WebRtcVideoEngine2::SetCallFactory(WebRtcCallFactory* call_factory) {
call_factory_ = call_factory;
}
bool WebRtcVideoEngine2::Init(rtc::Thread* worker_thread) { bool WebRtcVideoEngine2::Init(rtc::Thread* worker_thread) {
LOG(LS_INFO) << "WebRtcVideoEngine2::Init"; LOG(LS_INFO) << "WebRtcVideoEngine2::Init";
worker_thread_ = worker_thread; worker_thread_ = worker_thread;
@ -363,11 +369,8 @@ WebRtcVideoChannel2* WebRtcVideoEngine2::CreateChannel(
LOG(LS_INFO) << "CreateChannel: " LOG(LS_INFO) << "CreateChannel: "
<< (voice_channel != NULL ? "With" : "Without") << (voice_channel != NULL ? "With" : "Without")
<< " voice channel."; << " voice channel.";
WebRtcVideoChannel2* channel = WebRtcVideoChannel2* channel = new WebRtcVideoChannel2(
channel_factory_ != NULL call_factory_, voice_channel, GetVideoEncoderFactory());
? channel_factory_->Create(this, voice_channel)
: new WebRtcVideoChannel2(
this, voice_channel, GetVideoEncoderFactory());
if (!channel->Init()) { if (!channel->Init()) {
delete channel; delete channel;
return NULL; return NULL;
@ -668,39 +671,28 @@ class WebRtcVideoRenderFrame : public VideoFrame {
}; };
WebRtcVideoChannel2::WebRtcVideoChannel2( WebRtcVideoChannel2::WebRtcVideoChannel2(
WebRtcVideoEngine2* engine, WebRtcCallFactory* call_factory,
VoiceMediaChannel* voice_channel, VoiceMediaChannel* voice_channel,
WebRtcVideoEncoderFactory2* encoder_factory) WebRtcVideoEncoderFactory2* encoder_factory)
: unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_), : unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_),
encoder_factory_(encoder_factory) { encoder_factory_(encoder_factory) {
// TODO(pbos): Connect the video and audio with |voice_channel|. // TODO(pbos): Connect the video and audio with |voice_channel|.
webrtc::Call::Config config(this); webrtc::Call::Config config(this);
Construct(webrtc::Call::Create(config), engine); config.overuse_callback = this;
} call_.reset(call_factory->CreateCall(config));
WebRtcVideoChannel2::WebRtcVideoChannel2(
webrtc::Call* call,
WebRtcVideoEngine2* engine,
WebRtcVideoEncoderFactory2* encoder_factory)
: unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_),
encoder_factory_(encoder_factory) {
Construct(call, engine);
}
void WebRtcVideoChannel2::Construct(webrtc::Call* call,
WebRtcVideoEngine2* engine) {
rtcp_receiver_report_ssrc_ = kDefaultRtcpReceiverReportSsrc; rtcp_receiver_report_ssrc_ = kDefaultRtcpReceiverReportSsrc;
sending_ = false; sending_ = false;
call_.reset(call);
default_send_ssrc_ = 0; default_send_ssrc_ = 0;
SetDefaultOptions(); SetDefaultOptions();
} }
void WebRtcVideoChannel2::SetDefaultOptions() { void WebRtcVideoChannel2::SetDefaultOptions() {
options_.video_noise_reduction.Set(true); options_.cpu_overuse_detection.Set(false);
options_.use_payload_padding.Set(false);
options_.suspend_below_min_bitrate.Set(false); options_.suspend_below_min_bitrate.Set(false);
options_.use_payload_padding.Set(false);
options_.video_noise_reduction.Set(true);
} }
WebRtcVideoChannel2::~WebRtcVideoChannel2() { WebRtcVideoChannel2::~WebRtcVideoChannel2() {
@ -1265,6 +1257,17 @@ void WebRtcVideoChannel2::OnMessage(rtc::Message* msg) {
// Ignored. // Ignored.
} }
void WebRtcVideoChannel2::OnLoadUpdate(Load load) {
for (std::map<uint32, WebRtcVideoSendStream*>::iterator it =
send_streams_.begin();
it != send_streams_.end();
++it) {
it->second->OnCpuResolutionRequest(load == kOveruse
? CoordinatedVideoAdapter::DOWNGRADE
: CoordinatedVideoAdapter::UPGRADE);
}
}
bool WebRtcVideoChannel2::SendRtp(const uint8_t* data, size_t len) { bool WebRtcVideoChannel2::SendRtp(const uint8_t* data, size_t len) {
rtc::Buffer packet(data, len, kMaxRtpPacketLen); rtc::Buffer packet(data, len, kMaxRtpPacketLen);
return MediaChannel::SendPacket(&packet); return MediaChannel::SendPacket(&packet);
@ -1678,6 +1681,21 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo() {
return info; return info;
} }
void WebRtcVideoChannel2::WebRtcVideoSendStream::OnCpuResolutionRequest(
CoordinatedVideoAdapter::AdaptRequest adapt_request) {
rtc::CritScope cs(&lock_);
bool adapt_cpu;
parameters_.options.cpu_overuse_detection.Get(&adapt_cpu);
if (!adapt_cpu) {
return;
}
if (capturer_ == NULL || capturer_->video_adapter() == NULL) {
return;
}
capturer_->video_adapter()->OnCpuResolutionRequest(adapt_request);
}
void WebRtcVideoChannel2::WebRtcVideoSendStream::RecreateWebRtcStream() { void WebRtcVideoChannel2::WebRtcVideoSendStream::RecreateWebRtcStream() {
if (stream_ != NULL) { if (stream_ != NULL) {
call_->DestroyVideoSendStream(stream_); call_->DestroyVideoSendStream(stream_);

View File

@ -39,6 +39,7 @@
#include "webrtc/base/cpumonitor.h" #include "webrtc/base/cpumonitor.h"
#include "webrtc/base/scoped_ptr.h" #include "webrtc/base/scoped_ptr.h"
#include "webrtc/base/thread_annotations.h" #include "webrtc/base/thread_annotations.h"
#include "webrtc/call.h"
#include "webrtc/common_video/interface/i420_video_frame.h" #include "webrtc/common_video/interface/i420_video_frame.h"
#include "webrtc/transport.h" #include "webrtc/transport.h"
#include "webrtc/video_receive_stream.h" #include "webrtc/video_receive_stream.h"
@ -46,7 +47,6 @@
#include "webrtc/video_send_stream.h" #include "webrtc/video_send_stream.h"
namespace webrtc { namespace webrtc {
class Call;
class VideoCaptureModule; class VideoCaptureModule;
class VideoDecoder; class VideoDecoder;
class VideoEncoder; class VideoEncoder;
@ -79,7 +79,6 @@ class WebRtcVoiceEngine;
struct CapturedFrame; struct CapturedFrame;
struct Device; struct Device;
class WebRtcVideoEngine2;
class WebRtcVideoChannel2; class WebRtcVideoChannel2;
class WebRtcVideoRenderer; class WebRtcVideoRenderer;
@ -129,6 +128,14 @@ class WebRtcVideoEncoderFactory2 {
virtual bool SupportsCodec(const cricket::VideoCodec& codec); virtual bool SupportsCodec(const cricket::VideoCodec& codec);
}; };
// CallFactory, overridden for testing to verify that webrtc::Call is configured
// properly.
class WebRtcCallFactory {
public:
virtual ~WebRtcCallFactory();
virtual webrtc::Call* CreateCall(const webrtc::Call::Config& config);
};
// WebRtcVideoEngine2 is used for the new native WebRTC Video API (webrtc:1667). // WebRtcVideoEngine2 is used for the new native WebRTC Video API (webrtc:1667).
class WebRtcVideoEngine2 : public sigslot::has_slots<>, class WebRtcVideoEngine2 : public sigslot::has_slots<>,
public WebRtcVideoEncoderFactory::Observer { public WebRtcVideoEncoderFactory::Observer {
@ -137,8 +144,8 @@ class WebRtcVideoEngine2 : public sigslot::has_slots<>,
WebRtcVideoEngine2(); WebRtcVideoEngine2();
virtual ~WebRtcVideoEngine2(); virtual ~WebRtcVideoEngine2();
// Use a custom WebRtcVideoChannelFactory (for testing purposes). // Used for testing to be able to check and use the webrtc::Call config.
void SetChannelFactory(WebRtcVideoChannelFactory* channel_factory); void SetCallFactory(WebRtcCallFactory* call_factory);
// Basic video engine implementation. // Basic video engine implementation.
bool Init(rtc::Thread* worker_thread); bool Init(rtc::Thread* worker_thread);
@ -195,30 +202,24 @@ class WebRtcVideoEngine2 : public sigslot::has_slots<>,
bool initialized_; bool initialized_;
// Critical section to protect the media processor register/unregister
// while processing a frame
rtc::CriticalSection signal_media_critical_;
rtc::scoped_ptr<rtc::CpuMonitor> cpu_monitor_; rtc::scoped_ptr<rtc::CpuMonitor> cpu_monitor_;
WebRtcVideoChannelFactory* channel_factory_;
WebRtcVideoEncoderFactory2 default_video_encoder_factory_; WebRtcVideoEncoderFactory2 default_video_encoder_factory_;
WebRtcCallFactory default_call_factory_;
WebRtcCallFactory* call_factory_;
WebRtcVideoDecoderFactory* external_decoder_factory_; WebRtcVideoDecoderFactory* external_decoder_factory_;
WebRtcVideoEncoderFactory* external_encoder_factory_; WebRtcVideoEncoderFactory* external_encoder_factory_;
}; };
class WebRtcVideoChannel2 : public rtc::MessageHandler, class WebRtcVideoChannel2 : public rtc::MessageHandler,
public VideoMediaChannel, public VideoMediaChannel,
public webrtc::newapi::Transport { public webrtc::newapi::Transport,
public webrtc::LoadObserver {
public: public:
WebRtcVideoChannel2(WebRtcVideoEngine2* engine, WebRtcVideoChannel2(WebRtcCallFactory* call_factory,
VoiceMediaChannel* voice_channel, VoiceMediaChannel* voice_channel,
WebRtcVideoEncoderFactory2* encoder_factory); WebRtcVideoEncoderFactory2* encoder_factory);
// For testing purposes insert a pre-constructed call to verify that
// WebRtcVideoChannel2 calls the correct corresponding methods.
WebRtcVideoChannel2(webrtc::Call* call,
WebRtcVideoEngine2* engine,
WebRtcVideoEncoderFactory2* encoder_factory);
~WebRtcVideoChannel2(); ~WebRtcVideoChannel2();
bool Init(); bool Init();
@ -269,6 +270,8 @@ class WebRtcVideoChannel2 : public rtc::MessageHandler,
virtual void OnMessage(rtc::Message* msg) OVERRIDE; virtual void OnMessage(rtc::Message* msg) OVERRIDE;
virtual void OnLoadUpdate(Load load) OVERRIDE;
// Implemented for VideoMediaChannelTest. // Implemented for VideoMediaChannelTest.
bool sending() const { return sending_; } bool sending() const { return sending_; }
uint32 GetDefaultSendChannelSsrc() { return default_send_ssrc_; } uint32 GetDefaultSendChannelSsrc() { return default_send_ssrc_; }
@ -315,6 +318,9 @@ class WebRtcVideoChannel2 : public rtc::MessageHandler,
VideoSenderInfo GetVideoSenderInfo(); VideoSenderInfo GetVideoSenderInfo();
void OnCpuResolutionRequest(
CoordinatedVideoAdapter::AdaptRequest adapt_request);
private: private:
// Parameters needed to reconstruct the underlying stream. // Parameters needed to reconstruct the underlying stream.
// webrtc::VideoSendStream doesn't support setting a lot of options on the // webrtc::VideoSendStream doesn't support setting a lot of options on the
@ -416,6 +422,8 @@ class WebRtcVideoChannel2 : public rtc::MessageHandler,
uint32_t rtcp_receiver_report_ssrc_; uint32_t rtcp_receiver_report_ssrc_;
bool sending_; bool sending_;
rtc::scoped_ptr<webrtc::Call> call_; rtc::scoped_ptr<webrtc::Call> call_;
WebRtcCallFactory* call_factory_;
uint32_t default_send_ssrc_; uint32_t default_send_ssrc_;
DefaultUnsignalledSsrcHandler default_unsignalled_ssrc_handler_; DefaultUnsignalledSsrcHandler default_unsignalled_ssrc_handler_;

View File

@ -35,6 +35,7 @@
#include "talk/media/webrtc/webrtcvideoengine2_unittest.h" #include "talk/media/webrtc/webrtcvideoengine2_unittest.h"
#include "webrtc/base/gunit.h" #include "webrtc/base/gunit.h"
#include "webrtc/base/stringutils.h" #include "webrtc/base/stringutils.h"
#include "webrtc/video_encoder.h"
namespace { namespace {
static const cricket::VideoCodec kVp8Codec720p(100, "VP8", 1280, 720, 30, 0); static const cricket::VideoCodec kVp8Codec720p(100, "VP8", 1280, 720, 30, 0);
@ -69,7 +70,10 @@ namespace cricket {
FakeVideoSendStream::FakeVideoSendStream( FakeVideoSendStream::FakeVideoSendStream(
const webrtc::VideoSendStream::Config& config, const webrtc::VideoSendStream::Config& config,
const webrtc::VideoEncoderConfig& encoder_config) const webrtc::VideoEncoderConfig& encoder_config)
: sending_(false), config_(config), codec_settings_set_(false) { : sending_(false),
config_(config),
codec_settings_set_(false),
num_swapped_frames_(0) {
assert(config.encoder_settings.encoder != NULL); assert(config.encoder_settings.encoder != NULL);
ReconfigureVideoEncoder(encoder_config); ReconfigureVideoEncoder(encoder_config);
} }
@ -96,6 +100,22 @@ bool FakeVideoSendStream::GetVp8Settings(
return true; return true;
} }
int FakeVideoSendStream::GetNumberOfSwappedFrames() const {
return num_swapped_frames_;
}
int FakeVideoSendStream::GetLastWidth() const {
return last_frame_.width();
}
int FakeVideoSendStream::GetLastHeight() const {
return last_frame_.height();
}
void FakeVideoSendStream::SwapFrame(webrtc::I420VideoFrame* frame) {
++num_swapped_frames_;
last_frame_.SwapFrame(frame);
}
webrtc::VideoSendStream::Stats FakeVideoSendStream::GetStats() const { webrtc::VideoSendStream::Stats FakeVideoSendStream::GetStats() const {
return webrtc::VideoSendStream::Stats(); return webrtc::VideoSendStream::Stats();
} }
@ -113,8 +133,7 @@ bool FakeVideoSendStream::ReconfigureVideoEncoder(
} }
webrtc::VideoSendStreamInput* FakeVideoSendStream::Input() { webrtc::VideoSendStreamInput* FakeVideoSendStream::Input() {
// TODO(pbos): Fix. return this;
return NULL;
} }
void FakeVideoSendStream::Start() { void FakeVideoSendStream::Start() {
@ -153,7 +172,8 @@ void FakeVideoReceiveStream::Stop() {
void FakeVideoReceiveStream::GetCurrentReceiveCodec(webrtc::VideoCodec* codec) { void FakeVideoReceiveStream::GetCurrentReceiveCodec(webrtc::VideoCodec* codec) {
} }
FakeCall::FakeCall() : network_state_(kNetworkUp) { FakeCall::FakeCall(const webrtc::Call::Config& config)
: config_(config), network_state_(kNetworkUp) {
SetVideoCodecs(GetDefaultVideoCodecs()); SetVideoCodecs(GetDefaultVideoCodecs());
} }
@ -166,6 +186,10 @@ void FakeCall::SetVideoCodecs(const std::vector<webrtc::VideoCodec> codecs) {
codecs_ = codecs; codecs_ = codecs;
} }
webrtc::Call::Config FakeCall::GetConfig() const {
return config_;
}
std::vector<FakeVideoSendStream*> FakeCall::GetVideoSendStreams() { std::vector<FakeVideoSendStream*> FakeCall::GetVideoSendStreams() {
return video_send_streams_; return video_send_streams_;
} }
@ -190,8 +214,8 @@ webrtc::VideoCodec FakeCall::GetEmptyVideoCodec() {
webrtc::VideoCodec FakeCall::GetVideoCodecVp8() { webrtc::VideoCodec FakeCall::GetVideoCodecVp8() {
webrtc::VideoCodec vp8_codec = GetEmptyVideoCodec(); webrtc::VideoCodec vp8_codec = GetEmptyVideoCodec();
vp8_codec.codecType = webrtc::kVideoCodecVP8; vp8_codec.codecType = webrtc::kVideoCodecVP8;
rtc::strcpyn(vp8_codec.plName, ARRAY_SIZE(vp8_codec.plName), rtc::strcpyn(
kVp8Codec.name.c_str()); vp8_codec.plName, ARRAY_SIZE(vp8_codec.plName), kVp8Codec.name.c_str());
vp8_codec.plType = kVp8Codec.id; vp8_codec.plType = kVp8Codec.id;
return vp8_codec; return vp8_codec;
@ -201,8 +225,8 @@ webrtc::VideoCodec FakeCall::GetVideoCodecVp9() {
webrtc::VideoCodec vp9_codec = GetEmptyVideoCodec(); webrtc::VideoCodec vp9_codec = GetEmptyVideoCodec();
// TODO(pbos): Add a correct codecType when webrtc has one. // TODO(pbos): Add a correct codecType when webrtc has one.
vp9_codec.codecType = webrtc::kVideoCodecVP8; vp9_codec.codecType = webrtc::kVideoCodecVP8;
rtc::strcpyn(vp9_codec.plName, ARRAY_SIZE(vp9_codec.plName), rtc::strcpyn(
kVp9Codec.name.c_str()); vp9_codec.plName, ARRAY_SIZE(vp9_codec.plName), kVp9Codec.name.c_str());
vp9_codec.plType = kVp9Codec.id; vp9_codec.plType = kVp9Codec.id;
return vp9_codec; return vp9_codec;
@ -279,44 +303,9 @@ void FakeCall::SignalNetworkState(webrtc::Call::NetworkState state) {
network_state_ = state; network_state_ = state;
} }
FakeWebRtcVideoChannel2::FakeWebRtcVideoChannel2(
FakeCall* call,
WebRtcVideoEngine2* engine,
VoiceMediaChannel* voice_channel)
: WebRtcVideoChannel2(call, engine, engine->GetVideoEncoderFactory()),
fake_call_(call),
voice_channel_(voice_channel) {
}
FakeWebRtcVideoChannel2::~FakeWebRtcVideoChannel2() {
}
VoiceMediaChannel* FakeWebRtcVideoChannel2::GetVoiceChannel() {
return voice_channel_;
}
FakeCall* FakeWebRtcVideoChannel2::GetFakeCall() {
return fake_call_;
}
FakeWebRtcVideoChannel2* FakeWebRtcVideoMediaChannelFactory::GetFakeChannel(
VideoMediaChannel* channel) {
return channel_map_[channel];
}
WebRtcVideoChannel2* FakeWebRtcVideoMediaChannelFactory::Create(
WebRtcVideoEngine2* engine,
VoiceMediaChannel* voice_channel) {
FakeWebRtcVideoChannel2* channel =
new FakeWebRtcVideoChannel2(new FakeCall(), engine, voice_channel);
channel_map_[channel] = channel;
return channel;
}
class WebRtcVideoEngine2Test : public testing::Test { class WebRtcVideoEngine2Test : public testing::Test {
public: public:
WebRtcVideoEngine2Test() { WebRtcVideoEngine2Test() {
engine_.SetChannelFactory(&factory_);
std::vector<VideoCodec> engine_codecs = engine_.codecs(); std::vector<VideoCodec> engine_codecs = engine_.codecs();
assert(!engine_codecs.empty()); assert(!engine_codecs.empty());
bool codec_set = false; bool codec_set = false;
@ -337,7 +326,6 @@ class WebRtcVideoEngine2Test : public testing::Test {
} }
protected: protected:
FakeWebRtcVideoMediaChannelFactory factory_;
WebRtcVideoEngine2 engine_; WebRtcVideoEngine2 engine_;
VideoCodec default_codec_; VideoCodec default_codec_;
VideoCodec default_red_codec_; VideoCodec default_red_codec_;
@ -345,27 +333,9 @@ class WebRtcVideoEngine2Test : public testing::Test {
VideoCodec default_rtx_codec_; VideoCodec default_rtx_codec_;
}; };
TEST_F(WebRtcVideoEngine2Test, CreateChannel) { // TODO(pbos): Add test that verifies that sync is configured properly.
rtc::scoped_ptr<VideoMediaChannel> channel(engine_.CreateChannel(NULL)); TEST_F(WebRtcVideoEngine2Test, DISABLED_CreateChannelWithVoiceEngine) {
ASSERT_TRUE(channel.get() != NULL) << "Could not create channel."; FAIL() << "Not implemented."; // TODO(pbos): Implement.
EXPECT_TRUE(factory_.GetFakeChannel(channel.get()) != NULL)
<< "Channel not created through factory.";
}
TEST_F(WebRtcVideoEngine2Test, CreateChannelWithVoiceEngine) {
VoiceMediaChannel* voice_channel = reinterpret_cast<VoiceMediaChannel*>(0x42);
rtc::scoped_ptr<VideoMediaChannel> channel(
engine_.CreateChannel(voice_channel));
ASSERT_TRUE(channel.get() != NULL) << "Could not create channel.";
FakeWebRtcVideoChannel2* fake_channel =
factory_.GetFakeChannel(channel.get());
ASSERT_TRUE(fake_channel != NULL) << "Channel not created through factory.";
EXPECT_TRUE(fake_channel->GetVoiceChannel() != NULL)
<< "VoiceChannel not set.";
EXPECT_EQ(voice_channel, fake_channel->GetVoiceChannel())
<< "Different VoiceChannel set than the provided one.";
} }
TEST_F(WebRtcVideoEngine2Test, FindCodec) { TEST_F(WebRtcVideoEngine2Test, FindCodec) {
@ -483,15 +453,16 @@ WEBRTC_ENGINE_BASE_TEST(ConstrainNewCodec2);
class WebRtcVideoChannel2BaseTest class WebRtcVideoChannel2BaseTest
: public VideoMediaChannelTest<WebRtcVideoEngine2, WebRtcVideoChannel2> { : public VideoMediaChannelTest<WebRtcVideoEngine2, WebRtcVideoChannel2> {
protected: protected:
virtual cricket::VideoCodec DefaultCodec() OVERRIDE { return kVp8Codec; }
typedef VideoMediaChannelTest<WebRtcVideoEngine2, WebRtcVideoChannel2> Base; typedef VideoMediaChannelTest<WebRtcVideoEngine2, WebRtcVideoChannel2> Base;
virtual cricket::VideoCodec DefaultCodec() OVERRIDE { return kVp8Codec; }
}; };
#define WEBRTC_BASE_TEST(test) \ #define WEBRTC_BASE_TEST(test) \
TEST_F(WebRtcVideoChannel2BaseTest, test) { Base::test(); } TEST_F(WebRtcVideoChannel2BaseTest, test) { Base::test(); }
#define WEBRTC_DISABLED_BASE_TEST(test) \ #define WEBRTC_DISABLED_BASE_TEST(test) \
TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_ ## test) { Base::test(); } TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_##test) { Base::test(); }
// TODO(pbos): Fix WebRtcVideoEngine2BaseTest, where we want CheckCoInitialize. // TODO(pbos): Fix WebRtcVideoEngine2BaseTest, where we want CheckCoInitialize.
#if 0 #if 0
@ -604,46 +575,52 @@ TEST_F(WebRtcVideoChannel2BaseTest, DISABLED_SendVp8HdAndReceiveAdaptedVp8Vga) {
EXPECT_FRAME_WAIT(1, codec.width, codec.height, kTimeout); EXPECT_FRAME_WAIT(1, codec.width, codec.height, kTimeout);
} }
class WebRtcVideoChannel2Test : public WebRtcVideoEngine2Test { class WebRtcVideoChannel2Test : public WebRtcVideoEngine2Test,
public WebRtcCallFactory {
public: public:
WebRtcVideoChannel2Test() : fake_call_(NULL) {}
virtual void SetUp() OVERRIDE { virtual void SetUp() OVERRIDE {
engine_.SetCallFactory(this);
channel_.reset(engine_.CreateChannel(NULL)); channel_.reset(engine_.CreateChannel(NULL));
fake_channel_ = factory_.GetFakeChannel(channel_.get()); ASSERT_TRUE(fake_call_ != NULL) << "Call not created through factory.";
last_ssrc_ = 123; last_ssrc_ = 123;
ASSERT_TRUE(fake_channel_ != NULL) ASSERT_TRUE(channel_->SetSendCodecs(engine_.codecs()));
<< "Channel not created through factory.";
EXPECT_TRUE(fake_channel_->SetSendCodecs(engine_.codecs()));
} }
protected: protected:
virtual webrtc::Call* CreateCall(
const webrtc::Call::Config& config) OVERRIDE {
assert(fake_call_ == NULL);
fake_call_ = new FakeCall(config);
return fake_call_;
}
FakeVideoSendStream* AddSendStream() { FakeVideoSendStream* AddSendStream() {
return AddSendStream(StreamParams::CreateLegacy(last_ssrc_++)); return AddSendStream(StreamParams::CreateLegacy(++last_ssrc_));
} }
FakeVideoSendStream* AddSendStream(const StreamParams& sp) { FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
size_t num_streams = size_t num_streams = fake_call_->GetVideoSendStreams().size();
fake_channel_->GetFakeCall()->GetVideoSendStreams().size();
EXPECT_TRUE(channel_->AddSendStream(sp)); EXPECT_TRUE(channel_->AddSendStream(sp));
std::vector<FakeVideoSendStream*> streams = std::vector<FakeVideoSendStream*> streams =
fake_channel_->GetFakeCall()->GetVideoSendStreams(); fake_call_->GetVideoSendStreams();
EXPECT_EQ(num_streams + 1, streams.size()); EXPECT_EQ(num_streams + 1, streams.size());
return streams[streams.size() - 1]; return streams[streams.size() - 1];
} }
std::vector<FakeVideoSendStream*> GetFakeSendStreams() { std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
return fake_channel_->GetFakeCall()->GetVideoSendStreams(); return fake_call_->GetVideoSendStreams();
} }
FakeVideoReceiveStream* AddRecvStream() { FakeVideoReceiveStream* AddRecvStream() {
return AddRecvStream(StreamParams::CreateLegacy(last_ssrc_++)); return AddRecvStream(StreamParams::CreateLegacy(++last_ssrc_));
} }
FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) { FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
size_t num_streams = size_t num_streams = fake_call_->GetVideoReceiveStreams().size();
fake_channel_->GetFakeCall()->GetVideoReceiveStreams().size();
EXPECT_TRUE(channel_->AddRecvStream(sp)); EXPECT_TRUE(channel_->AddRecvStream(sp));
std::vector<FakeVideoReceiveStream*> streams = std::vector<FakeVideoReceiveStream*> streams =
fake_channel_->GetFakeCall()->GetVideoReceiveStreams(); fake_call_->GetVideoReceiveStreams();
EXPECT_EQ(num_streams + 1, streams.size()); EXPECT_EQ(num_streams + 1, streams.size());
return streams[streams.size() - 1]; return streams[streams.size() - 1];
} }
@ -671,7 +648,7 @@ class WebRtcVideoChannel2Test : public WebRtcVideoEngine2Test {
void TestSetSendRtpHeaderExtensions(const std::string& cricket_ext, void TestSetSendRtpHeaderExtensions(const std::string& cricket_ext,
const std::string& webrtc_ext) { const std::string& webrtc_ext) {
FakeCall* call = fake_channel_->GetFakeCall(); FakeCall* call = fake_call_;
// Enable extension. // Enable extension.
const int id = 1; const int id = 1;
std::vector<cricket::RtpHeaderExtension> extensions; std::vector<cricket::RtpHeaderExtension> extensions;
@ -711,7 +688,7 @@ class WebRtcVideoChannel2Test : public WebRtcVideoEngine2Test {
void TestSetRecvRtpHeaderExtensions(const std::string& cricket_ext, void TestSetRecvRtpHeaderExtensions(const std::string& cricket_ext,
const std::string& webrtc_ext) { const std::string& webrtc_ext) {
FakeCall* call = fake_channel_->GetFakeCall(); FakeCall* call = fake_call_;
// Enable extension. // Enable extension.
const int id = 1; const int id = 1;
std::vector<cricket::RtpHeaderExtension> extensions; std::vector<cricket::RtpHeaderExtension> extensions;
@ -750,8 +727,10 @@ class WebRtcVideoChannel2Test : public WebRtcVideoEngine2Test {
EXPECT_EQ(webrtc_ext, recv_stream->GetConfig().rtp.extensions[0].name); EXPECT_EQ(webrtc_ext, recv_stream->GetConfig().rtp.extensions[0].name);
} }
void TestCpuAdaptation(bool enable_overuse);
FakeCall* fake_call_;
rtc::scoped_ptr<VideoMediaChannel> channel_; rtc::scoped_ptr<VideoMediaChannel> channel_;
FakeWebRtcVideoChannel2* fake_channel_;
uint32 last_ssrc_; uint32 last_ssrc_;
}; };
@ -893,10 +872,10 @@ TEST_F(WebRtcVideoChannel2Test,
const int kTOffsetId = 2; const int kTOffsetId = 2;
std::vector<cricket::RtpHeaderExtension> extensions; std::vector<cricket::RtpHeaderExtension> extensions;
extensions.push_back(cricket::RtpHeaderExtension( extensions.push_back(
kUnsupportedExtensionName, kUnsupportedId)); cricket::RtpHeaderExtension(kUnsupportedExtensionName, kUnsupportedId));
extensions.push_back(cricket::RtpHeaderExtension( extensions.push_back(
webrtc::RtpExtension::kTOffset, kTOffsetId)); cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, kTOffsetId));
EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions)); EXPECT_TRUE(channel_->SetSendRtpHeaderExtensions(extensions));
FakeVideoSendStream* send_stream = FakeVideoSendStream* send_stream =
AddSendStream(cricket::StreamParams::CreateLegacy(123)); AddSendStream(cricket::StreamParams::CreateLegacy(123));
@ -914,10 +893,10 @@ TEST_F(WebRtcVideoChannel2Test,
const int kTOffsetId = 2; const int kTOffsetId = 2;
std::vector<cricket::RtpHeaderExtension> extensions; std::vector<cricket::RtpHeaderExtension> extensions;
extensions.push_back(cricket::RtpHeaderExtension( extensions.push_back(
kUnsupportedExtensionName, kUnsupportedId)); cricket::RtpHeaderExtension(kUnsupportedExtensionName, kUnsupportedId));
extensions.push_back(cricket::RtpHeaderExtension( extensions.push_back(
webrtc::RtpExtension::kTOffset, kTOffsetId)); cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, kTOffsetId));
EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions)); EXPECT_TRUE(channel_->SetRecvRtpHeaderExtensions(extensions));
FakeVideoReceiveStream* recv_stream = FakeVideoReceiveStream* recv_stream =
AddRecvStream(cricket::StreamParams::CreateLegacy(123)); AddRecvStream(cricket::StreamParams::CreateLegacy(123));
@ -929,8 +908,7 @@ TEST_F(WebRtcVideoChannel2Test,
recv_stream->GetConfig().rtp.extensions[0].name.c_str()); recv_stream->GetConfig().rtp.extensions[0].name.c_str());
} }
TEST_F(WebRtcVideoChannel2Test, TEST_F(WebRtcVideoChannel2Test, SetSendRtpHeaderExtensionsRejectsIncorrectIds) {
SetSendRtpHeaderExtensionsRejectsIncorrectIds) {
const size_t kNumIncorrectIds = 4; const size_t kNumIncorrectIds = 4;
const int kIncorrectIds[kNumIncorrectIds] = {-2, -1, 15, 16}; const int kIncorrectIds[kNumIncorrectIds] = {-2, -1, 15, 16};
for (size_t i = 0; i < kNumIncorrectIds; ++i) { for (size_t i = 0; i < kNumIncorrectIds; ++i) {
@ -942,8 +920,7 @@ TEST_F(WebRtcVideoChannel2Test,
} }
} }
TEST_F(WebRtcVideoChannel2Test, TEST_F(WebRtcVideoChannel2Test, SetRecvRtpHeaderExtensionsRejectsIncorrectIds) {
SetRecvRtpHeaderExtensionsRejectsIncorrectIds) {
const size_t kNumIncorrectIds = 4; const size_t kNumIncorrectIds = 4;
const int kIncorrectIds[kNumIncorrectIds] = {-2, -1, 15, 16}; const int kIncorrectIds[kNumIncorrectIds] = {-2, -1, 15, 16};
for (size_t i = 0; i < kNumIncorrectIds; ++i) { for (size_t i = 0; i < kNumIncorrectIds; ++i) {
@ -955,38 +932,36 @@ TEST_F(WebRtcVideoChannel2Test,
} }
} }
TEST_F(WebRtcVideoChannel2Test, TEST_F(WebRtcVideoChannel2Test, SetSendRtpHeaderExtensionsRejectsDuplicateIds) {
SetSendRtpHeaderExtensionsRejectsDuplicateIds) {
const int id = 1; const int id = 1;
std::vector<cricket::RtpHeaderExtension> extensions; std::vector<cricket::RtpHeaderExtension> extensions;
extensions.push_back(cricket::RtpHeaderExtension( extensions.push_back(
webrtc::RtpExtension::kTOffset, id)); cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, id));
extensions.push_back(cricket::RtpHeaderExtension( extensions.push_back(
kRtpAbsoluteSenderTimeHeaderExtension, id)); cricket::RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, id));
EXPECT_FALSE(channel_->SetSendRtpHeaderExtensions(extensions)); EXPECT_FALSE(channel_->SetSendRtpHeaderExtensions(extensions));
// Duplicate entries are also not supported. // Duplicate entries are also not supported.
extensions.clear(); extensions.clear();
extensions.push_back(cricket::RtpHeaderExtension( extensions.push_back(
webrtc::RtpExtension::kTOffset, id)); cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, id));
extensions.push_back(extensions.back()); extensions.push_back(extensions.back());
EXPECT_FALSE(channel_->SetSendRtpHeaderExtensions(extensions)); EXPECT_FALSE(channel_->SetSendRtpHeaderExtensions(extensions));
} }
TEST_F(WebRtcVideoChannel2Test, TEST_F(WebRtcVideoChannel2Test, SetRecvRtpHeaderExtensionsRejectsDuplicateIds) {
SetRecvRtpHeaderExtensionsRejectsDuplicateIds) {
const int id = 1; const int id = 1;
std::vector<cricket::RtpHeaderExtension> extensions; std::vector<cricket::RtpHeaderExtension> extensions;
extensions.push_back(cricket::RtpHeaderExtension( extensions.push_back(
webrtc::RtpExtension::kTOffset, id)); cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, id));
extensions.push_back(cricket::RtpHeaderExtension( extensions.push_back(
kRtpAbsoluteSenderTimeHeaderExtension, id)); cricket::RtpHeaderExtension(kRtpAbsoluteSenderTimeHeaderExtension, id));
EXPECT_FALSE(channel_->SetRecvRtpHeaderExtensions(extensions)); EXPECT_FALSE(channel_->SetRecvRtpHeaderExtensions(extensions));
// Duplicate entries are also not supported. // Duplicate entries are also not supported.
extensions.clear(); extensions.clear();
extensions.push_back(cricket::RtpHeaderExtension( extensions.push_back(
webrtc::RtpExtension::kTOffset, id)); cricket::RtpHeaderExtension(webrtc::RtpExtension::kTOffset, id));
extensions.push_back(extensions.back()); extensions.push_back(extensions.back());
EXPECT_FALSE(channel_->SetRecvRtpHeaderExtensions(extensions)); EXPECT_FALSE(channel_->SetRecvRtpHeaderExtensions(extensions));
} }
@ -1005,7 +980,7 @@ TEST_F(WebRtcVideoChannel2Test, DISABLED_AdditiveVideoOptions) {
TEST_F(WebRtcVideoChannel2Test, AddRecvStreamOnlyUsesOneReceiveStream) { TEST_F(WebRtcVideoChannel2Test, AddRecvStreamOnlyUsesOneReceiveStream) {
EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1))); EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
EXPECT_EQ(1u, fake_channel_->GetFakeCall()->GetVideoReceiveStreams().size()); EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
} }
TEST_F(WebRtcVideoChannel2Test, RembIsEnabledByDefault) { TEST_F(WebRtcVideoChannel2Test, RembIsEnabledByDefault) {
@ -1022,13 +997,13 @@ TEST_F(WebRtcVideoChannel2Test, RembCanBeEnabledAndDisabled) {
codecs.push_back(kVp8Codec); codecs.push_back(kVp8Codec);
EXPECT_TRUE(codecs[0].feedback_params.params().empty()); EXPECT_TRUE(codecs[0].feedback_params.params().empty());
EXPECT_TRUE(channel_->SetRecvCodecs(codecs)); EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
stream = fake_channel_->GetFakeCall()->GetVideoReceiveStreams()[0]; stream = fake_call_->GetVideoReceiveStreams()[0];
EXPECT_FALSE(stream->GetConfig().rtp.remb); EXPECT_FALSE(stream->GetConfig().rtp.remb);
// Verify that REMB is turned on when setting default codecs since the // Verify that REMB is turned on when setting default codecs since the
// default codecs have REMB enabled. // default codecs have REMB enabled.
EXPECT_TRUE(channel_->SetRecvCodecs(engine_.codecs())); EXPECT_TRUE(channel_->SetRecvCodecs(engine_.codecs()));
stream = fake_channel_->GetFakeCall()->GetVideoReceiveStreams()[0]; stream = fake_call_->GetVideoReceiveStreams()[0];
EXPECT_TRUE(stream->GetConfig().rtp.remb); EXPECT_TRUE(stream->GetConfig().rtp.remb);
} }
@ -1135,7 +1110,7 @@ TEST_F(WebRtcVideoChannel2Test, SetOptionsWithSuspendBelowMinBitrate) {
options.suspend_below_min_bitrate.Set(false); options.suspend_below_min_bitrate.Set(false);
channel_->SetOptions(options); channel_->SetOptions(options);
stream = fake_channel_->GetFakeCall()->GetVideoSendStreams()[0]; stream = fake_call_->GetVideoSendStreams()[0];
EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate); EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
} }
@ -1161,7 +1136,7 @@ TEST_F(WebRtcVideoChannel2Test, SetOptionsWithPayloadPadding) {
options.use_payload_padding.Set(false); options.use_payload_padding.Set(false);
channel_->SetOptions(options); channel_->SetOptions(options);
stream = fake_channel_->GetFakeCall()->GetVideoSendStreams()[0]; stream = fake_call_->GetVideoSendStreams()[0];
EXPECT_FALSE(stream->GetConfig().rtp.rtx.pad_with_redundant_payloads); EXPECT_FALSE(stream->GetConfig().rtp.rtx.pad_with_redundant_payloads);
} }
@ -1185,7 +1160,7 @@ TEST_F(WebRtcVideoChannel2Test, SetOptionsWithDenoising) {
options.video_noise_reduction.Set(true); options.video_noise_reduction.Set(true);
channel_->SetOptions(options); channel_->SetOptions(options);
stream = fake_channel_->GetFakeCall()->GetVideoSendStreams()[0]; stream = fake_call_->GetVideoSendStreams()[0];
ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set."; ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
EXPECT_TRUE(vp8_settings.denoisingOn); EXPECT_TRUE(vp8_settings.denoisingOn);
} }
@ -1198,16 +1173,65 @@ TEST_F(WebRtcVideoChannel2Test, DISABLED_SendReceiveBitratesStats) {
FAIL() << "Not implemented."; // TODO(pbos): Implement. FAIL() << "Not implemented."; // TODO(pbos): Implement.
} }
TEST_F(WebRtcVideoChannel2Test, DISABLED_TestSetAdaptInputToCpuUsage) { TEST_F(WebRtcVideoChannel2Test, AdaptsOnOveruse) {
FAIL() << "Not implemented."; // TODO(pbos): Implement. TestCpuAdaptation(true);
} }
TEST_F(WebRtcVideoChannel2Test, DISABLED_TestSetCpuThreshold) { TEST_F(WebRtcVideoChannel2Test, DoesNotAdaptOnOveruseWhenDisabled) {
FAIL() << "Not implemented."; // TODO(pbos): Implement. TestCpuAdaptation(false);
} }
TEST_F(WebRtcVideoChannel2Test, DISABLED_TestSetInvalidCpuThreshold) { void WebRtcVideoChannel2Test::TestCpuAdaptation(bool enable_overuse) {
FAIL() << "Not implemented."; // TODO(pbos): Implement. cricket::VideoCodec codec(100, "VP8", 1280, 720, 30, 0);
std::vector<cricket::VideoCodec> codecs;
codecs.push_back(codec);
EXPECT_TRUE(channel_->SetSendCodecs(codecs));
if (enable_overuse) {
VideoOptions options;
options.cpu_overuse_detection.Set(true);
channel_->SetOptions(options);
}
AddSendStream();
cricket::FakeVideoCapturer capturer;
EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer));
EXPECT_EQ(cricket::CS_RUNNING,
capturer.Start(capturer.GetSupportedFormats()->front()));
EXPECT_TRUE(channel_->SetSend(true));
// Trigger overuse.
webrtc::LoadObserver* overuse_callback =
fake_call_->GetConfig().overuse_callback;
ASSERT_TRUE(overuse_callback != NULL);
overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kOveruse);
EXPECT_TRUE(capturer.CaptureFrame());
ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
if (enable_overuse) {
EXPECT_LT(send_stream->GetLastWidth(), codec.width);
EXPECT_LT(send_stream->GetLastHeight(), codec.height);
} else {
EXPECT_EQ(codec.width, send_stream->GetLastWidth());
EXPECT_EQ(codec.height, send_stream->GetLastHeight());
}
// Trigger underuse which should go back to normal resolution.
overuse_callback->OnLoadUpdate(webrtc::LoadObserver::kUnderuse);
EXPECT_TRUE(capturer.CaptureFrame());
EXPECT_EQ(2, send_stream->GetNumberOfSwappedFrames());
EXPECT_EQ(codec.width, send_stream->GetLastWidth());
EXPECT_EQ(codec.height, send_stream->GetLastHeight());
EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL));
} }
TEST_F(WebRtcVideoChannel2Test, DISABLED_WebRtcShouldLog) { TEST_F(WebRtcVideoChannel2Test, DISABLED_WebRtcShouldLog) {
@ -1295,7 +1319,7 @@ TEST_F(WebRtcVideoChannel2Test, SetSendCodecsWithoutFecDisablesFec) {
codecs.pop_back(); codecs.pop_back();
ASSERT_TRUE(channel_->SetSendCodecs(codecs)); ASSERT_TRUE(channel_->SetSendCodecs(codecs));
stream = fake_channel_->GetFakeCall()->GetVideoSendStreams()[0]; stream = fake_call_->GetVideoSendStreams()[0];
ASSERT_TRUE(stream != NULL); ASSERT_TRUE(stream != NULL);
config = stream->GetConfig(); config = stream->GetConfig();
EXPECT_EQ(-1, config.rtp.fec.ulpfec_payload_type) EXPECT_EQ(-1, config.rtp.fec.ulpfec_payload_type)
@ -1307,16 +1331,14 @@ TEST_F(WebRtcVideoChannel2Test, SetSendCodecsChangesExistingStreams) {
codecs.push_back(kVp8Codec720p); codecs.push_back(kVp8Codec720p);
ASSERT_TRUE(channel_->SetSendCodecs(codecs)); ASSERT_TRUE(channel_->SetSendCodecs(codecs));
std::vector<webrtc::VideoStream> streams = std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
AddSendStream()->GetVideoStreams();
EXPECT_EQ(kVp8Codec720p.width, streams[0].width); EXPECT_EQ(kVp8Codec720p.width, streams[0].width);
EXPECT_EQ(kVp8Codec720p.height, streams[0].height); EXPECT_EQ(kVp8Codec720p.height, streams[0].height);
codecs.clear(); codecs.clear();
codecs.push_back(kVp8Codec360p); codecs.push_back(kVp8Codec360p);
ASSERT_TRUE(channel_->SetSendCodecs(codecs)); ASSERT_TRUE(channel_->SetSendCodecs(codecs));
streams = fake_channel_->GetFakeCall()->GetVideoSendStreams()[0] streams = fake_call_->GetVideoSendStreams()[0]->GetVideoStreams();
->GetVideoStreams();
EXPECT_EQ(kVp8Codec360p.width, streams[0].width); EXPECT_EQ(kVp8Codec360p.width, streams[0].width);
EXPECT_EQ(kVp8Codec360p.height, streams[0].height); EXPECT_EQ(kVp8Codec360p.height, streams[0].height);
} }
@ -1367,8 +1389,8 @@ TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectBadDimensions) {
TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectBadPayloadTypes) { TEST_F(WebRtcVideoChannel2Test, SetSendCodecsRejectBadPayloadTypes) {
// TODO(pbos): Should we only allow the dynamic range? // TODO(pbos): Should we only allow the dynamic range?
static const size_t kNumIncorrectPayloads = 4; static const size_t kNumIncorrectPayloads = 4;
static const int kIncorrectPayloads[kNumIncorrectPayloads] = {-2, -1, 128, static const int kIncorrectPayloads[kNumIncorrectPayloads] = {
129}; -2, -1, 128, 129};
std::vector<cricket::VideoCodec> codecs; std::vector<cricket::VideoCodec> codecs;
codecs.push_back(kVp8Codec); codecs.push_back(kVp8Codec);
for (size_t i = 0; i < kNumIncorrectPayloads; ++i) { for (size_t i = 0; i < kNumIncorrectPayloads; ++i) {
@ -1478,7 +1500,7 @@ TEST_F(WebRtcVideoChannel2Test, SetRecvCodecsWithoutFecDisablesFec) {
codecs.pop_back(); codecs.pop_back();
ASSERT_TRUE(channel_->SetRecvCodecs(codecs)); ASSERT_TRUE(channel_->SetRecvCodecs(codecs));
stream = fake_channel_->GetFakeCall()->GetVideoReceiveStreams()[0]; stream = fake_call_->GetVideoReceiveStreams()[0];
ASSERT_TRUE(stream != NULL); ASSERT_TRUE(stream != NULL);
config = stream->GetConfig(); config = stream->GetConfig();
EXPECT_EQ(-1, config.rtp.fec.ulpfec_payload_type) EXPECT_EQ(-1, config.rtp.fec.ulpfec_payload_type)
@ -1621,16 +1643,13 @@ TEST_F(WebRtcVideoChannel2Test, DISABLED_UpdateEncoderCodecsAfterSetFactory) {
} }
TEST_F(WebRtcVideoChannel2Test, OnReadyToSendSignalsNetworkState) { TEST_F(WebRtcVideoChannel2Test, OnReadyToSendSignalsNetworkState) {
EXPECT_EQ(webrtc::Call::kNetworkUp, EXPECT_EQ(webrtc::Call::kNetworkUp, fake_call_->GetNetworkState());
fake_channel_->GetFakeCall()->GetNetworkState());
channel_->OnReadyToSend(false); channel_->OnReadyToSend(false);
EXPECT_EQ(webrtc::Call::kNetworkDown, EXPECT_EQ(webrtc::Call::kNetworkDown, fake_call_->GetNetworkState());
fake_channel_->GetFakeCall()->GetNetworkState());
channel_->OnReadyToSend(true); channel_->OnReadyToSend(true);
EXPECT_EQ(webrtc::Call::kNetworkUp, EXPECT_EQ(webrtc::Call::kNetworkUp, fake_call_->GetNetworkState());
fake_channel_->GetFakeCall()->GetNetworkState());
} }
TEST_F(WebRtcVideoChannel2Test, DISABLED_CaptureFrameTimestampToNtpTimestamp) { TEST_F(WebRtcVideoChannel2Test, DISABLED_CaptureFrameTimestampToNtpTimestamp) {

View File

@ -36,7 +36,8 @@
#include "webrtc/video_send_stream.h" #include "webrtc/video_send_stream.h"
namespace cricket { namespace cricket {
class FakeVideoSendStream : public webrtc::VideoSendStream { class FakeVideoSendStream : public webrtc::VideoSendStream,
public webrtc::VideoSendStreamInput {
public: public:
FakeVideoSendStream(const webrtc::VideoSendStream::Config& config, FakeVideoSendStream(const webrtc::VideoSendStream::Config& config,
const webrtc::VideoEncoderConfig& encoder_config); const webrtc::VideoEncoderConfig& encoder_config);
@ -46,7 +47,12 @@ class FakeVideoSendStream : public webrtc::VideoSendStream {
bool IsSending() const; bool IsSending() const;
bool GetVp8Settings(webrtc::VideoCodecVP8* settings) const; bool GetVp8Settings(webrtc::VideoCodecVP8* settings) const;
int GetNumberOfSwappedFrames() const;
int GetLastWidth() const;
int GetLastHeight() const;
private: private:
virtual void SwapFrame(webrtc::I420VideoFrame* frame) OVERRIDE;
virtual webrtc::VideoSendStream::Stats GetStats() const OVERRIDE; virtual webrtc::VideoSendStream::Stats GetStats() const OVERRIDE;
virtual bool ReconfigureVideoEncoder( virtual bool ReconfigureVideoEncoder(
@ -62,6 +68,8 @@ class FakeVideoSendStream : public webrtc::VideoSendStream {
webrtc::VideoEncoderConfig encoder_config_; webrtc::VideoEncoderConfig encoder_config_;
bool codec_settings_set_; bool codec_settings_set_;
webrtc::VideoCodecVP8 vp8_settings_; webrtc::VideoCodecVP8 vp8_settings_;
int num_swapped_frames_;
webrtc::I420VideoFrame last_frame_;
}; };
class FakeVideoReceiveStream : public webrtc::VideoReceiveStream { class FakeVideoReceiveStream : public webrtc::VideoReceiveStream {
@ -86,11 +94,12 @@ class FakeVideoReceiveStream : public webrtc::VideoReceiveStream {
class FakeCall : public webrtc::Call { class FakeCall : public webrtc::Call {
public: public:
FakeCall(); FakeCall(const webrtc::Call::Config& config);
~FakeCall(); ~FakeCall();
void SetVideoCodecs(const std::vector<webrtc::VideoCodec> codecs); void SetVideoCodecs(const std::vector<webrtc::VideoCodec> codecs);
webrtc::Call::Config GetConfig() const;
std::vector<FakeVideoSendStream*> GetVideoSendStreams(); std::vector<FakeVideoSendStream*> GetVideoSendStreams();
std::vector<FakeVideoReceiveStream*> GetVideoReceiveStreams(); std::vector<FakeVideoReceiveStream*> GetVideoReceiveStreams();
@ -123,39 +132,12 @@ class FakeCall : public webrtc::Call {
virtual void SignalNetworkState(webrtc::Call::NetworkState state) OVERRIDE; virtual void SignalNetworkState(webrtc::Call::NetworkState state) OVERRIDE;
const webrtc::Call::Config config_;
webrtc::Call::NetworkState network_state_; webrtc::Call::NetworkState network_state_;
std::vector<webrtc::VideoCodec> codecs_; std::vector<webrtc::VideoCodec> codecs_;
std::vector<FakeVideoSendStream*> video_send_streams_; std::vector<FakeVideoSendStream*> video_send_streams_;
std::vector<FakeVideoReceiveStream*> video_receive_streams_; std::vector<FakeVideoReceiveStream*> video_receive_streams_;
}; };
class FakeWebRtcVideoChannel2 : public WebRtcVideoChannel2 {
public:
FakeWebRtcVideoChannel2(FakeCall* call,
WebRtcVideoEngine2* engine,
VoiceMediaChannel* voice_channel);
virtual ~FakeWebRtcVideoChannel2();
VoiceMediaChannel* GetVoiceChannel();
FakeCall* GetFakeCall();
private:
FakeCall* fake_call_;
VoiceMediaChannel* voice_channel_;
};
class FakeWebRtcVideoMediaChannelFactory : public WebRtcVideoChannelFactory {
public:
FakeWebRtcVideoChannel2* GetFakeChannel(VideoMediaChannel* channel);
private:
virtual WebRtcVideoChannel2* Create(
WebRtcVideoEngine2* engine,
VoiceMediaChannel* voice_channel) OVERRIDE;
std::map<VideoMediaChannel*, FakeWebRtcVideoChannel2*> channel_map_;
};
} // namespace cricket } // namespace cricket
#endif // TALK_MEDIA_WEBRTC_WEBRTCVIDEOENGINE2_UNITTEST_H_ #endif // TALK_MEDIA_WEBRTC_WEBRTCVIDEOENGINE2_UNITTEST_H_

View File

@ -39,16 +39,16 @@ class PacketReceiver {
}; };
// Callback interface for reporting when a system overuse is detected. // Callback interface for reporting when a system overuse is detected.
// The detection is based on the jitter of incoming captured frames. class LoadObserver {
class OveruseCallback {
public: public:
// Called as soon as an overuse is detected. enum Load { kOveruse, kUnderuse };
virtual void OnOveruse() = 0;
// Called periodically when the system is not overused any longer. // Triggered when overuse is detected or when we believe the system can take
virtual void OnNormalUse() = 0; // more load.
virtual void OnLoadUpdate(Load load) = 0;
protected: protected:
virtual ~OveruseCallback() {} virtual ~LoadObserver() {}
}; };
// A Call instance can contain several send and/or receive streams. All streams // A Call instance can contain several send and/or receive streams. All streams
@ -77,7 +77,7 @@ class Call {
// Callback for overuse and normal usage based on the jitter of incoming // Callback for overuse and normal usage based on the jitter of incoming
// captured frames. 'NULL' disables the callback. // captured frames. 'NULL' disables the callback.
OveruseCallback* overuse_callback; LoadObserver* overuse_callback;
// Start bitrate used before a valid bitrate estimate is calculated. '-1' // Start bitrate used before a valid bitrate estimate is calculated. '-1'
// lets the call decide start bitrate. // lets the call decide start bitrate.

View File

@ -55,7 +55,7 @@ namespace internal {
class CpuOveruseObserverProxy : public webrtc::CpuOveruseObserver { class CpuOveruseObserverProxy : public webrtc::CpuOveruseObserver {
public: public:
explicit CpuOveruseObserverProxy(OveruseCallback* overuse_callback) explicit CpuOveruseObserverProxy(LoadObserver* overuse_callback)
: crit_(CriticalSectionWrapper::CreateCriticalSection()), : crit_(CriticalSectionWrapper::CreateCriticalSection()),
overuse_callback_(overuse_callback) { overuse_callback_(overuse_callback) {
assert(overuse_callback != NULL); assert(overuse_callback != NULL);
@ -65,17 +65,17 @@ class CpuOveruseObserverProxy : public webrtc::CpuOveruseObserver {
virtual void OveruseDetected() OVERRIDE { virtual void OveruseDetected() OVERRIDE {
CriticalSectionScoped lock(crit_.get()); CriticalSectionScoped lock(crit_.get());
overuse_callback_->OnOveruse(); overuse_callback_->OnLoadUpdate(LoadObserver::kOveruse);
} }
virtual void NormalUsage() OVERRIDE { virtual void NormalUsage() OVERRIDE {
CriticalSectionScoped lock(crit_.get()); CriticalSectionScoped lock(crit_.get());
overuse_callback_->OnNormalUse(); overuse_callback_->OnLoadUpdate(LoadObserver::kUnderuse);
} }
private: private:
const scoped_ptr<CriticalSectionWrapper> crit_; const scoped_ptr<CriticalSectionWrapper> crit_;
OveruseCallback* overuse_callback_ GUARDED_BY(crit_); LoadObserver* overuse_callback_ GUARDED_BY(crit_);
}; };
class Call : public webrtc::Call, public PacketReceiver { class Call : public webrtc::Call, public PacketReceiver {

View File

@ -451,16 +451,11 @@ TEST_F(CallPerfTest, CaptureNtpTimeWithNetworkJitter) {
TEST_F(CallPerfTest, RegisterCpuOveruseObserver) { TEST_F(CallPerfTest, RegisterCpuOveruseObserver) {
// Verifies that either a normal or overuse callback is triggered. // Verifies that either a normal or overuse callback is triggered.
class OveruseCallbackObserver : public test::SendTest, class LoadObserver : public test::SendTest, public webrtc::LoadObserver {
public webrtc::OveruseCallback {
public: public:
OveruseCallbackObserver() : SendTest(kLongTimeoutMs) {} LoadObserver() : SendTest(kLongTimeoutMs) {}
virtual void OnOveruse() OVERRIDE { virtual void OnLoadUpdate(Load load) OVERRIDE {
observation_complete_->Set();
}
virtual void OnNormalUse() OVERRIDE {
observation_complete_->Set(); observation_complete_->Set();
} }