Remove Soundclip handling from libjingle.
BUG= R=pthatcher@webrtc.org Review URL: https://webrtc-codereview.appspot.com/51009004 Cr-Commit-Position: refs/heads/master@{#9216}
This commit is contained in:
parent
1ab67aef80
commit
ccb49e79fd
@ -276,7 +276,7 @@ rtc::Thread* PeerConnectionFactory::worker_thread() {
|
||||
cricket::MediaEngineInterface* PeerConnectionFactory::CreateMediaEngine_w() {
|
||||
ASSERT(worker_thread_ == rtc::Thread::Current());
|
||||
return cricket::WebRtcMediaEngineFactory::Create(
|
||||
default_adm_.get(), NULL, video_encoder_factory_.get(),
|
||||
default_adm_.get(), video_encoder_factory_.get(),
|
||||
video_decoder_factory_.get());
|
||||
}
|
||||
|
||||
|
@ -673,8 +673,6 @@
|
||||
'session/media/mediasink.h',
|
||||
'session/media/rtcpmuxfilter.cc',
|
||||
'session/media/rtcpmuxfilter.h',
|
||||
'session/media/soundclip.cc',
|
||||
'session/media/soundclip.h',
|
||||
'session/media/srtpfilter.cc',
|
||||
'session/media/srtpfilter.h',
|
||||
'session/media/typingmonitor.cc',
|
||||
|
@ -630,11 +630,6 @@ class FakeVideoMediaChannel : public RtpHelper<VideoMediaChannel> {
|
||||
int max_bps_;
|
||||
};
|
||||
|
||||
class FakeSoundclipMedia : public SoundclipMedia {
|
||||
public:
|
||||
virtual bool PlaySound(const char* buf, int len, int flags) { return true; }
|
||||
};
|
||||
|
||||
class FakeDataMediaChannel : public RtpHelper<DataMediaChannel> {
|
||||
public:
|
||||
explicit FakeDataMediaChannel(void* unused)
|
||||
@ -784,7 +779,6 @@ class FakeVoiceEngine : public FakeBaseEngine {
|
||||
void UnregisterChannel(VoiceMediaChannel* channel) {
|
||||
channels_.erase(std::find(channels_.begin(), channels_.end(), channel));
|
||||
}
|
||||
SoundclipMedia* CreateSoundclip() { return new FakeSoundclipMedia(); }
|
||||
|
||||
const std::vector<AudioCodec>& codecs() { return codecs_; }
|
||||
void SetCodecs(const std::vector<AudioCodec> codecs) { codecs_ = codecs; }
|
||||
|
@ -88,7 +88,6 @@ class FileMediaEngine : public MediaEngineInterface {
|
||||
virtual VoiceMediaChannel* CreateChannel();
|
||||
virtual VideoMediaChannel* CreateVideoChannel(const VideoOptions& options,
|
||||
VoiceMediaChannel* voice_ch);
|
||||
virtual SoundclipMedia* CreateSoundclip() { return NULL; }
|
||||
virtual AudioOptions GetAudioOptions() const { return AudioOptions(); }
|
||||
virtual bool SetAudioOptions(const AudioOptions& options) { return true; }
|
||||
virtual bool SetAudioDelayOffset(int offset) { return true; }
|
||||
|
@ -215,7 +215,6 @@ TEST_F(FileMediaEngineTest, TestDefaultImplementation) {
|
||||
EXPECT_EQ(0, engine_->GetCapabilities());
|
||||
EXPECT_TRUE(NULL == voice_channel_.get());
|
||||
EXPECT_TRUE(NULL == video_channel_.get());
|
||||
EXPECT_TRUE(NULL == engine_->CreateSoundclip());
|
||||
cricket::AudioOptions audio_options;
|
||||
EXPECT_TRUE(engine_->SetAudioOptions(audio_options));
|
||||
VideoEncoderConfig video_encoder_config;
|
||||
|
@ -446,22 +446,6 @@ struct VideoOptions {
|
||||
Settable<int> screencast_min_bitrate;
|
||||
};
|
||||
|
||||
// A class for playing out soundclips.
|
||||
class SoundclipMedia {
|
||||
public:
|
||||
enum SoundclipFlags {
|
||||
SF_LOOP = 1,
|
||||
};
|
||||
|
||||
virtual ~SoundclipMedia() {}
|
||||
|
||||
// Plays a sound out to the speakers with the given audio stream. The stream
|
||||
// must be 16-bit little-endian 16 kHz PCM. If a stream is already playing
|
||||
// on this SoundclipMedia, it is stopped. If clip is NULL, nothing is played.
|
||||
// Returns whether it was successful.
|
||||
virtual bool PlaySound(const char *clip, int len, int flags) = 0;
|
||||
};
|
||||
|
||||
struct RtpHeaderExtension {
|
||||
RtpHeaderExtension() : id(0) {}
|
||||
RtpHeaderExtension(const std::string& u, int i) : uri(u), id(i) {}
|
||||
|
@ -84,9 +84,6 @@ class MediaEngineInterface {
|
||||
const VideoOptions& options,
|
||||
VoiceMediaChannel* voice_media_channel) = 0;
|
||||
|
||||
// Creates a soundclip object for playing sounds on. Returns NULL on failure.
|
||||
virtual SoundclipMedia *CreateSoundclip() = 0;
|
||||
|
||||
// Configuration
|
||||
// Gets global audio options.
|
||||
virtual AudioOptions GetAudioOptions() const = 0;
|
||||
@ -101,7 +98,6 @@ class MediaEngineInterface {
|
||||
= 0;
|
||||
|
||||
// Device selection
|
||||
// TODO(tschmelcher): Add method for selecting the soundclip device.
|
||||
virtual bool SetSoundDevices(const Device* in_device,
|
||||
const Device* out_device) = 0;
|
||||
|
||||
@ -193,9 +189,6 @@ class CompositeMediaEngine : public MediaEngineInterface {
|
||||
VoiceMediaChannel* channel) {
|
||||
return video_.CreateChannel(options, channel);
|
||||
}
|
||||
virtual SoundclipMedia *CreateSoundclip() {
|
||||
return voice_.CreateSoundclip();
|
||||
}
|
||||
|
||||
virtual AudioOptions GetAudioOptions() const {
|
||||
return voice_.GetOptions();
|
||||
@ -279,9 +272,6 @@ class NullVoiceEngine {
|
||||
VoiceMediaChannel* CreateChannel() {
|
||||
return NULL;
|
||||
}
|
||||
SoundclipMedia* CreateSoundclip() {
|
||||
return NULL;
|
||||
}
|
||||
bool SetDelayOffset(int offset) { return true; }
|
||||
AudioOptions GetOptions() const { return AudioOptions(); }
|
||||
bool SetOptions(const AudioOptions& options) { return true; }
|
||||
|
@ -68,7 +68,6 @@ class LinphoneMediaEngine : public MediaEngineInterface {
|
||||
virtual int GetCapabilities();
|
||||
virtual VoiceMediaChannel* CreateChannel();
|
||||
virtual VideoMediaChannel* CreateVideoChannel(VoiceMediaChannel* voice_ch);
|
||||
virtual SoundclipMedia* CreateSoundclip() { return NULL; }
|
||||
virtual bool SetAudioOptions(int options) { return true; }
|
||||
virtual bool SetDefaultVideoEncoderConfig(const VideoEncoderConfig& config) {
|
||||
return true;
|
||||
|
@ -37,10 +37,9 @@ class WebRtcMediaEngine2
|
||||
: public CompositeMediaEngine<WebRtcVoiceEngine, WebRtcVideoEngine2> {
|
||||
public:
|
||||
WebRtcMediaEngine2(webrtc::AudioDeviceModule* adm,
|
||||
webrtc::AudioDeviceModule* adm_sc,
|
||||
WebRtcVideoEncoderFactory* encoder_factory,
|
||||
WebRtcVideoDecoderFactory* decoder_factory) {
|
||||
voice_.SetAudioDeviceModule(adm, adm_sc);
|
||||
voice_.SetAudioDeviceModule(adm);
|
||||
video_.SetExternalDecoderFactory(decoder_factory);
|
||||
video_.SetExternalEncoderFactory(encoder_factory);
|
||||
}
|
||||
@ -51,10 +50,9 @@ class WebRtcMediaEngine2
|
||||
WRME_EXPORT
|
||||
cricket::MediaEngineInterface* CreateWebRtcMediaEngine(
|
||||
webrtc::AudioDeviceModule* adm,
|
||||
webrtc::AudioDeviceModule* adm_sc,
|
||||
cricket::WebRtcVideoEncoderFactory* encoder_factory,
|
||||
cricket::WebRtcVideoDecoderFactory* decoder_factory) {
|
||||
return new cricket::WebRtcMediaEngine2(adm, adm_sc, encoder_factory,
|
||||
return new cricket::WebRtcMediaEngine2(adm, encoder_factory,
|
||||
decoder_factory);
|
||||
}
|
||||
|
||||
@ -69,10 +67,9 @@ namespace cricket {
|
||||
// ChannelManager.
|
||||
MediaEngineInterface* WebRtcMediaEngineFactory::Create(
|
||||
webrtc::AudioDeviceModule* adm,
|
||||
webrtc::AudioDeviceModule* adm_sc,
|
||||
WebRtcVideoEncoderFactory* encoder_factory,
|
||||
WebRtcVideoDecoderFactory* decoder_factory) {
|
||||
return CreateWebRtcMediaEngine(adm, adm_sc, encoder_factory, decoder_factory);
|
||||
return CreateWebRtcMediaEngine(adm, encoder_factory, decoder_factory);
|
||||
}
|
||||
|
||||
} // namespace cricket
|
||||
|
@ -45,7 +45,7 @@ class WebRtcVideoEncoderFactory;
|
||||
|
||||
WRME_EXPORT
|
||||
cricket::MediaEngineInterface* CreateWebRtcMediaEngine(
|
||||
webrtc::AudioDeviceModule* adm, webrtc::AudioDeviceModule* adm_sc,
|
||||
webrtc::AudioDeviceModule* adm,
|
||||
cricket::WebRtcVideoEncoderFactory* encoder_factory,
|
||||
cricket::WebRtcVideoDecoderFactory* decoder_factory);
|
||||
|
||||
@ -69,7 +69,6 @@ class WebRtcMediaEngineFactory {
|
||||
// !defined(LIBPEERCONNECTION_IMPLEMENTATION)
|
||||
static MediaEngineInterface* Create(
|
||||
webrtc::AudioDeviceModule* adm,
|
||||
webrtc::AudioDeviceModule* adm_sc,
|
||||
WebRtcVideoEncoderFactory* encoder_factory,
|
||||
WebRtcVideoDecoderFactory* decoder_factory);
|
||||
};
|
||||
@ -88,11 +87,10 @@ class DelegatingWebRtcMediaEngine : public cricket::MediaEngineInterface {
|
||||
public:
|
||||
DelegatingWebRtcMediaEngine(
|
||||
webrtc::AudioDeviceModule* adm,
|
||||
webrtc::AudioDeviceModule* adm_sc,
|
||||
WebRtcVideoEncoderFactory* encoder_factory,
|
||||
WebRtcVideoDecoderFactory* decoder_factory)
|
||||
: delegate_(CreateWebRtcMediaEngine(
|
||||
adm, adm_sc, encoder_factory, decoder_factory)) {
|
||||
adm, encoder_factory, decoder_factory)) {
|
||||
}
|
||||
virtual ~DelegatingWebRtcMediaEngine() {
|
||||
DestroyWebRtcMediaEngine(delegate_);
|
||||
@ -110,9 +108,6 @@ class DelegatingWebRtcMediaEngine : public cricket::MediaEngineInterface {
|
||||
VoiceMediaChannel* voice_media_channel) override {
|
||||
return delegate_->CreateVideoChannel(options, voice_media_channel);
|
||||
}
|
||||
SoundclipMedia* CreateSoundclip() override {
|
||||
return delegate_->CreateSoundclip();
|
||||
}
|
||||
AudioOptions GetAudioOptions() const override {
|
||||
return delegate_->GetAudioOptions();
|
||||
}
|
||||
@ -186,11 +181,10 @@ class DelegatingWebRtcMediaEngine : public cricket::MediaEngineInterface {
|
||||
// ChannelManager.
|
||||
MediaEngineInterface* WebRtcMediaEngineFactory::Create(
|
||||
webrtc::AudioDeviceModule* adm,
|
||||
webrtc::AudioDeviceModule* adm_sc,
|
||||
WebRtcVideoEncoderFactory* encoder_factory,
|
||||
WebRtcVideoDecoderFactory* decoder_factory) {
|
||||
return new cricket::DelegatingWebRtcMediaEngine(
|
||||
adm, adm_sc, encoder_factory, decoder_factory);
|
||||
adm, encoder_factory, decoder_factory);
|
||||
}
|
||||
|
||||
} // namespace cricket
|
||||
|
@ -103,7 +103,6 @@ static const CodecPref kCodecPrefs[] = {
|
||||
|
||||
#ifdef WIN32
|
||||
static const int kDefaultAudioDeviceId = -1;
|
||||
static const int kDefaultSoundclipDeviceId = -2;
|
||||
#else
|
||||
static const int kDefaultAudioDeviceId = 0;
|
||||
#endif
|
||||
@ -368,103 +367,10 @@ static std::string GetEnableString(bool enable) {
|
||||
return enable ? "enable" : "disable";
|
||||
}
|
||||
|
||||
class WebRtcSoundclipMedia : public SoundclipMedia {
|
||||
public:
|
||||
explicit WebRtcSoundclipMedia(WebRtcVoiceEngine *engine)
|
||||
: engine_(engine), webrtc_channel_(-1) {
|
||||
engine_->RegisterSoundclip(this);
|
||||
}
|
||||
|
||||
~WebRtcSoundclipMedia() override {
|
||||
engine_->UnregisterSoundclip(this);
|
||||
if (webrtc_channel_ != -1) {
|
||||
// We shouldn't have to call Disable() here. DeleteChannel() should call
|
||||
// StopPlayout() while deleting the channel. We should fix the bug
|
||||
// inside WebRTC and remove the Disable() call bellow. This work is
|
||||
// tracked by bug http://b/issue?id=5382855.
|
||||
PlaySound(NULL, 0, 0);
|
||||
Disable();
|
||||
if (engine_->voe_sc()->base()->DeleteChannel(webrtc_channel_)
|
||||
== -1) {
|
||||
LOG_RTCERR1(DeleteChannel, webrtc_channel_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Init() {
|
||||
if (!engine_->voe_sc()) {
|
||||
return false;
|
||||
}
|
||||
webrtc_channel_ = engine_->CreateSoundclipVoiceChannel();
|
||||
if (webrtc_channel_ == -1) {
|
||||
LOG_RTCERR0(CreateChannel);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Enable() {
|
||||
if (engine_->voe_sc()->base()->StartPlayout(webrtc_channel_) == -1) {
|
||||
LOG_RTCERR1(StartPlayout, webrtc_channel_);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Disable() {
|
||||
if (engine_->voe_sc()->base()->StopPlayout(webrtc_channel_) == -1) {
|
||||
LOG_RTCERR1(StopPlayout, webrtc_channel_);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PlaySound(const char* buf, int len, int flags) override {
|
||||
// The voe file api is not available in chrome.
|
||||
if (!engine_->voe_sc()->file()) {
|
||||
return false;
|
||||
}
|
||||
// Must stop playing the current sound (if any), because we are about to
|
||||
// modify the stream.
|
||||
if (engine_->voe_sc()->file()->StopPlayingFileLocally(webrtc_channel_)
|
||||
== -1) {
|
||||
LOG_RTCERR1(StopPlayingFileLocally, webrtc_channel_);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (buf) {
|
||||
stream_.reset(new WebRtcSoundclipStream(buf, len));
|
||||
stream_->set_loop((flags & SF_LOOP) != 0);
|
||||
stream_->Rewind();
|
||||
|
||||
// Play it.
|
||||
if (engine_->voe_sc()->file()->StartPlayingFileLocally(
|
||||
webrtc_channel_, stream_.get()) == -1) {
|
||||
LOG_RTCERR2(StartPlayingFileLocally, webrtc_channel_, stream_.get());
|
||||
LOG(LS_ERROR) << "Unable to start soundclip";
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
stream_.reset();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int GetLastEngineError() const { return engine_->voe_sc()->error(); }
|
||||
|
||||
private:
|
||||
WebRtcVoiceEngine *engine_;
|
||||
int webrtc_channel_;
|
||||
rtc::scoped_ptr<WebRtcSoundclipStream> stream_;
|
||||
};
|
||||
|
||||
WebRtcVoiceEngine::WebRtcVoiceEngine()
|
||||
: voe_wrapper_(new VoEWrapper()),
|
||||
voe_wrapper_sc_(new VoEWrapper()),
|
||||
voe_wrapper_sc_initialized_(false),
|
||||
tracing_(new VoETraceWrapper()),
|
||||
adm_(NULL),
|
||||
adm_sc_(NULL),
|
||||
log_filter_(SeverityToFilter(kDefaultLogSeverity)),
|
||||
is_dumping_aec_(false),
|
||||
desired_local_monitor_enable_(false),
|
||||
@ -474,14 +380,10 @@ WebRtcVoiceEngine::WebRtcVoiceEngine()
|
||||
}
|
||||
|
||||
WebRtcVoiceEngine::WebRtcVoiceEngine(VoEWrapper* voe_wrapper,
|
||||
VoEWrapper* voe_wrapper_sc,
|
||||
VoETraceWrapper* tracing)
|
||||
: voe_wrapper_(voe_wrapper),
|
||||
voe_wrapper_sc_(voe_wrapper_sc),
|
||||
voe_wrapper_sc_initialized_(false),
|
||||
tracing_(tracing),
|
||||
adm_(NULL),
|
||||
adm_sc_(NULL),
|
||||
log_filter_(SeverityToFilter(kDefaultLogSeverity)),
|
||||
is_dumping_aec_(false),
|
||||
desired_local_monitor_enable_(false),
|
||||
@ -593,11 +495,6 @@ WebRtcVoiceEngine::~WebRtcVoiceEngine() {
|
||||
adm_->Release();
|
||||
adm_ = NULL;
|
||||
}
|
||||
if (adm_sc_) {
|
||||
voe_wrapper_sc_.reset();
|
||||
adm_sc_->Release();
|
||||
adm_sc_ = NULL;
|
||||
}
|
||||
|
||||
// Test to see if the media processor was deregistered properly
|
||||
DCHECK(SignalRxMediaFrame.is_empty());
|
||||
@ -673,61 +570,12 @@ bool WebRtcVoiceEngine::InitInternal() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WebRtcVoiceEngine::EnsureSoundclipEngineInit() {
|
||||
if (voe_wrapper_sc_initialized_) {
|
||||
return true;
|
||||
}
|
||||
// Note that, if initialization fails, voe_wrapper_sc_initialized_ will still
|
||||
// be false, so subsequent calls to EnsureSoundclipEngineInit will
|
||||
// probably just fail again. That's acceptable behavior.
|
||||
#if defined(LINUX) && !defined(HAVE_LIBPULSE)
|
||||
voe_wrapper_sc_->hw()->SetAudioDeviceLayer(webrtc::kAudioLinuxAlsa);
|
||||
#endif
|
||||
|
||||
// Initialize the VoiceEngine instance that we'll use to play out sound clips.
|
||||
if (voe_wrapper_sc_->base()->Init(adm_sc_) == -1) {
|
||||
LOG_RTCERR0_EX(Init, voe_wrapper_sc_->error());
|
||||
return false;
|
||||
}
|
||||
|
||||
// On Windows, tell it to use the default sound (not communication) devices.
|
||||
// First check whether there is a valid sound device for playback.
|
||||
// TODO(juberti): Clean this up when we support setting the soundclip device.
|
||||
#ifdef WIN32
|
||||
// The SetPlayoutDevice may not be implemented in the case of external ADM.
|
||||
// TODO(ronghuawu): We should only check the adm_sc_ here, but current
|
||||
// PeerConnection interface never set the adm_sc_, so need to check both
|
||||
// in order to determine if the external adm is used.
|
||||
if (!adm_ && !adm_sc_) {
|
||||
int num_of_devices = 0;
|
||||
if (voe_wrapper_sc_->hw()->GetNumOfPlayoutDevices(num_of_devices) != -1 &&
|
||||
num_of_devices > 0) {
|
||||
if (voe_wrapper_sc_->hw()->SetPlayoutDevice(kDefaultSoundclipDeviceId)
|
||||
== -1) {
|
||||
LOG_RTCERR1_EX(SetPlayoutDevice, kDefaultSoundclipDeviceId,
|
||||
voe_wrapper_sc_->error());
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
LOG(LS_WARNING) << "No valid sound playout device found.";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
voe_wrapper_sc_initialized_ = true;
|
||||
LOG(LS_INFO) << "Initialized WebRtc soundclip engine.";
|
||||
return true;
|
||||
}
|
||||
|
||||
void WebRtcVoiceEngine::Terminate() {
|
||||
LOG(LS_INFO) << "WebRtcVoiceEngine::Terminate";
|
||||
initialized_ = false;
|
||||
|
||||
StopAecDump();
|
||||
|
||||
if (voe_wrapper_sc_) {
|
||||
voe_wrapper_sc_initialized_ = false;
|
||||
voe_wrapper_sc_->base()->Terminate();
|
||||
}
|
||||
voe_wrapper_->base()->Terminate();
|
||||
desired_local_monitor_enable_ = false;
|
||||
}
|
||||
@ -745,20 +593,6 @@ VoiceMediaChannel *WebRtcVoiceEngine::CreateChannel() {
|
||||
return ch;
|
||||
}
|
||||
|
||||
SoundclipMedia *WebRtcVoiceEngine::CreateSoundclip() {
|
||||
if (!EnsureSoundclipEngineInit()) {
|
||||
LOG(LS_ERROR) << "Unable to create soundclip: soundclip engine failed to "
|
||||
<< "initialize.";
|
||||
return NULL;
|
||||
}
|
||||
WebRtcSoundclipMedia *soundclip = new WebRtcSoundclipMedia(this);
|
||||
if (!soundclip->Init() || !soundclip->Enable()) {
|
||||
delete soundclip;
|
||||
return NULL;
|
||||
}
|
||||
return soundclip;
|
||||
}
|
||||
|
||||
bool WebRtcVoiceEngine::SetOptions(const AudioOptions& options) {
|
||||
if (!ApplyOptions(options)) {
|
||||
return false;
|
||||
@ -1532,19 +1366,6 @@ void WebRtcVoiceEngine::UnregisterChannel(WebRtcVoiceMediaChannel *channel) {
|
||||
}
|
||||
}
|
||||
|
||||
void WebRtcVoiceEngine::RegisterSoundclip(WebRtcSoundclipMedia *soundclip) {
|
||||
soundclips_.push_back(soundclip);
|
||||
}
|
||||
|
||||
void WebRtcVoiceEngine::UnregisterSoundclip(WebRtcSoundclipMedia *soundclip) {
|
||||
SoundclipList::iterator i = std::find(soundclips_.begin(),
|
||||
soundclips_.end(),
|
||||
soundclip);
|
||||
if (i != soundclips_.end()) {
|
||||
soundclips_.erase(i);
|
||||
}
|
||||
}
|
||||
|
||||
// Adjusts the default AGC target level by the specified delta.
|
||||
// NB: If we start messing with other config fields, we'll want
|
||||
// to save the current webrtc::AgcConfig as well.
|
||||
@ -1563,8 +1384,7 @@ bool WebRtcVoiceEngine::AdjustAgcLevel(int delta) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WebRtcVoiceEngine::SetAudioDeviceModule(webrtc::AudioDeviceModule* adm,
|
||||
webrtc::AudioDeviceModule* adm_sc) {
|
||||
bool WebRtcVoiceEngine::SetAudioDeviceModule(webrtc::AudioDeviceModule* adm) {
|
||||
if (initialized_) {
|
||||
LOG(LS_WARNING) << "SetAudioDeviceModule can not be called after Init.";
|
||||
return false;
|
||||
@ -1577,15 +1397,6 @@ bool WebRtcVoiceEngine::SetAudioDeviceModule(webrtc::AudioDeviceModule* adm,
|
||||
adm_ = adm;
|
||||
adm_->AddRef();
|
||||
}
|
||||
|
||||
if (adm_sc_) {
|
||||
adm_sc_->Release();
|
||||
adm_sc_ = NULL;
|
||||
}
|
||||
if (adm_sc) {
|
||||
adm_sc_ = adm_sc;
|
||||
adm_sc_->AddRef();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1791,10 +1602,6 @@ int WebRtcVoiceEngine::CreateMediaVoiceChannel() {
|
||||
return CreateVoiceChannel(voe_wrapper_.get());
|
||||
}
|
||||
|
||||
int WebRtcVoiceEngine::CreateSoundclipVoiceChannel() {
|
||||
return CreateVoiceChannel(voe_wrapper_sc_.get());
|
||||
}
|
||||
|
||||
class WebRtcVoiceMediaChannel::WebRtcVoiceChannelRenderer
|
||||
: public AudioRenderer::Sink {
|
||||
public:
|
||||
|
@ -91,7 +91,6 @@ class AudioRenderer;
|
||||
class VoETraceWrapper;
|
||||
class VoEWrapper;
|
||||
class VoiceProcessor;
|
||||
class WebRtcSoundclipMedia;
|
||||
class WebRtcVoiceMediaChannel;
|
||||
|
||||
// WebRtcVoiceEngine is a class to be used with CompositeMediaEngine.
|
||||
@ -103,9 +102,7 @@ class WebRtcVoiceEngine
|
||||
public:
|
||||
WebRtcVoiceEngine();
|
||||
// Dependency injection for testing.
|
||||
WebRtcVoiceEngine(VoEWrapper* voe_wrapper,
|
||||
VoEWrapper* voe_wrapper_sc,
|
||||
VoETraceWrapper* tracing);
|
||||
WebRtcVoiceEngine(VoEWrapper* voe_wrapper, VoETraceWrapper* tracing);
|
||||
~WebRtcVoiceEngine();
|
||||
bool Init(rtc::Thread* worker_thread);
|
||||
void Terminate();
|
||||
@ -113,8 +110,6 @@ class WebRtcVoiceEngine
|
||||
int GetCapabilities();
|
||||
VoiceMediaChannel* CreateChannel();
|
||||
|
||||
SoundclipMedia* CreateSoundclip();
|
||||
|
||||
AudioOptions GetOptions() const { return options_; }
|
||||
bool SetOptions(const AudioOptions& options);
|
||||
// Overrides, when set, take precedence over the options on a
|
||||
@ -166,21 +161,15 @@ class WebRtcVoiceEngine
|
||||
void RegisterChannel(WebRtcVoiceMediaChannel *channel);
|
||||
void UnregisterChannel(WebRtcVoiceMediaChannel *channel);
|
||||
|
||||
// May only be called by WebRtcSoundclipMedia.
|
||||
void RegisterSoundclip(WebRtcSoundclipMedia *channel);
|
||||
void UnregisterSoundclip(WebRtcSoundclipMedia *channel);
|
||||
|
||||
// Called by WebRtcVoiceMediaChannel to set a gain offset from
|
||||
// the default AGC target level.
|
||||
bool AdjustAgcLevel(int delta);
|
||||
|
||||
VoEWrapper* voe() { return voe_wrapper_.get(); }
|
||||
VoEWrapper* voe_sc() { return voe_wrapper_sc_.get(); }
|
||||
int GetLastEngineError();
|
||||
|
||||
// Set the external ADMs. This can only be called before Init.
|
||||
bool SetAudioDeviceModule(webrtc::AudioDeviceModule* adm,
|
||||
webrtc::AudioDeviceModule* adm_sc);
|
||||
// Set the external ADM. This can only be called before Init.
|
||||
bool SetAudioDeviceModule(webrtc::AudioDeviceModule* adm);
|
||||
|
||||
// Starts AEC dump using existing file.
|
||||
bool StartAecDump(rtc::PlatformFile file);
|
||||
@ -190,10 +179,8 @@ class WebRtcVoiceEngine
|
||||
|
||||
// Create a VoiceEngine Channel.
|
||||
int CreateMediaVoiceChannel();
|
||||
int CreateSoundclipVoiceChannel();
|
||||
|
||||
private:
|
||||
typedef std::vector<WebRtcSoundclipMedia *> SoundclipList;
|
||||
typedef std::vector<WebRtcVoiceMediaChannel *> ChannelList;
|
||||
typedef sigslot::
|
||||
signal3<uint32, MediaProcessorDirection, AudioFrame*> FrameSignal;
|
||||
@ -202,7 +189,6 @@ class WebRtcVoiceEngine
|
||||
void ConstructCodecs();
|
||||
bool GetVoeCodec(int index, webrtc::CodecInst* codec);
|
||||
bool InitInternal();
|
||||
bool EnsureSoundclipEngineInit();
|
||||
void SetTraceFilter(int filter);
|
||||
void SetTraceOptions(const std::string& options);
|
||||
// Applies either options or overrides. Every option that is "set"
|
||||
@ -250,13 +236,9 @@ class WebRtcVoiceEngine
|
||||
|
||||
// The primary instance of WebRtc VoiceEngine.
|
||||
rtc::scoped_ptr<VoEWrapper> voe_wrapper_;
|
||||
// A secondary instance, for playing out soundclips (on the 'ring' device).
|
||||
rtc::scoped_ptr<VoEWrapper> voe_wrapper_sc_;
|
||||
bool voe_wrapper_sc_initialized_;
|
||||
rtc::scoped_ptr<VoETraceWrapper> tracing_;
|
||||
// The external audio device manager
|
||||
webrtc::AudioDeviceModule* adm_;
|
||||
webrtc::AudioDeviceModule* adm_sc_;
|
||||
int log_filter_;
|
||||
std::string log_options_;
|
||||
bool is_dumping_aec_;
|
||||
@ -264,7 +246,6 @@ class WebRtcVoiceEngine
|
||||
std::vector<RtpHeaderExtension> rtp_header_extensions_;
|
||||
bool desired_local_monitor_enable_;
|
||||
rtc::scoped_ptr<WebRtcMonitorStream> monitor_;
|
||||
SoundclipList soundclips_;
|
||||
ChannelList channels_;
|
||||
// channels_ can be read from WebRtc callback thread. We need a lock on that
|
||||
// callback as well as the RegisterChannel/UnregisterChannel.
|
||||
|
@ -128,12 +128,10 @@ class WebRtcVoiceEngineTestFake : public testing::Test {
|
||||
|
||||
WebRtcVoiceEngineTestFake()
|
||||
: voe_(kAudioCodecs, ARRAY_SIZE(kAudioCodecs)),
|
||||
voe_sc_(kAudioCodecs, ARRAY_SIZE(kAudioCodecs)),
|
||||
trace_wrapper_(new FakeVoETraceWrapper()),
|
||||
engine_(new FakeVoEWrapper(&voe_),
|
||||
new FakeVoEWrapper(&voe_sc_),
|
||||
trace_wrapper_),
|
||||
channel_(NULL), soundclip_(NULL) {
|
||||
channel_(NULL) {
|
||||
options_conference_.conference_mode.Set(true);
|
||||
options_adjust_agc_.adjust_agc_delta.Set(-10);
|
||||
}
|
||||
@ -168,7 +166,6 @@ class WebRtcVoiceEngineTestFake : public testing::Test {
|
||||
channel_->OnPacketReceived(&packet, rtc::PacketTime());
|
||||
}
|
||||
void TearDown() override {
|
||||
delete soundclip_;
|
||||
delete channel_;
|
||||
engine_.Terminate();
|
||||
}
|
||||
@ -335,11 +332,9 @@ class WebRtcVoiceEngineTestFake : public testing::Test {
|
||||
|
||||
protected:
|
||||
cricket::FakeWebRtcVoiceEngine voe_;
|
||||
cricket::FakeWebRtcVoiceEngine voe_sc_;
|
||||
FakeVoETraceWrapper* trace_wrapper_;
|
||||
cricket::WebRtcVoiceEngine engine_;
|
||||
cricket::VoiceMediaChannel* channel_;
|
||||
cricket::SoundclipMedia* soundclip_;
|
||||
|
||||
cricket::AudioOptions options_conference_;
|
||||
cricket::AudioOptions options_adjust_agc_;
|
||||
@ -348,14 +343,10 @@ class WebRtcVoiceEngineTestFake : public testing::Test {
|
||||
// Tests that our stub library "works".
|
||||
TEST_F(WebRtcVoiceEngineTestFake, StartupShutdown) {
|
||||
EXPECT_FALSE(voe_.IsInited());
|
||||
EXPECT_FALSE(voe_sc_.IsInited());
|
||||
EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
|
||||
EXPECT_TRUE(voe_.IsInited());
|
||||
// The soundclip engine is lazily initialized.
|
||||
EXPECT_FALSE(voe_sc_.IsInited());
|
||||
engine_.Terminate();
|
||||
EXPECT_FALSE(voe_.IsInited());
|
||||
EXPECT_FALSE(voe_sc_.IsInited());
|
||||
}
|
||||
|
||||
// Tests that we can create and destroy a channel.
|
||||
@ -2652,35 +2643,6 @@ TEST_F(WebRtcVoiceEngineTestFake, PlayRingbackWithMultipleStreams) {
|
||||
EXPECT_EQ(0, voe_.IsPlayingFileLocally(channel_num));
|
||||
}
|
||||
|
||||
// Tests creating soundclips, and make sure they come from the right engine.
|
||||
TEST_F(WebRtcVoiceEngineTestFake, CreateSoundclip) {
|
||||
EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
|
||||
EXPECT_FALSE(voe_sc_.IsInited());
|
||||
soundclip_ = engine_.CreateSoundclip();
|
||||
EXPECT_TRUE(voe_sc_.IsInited());
|
||||
ASSERT_TRUE(soundclip_ != NULL);
|
||||
EXPECT_EQ(0, voe_.GetNumChannels());
|
||||
EXPECT_EQ(1, voe_sc_.GetNumChannels());
|
||||
int channel_num = voe_sc_.GetLastChannel();
|
||||
EXPECT_TRUE(voe_sc_.GetPlayout(channel_num));
|
||||
delete soundclip_;
|
||||
soundclip_ = NULL;
|
||||
EXPECT_EQ(0, voe_sc_.GetNumChannels());
|
||||
// Make sure the soundclip engine is uninitialized on shutdown, now that
|
||||
// we've initialized it by creating a soundclip.
|
||||
engine_.Terminate();
|
||||
EXPECT_FALSE(voe_sc_.IsInited());
|
||||
}
|
||||
|
||||
// Tests playing out a fake sound.
|
||||
TEST_F(WebRtcVoiceEngineTestFake, PlaySoundclip) {
|
||||
static const char kZeroes[16000] = {};
|
||||
EXPECT_TRUE(engine_.Init(rtc::Thread::Current()));
|
||||
soundclip_ = engine_.CreateSoundclip();
|
||||
ASSERT_TRUE(soundclip_ != NULL);
|
||||
EXPECT_TRUE(soundclip_->PlaySound(kZeroes, sizeof(kZeroes), 0));
|
||||
}
|
||||
|
||||
TEST_F(WebRtcVoiceEngineTestFake, MediaEngineCallbackOnError) {
|
||||
rtc::scoped_ptr<ChannelErrorListener> listener;
|
||||
cricket::WebRtcVoiceMediaChannel* media_channel;
|
||||
|
@ -41,7 +41,6 @@
|
||||
#ifdef HAVE_SCTP
|
||||
#include "talk/media/sctp/sctpdataengine.h"
|
||||
#endif
|
||||
#include "talk/session/media/soundclip.h"
|
||||
#include "talk/session/media/srtpfilter.h"
|
||||
#include "webrtc/base/bind.h"
|
||||
#include "webrtc/base/common.h"
|
||||
@ -311,9 +310,6 @@ void ChannelManager::Terminate_w() {
|
||||
while (!voice_channels_.empty()) {
|
||||
DestroyVoiceChannel_w(voice_channels_.back(), nullptr);
|
||||
}
|
||||
while (!soundclips_.empty()) {
|
||||
DestroySoundclip_w(soundclips_.back());
|
||||
}
|
||||
if (!SetCaptureDevice_w(NULL)) {
|
||||
LOG(LS_WARNING) << "failed to delete video capturer";
|
||||
}
|
||||
@ -504,45 +500,6 @@ void ChannelManager::DestroyDataChannel_w(DataChannel* data_channel) {
|
||||
delete data_channel;
|
||||
}
|
||||
|
||||
Soundclip* ChannelManager::CreateSoundclip() {
|
||||
return worker_thread_->Invoke<Soundclip*>(
|
||||
Bind(&ChannelManager::CreateSoundclip_w, this));
|
||||
}
|
||||
|
||||
Soundclip* ChannelManager::CreateSoundclip_w() {
|
||||
ASSERT(initialized_);
|
||||
ASSERT(worker_thread_ == rtc::Thread::Current());
|
||||
|
||||
SoundclipMedia* soundclip_media = media_engine_->CreateSoundclip();
|
||||
if (!soundclip_media) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Soundclip* soundclip = new Soundclip(worker_thread_, soundclip_media);
|
||||
soundclips_.push_back(soundclip);
|
||||
return soundclip;
|
||||
}
|
||||
|
||||
void ChannelManager::DestroySoundclip(Soundclip* soundclip) {
|
||||
if (soundclip) {
|
||||
worker_thread_->Invoke<void>(
|
||||
Bind(&ChannelManager::DestroySoundclip_w, this, soundclip));
|
||||
}
|
||||
}
|
||||
|
||||
void ChannelManager::DestroySoundclip_w(Soundclip* soundclip) {
|
||||
// Destroy soundclip.
|
||||
ASSERT(initialized_);
|
||||
Soundclips::iterator it = std::find(soundclips_.begin(),
|
||||
soundclips_.end(), soundclip);
|
||||
ASSERT(it != soundclips_.end());
|
||||
if (it == soundclips_.end())
|
||||
return;
|
||||
|
||||
soundclips_.erase(it);
|
||||
delete soundclip;
|
||||
}
|
||||
|
||||
bool ChannelManager::GetAudioOptions(std::string* in_name,
|
||||
std::string* out_name,
|
||||
AudioOptions* options) {
|
||||
|
@ -44,7 +44,6 @@ namespace cricket {
|
||||
|
||||
const int kDefaultAudioDelayOffset = 0;
|
||||
|
||||
class Soundclip;
|
||||
class VideoProcessor;
|
||||
class VoiceChannel;
|
||||
class VoiceProcessor;
|
||||
@ -129,15 +128,9 @@ class ChannelManager : public rtc::MessageHandler,
|
||||
// Destroys a data channel created with the Create API.
|
||||
void DestroyDataChannel(DataChannel* data_channel);
|
||||
|
||||
// Creates a soundclip.
|
||||
Soundclip* CreateSoundclip();
|
||||
// Destroys a soundclip created with the Create API.
|
||||
void DestroySoundclip(Soundclip* soundclip);
|
||||
|
||||
// Indicates whether any channels exist.
|
||||
bool has_channels() const {
|
||||
return (!voice_channels_.empty() || !video_channels_.empty() ||
|
||||
!soundclips_.empty());
|
||||
return (!voice_channels_.empty() || !video_channels_.empty());
|
||||
}
|
||||
|
||||
// Configures the audio and video devices. A null pointer can be passed to
|
||||
@ -253,7 +246,6 @@ class ChannelManager : public rtc::MessageHandler,
|
||||
typedef std::vector<VoiceChannel*> VoiceChannels;
|
||||
typedef std::vector<VideoChannel*> VideoChannels;
|
||||
typedef std::vector<DataChannel*> DataChannels;
|
||||
typedef std::vector<Soundclip*> Soundclips;
|
||||
|
||||
void Construct(MediaEngineInterface* me,
|
||||
DataEngineInterface* dme,
|
||||
@ -277,8 +269,6 @@ class ChannelManager : public rtc::MessageHandler,
|
||||
BaseSession* session, const std::string& content_name,
|
||||
bool rtcp, DataChannelType data_channel_type);
|
||||
void DestroyDataChannel_w(DataChannel* data_channel);
|
||||
Soundclip* CreateSoundclip_w();
|
||||
void DestroySoundclip_w(Soundclip* soundclip);
|
||||
bool SetAudioOptions_w(const AudioOptions& options, int delay_offset,
|
||||
const Device* in_dev, const Device* out_dev);
|
||||
bool SetEngineAudioOptions_w(const AudioOptions& options);
|
||||
@ -306,7 +296,6 @@ class ChannelManager : public rtc::MessageHandler,
|
||||
VoiceChannels voice_channels_;
|
||||
VideoChannels video_channels_;
|
||||
DataChannels data_channels_;
|
||||
Soundclips soundclips_;
|
||||
|
||||
std::string audio_in_device_;
|
||||
std::string audio_out_device_;
|
||||
|
@ -1,82 +1 @@
|
||||
/*
|
||||
* libjingle
|
||||
* Copyright 2004 Google Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "talk/session/media/soundclip.h"
|
||||
|
||||
namespace cricket {
|
||||
|
||||
enum {
|
||||
MSG_PLAYSOUND = 1,
|
||||
};
|
||||
|
||||
struct PlaySoundMessageData : rtc::MessageData {
|
||||
PlaySoundMessageData(const void *c,
|
||||
int l,
|
||||
SoundclipMedia::SoundclipFlags f)
|
||||
: clip(c),
|
||||
len(l),
|
||||
flags(f),
|
||||
result(false) {
|
||||
}
|
||||
|
||||
const void *clip;
|
||||
int len;
|
||||
SoundclipMedia::SoundclipFlags flags;
|
||||
bool result;
|
||||
};
|
||||
|
||||
Soundclip::Soundclip(rtc::Thread *thread, SoundclipMedia *soundclip_media)
|
||||
: worker_thread_(thread),
|
||||
soundclip_media_(soundclip_media) {
|
||||
}
|
||||
|
||||
bool Soundclip::PlaySound(const void *clip,
|
||||
int len,
|
||||
SoundclipMedia::SoundclipFlags flags) {
|
||||
PlaySoundMessageData data(clip, len, flags);
|
||||
worker_thread_->Send(this, MSG_PLAYSOUND, &data);
|
||||
return data.result;
|
||||
}
|
||||
|
||||
bool Soundclip::PlaySound_w(const void *clip,
|
||||
int len,
|
||||
SoundclipMedia::SoundclipFlags flags) {
|
||||
return soundclip_media_->PlaySound(static_cast<const char *>(clip),
|
||||
len,
|
||||
flags);
|
||||
}
|
||||
|
||||
void Soundclip::OnMessage(rtc::Message *message) {
|
||||
ASSERT(message->message_id == MSG_PLAYSOUND);
|
||||
PlaySoundMessageData *data =
|
||||
static_cast<PlaySoundMessageData *>(message->pdata);
|
||||
data->result = PlaySound_w(data->clip,
|
||||
data->len,
|
||||
data->flags);
|
||||
}
|
||||
|
||||
} // namespace cricket
|
||||
// TODO(solenberg): Remove this file when it's no longer built in Chromium.
|
||||
|
@ -1,70 +1,2 @@
|
||||
/*
|
||||
* libjingle
|
||||
* Copyright 2004 Google Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
// TODO(solenberg): Remove this file when it's no longer built in Chromium.
|
||||
|
||||
#ifndef TALK_SESSION_MEDIA_SOUNDCLIP_H_
|
||||
#define TALK_SESSION_MEDIA_SOUNDCLIP_H_
|
||||
|
||||
#include "talk/media/base/mediaengine.h"
|
||||
#include "webrtc/base/scoped_ptr.h"
|
||||
|
||||
namespace rtc {
|
||||
|
||||
class Thread;
|
||||
|
||||
}
|
||||
|
||||
namespace cricket {
|
||||
|
||||
// Soundclip wraps SoundclipMedia to support marshalling calls to the proper
|
||||
// thread.
|
||||
class Soundclip : private rtc::MessageHandler {
|
||||
public:
|
||||
Soundclip(rtc::Thread* thread, SoundclipMedia* soundclip_media);
|
||||
|
||||
// Plays a sound out to the speakers with the given audio stream. The stream
|
||||
// must be 16-bit little-endian 16 kHz PCM. If a stream is already playing
|
||||
// on this Soundclip, it is stopped. If clip is NULL, nothing is played.
|
||||
// Returns whether it was successful.
|
||||
bool PlaySound(const void* clip,
|
||||
int len,
|
||||
SoundclipMedia::SoundclipFlags flags);
|
||||
|
||||
private:
|
||||
bool PlaySound_w(const void* clip,
|
||||
int len,
|
||||
SoundclipMedia::SoundclipFlags flags);
|
||||
|
||||
// From MessageHandler
|
||||
virtual void OnMessage(rtc::Message* message);
|
||||
|
||||
rtc::Thread* worker_thread_;
|
||||
rtc::scoped_ptr<SoundclipMedia> soundclip_media_;
|
||||
};
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
#endif // TALK_SESSION_MEDIA_SOUNDCLIP_H_
|
||||
|
Loading…
Reference in New Issue
Block a user