blob: 8e985d7054e9533569341348d949d31c9d7dab6a [file] [log] [blame]
// Copyright 2008 Google Inc. All Rights Reserved.
//
// Author: Ronghua Wu (ronghuawu@google.com)
// Zhurun Zhang (zhurunz@google.com)
#include "talk/base/byteorder.h"
#include "talk/base/gunit.h"
#include "talk/session/phone/channel.h"
#include "talk/session/phone/fakemediaengine.h"
#include "talk/session/phone/fakertp.h"
#include "talk/session/phone/fakesession.h"
#include "talk/session/phone/fakewebrtcvideoengine.h"
#include "talk/session/phone/fakewebrtcvoiceengine.h"
#include "talk/session/phone/webrtcvideoengine.h"
#include "talk/session/phone/webrtcvoiceengine.h"
// Tests for the WebRtcVideoEngine/VideoChannel code.
static const cricket::VideoCodec kVP8Codec(104, "VP8", 320, 200, 30, 0);
static const cricket::VideoCodec* const kVideoCodecs[] = {
&kVP8Codec,
};
class FakeViEWrapper : public cricket::ViEWrapper {
public:
explicit FakeViEWrapper(cricket::FakeWebRtcVideoEngine* engine)
: cricket::ViEWrapper(engine, engine, engine, engine,
engine, engine, engine) {
}
};
class WebRtcVideoEngineTest : public testing::Test {
public:
class ChannelErrorListener : public sigslot::has_slots<> {
public:
explicit ChannelErrorListener(cricket::WebRtcVideoMediaChannel* channel)
: ssrc_(0), error_(cricket::WebRtcVideoMediaChannel::ERROR_NONE) {
ASSERT(channel != NULL);
channel->SignalMediaError.connect(
this, &ChannelErrorListener::OnVideoChannelError);
}
void OnVideoChannelError(uint32 ssrc,
cricket::WebRtcVideoMediaChannel::Error error) {
ssrc_ = ssrc;
error_ = error;
}
void Reset() {
ssrc_ = 0;
error_ = cricket::WebRtcVideoMediaChannel::ERROR_NONE;
}
uint32 ssrc() const {
return ssrc_;
}
cricket::WebRtcVideoMediaChannel::Error error() const {
return error_;
}
private:
uint32 ssrc_;
cricket::WebRtcVideoMediaChannel::Error error_;
};
WebRtcVideoEngineTest()
: vie_(kVideoCodecs, ARRAY_SIZE(kVideoCodecs)),
engine_(NULL, // cricket::WebRtcVoiceEngine
new FakeViEWrapper(&vie_)),
channel_(NULL),
voice_channel_(NULL) {
}
bool SetupEngine() {
bool result = engine_.Init();
if (result) {
channel_ = engine_.CreateChannel(voice_channel_);
result = (channel_ != NULL);
}
return result;
}
void DeliverPacket(const void* data, int len) {
talk_base::Buffer packet(data, len);
channel_->OnPacketReceived(&packet);
}
virtual void TearDown() {
delete channel_;
engine_.Terminate();
}
protected:
cricket::FakeWebRtcVideoEngine vie_;
cricket::WebRtcVideoEngine engine_;
cricket::WebRtcVideoMediaChannel* channel_;
cricket::WebRtcVoiceMediaChannel* voice_channel_;
};
// Tests that our stub library "works".
TEST_F(WebRtcVideoEngineTest, StartupShutdown) {
EXPECT_FALSE(vie_.IsInited());
EXPECT_TRUE(engine_.Init());
EXPECT_TRUE(vie_.IsInited());
engine_.Terminate();
// TODO: what to expect after Terminate
// EXPECT_FALSE(vie_.IsInited());
}
// Tests that we can create and destroy a channel.
TEST_F(WebRtcVideoEngineTest, CreateChannel) {
EXPECT_TRUE(engine_.Init());
channel_ = engine_.CreateChannel(voice_channel_);
EXPECT_TRUE(channel_ != NULL);
}
// Tests that we properly handle failures in CreateChannel.
TEST_F(WebRtcVideoEngineTest, CreateChannelFail) {
vie_.set_fail_create_channel(true);
EXPECT_TRUE(engine_.Init());
channel_ = engine_.CreateChannel(voice_channel_);
EXPECT_TRUE(channel_ == NULL);
}
// 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(1U, c.size());
cricket::VideoCodec vp8(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));
}
// Test that we set our inbound codecs properly
TEST_F(WebRtcVideoEngineTest, SetRecvCodecs) {
EXPECT_TRUE(SetupEngine());
std::vector<cricket::VideoCodec> codecs;
codecs.push_back(kVP8Codec);
EXPECT_TRUE(channel_->SetRecvCodecs(codecs));
}
// Test that we apply codecs properly.
TEST_F(WebRtcVideoEngineTest, SetSendCodecs) {
EXPECT_TRUE(SetupEngine());
int channel_num = vie_.GetLastChannel();
std::vector<cricket::VideoCodec> codecs;
codecs.push_back(kVP8Codec);
EXPECT_TRUE(channel_->SetSendCodecs(codecs));
webrtc::VideoCodec gcodec;
EXPECT_EQ(0, vie_.GetSendCodec(channel_num, gcodec));
EXPECT_EQ(kVP8Codec.id, gcodec.plType);
EXPECT_EQ(kVP8Codec.width, gcodec.width);
EXPECT_EQ(kVP8Codec.height, gcodec.height);
EXPECT_STREQ(kVP8Codec.name.c_str(), gcodec.plName);
}
// TODO: add tests for below interfaces
// bool SetOptions(int options);
// bool SetCaptureDevice(const Device* device);
// bool SetLocalRenderer(VideoRenderer* renderer);
// CaptureResult SetCapture(bool capture);
// virtual bool SetRender(bool render);
// virtual bool SetSend(bool send);
// virtual bool AddStream(uint32 ssrc, uint32 voice_ssrc);
// virtual bool RemoveStream(uint32 ssrc);
// virtual bool SetRenderer(uint32 ssrc, VideoRenderer* renderer);
// virtual bool GetStats(VideoMediaInfo* info);
// virtual bool SendIntraFrame();
// virtual bool RequestIntraFrame();
// virtual void OnPacketReceived(talk_base::Buffer* packet);
// virtual void OnRtcpReceived(talk_base::Buffer* packet);
// virtual void SetSendSsrc(uint32 id);
// virtual bool SetRtcpCName(const std::string& cname);
// virtual bool Mute(bool on);
// virtual bool SetSendBandwidth(bool autobw, int bps);
// virtual bool SetOptions(int options);