| // 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); |
| |