Open backdoor in VoiceEngineImpl to get at the actual voe::Channel objects from an ID.
This will allow Audio[Send|Receive]Stream to bypass the VoE interfaces in many cases and talk directly to the channel. BUG=webrtc:4690 Review URL: https://codereview.webrtc.org/1459083007 Cr-Commit-Position: refs/heads/master@{#10788}
This commit is contained in:
@ -18,12 +18,14 @@
|
|||||||
#include "webrtc/base/logging.h"
|
#include "webrtc/base/logging.h"
|
||||||
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
|
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
|
||||||
#include "webrtc/system_wrappers/include/tick_util.h"
|
#include "webrtc/system_wrappers/include/tick_util.h"
|
||||||
|
#include "webrtc/voice_engine/channel_proxy.h"
|
||||||
#include "webrtc/voice_engine/include/voe_base.h"
|
#include "webrtc/voice_engine/include/voe_base.h"
|
||||||
#include "webrtc/voice_engine/include/voe_codec.h"
|
#include "webrtc/voice_engine/include/voe_codec.h"
|
||||||
#include "webrtc/voice_engine/include/voe_neteq_stats.h"
|
#include "webrtc/voice_engine/include/voe_neteq_stats.h"
|
||||||
#include "webrtc/voice_engine/include/voe_rtp_rtcp.h"
|
#include "webrtc/voice_engine/include/voe_rtp_rtcp.h"
|
||||||
#include "webrtc/voice_engine/include/voe_video_sync.h"
|
#include "webrtc/voice_engine/include/voe_video_sync.h"
|
||||||
#include "webrtc/voice_engine/include/voe_volume_control.h"
|
#include "webrtc/voice_engine/include/voe_volume_control.h"
|
||||||
|
#include "webrtc/voice_engine/voice_engine_impl.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
std::string AudioReceiveStream::Config::Rtp::ToString() const {
|
std::string AudioReceiveStream::Config::Rtp::ToString() const {
|
||||||
@ -74,24 +76,26 @@ AudioReceiveStream::AudioReceiveStream(
|
|||||||
RTC_DCHECK(audio_state_.get());
|
RTC_DCHECK(audio_state_.get());
|
||||||
RTC_DCHECK(rtp_header_parser_);
|
RTC_DCHECK(rtp_header_parser_);
|
||||||
|
|
||||||
|
VoiceEngineImpl* voe_impl = static_cast<VoiceEngineImpl*>(voice_engine());
|
||||||
|
channel_proxy_ = voe_impl->GetChannelProxy(config_.voe_channel_id);
|
||||||
|
channel_proxy_->SetLocalSSRC(config.rtp.local_ssrc);
|
||||||
|
|
||||||
const int channel_id = config.voe_channel_id;
|
const int channel_id = config.voe_channel_id;
|
||||||
ScopedVoEInterface<VoERTP_RTCP> rtp(voice_engine());
|
ScopedVoEInterface<VoERTP_RTCP> rtp(voice_engine());
|
||||||
int error = rtp->SetLocalSSRC(channel_id, config.rtp.local_ssrc);
|
|
||||||
RTC_DCHECK_EQ(0, error);
|
|
||||||
for (const auto& extension : config.rtp.extensions) {
|
for (const auto& extension : config.rtp.extensions) {
|
||||||
// One-byte-extension local identifiers are in the range 1-14 inclusive.
|
// One-byte-extension local identifiers are in the range 1-14 inclusive.
|
||||||
RTC_DCHECK_GE(extension.id, 1);
|
RTC_DCHECK_GE(extension.id, 1);
|
||||||
RTC_DCHECK_LE(extension.id, 14);
|
RTC_DCHECK_LE(extension.id, 14);
|
||||||
if (extension.name == RtpExtension::kAudioLevel) {
|
if (extension.name == RtpExtension::kAudioLevel) {
|
||||||
error = rtp->SetReceiveAudioLevelIndicationStatus(channel_id, true,
|
int error = rtp->SetReceiveAudioLevelIndicationStatus(channel_id, true,
|
||||||
extension.id);
|
extension.id);
|
||||||
RTC_DCHECK_EQ(0, error);
|
RTC_DCHECK_EQ(0, error);
|
||||||
bool registered = rtp_header_parser_->RegisterRtpHeaderExtension(
|
bool registered = rtp_header_parser_->RegisterRtpHeaderExtension(
|
||||||
kRtpExtensionAudioLevel, extension.id);
|
kRtpExtensionAudioLevel, extension.id);
|
||||||
RTC_DCHECK(registered);
|
RTC_DCHECK(registered);
|
||||||
} else if (extension.name == RtpExtension::kAbsSendTime) {
|
} else if (extension.name == RtpExtension::kAbsSendTime) {
|
||||||
error = rtp->SetReceiveAbsoluteSenderTimeStatus(channel_id, true,
|
int error = rtp->SetReceiveAbsoluteSenderTimeStatus(channel_id, true,
|
||||||
extension.id);
|
extension.id);
|
||||||
RTC_DCHECK_EQ(0, error);
|
RTC_DCHECK_EQ(0, error);
|
||||||
bool registered = rtp_header_parser_->RegisterRtpHeaderExtension(
|
bool registered = rtp_header_parser_->RegisterRtpHeaderExtension(
|
||||||
kRtpExtensionAbsoluteSendTime, extension.id);
|
kRtpExtensionAbsoluteSendTime, extension.id);
|
||||||
|
@ -17,11 +17,13 @@
|
|||||||
#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
|
#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
class RemoteBitrateEstimator;
|
class RemoteBitrateEstimator;
|
||||||
|
|
||||||
namespace internal {
|
namespace voe {
|
||||||
|
class ChannelProxy;
|
||||||
|
} // namespace voe
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
class AudioReceiveStream final : public webrtc::AudioReceiveStream {
|
class AudioReceiveStream final : public webrtc::AudioReceiveStream {
|
||||||
public:
|
public:
|
||||||
AudioReceiveStream(RemoteBitrateEstimator* remote_bitrate_estimator,
|
AudioReceiveStream(RemoteBitrateEstimator* remote_bitrate_estimator,
|
||||||
@ -51,6 +53,7 @@ class AudioReceiveStream final : public webrtc::AudioReceiveStream {
|
|||||||
const webrtc::AudioReceiveStream::Config config_;
|
const webrtc::AudioReceiveStream::Config config_;
|
||||||
rtc::scoped_refptr<webrtc::AudioState> audio_state_;
|
rtc::scoped_refptr<webrtc::AudioState> audio_state_;
|
||||||
rtc::scoped_ptr<RtpHeaderParser> rtp_header_parser_;
|
rtc::scoped_ptr<RtpHeaderParser> rtp_header_parser_;
|
||||||
|
rtc::scoped_ptr<voe::ChannelProxy> channel_proxy_;
|
||||||
|
|
||||||
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AudioReceiveStream);
|
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AudioReceiveStream);
|
||||||
};
|
};
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "webrtc/audio/conversion.h"
|
#include "webrtc/audio/conversion.h"
|
||||||
#include "webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_estimator.h"
|
#include "webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_estimator.h"
|
||||||
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
|
#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
|
||||||
|
#include "webrtc/test/mock_voe_channel_proxy.h"
|
||||||
#include "webrtc/test/mock_voice_engine.h"
|
#include "webrtc/test/mock_voice_engine.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
@ -53,6 +54,8 @@ const AudioDecodingCallStats kAudioDecodeStats = MakeAudioDecodeStatsForTest();
|
|||||||
|
|
||||||
struct ConfigHelper {
|
struct ConfigHelper {
|
||||||
ConfigHelper() {
|
ConfigHelper() {
|
||||||
|
using testing::Invoke;
|
||||||
|
|
||||||
EXPECT_CALL(voice_engine_,
|
EXPECT_CALL(voice_engine_,
|
||||||
RegisterVoiceEngineObserver(_)).WillOnce(Return(0));
|
RegisterVoiceEngineObserver(_)).WillOnce(Return(0));
|
||||||
EXPECT_CALL(voice_engine_,
|
EXPECT_CALL(voice_engine_,
|
||||||
@ -61,8 +64,13 @@ struct ConfigHelper {
|
|||||||
config.voice_engine = &voice_engine_;
|
config.voice_engine = &voice_engine_;
|
||||||
audio_state_ = AudioState::Create(config);
|
audio_state_ = AudioState::Create(config);
|
||||||
|
|
||||||
EXPECT_CALL(voice_engine_, SetLocalSSRC(kChannelId, kLocalSsrc))
|
EXPECT_CALL(voice_engine_, ChannelProxyFactory(kChannelId))
|
||||||
.WillOnce(Return(0));
|
.WillOnce(Invoke([this](int channel_id) {
|
||||||
|
EXPECT_FALSE(channel_proxy_);
|
||||||
|
channel_proxy_ = new testing::StrictMock<MockVoEChannelProxy>();
|
||||||
|
EXPECT_CALL(*channel_proxy_, SetLocalSSRC(kLocalSsrc)).Times(1);
|
||||||
|
return channel_proxy_;
|
||||||
|
}));
|
||||||
EXPECT_CALL(voice_engine_,
|
EXPECT_CALL(voice_engine_,
|
||||||
SetReceiveAbsoluteSenderTimeStatus(kChannelId, true, kAbsSendTimeId))
|
SetReceiveAbsoluteSenderTimeStatus(kChannelId, true, kAbsSendTimeId))
|
||||||
.WillOnce(Return(0));
|
.WillOnce(Return(0));
|
||||||
@ -76,7 +84,7 @@ struct ConfigHelper {
|
|||||||
RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeId));
|
RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeId));
|
||||||
stream_config_.rtp.extensions.push_back(
|
stream_config_.rtp.extensions.push_back(
|
||||||
RtpExtension(RtpExtension::kAudioLevel, kAudioLevelId));
|
RtpExtension(RtpExtension::kAudioLevel, kAudioLevelId));
|
||||||
}
|
}
|
||||||
|
|
||||||
MockRemoteBitrateEstimator* remote_bitrate_estimator() {
|
MockRemoteBitrateEstimator* remote_bitrate_estimator() {
|
||||||
return &remote_bitrate_estimator_;
|
return &remote_bitrate_estimator_;
|
||||||
@ -89,6 +97,7 @@ struct ConfigHelper {
|
|||||||
using testing::DoAll;
|
using testing::DoAll;
|
||||||
using testing::SetArgPointee;
|
using testing::SetArgPointee;
|
||||||
using testing::SetArgReferee;
|
using testing::SetArgReferee;
|
||||||
|
|
||||||
EXPECT_CALL(voice_engine_, GetRTCPStatistics(kChannelId, _))
|
EXPECT_CALL(voice_engine_, GetRTCPStatistics(kChannelId, _))
|
||||||
.WillOnce(DoAll(SetArgReferee<1>(kCallStats), Return(0)));
|
.WillOnce(DoAll(SetArgReferee<1>(kCallStats), Return(0)));
|
||||||
EXPECT_CALL(voice_engine_, GetRecCodec(kChannelId, _))
|
EXPECT_CALL(voice_engine_, GetRecCodec(kChannelId, _))
|
||||||
@ -110,6 +119,7 @@ struct ConfigHelper {
|
|||||||
testing::StrictMock<MockVoiceEngine> voice_engine_;
|
testing::StrictMock<MockVoiceEngine> voice_engine_;
|
||||||
rtc::scoped_refptr<AudioState> audio_state_;
|
rtc::scoped_refptr<AudioState> audio_state_;
|
||||||
AudioReceiveStream::Config stream_config_;
|
AudioReceiveStream::Config stream_config_;
|
||||||
|
testing::StrictMock<MockVoEChannelProxy>* channel_proxy_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
void BuildAbsoluteSendTimeExtension(uint8_t* buffer,
|
void BuildAbsoluteSendTimeExtension(uint8_t* buffer,
|
||||||
|
@ -17,10 +17,12 @@
|
|||||||
#include "webrtc/audio/scoped_voe_interface.h"
|
#include "webrtc/audio/scoped_voe_interface.h"
|
||||||
#include "webrtc/base/checks.h"
|
#include "webrtc/base/checks.h"
|
||||||
#include "webrtc/base/logging.h"
|
#include "webrtc/base/logging.h"
|
||||||
|
#include "webrtc/voice_engine/channel_proxy.h"
|
||||||
#include "webrtc/voice_engine/include/voe_audio_processing.h"
|
#include "webrtc/voice_engine/include/voe_audio_processing.h"
|
||||||
#include "webrtc/voice_engine/include/voe_codec.h"
|
#include "webrtc/voice_engine/include/voe_codec.h"
|
||||||
#include "webrtc/voice_engine/include/voe_rtp_rtcp.h"
|
#include "webrtc/voice_engine/include/voe_rtp_rtcp.h"
|
||||||
#include "webrtc/voice_engine/include/voe_volume_control.h"
|
#include "webrtc/voice_engine/include/voe_volume_control.h"
|
||||||
|
#include "webrtc/voice_engine/voice_engine_impl.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
std::string AudioSendStream::Config::Rtp::ToString() const {
|
std::string AudioSendStream::Config::Rtp::ToString() const {
|
||||||
@ -51,7 +53,6 @@ std::string AudioSendStream::Config::ToString() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
AudioSendStream::AudioSendStream(
|
AudioSendStream::AudioSendStream(
|
||||||
const webrtc::AudioSendStream::Config& config,
|
const webrtc::AudioSendStream::Config& config,
|
||||||
const rtc::scoped_refptr<webrtc::AudioState>& audio_state)
|
const rtc::scoped_refptr<webrtc::AudioState>& audio_state)
|
||||||
@ -60,25 +61,25 @@ AudioSendStream::AudioSendStream(
|
|||||||
RTC_DCHECK_NE(config_.voe_channel_id, -1);
|
RTC_DCHECK_NE(config_.voe_channel_id, -1);
|
||||||
RTC_DCHECK(audio_state_.get());
|
RTC_DCHECK(audio_state_.get());
|
||||||
|
|
||||||
|
VoiceEngineImpl* voe_impl = static_cast<VoiceEngineImpl*>(voice_engine());
|
||||||
|
channel_proxy_ = voe_impl->GetChannelProxy(config_.voe_channel_id);
|
||||||
|
channel_proxy_->SetRTCPStatus(true);
|
||||||
|
channel_proxy_->SetLocalSSRC(config.rtp.ssrc);
|
||||||
|
channel_proxy_->SetRTCP_CNAME(config.rtp.c_name);
|
||||||
|
|
||||||
const int channel_id = config.voe_channel_id;
|
const int channel_id = config.voe_channel_id;
|
||||||
ScopedVoEInterface<VoERTP_RTCP> rtp(voice_engine());
|
ScopedVoEInterface<VoERTP_RTCP> rtp(voice_engine());
|
||||||
int error = rtp->SetRTCPStatus(channel_id, true);
|
|
||||||
RTC_DCHECK_EQ(0, error);
|
|
||||||
error = rtp->SetLocalSSRC(channel_id, config.rtp.ssrc);
|
|
||||||
RTC_DCHECK_EQ(0, error);
|
|
||||||
error = rtp->SetRTCP_CNAME(channel_id, config.rtp.c_name.c_str());
|
|
||||||
RTC_DCHECK_EQ(0, error);
|
|
||||||
for (const auto& extension : config.rtp.extensions) {
|
for (const auto& extension : config.rtp.extensions) {
|
||||||
// One-byte-extension local identifiers are in the range 1-14 inclusive.
|
// One-byte-extension local identifiers are in the range 1-14 inclusive.
|
||||||
RTC_DCHECK_GE(extension.id, 1);
|
RTC_DCHECK_GE(extension.id, 1);
|
||||||
RTC_DCHECK_LE(extension.id, 14);
|
RTC_DCHECK_LE(extension.id, 14);
|
||||||
if (extension.name == RtpExtension::kAbsSendTime) {
|
if (extension.name == RtpExtension::kAbsSendTime) {
|
||||||
error = rtp->SetSendAbsoluteSenderTimeStatus(channel_id, true,
|
int error = rtp->SetSendAbsoluteSenderTimeStatus(channel_id, true,
|
||||||
extension.id);
|
extension.id);
|
||||||
RTC_DCHECK_EQ(0, error);
|
RTC_DCHECK_EQ(0, error);
|
||||||
} else if (extension.name == RtpExtension::kAudioLevel) {
|
} else if (extension.name == RtpExtension::kAudioLevel) {
|
||||||
error = rtp->SetSendAudioLevelIndicationStatus(channel_id, true,
|
int error = rtp->SetSendAudioLevelIndicationStatus(channel_id, true,
|
||||||
extension.id);
|
extension.id);
|
||||||
RTC_DCHECK_EQ(0, error);
|
RTC_DCHECK_EQ(0, error);
|
||||||
} else {
|
} else {
|
||||||
RTC_NOTREACHED() << "Registering unsupported RTP extension.";
|
RTC_NOTREACHED() << "Registering unsupported RTP extension.";
|
||||||
|
@ -14,13 +14,16 @@
|
|||||||
#include "webrtc/audio_send_stream.h"
|
#include "webrtc/audio_send_stream.h"
|
||||||
#include "webrtc/audio_state.h"
|
#include "webrtc/audio_state.h"
|
||||||
#include "webrtc/base/thread_checker.h"
|
#include "webrtc/base/thread_checker.h"
|
||||||
|
#include "webrtc/base/scoped_ptr.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
class VoiceEngine;
|
class VoiceEngine;
|
||||||
|
|
||||||
namespace internal {
|
namespace voe {
|
||||||
|
class ChannelProxy;
|
||||||
|
} // namespace voe
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
class AudioSendStream final : public webrtc::AudioSendStream {
|
class AudioSendStream final : public webrtc::AudioSendStream {
|
||||||
public:
|
public:
|
||||||
AudioSendStream(const webrtc::AudioSendStream::Config& config,
|
AudioSendStream(const webrtc::AudioSendStream::Config& config,
|
||||||
@ -44,6 +47,7 @@ class AudioSendStream final : public webrtc::AudioSendStream {
|
|||||||
rtc::ThreadChecker thread_checker_;
|
rtc::ThreadChecker thread_checker_;
|
||||||
const webrtc::AudioSendStream::Config config_;
|
const webrtc::AudioSendStream::Config config_;
|
||||||
rtc::scoped_refptr<webrtc::AudioState> audio_state_;
|
rtc::scoped_refptr<webrtc::AudioState> audio_state_;
|
||||||
|
rtc::scoped_ptr<voe::ChannelProxy> channel_proxy_;
|
||||||
|
|
||||||
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AudioSendStream);
|
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AudioSendStream);
|
||||||
};
|
};
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "webrtc/audio/audio_send_stream.h"
|
#include "webrtc/audio/audio_send_stream.h"
|
||||||
#include "webrtc/audio/audio_state.h"
|
#include "webrtc/audio/audio_state.h"
|
||||||
#include "webrtc/audio/conversion.h"
|
#include "webrtc/audio/conversion.h"
|
||||||
|
#include "webrtc/test/mock_voe_channel_proxy.h"
|
||||||
#include "webrtc/test/mock_voice_engine.h"
|
#include "webrtc/test/mock_voice_engine.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
@ -39,6 +40,7 @@ const ReportBlock kReportBlock = {456, 780, 123, 567, 890, 132, 143, 13354};
|
|||||||
|
|
||||||
struct ConfigHelper {
|
struct ConfigHelper {
|
||||||
ConfigHelper() : stream_config_(nullptr) {
|
ConfigHelper() : stream_config_(nullptr) {
|
||||||
|
using testing::Invoke;
|
||||||
using testing::StrEq;
|
using testing::StrEq;
|
||||||
|
|
||||||
EXPECT_CALL(voice_engine_,
|
EXPECT_CALL(voice_engine_,
|
||||||
@ -49,12 +51,15 @@ struct ConfigHelper {
|
|||||||
config.voice_engine = &voice_engine_;
|
config.voice_engine = &voice_engine_;
|
||||||
audio_state_ = AudioState::Create(config);
|
audio_state_ = AudioState::Create(config);
|
||||||
|
|
||||||
EXPECT_CALL(voice_engine_, SetRTCPStatus(kChannelId, true))
|
EXPECT_CALL(voice_engine_, ChannelProxyFactory(kChannelId))
|
||||||
.WillOnce(Return(0));
|
.WillOnce(Invoke([this](int channel_id) {
|
||||||
EXPECT_CALL(voice_engine_, SetLocalSSRC(kChannelId, kSsrc))
|
EXPECT_FALSE(channel_proxy_);
|
||||||
.WillOnce(Return(0));
|
channel_proxy_ = new testing::StrictMock<MockVoEChannelProxy>();
|
||||||
EXPECT_CALL(voice_engine_, SetRTCP_CNAME(kChannelId, StrEq(kCName)))
|
EXPECT_CALL(*channel_proxy_, SetRTCPStatus(true)).Times(1);
|
||||||
.WillOnce(Return(0));
|
EXPECT_CALL(*channel_proxy_, SetLocalSSRC(kSsrc)).Times(1);
|
||||||
|
EXPECT_CALL(*channel_proxy_, SetRTCP_CNAME(StrEq(kCName))).Times(1);
|
||||||
|
return channel_proxy_;
|
||||||
|
}));
|
||||||
EXPECT_CALL(voice_engine_,
|
EXPECT_CALL(voice_engine_,
|
||||||
SetSendAbsoluteSenderTimeStatus(kChannelId, true, kAbsSendTimeId))
|
SetSendAbsoluteSenderTimeStatus(kChannelId, true, kAbsSendTimeId))
|
||||||
.WillOnce(Return(0));
|
.WillOnce(Return(0));
|
||||||
@ -109,6 +114,7 @@ struct ConfigHelper {
|
|||||||
testing::StrictMock<MockVoiceEngine> voice_engine_;
|
testing::StrictMock<MockVoiceEngine> voice_engine_;
|
||||||
rtc::scoped_refptr<AudioState> audio_state_;
|
rtc::scoped_refptr<AudioState> audio_state_;
|
||||||
AudioSendStream::Config stream_config_;
|
AudioSendStream::Config stream_config_;
|
||||||
|
testing::StrictMock<MockVoEChannelProxy>* channel_proxy_ = nullptr;
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
30
webrtc/test/mock_voe_channel_proxy.h
Normal file
30
webrtc/test/mock_voe_channel_proxy.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WEBRTC_TEST_MOCK_VOE_CHANNEL_PROXY_H_
|
||||||
|
#define WEBRTC_TEST_MOCK_VOE_CHANNEL_PROXY_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "testing/gmock/include/gmock/gmock.h"
|
||||||
|
#include "webrtc/voice_engine/channel_proxy.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
namespace test {
|
||||||
|
|
||||||
|
class MockVoEChannelProxy : public voe::ChannelProxy {
|
||||||
|
public:
|
||||||
|
MOCK_METHOD1(SetRTCPStatus, void(bool enable));
|
||||||
|
MOCK_METHOD1(SetLocalSSRC, void(uint32_t ssrc));
|
||||||
|
MOCK_METHOD1(SetRTCP_CNAME, void(const std::string& c_name));
|
||||||
|
};
|
||||||
|
} // namespace test
|
||||||
|
} // namespace webrtc
|
||||||
|
|
||||||
|
#endif // WEBRTC_TEST_MOCK_VOE_CHANNEL_PROXY_H_
|
@ -12,6 +12,7 @@
|
|||||||
#define WEBRTC_AUDIO_MOCK_VOICE_ENGINE_H_
|
#define WEBRTC_AUDIO_MOCK_VOICE_ENGINE_H_
|
||||||
|
|
||||||
#include "testing/gmock/include/gmock/gmock.h"
|
#include "testing/gmock/include/gmock/gmock.h"
|
||||||
|
#include "webrtc/test/mock_voe_channel_proxy.h"
|
||||||
#include "webrtc/voice_engine/voice_engine_impl.h"
|
#include "webrtc/voice_engine/voice_engine_impl.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
@ -25,12 +26,26 @@ class MockVoiceEngine : public VoiceEngineImpl {
|
|||||||
// Increase ref count so this object isn't automatically deleted whenever
|
// Increase ref count so this object isn't automatically deleted whenever
|
||||||
// interfaces are Release():d.
|
// interfaces are Release():d.
|
||||||
++_ref_count;
|
++_ref_count;
|
||||||
|
// We add this default behavior to make the mock easier to use in tests. It
|
||||||
|
// will create a NiceMock of a voe::ChannelProxy.
|
||||||
|
ON_CALL(*this, ChannelProxyFactory(testing::_))
|
||||||
|
.WillByDefault(
|
||||||
|
testing::Invoke([](int channel_id) {
|
||||||
|
return new testing::NiceMock<MockVoEChannelProxy>();
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
~MockVoiceEngine() override {
|
~MockVoiceEngine() override {
|
||||||
// Decrease ref count before base class d-tor is called; otherwise it will
|
// Decrease ref count before base class d-tor is called; otherwise it will
|
||||||
// trigger an assertion.
|
// trigger an assertion.
|
||||||
--_ref_count;
|
--_ref_count;
|
||||||
}
|
}
|
||||||
|
// Allows injecting a ChannelProxy factory.
|
||||||
|
MOCK_METHOD1(ChannelProxyFactory, voe::ChannelProxy*(int channel_id));
|
||||||
|
|
||||||
|
// VoiceEngineImpl
|
||||||
|
rtc::scoped_ptr<voe::ChannelProxy> GetChannelProxy(int channel_id) override {
|
||||||
|
return rtc::scoped_ptr<voe::ChannelProxy>(ChannelProxyFactory(channel_id));
|
||||||
|
}
|
||||||
|
|
||||||
// VoEAudioProcessing
|
// VoEAudioProcessing
|
||||||
MOCK_METHOD2(SetNsStatus, int(bool enable, NsModes mode));
|
MOCK_METHOD2(SetNsStatus, int(bool enable, NsModes mode));
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
'layer_filtering_transport.cc',
|
'layer_filtering_transport.cc',
|
||||||
'layer_filtering_transport.h',
|
'layer_filtering_transport.h',
|
||||||
'mock_transport.h',
|
'mock_transport.h',
|
||||||
|
'mock_voe_channel_proxy.h',
|
||||||
'mock_voice_engine.h',
|
'mock_voice_engine.h',
|
||||||
'null_transport.cc',
|
'null_transport.cc',
|
||||||
'null_transport.h',
|
'null_transport.h',
|
||||||
|
@ -14,6 +14,8 @@ source_set("voice_engine") {
|
|||||||
"channel.h",
|
"channel.h",
|
||||||
"channel_manager.cc",
|
"channel_manager.cc",
|
||||||
"channel_manager.h",
|
"channel_manager.h",
|
||||||
|
"channel_proxy.cc",
|
||||||
|
"channel_proxy.h",
|
||||||
"dtmf_inband.cc",
|
"dtmf_inband.cc",
|
||||||
"dtmf_inband.h",
|
"dtmf_inband.h",
|
||||||
"dtmf_inband_queue.cc",
|
"dtmf_inband_queue.cc",
|
||||||
|
44
webrtc/voice_engine/channel_proxy.cc
Normal file
44
webrtc/voice_engine/channel_proxy.cc
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "webrtc/voice_engine/channel_proxy.h"
|
||||||
|
|
||||||
|
#include "webrtc/base/checks.h"
|
||||||
|
#include "webrtc/voice_engine/channel.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
namespace voe {
|
||||||
|
ChannelProxy::ChannelProxy() : channel_owner_(nullptr) {}
|
||||||
|
|
||||||
|
ChannelProxy::ChannelProxy(const ChannelOwner& channel_owner) :
|
||||||
|
channel_owner_(channel_owner) {
|
||||||
|
RTC_CHECK(channel_owner_.channel());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChannelProxy::SetRTCPStatus(bool enable) {
|
||||||
|
RTC_DCHECK(channel_owner_.channel());
|
||||||
|
channel_owner_.channel()->SetRTCPStatus(enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChannelProxy::SetLocalSSRC(uint32_t ssrc) {
|
||||||
|
RTC_DCHECK(channel_owner_.channel());
|
||||||
|
int error = channel_owner_.channel()->SetLocalSSRC(ssrc);
|
||||||
|
RTC_DCHECK_EQ(0, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChannelProxy::SetRTCP_CNAME(const std::string& c_name) {
|
||||||
|
// Note: VoERTP_RTCP::SetRTCP_CNAME() accepts a char[256] array.
|
||||||
|
std::string c_name_limited = c_name.substr(0, 255);
|
||||||
|
RTC_DCHECK(channel_owner_.channel());
|
||||||
|
int error = channel_owner_.channel()->SetRTCP_CNAME(c_name_limited.c_str());
|
||||||
|
RTC_DCHECK_EQ(0, error);
|
||||||
|
}
|
||||||
|
} // namespace voe
|
||||||
|
} // namespace webrtc
|
44
webrtc/voice_engine/channel_proxy.h
Normal file
44
webrtc/voice_engine/channel_proxy.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license
|
||||||
|
* that can be found in the LICENSE file in the root of the source
|
||||||
|
* tree. An additional intellectual property rights grant can be found
|
||||||
|
* in the file PATENTS. All contributing project authors may
|
||||||
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WEBRTC_VOICE_ENGINE_CHANNEL_PROXY_H_
|
||||||
|
#define WEBRTC_VOICE_ENGINE_CHANNEL_PROXY_H_
|
||||||
|
|
||||||
|
#include "webrtc/voice_engine/channel_manager.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
namespace voe {
|
||||||
|
|
||||||
|
// This class provides the "view" of a voe::Channel that we need to implement
|
||||||
|
// webrtc::AudioSendStream and webrtc::AudioReceiveStream. It serves two
|
||||||
|
// purposes:
|
||||||
|
// 1. Allow mocking just the interfaces used, instead of the entire
|
||||||
|
// voe::Channel class.
|
||||||
|
// 2. Provide a refined interface for the stream classes, including assumptions
|
||||||
|
// on return values and input adaptation.
|
||||||
|
class ChannelProxy {
|
||||||
|
public:
|
||||||
|
ChannelProxy();
|
||||||
|
explicit ChannelProxy(const ChannelOwner& channel_owner);
|
||||||
|
virtual ~ChannelProxy() {}
|
||||||
|
|
||||||
|
virtual void SetRTCPStatus(bool enable);
|
||||||
|
virtual void SetLocalSSRC(uint32_t ssrc);
|
||||||
|
virtual void SetRTCP_CNAME(const std::string& c_name);
|
||||||
|
|
||||||
|
private:
|
||||||
|
ChannelOwner channel_owner_;
|
||||||
|
};
|
||||||
|
} // namespace voe
|
||||||
|
} // namespace webrtc
|
||||||
|
|
||||||
|
#endif // WEBRTC_VOICE_ENGINE_CHANNEL_PROXY_H_
|
@ -47,7 +47,7 @@ VoEBaseImpl::~VoEBaseImpl() {
|
|||||||
delete &callbackCritSect_;
|
delete &callbackCritSect_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoEBaseImpl::OnErrorIsReported(ErrorCode error) {
|
void VoEBaseImpl::OnErrorIsReported(const ErrorCode error) {
|
||||||
CriticalSectionScoped cs(&callbackCritSect_);
|
CriticalSectionScoped cs(&callbackCritSect_);
|
||||||
int errCode = 0;
|
int errCode = 0;
|
||||||
if (error == AudioDeviceObserver::kRecordingError) {
|
if (error == AudioDeviceObserver::kRecordingError) {
|
||||||
@ -63,7 +63,7 @@ void VoEBaseImpl::OnErrorIsReported(ErrorCode error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoEBaseImpl::OnWarningIsReported(WarningCode warning) {
|
void VoEBaseImpl::OnWarningIsReported(const WarningCode warning) {
|
||||||
CriticalSectionScoped cs(&callbackCritSect_);
|
CriticalSectionScoped cs(&callbackCritSect_);
|
||||||
int warningCode = 0;
|
int warningCode = 0;
|
||||||
if (warning == AudioDeviceObserver::kRecordingWarning) {
|
if (warning == AudioDeviceObserver::kRecordingWarning) {
|
||||||
@ -79,21 +79,28 @@ void VoEBaseImpl::OnWarningIsReported(WarningCode warning) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t VoEBaseImpl::RecordedDataIsAvailable(
|
int32_t VoEBaseImpl::RecordedDataIsAvailable(const void* audioSamples,
|
||||||
const void* audioSamples, size_t nSamples, size_t nBytesPerSample,
|
const size_t nSamples,
|
||||||
uint8_t nChannels, uint32_t samplesPerSec, uint32_t totalDelayMS,
|
const size_t nBytesPerSample,
|
||||||
int32_t clockDrift, uint32_t micLevel, bool keyPressed,
|
const uint8_t nChannels,
|
||||||
uint32_t& newMicLevel) {
|
const uint32_t samplesPerSec,
|
||||||
|
const uint32_t totalDelayMS,
|
||||||
|
const int32_t clockDrift,
|
||||||
|
const uint32_t currentMicLevel,
|
||||||
|
const bool keyPressed,
|
||||||
|
uint32_t& newMicLevel) {
|
||||||
newMicLevel = static_cast<uint32_t>(ProcessRecordedDataWithAPM(
|
newMicLevel = static_cast<uint32_t>(ProcessRecordedDataWithAPM(
|
||||||
nullptr, 0, audioSamples, samplesPerSec, nChannels, nSamples,
|
nullptr, 0, audioSamples, samplesPerSec, nChannels, nSamples,
|
||||||
totalDelayMS, clockDrift, micLevel, keyPressed));
|
totalDelayMS, clockDrift, currentMicLevel, keyPressed));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t VoEBaseImpl::NeedMorePlayData(size_t nSamples,
|
int32_t VoEBaseImpl::NeedMorePlayData(const size_t nSamples,
|
||||||
size_t nBytesPerSample,
|
const size_t nBytesPerSample,
|
||||||
uint8_t nChannels, uint32_t samplesPerSec,
|
const uint8_t nChannels,
|
||||||
void* audioSamples, size_t& nSamplesOut,
|
const uint32_t samplesPerSec,
|
||||||
|
void* audioSamples,
|
||||||
|
size_t& nSamplesOut,
|
||||||
int64_t* elapsed_time_ms,
|
int64_t* elapsed_time_ms,
|
||||||
int64_t* ntp_time_ms) {
|
int64_t* ntp_time_ms) {
|
||||||
GetPlayoutData(static_cast<int>(samplesPerSec), static_cast<int>(nChannels),
|
GetPlayoutData(static_cast<int>(samplesPerSec), static_cast<int>(nChannels),
|
||||||
|
@ -54,37 +54,57 @@ class VoEBaseImpl : public VoEBase,
|
|||||||
int AssociateSendChannel(int channel, int accociate_send_channel) override;
|
int AssociateSendChannel(int channel, int accociate_send_channel) override;
|
||||||
|
|
||||||
// AudioTransport
|
// AudioTransport
|
||||||
int32_t RecordedDataIsAvailable(const void* audioSamples, size_t nSamples,
|
int32_t RecordedDataIsAvailable(const void* audioSamples,
|
||||||
size_t nBytesPerSample, uint8_t nChannels,
|
const size_t nSamples,
|
||||||
uint32_t samplesPerSec, uint32_t totalDelayMS,
|
const size_t nBytesPerSample,
|
||||||
int32_t clockDrift, uint32_t micLevel,
|
const uint8_t nChannels,
|
||||||
bool keyPressed,
|
const uint32_t samplesPerSec,
|
||||||
|
const uint32_t totalDelayMS,
|
||||||
|
const int32_t clockDrift,
|
||||||
|
const uint32_t currentMicLevel,
|
||||||
|
const bool keyPressed,
|
||||||
uint32_t& newMicLevel) override;
|
uint32_t& newMicLevel) override;
|
||||||
int32_t NeedMorePlayData(size_t nSamples, size_t nBytesPerSample,
|
int32_t NeedMorePlayData(const size_t nSamples,
|
||||||
uint8_t nChannels, uint32_t samplesPerSec,
|
const size_t nBytesPerSample,
|
||||||
void* audioSamples, size_t& nSamplesOut,
|
const uint8_t nChannels,
|
||||||
|
const uint32_t samplesPerSec,
|
||||||
|
void* audioSamples,
|
||||||
|
size_t& nSamplesOut,
|
||||||
int64_t* elapsed_time_ms,
|
int64_t* elapsed_time_ms,
|
||||||
int64_t* ntp_time_ms) override;
|
int64_t* ntp_time_ms) override;
|
||||||
int OnDataAvailable(const int voe_channels[], int number_of_voe_channels,
|
int OnDataAvailable(const int voe_channels[],
|
||||||
const int16_t* audio_data, int sample_rate,
|
int number_of_voe_channels,
|
||||||
int number_of_channels, size_t number_of_frames,
|
const int16_t* audio_data,
|
||||||
int audio_delay_milliseconds, int volume,
|
int sample_rate,
|
||||||
bool key_pressed, bool need_audio_processing) override;
|
int number_of_channels,
|
||||||
void OnData(int voe_channel, const void* audio_data, int bits_per_sample,
|
size_t number_of_frames,
|
||||||
int sample_rate, int number_of_channels,
|
int audio_delay_milliseconds,
|
||||||
|
int current_volume,
|
||||||
|
bool key_pressed,
|
||||||
|
bool need_audio_processing) override;
|
||||||
|
void OnData(int voe_channel,
|
||||||
|
const void* audio_data,
|
||||||
|
int bits_per_sample,
|
||||||
|
int sample_rate,
|
||||||
|
int number_of_channels,
|
||||||
size_t number_of_frames) override;
|
size_t number_of_frames) override;
|
||||||
void PushCaptureData(int voe_channel, const void* audio_data,
|
void PushCaptureData(int voe_channel,
|
||||||
int bits_per_sample, int sample_rate,
|
const void* audio_data,
|
||||||
|
int bits_per_sample,
|
||||||
|
int sample_rate,
|
||||||
int number_of_channels,
|
int number_of_channels,
|
||||||
size_t number_of_frames) override;
|
size_t number_of_frames) override;
|
||||||
void PullRenderData(int bits_per_sample, int sample_rate,
|
void PullRenderData(int bits_per_sample,
|
||||||
int number_of_channels, size_t number_of_frames,
|
int sample_rate,
|
||||||
void* audio_data, int64_t* elapsed_time_ms,
|
int number_of_channels,
|
||||||
|
size_t number_of_frames,
|
||||||
|
void* audio_data,
|
||||||
|
int64_t* elapsed_time_ms,
|
||||||
int64_t* ntp_time_ms) override;
|
int64_t* ntp_time_ms) override;
|
||||||
|
|
||||||
// AudioDeviceObserver
|
// AudioDeviceObserver
|
||||||
void OnErrorIsReported(ErrorCode error) override;
|
void OnErrorIsReported(const ErrorCode error) override;
|
||||||
void OnWarningIsReported(WarningCode warning) override;
|
void OnWarningIsReported(const WarningCode warning) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
VoEBaseImpl(voe::SharedData* shared);
|
VoEBaseImpl(voe::SharedData* shared);
|
||||||
|
@ -49,6 +49,8 @@
|
|||||||
'channel.h',
|
'channel.h',
|
||||||
'channel_manager.cc',
|
'channel_manager.cc',
|
||||||
'channel_manager.h',
|
'channel_manager.h',
|
||||||
|
'channel_proxy.cc',
|
||||||
|
'channel_proxy.h',
|
||||||
'dtmf_inband.cc',
|
'dtmf_inband.cc',
|
||||||
'dtmf_inband.h',
|
'dtmf_inband.h',
|
||||||
'dtmf_inband_queue.cc',
|
'dtmf_inband_queue.cc',
|
||||||
|
@ -15,8 +15,11 @@
|
|||||||
#include "webrtc/modules/utility/include/jvm_android.h"
|
#include "webrtc/modules/utility/include/jvm_android.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "webrtc/base/checks.h"
|
||||||
#include "webrtc/modules/audio_coding/main/include/audio_coding_module.h"
|
#include "webrtc/modules/audio_coding/main/include/audio_coding_module.h"
|
||||||
|
#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
|
||||||
#include "webrtc/system_wrappers/include/trace.h"
|
#include "webrtc/system_wrappers/include/trace.h"
|
||||||
|
#include "webrtc/voice_engine/channel_proxy.h"
|
||||||
#include "webrtc/voice_engine/voice_engine_impl.h"
|
#include "webrtc/voice_engine/voice_engine_impl.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
@ -77,6 +80,15 @@ int VoiceEngineImpl::Release() {
|
|||||||
return new_ref;
|
return new_ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rtc::scoped_ptr<voe::ChannelProxy> VoiceEngineImpl::GetChannelProxy(
|
||||||
|
int channel_id) {
|
||||||
|
RTC_DCHECK(channel_id >= 0);
|
||||||
|
CriticalSectionScoped cs(crit_sec());
|
||||||
|
RTC_DCHECK(statistics().Initialized());
|
||||||
|
return rtc::scoped_ptr<voe::ChannelProxy>(
|
||||||
|
new voe::ChannelProxy(channel_manager().GetChannel(channel_id)));
|
||||||
|
}
|
||||||
|
|
||||||
VoiceEngine* VoiceEngine::Create() {
|
VoiceEngine* VoiceEngine::Create() {
|
||||||
Config* config = new Config();
|
Config* config = new Config();
|
||||||
return GetVoiceEngine(config, true);
|
return GetVoiceEngine(config, true);
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#ifndef WEBRTC_VOICE_ENGINE_VOICE_ENGINE_IMPL_H
|
#ifndef WEBRTC_VOICE_ENGINE_VOICE_ENGINE_IMPL_H
|
||||||
#define WEBRTC_VOICE_ENGINE_VOICE_ENGINE_IMPL_H
|
#define WEBRTC_VOICE_ENGINE_VOICE_ENGINE_IMPL_H
|
||||||
|
|
||||||
|
#include "webrtc/base/scoped_ptr.h"
|
||||||
#include "webrtc/engine_configurations.h"
|
#include "webrtc/engine_configurations.h"
|
||||||
#include "webrtc/system_wrappers/include/atomic32.h"
|
#include "webrtc/system_wrappers/include/atomic32.h"
|
||||||
#include "webrtc/voice_engine/voe_base_impl.h"
|
#include "webrtc/voice_engine/voe_base_impl.h"
|
||||||
@ -48,6 +49,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
namespace voe {
|
||||||
|
class ChannelProxy;
|
||||||
|
} // namespace voe
|
||||||
|
|
||||||
class VoiceEngineImpl : public voe::SharedData, // Must be the first base class
|
class VoiceEngineImpl : public voe::SharedData, // Must be the first base class
|
||||||
public VoiceEngine,
|
public VoiceEngine,
|
||||||
@ -128,6 +132,10 @@ class VoiceEngineImpl : public voe::SharedData, // Must be the first base class
|
|||||||
// This implements the Release() method for all the inherited interfaces.
|
// This implements the Release() method for all the inherited interfaces.
|
||||||
int Release() override;
|
int Release() override;
|
||||||
|
|
||||||
|
// Backdoor to access a voe::Channel object without a channel ID. This is only
|
||||||
|
// to be used while refactoring the VoE API!
|
||||||
|
virtual rtc::scoped_ptr<voe::ChannelProxy> GetChannelProxy(int channel_id);
|
||||||
|
|
||||||
// This is *protected* so that FakeVoiceEngine can inherit from the class and
|
// This is *protected* so that FakeVoiceEngine can inherit from the class and
|
||||||
// manipulate the reference count. See: fake_voice_engine.h.
|
// manipulate the reference count. See: fake_voice_engine.h.
|
||||||
protected:
|
protected:
|
||||||
|
Reference in New Issue
Block a user