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:
solenberg
2015-11-25 08:16:52 -08:00
committed by Commit bot
parent 54eb5e2e9a
commit 13725089ef
17 changed files with 277 additions and 64 deletions

View File

@ -18,12 +18,14 @@
#include "webrtc/base/logging.h"
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.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_codec.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_video_sync.h"
#include "webrtc/voice_engine/include/voe_volume_control.h"
#include "webrtc/voice_engine/voice_engine_impl.h"
namespace webrtc {
std::string AudioReceiveStream::Config::Rtp::ToString() const {
@ -74,24 +76,26 @@ AudioReceiveStream::AudioReceiveStream(
RTC_DCHECK(audio_state_.get());
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;
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) {
// One-byte-extension local identifiers are in the range 1-14 inclusive.
RTC_DCHECK_GE(extension.id, 1);
RTC_DCHECK_LE(extension.id, 14);
if (extension.name == RtpExtension::kAudioLevel) {
error = rtp->SetReceiveAudioLevelIndicationStatus(channel_id, true,
extension.id);
int error = rtp->SetReceiveAudioLevelIndicationStatus(channel_id, true,
extension.id);
RTC_DCHECK_EQ(0, error);
bool registered = rtp_header_parser_->RegisterRtpHeaderExtension(
kRtpExtensionAudioLevel, extension.id);
RTC_DCHECK(registered);
} else if (extension.name == RtpExtension::kAbsSendTime) {
error = rtp->SetReceiveAbsoluteSenderTimeStatus(channel_id, true,
extension.id);
int error = rtp->SetReceiveAbsoluteSenderTimeStatus(channel_id, true,
extension.id);
RTC_DCHECK_EQ(0, error);
bool registered = rtp_header_parser_->RegisterRtpHeaderExtension(
kRtpExtensionAbsoluteSendTime, extension.id);

View File

@ -17,11 +17,13 @@
#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
namespace webrtc {
class RemoteBitrateEstimator;
namespace internal {
namespace voe {
class ChannelProxy;
} // namespace voe
namespace internal {
class AudioReceiveStream final : public webrtc::AudioReceiveStream {
public:
AudioReceiveStream(RemoteBitrateEstimator* remote_bitrate_estimator,
@ -51,6 +53,7 @@ class AudioReceiveStream final : public webrtc::AudioReceiveStream {
const webrtc::AudioReceiveStream::Config config_;
rtc::scoped_refptr<webrtc::AudioState> audio_state_;
rtc::scoped_ptr<RtpHeaderParser> rtp_header_parser_;
rtc::scoped_ptr<voe::ChannelProxy> channel_proxy_;
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AudioReceiveStream);
};

View File

@ -14,6 +14,7 @@
#include "webrtc/audio/conversion.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/test/mock_voe_channel_proxy.h"
#include "webrtc/test/mock_voice_engine.h"
namespace webrtc {
@ -53,6 +54,8 @@ const AudioDecodingCallStats kAudioDecodeStats = MakeAudioDecodeStatsForTest();
struct ConfigHelper {
ConfigHelper() {
using testing::Invoke;
EXPECT_CALL(voice_engine_,
RegisterVoiceEngineObserver(_)).WillOnce(Return(0));
EXPECT_CALL(voice_engine_,
@ -61,8 +64,13 @@ struct ConfigHelper {
config.voice_engine = &voice_engine_;
audio_state_ = AudioState::Create(config);
EXPECT_CALL(voice_engine_, SetLocalSSRC(kChannelId, kLocalSsrc))
.WillOnce(Return(0));
EXPECT_CALL(voice_engine_, ChannelProxyFactory(kChannelId))
.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_,
SetReceiveAbsoluteSenderTimeStatus(kChannelId, true, kAbsSendTimeId))
.WillOnce(Return(0));
@ -76,7 +84,7 @@ struct ConfigHelper {
RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeId));
stream_config_.rtp.extensions.push_back(
RtpExtension(RtpExtension::kAudioLevel, kAudioLevelId));
}
}
MockRemoteBitrateEstimator* remote_bitrate_estimator() {
return &remote_bitrate_estimator_;
@ -89,6 +97,7 @@ struct ConfigHelper {
using testing::DoAll;
using testing::SetArgPointee;
using testing::SetArgReferee;
EXPECT_CALL(voice_engine_, GetRTCPStatistics(kChannelId, _))
.WillOnce(DoAll(SetArgReferee<1>(kCallStats), Return(0)));
EXPECT_CALL(voice_engine_, GetRecCodec(kChannelId, _))
@ -110,6 +119,7 @@ struct ConfigHelper {
testing::StrictMock<MockVoiceEngine> voice_engine_;
rtc::scoped_refptr<AudioState> audio_state_;
AudioReceiveStream::Config stream_config_;
testing::StrictMock<MockVoEChannelProxy>* channel_proxy_ = nullptr;
};
void BuildAbsoluteSendTimeExtension(uint8_t* buffer,

View File

@ -17,10 +17,12 @@
#include "webrtc/audio/scoped_voe_interface.h"
#include "webrtc/base/checks.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_codec.h"
#include "webrtc/voice_engine/include/voe_rtp_rtcp.h"
#include "webrtc/voice_engine/include/voe_volume_control.h"
#include "webrtc/voice_engine/voice_engine_impl.h"
namespace webrtc {
std::string AudioSendStream::Config::Rtp::ToString() const {
@ -51,7 +53,6 @@ std::string AudioSendStream::Config::ToString() const {
}
namespace internal {
AudioSendStream::AudioSendStream(
const webrtc::AudioSendStream::Config& config,
const rtc::scoped_refptr<webrtc::AudioState>& audio_state)
@ -60,25 +61,25 @@ AudioSendStream::AudioSendStream(
RTC_DCHECK_NE(config_.voe_channel_id, -1);
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;
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) {
// One-byte-extension local identifiers are in the range 1-14 inclusive.
RTC_DCHECK_GE(extension.id, 1);
RTC_DCHECK_LE(extension.id, 14);
if (extension.name == RtpExtension::kAbsSendTime) {
error = rtp->SetSendAbsoluteSenderTimeStatus(channel_id, true,
extension.id);
int error = rtp->SetSendAbsoluteSenderTimeStatus(channel_id, true,
extension.id);
RTC_DCHECK_EQ(0, error);
} else if (extension.name == RtpExtension::kAudioLevel) {
error = rtp->SetSendAudioLevelIndicationStatus(channel_id, true,
extension.id);
int error = rtp->SetSendAudioLevelIndicationStatus(channel_id, true,
extension.id);
RTC_DCHECK_EQ(0, error);
} else {
RTC_NOTREACHED() << "Registering unsupported RTP extension.";

View File

@ -14,13 +14,16 @@
#include "webrtc/audio_send_stream.h"
#include "webrtc/audio_state.h"
#include "webrtc/base/thread_checker.h"
#include "webrtc/base/scoped_ptr.h"
namespace webrtc {
class VoiceEngine;
namespace internal {
namespace voe {
class ChannelProxy;
} // namespace voe
namespace internal {
class AudioSendStream final : public webrtc::AudioSendStream {
public:
AudioSendStream(const webrtc::AudioSendStream::Config& config,
@ -44,6 +47,7 @@ class AudioSendStream final : public webrtc::AudioSendStream {
rtc::ThreadChecker thread_checker_;
const webrtc::AudioSendStream::Config config_;
rtc::scoped_refptr<webrtc::AudioState> audio_state_;
rtc::scoped_ptr<voe::ChannelProxy> channel_proxy_;
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AudioSendStream);
};

View File

@ -13,6 +13,7 @@
#include "webrtc/audio/audio_send_stream.h"
#include "webrtc/audio/audio_state.h"
#include "webrtc/audio/conversion.h"
#include "webrtc/test/mock_voe_channel_proxy.h"
#include "webrtc/test/mock_voice_engine.h"
namespace webrtc {
@ -39,6 +40,7 @@ const ReportBlock kReportBlock = {456, 780, 123, 567, 890, 132, 143, 13354};
struct ConfigHelper {
ConfigHelper() : stream_config_(nullptr) {
using testing::Invoke;
using testing::StrEq;
EXPECT_CALL(voice_engine_,
@ -49,12 +51,15 @@ struct ConfigHelper {
config.voice_engine = &voice_engine_;
audio_state_ = AudioState::Create(config);
EXPECT_CALL(voice_engine_, SetRTCPStatus(kChannelId, true))
.WillOnce(Return(0));
EXPECT_CALL(voice_engine_, SetLocalSSRC(kChannelId, kSsrc))
.WillOnce(Return(0));
EXPECT_CALL(voice_engine_, SetRTCP_CNAME(kChannelId, StrEq(kCName)))
.WillOnce(Return(0));
EXPECT_CALL(voice_engine_, ChannelProxyFactory(kChannelId))
.WillOnce(Invoke([this](int channel_id) {
EXPECT_FALSE(channel_proxy_);
channel_proxy_ = new testing::StrictMock<MockVoEChannelProxy>();
EXPECT_CALL(*channel_proxy_, SetRTCPStatus(true)).Times(1);
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_,
SetSendAbsoluteSenderTimeStatus(kChannelId, true, kAbsSendTimeId))
.WillOnce(Return(0));
@ -109,6 +114,7 @@ struct ConfigHelper {
testing::StrictMock<MockVoiceEngine> voice_engine_;
rtc::scoped_refptr<AudioState> audio_state_;
AudioSendStream::Config stream_config_;
testing::StrictMock<MockVoEChannelProxy>* channel_proxy_ = nullptr;
};
} // namespace

View 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_

View File

@ -12,6 +12,7 @@
#define WEBRTC_AUDIO_MOCK_VOICE_ENGINE_H_
#include "testing/gmock/include/gmock/gmock.h"
#include "webrtc/test/mock_voe_channel_proxy.h"
#include "webrtc/voice_engine/voice_engine_impl.h"
namespace webrtc {
@ -25,12 +26,26 @@ class MockVoiceEngine : public VoiceEngineImpl {
// Increase ref count so this object isn't automatically deleted whenever
// interfaces are Release():d.
++_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 {
// Decrease ref count before base class d-tor is called; otherwise it will
// trigger an assertion.
--_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
MOCK_METHOD2(SetNsStatus, int(bool enable, NsModes mode));

View File

@ -37,6 +37,7 @@
'layer_filtering_transport.cc',
'layer_filtering_transport.h',
'mock_transport.h',
'mock_voe_channel_proxy.h',
'mock_voice_engine.h',
'null_transport.cc',
'null_transport.h',

View File

@ -14,6 +14,8 @@ source_set("voice_engine") {
"channel.h",
"channel_manager.cc",
"channel_manager.h",
"channel_proxy.cc",
"channel_proxy.h",
"dtmf_inband.cc",
"dtmf_inband.h",
"dtmf_inband_queue.cc",

View 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

View 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_

View File

@ -47,7 +47,7 @@ VoEBaseImpl::~VoEBaseImpl() {
delete &callbackCritSect_;
}
void VoEBaseImpl::OnErrorIsReported(ErrorCode error) {
void VoEBaseImpl::OnErrorIsReported(const ErrorCode error) {
CriticalSectionScoped cs(&callbackCritSect_);
int errCode = 0;
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_);
int warningCode = 0;
if (warning == AudioDeviceObserver::kRecordingWarning) {
@ -79,21 +79,28 @@ void VoEBaseImpl::OnWarningIsReported(WarningCode warning) {
}
}
int32_t VoEBaseImpl::RecordedDataIsAvailable(
const void* audioSamples, size_t nSamples, size_t nBytesPerSample,
uint8_t nChannels, uint32_t samplesPerSec, uint32_t totalDelayMS,
int32_t clockDrift, uint32_t micLevel, bool keyPressed,
uint32_t& newMicLevel) {
int32_t VoEBaseImpl::RecordedDataIsAvailable(const void* audioSamples,
const size_t nSamples,
const size_t nBytesPerSample,
const uint8_t nChannels,
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(
nullptr, 0, audioSamples, samplesPerSec, nChannels, nSamples,
totalDelayMS, clockDrift, micLevel, keyPressed));
totalDelayMS, clockDrift, currentMicLevel, keyPressed));
return 0;
}
int32_t VoEBaseImpl::NeedMorePlayData(size_t nSamples,
size_t nBytesPerSample,
uint8_t nChannels, uint32_t samplesPerSec,
void* audioSamples, size_t& nSamplesOut,
int32_t VoEBaseImpl::NeedMorePlayData(const size_t nSamples,
const size_t nBytesPerSample,
const uint8_t nChannels,
const uint32_t samplesPerSec,
void* audioSamples,
size_t& nSamplesOut,
int64_t* elapsed_time_ms,
int64_t* ntp_time_ms) {
GetPlayoutData(static_cast<int>(samplesPerSec), static_cast<int>(nChannels),

View File

@ -54,37 +54,57 @@ class VoEBaseImpl : public VoEBase,
int AssociateSendChannel(int channel, int accociate_send_channel) override;
// AudioTransport
int32_t RecordedDataIsAvailable(const void* audioSamples, size_t nSamples,
size_t nBytesPerSample, uint8_t nChannels,
uint32_t samplesPerSec, uint32_t totalDelayMS,
int32_t clockDrift, uint32_t micLevel,
bool keyPressed,
int32_t RecordedDataIsAvailable(const void* audioSamples,
const size_t nSamples,
const size_t nBytesPerSample,
const uint8_t nChannels,
const uint32_t samplesPerSec,
const uint32_t totalDelayMS,
const int32_t clockDrift,
const uint32_t currentMicLevel,
const bool keyPressed,
uint32_t& newMicLevel) override;
int32_t NeedMorePlayData(size_t nSamples, size_t nBytesPerSample,
uint8_t nChannels, uint32_t samplesPerSec,
void* audioSamples, size_t& nSamplesOut,
int32_t NeedMorePlayData(const size_t nSamples,
const size_t nBytesPerSample,
const uint8_t nChannels,
const uint32_t samplesPerSec,
void* audioSamples,
size_t& nSamplesOut,
int64_t* elapsed_time_ms,
int64_t* ntp_time_ms) override;
int OnDataAvailable(const int voe_channels[], int number_of_voe_channels,
const int16_t* audio_data, int sample_rate,
int number_of_channels, size_t number_of_frames,
int audio_delay_milliseconds, int 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,
int OnDataAvailable(const int voe_channels[],
int number_of_voe_channels,
const int16_t* audio_data,
int sample_rate,
int number_of_channels,
size_t number_of_frames,
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;
void PushCaptureData(int voe_channel, const void* audio_data,
int bits_per_sample, int sample_rate,
void PushCaptureData(int voe_channel,
const void* audio_data,
int bits_per_sample,
int sample_rate,
int number_of_channels,
size_t number_of_frames) override;
void PullRenderData(int bits_per_sample, int sample_rate,
int number_of_channels, size_t number_of_frames,
void* audio_data, int64_t* elapsed_time_ms,
void PullRenderData(int bits_per_sample,
int sample_rate,
int number_of_channels,
size_t number_of_frames,
void* audio_data,
int64_t* elapsed_time_ms,
int64_t* ntp_time_ms) override;
// AudioDeviceObserver
void OnErrorIsReported(ErrorCode error) override;
void OnWarningIsReported(WarningCode warning) override;
void OnErrorIsReported(const ErrorCode error) override;
void OnWarningIsReported(const WarningCode warning) override;
protected:
VoEBaseImpl(voe::SharedData* shared);

View File

@ -49,6 +49,8 @@
'channel.h',
'channel_manager.cc',
'channel_manager.h',
'channel_proxy.cc',
'channel_proxy.h',
'dtmf_inband.cc',
'dtmf_inband.h',
'dtmf_inband_queue.cc',

View File

@ -15,8 +15,11 @@
#include "webrtc/modules/utility/include/jvm_android.h"
#endif
#include "webrtc/base/checks.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/voice_engine/channel_proxy.h"
#include "webrtc/voice_engine/voice_engine_impl.h"
namespace webrtc {
@ -77,6 +80,15 @@ int VoiceEngineImpl::Release() {
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() {
Config* config = new Config();
return GetVoiceEngine(config, true);

View File

@ -11,6 +11,7 @@
#ifndef 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/system_wrappers/include/atomic32.h"
#include "webrtc/voice_engine/voe_base_impl.h"
@ -48,6 +49,9 @@
#endif
namespace webrtc {
namespace voe {
class ChannelProxy;
} // namespace voe
class VoiceEngineImpl : public voe::SharedData, // Must be the first base class
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.
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
// manipulate the reference count. See: fake_voice_engine.h.
protected: