diff options
author | pbos@webrtc.org <pbos@webrtc.org> | 2014-10-31 12:59:34 +0000 |
---|---|---|
committer | pbos@webrtc.org <pbos@webrtc.org> | 2014-10-31 12:59:34 +0000 |
commit | a1feeae09e5412881352c7ccf11f51be9fe47946 (patch) | |
tree | 2fffdf7a1e6c201a3f693557ae961432b462ba6e | |
parent | 36330f305227a7b4649a6df7c619c6f1de0cc802 (diff) | |
download | talk-a1feeae09e5412881352c7ccf11f51be9fe47946.tar.gz |
Configure A/V sync in WebRtcVideoEngine2.
Sets up A/V sync for the first video receive channel with the default
voice channel. This is only done when conference mode is disabled to
preserve existing behavior. Ideally we'd know which voice channel to
sync with here.
R=mflodman@webrtc.org, stefan@webrtc.org
BUG=1788
Review URL: https://webrtc-codereview.appspot.com/23249004
git-svn-id: http://webrtc.googlecode.com/svn/trunk/talk@7577 4adac7df-926f-26a2-2b94-8c16560cd09d
-rw-r--r-- | media/webrtc/webrtcvideoengine2.cc | 19 | ||||
-rw-r--r-- | media/webrtc/webrtcvideoengine2.h | 2 | ||||
-rw-r--r-- | media/webrtc/webrtcvideoengine2_unittest.cc | 75 |
3 files changed, 73 insertions, 23 deletions
diff --git a/media/webrtc/webrtcvideoengine2.cc b/media/webrtc/webrtcvideoengine2.cc index 7df6809..d10870b 100644 --- a/media/webrtc/webrtcvideoengine2.cc +++ b/media/webrtc/webrtcvideoengine2.cc @@ -423,6 +423,7 @@ WebRtcVideoChannel2* WebRtcVideoEngine2::CreateChannel( << " voice channel. Options: " << options.ToString(); WebRtcVideoChannel2* channel = new WebRtcVideoChannel2(call_factory_, + voice_engine_, voice_channel, options, external_encoder_factory_, @@ -745,20 +746,24 @@ class WebRtcVideoRenderFrame : public VideoFrame { WebRtcVideoChannel2::WebRtcVideoChannel2( WebRtcCallFactory* call_factory, + WebRtcVoiceEngine* voice_engine, VoiceMediaChannel* voice_channel, const VideoOptions& options, WebRtcVideoEncoderFactory* external_encoder_factory, WebRtcVideoDecoderFactory* external_decoder_factory, WebRtcVideoEncoderFactory2* encoder_factory) : unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_), + voice_channel_(voice_channel), external_encoder_factory_(external_encoder_factory), external_decoder_factory_(external_decoder_factory), encoder_factory_(encoder_factory) { - // TODO(pbos): Connect the video and audio with |voice_channel|. SetDefaultOptions(); options_.SetAll(options); webrtc::Call::Config config(this); config.overuse_callback = this; + if (voice_engine != NULL) { + config.voice_engine = voice_engine->voe()->engine(); + } // Set start bitrate for the call. A default is provided by SetDefaultOptions. int start_bitrate_kbps; @@ -1009,6 +1014,18 @@ bool WebRtcVideoChannel2::AddRecvStream(const StreamParams& sp) { webrtc::VideoReceiveStream::Config config; ConfigureReceiverRtp(&config, sp); + + // Set up A/V sync if there is a VoiceChannel. + // TODO(pbos): The A/V is synched by the receiving channel. So we need to know + // the SSRC of the remote audio channel in order to sync the correct webrtc + // VoiceEngine channel. For now sync the first channel in non-conference to + // match existing behavior in WebRtcVideoEngine. + if (voice_channel_ != NULL && receive_streams_.empty() && + !options_.conference_mode.GetWithDefaultIfUnset(false)) { + config.audio_channel_id = + static_cast<WebRtcVoiceMediaChannel*>(voice_channel_)->voe_channel(); + } + receive_streams_[ssrc] = new WebRtcVideoReceiveStream( call_.get(), external_decoder_factory_, config, recv_codecs_); diff --git a/media/webrtc/webrtcvideoengine2.h b/media/webrtc/webrtcvideoengine2.h index d32abb2..b9a8682 100644 --- a/media/webrtc/webrtcvideoengine2.h +++ b/media/webrtc/webrtcvideoengine2.h @@ -211,6 +211,7 @@ class WebRtcVideoChannel2 : public rtc::MessageHandler, public webrtc::LoadObserver { public: WebRtcVideoChannel2(WebRtcCallFactory* call_factory, + WebRtcVoiceEngine* voice_engine, VoiceMediaChannel* voice_channel, const VideoOptions& options, WebRtcVideoEncoderFactory* external_encoder_factory, @@ -470,6 +471,7 @@ class WebRtcVideoChannel2 : public rtc::MessageHandler, Settable<VideoCodecSettings> send_codec_; std::vector<webrtc::RtpExtension> send_rtp_extensions_; + VoiceMediaChannel* const voice_channel_; WebRtcVideoEncoderFactory* const external_encoder_factory_; WebRtcVideoDecoderFactory* const external_decoder_factory_; WebRtcVideoEncoderFactory2* const encoder_factory_; diff --git a/media/webrtc/webrtcvideoengine2_unittest.cc b/media/webrtc/webrtcvideoengine2_unittest.cc index 835bb7c..c5ce503 100644 --- a/media/webrtc/webrtcvideoengine2_unittest.cc +++ b/media/webrtc/webrtcvideoengine2_unittest.cc @@ -34,6 +34,7 @@ #include "talk/media/webrtc/webrtcvideochannelfactory.h" #include "talk/media/webrtc/webrtcvideoengine2.h" #include "talk/media/webrtc/webrtcvideoengine2_unittest.h" +#include "talk/media/webrtc/webrtcvoiceengine.h" #include "webrtc/base/gunit.h" #include "webrtc/base/stringutils.h" #include "webrtc/video_encoder.h" @@ -328,6 +329,22 @@ class WebRtcVideoEngine2Test : public ::testing::Test { } protected: + class FakeCallFactory : public WebRtcCallFactory { + public: + FakeCallFactory() : fake_call_(NULL) {} + FakeCall* GetCall() { return fake_call_; } + + private: + virtual webrtc::Call* CreateCall( + const webrtc::Call::Config& config) OVERRIDE { + assert(fake_call_ == NULL); + fake_call_ = new FakeCall(config); + return fake_call_; + } + + FakeCall* fake_call_; + }; + VideoMediaChannel* SetUpForExternalEncoderFactory( cricket::WebRtcVideoEncoderFactory* encoder_factory, const std::vector<VideoCodec>& codecs); @@ -341,9 +358,42 @@ class WebRtcVideoEngine2Test : public ::testing::Test { VideoCodec default_rtx_codec_; }; -// TODO(pbos): Add test that verifies that sync is configured properly. -TEST_F(WebRtcVideoEngine2Test, DISABLED_CreateChannelWithVoiceEngine) { - FAIL() << "Not implemented."; // TODO(pbos): Implement. +TEST_F(WebRtcVideoEngine2Test, ConfiguresAvSyncForFirstReceiveChannel) { + FakeCallFactory call_factory; + engine_.SetCallFactory(&call_factory); + + WebRtcVoiceEngine voice_engine; + engine_.SetVoiceEngine(&voice_engine); + voice_engine.Init(rtc::Thread::Current()); + engine_.Init(rtc::Thread::Current()); + + rtc::scoped_ptr<VoiceMediaChannel> voice_channel( + voice_engine.CreateChannel()); + ASSERT_TRUE(voice_channel.get() != NULL); + WebRtcVoiceMediaChannel* webrtc_voice_channel = + static_cast<WebRtcVoiceMediaChannel*>(voice_channel.get()); + ASSERT_NE(webrtc_voice_channel->voe_channel(), -1); + rtc::scoped_ptr<VideoMediaChannel> channel( + engine_.CreateChannel(cricket::VideoOptions(), voice_channel.get())); + + FakeCall* fake_call = call_factory.GetCall(); + ASSERT_TRUE(fake_call != NULL); + + webrtc::Call::Config call_config = fake_call->GetConfig(); + + ASSERT_TRUE(voice_engine.voe()->engine() != NULL); + ASSERT_EQ(voice_engine.voe()->engine(), call_config.voice_engine); + + EXPECT_TRUE(channel->AddRecvStream(StreamParams::CreateLegacy(kSsrc))); + EXPECT_TRUE(channel->AddRecvStream(StreamParams::CreateLegacy(kSsrc + 1))); + std::vector<FakeVideoReceiveStream*> receive_streams = + fake_call->GetVideoReceiveStreams(); + + ASSERT_EQ(2u, receive_streams.size()); + EXPECT_EQ(webrtc_voice_channel->voe_channel(), + receive_streams[0]->GetConfig().audio_channel_id); + EXPECT_EQ(-1, receive_streams[1]->GetConfig().audio_channel_id) + << "AV sync should only be set up for the first receive channel."; } TEST_F(WebRtcVideoEngine2Test, FindCodec) { @@ -431,25 +481,6 @@ TEST_F(WebRtcVideoEngine2Test, SupportsAbsoluteSenderTimeHeaderExtension) { void WebRtcVideoEngine2Test::TestStartBitrate(bool override_start_bitrate, int start_bitrate_bps) { - class FakeCallFactory : public WebRtcCallFactory { - public: - FakeCallFactory() : fake_call_(NULL) {} - - FakeCall* GetCall() { - return fake_call_; - } - - private: - virtual webrtc::Call* CreateCall( - const webrtc::Call::Config& config) OVERRIDE { - assert(fake_call_ == NULL); - fake_call_ = new FakeCall(config); - return fake_call_; - } - - FakeCall* fake_call_; - }; - FakeCallFactory call_factory; engine_.SetCallFactory(&call_factory); |