summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpbos@webrtc.org <pbos@webrtc.org>2014-10-31 12:59:34 +0000
committerpbos@webrtc.org <pbos@webrtc.org>2014-10-31 12:59:34 +0000
commita1feeae09e5412881352c7ccf11f51be9fe47946 (patch)
tree2fffdf7a1e6c201a3f693557ae961432b462ba6e
parent36330f305227a7b4649a6df7c619c6f1de0cc802 (diff)
downloadtalk-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.cc19
-rw-r--r--media/webrtc/webrtcvideoengine2.h2
-rw-r--r--media/webrtc/webrtcvideoengine2_unittest.cc75
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);