|  | /* | 
|  | *  Copyright (c) 2012 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/voe_external_media_impl.h" | 
|  |  | 
|  | #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" | 
|  | #include "webrtc/system_wrappers/interface/trace.h" | 
|  | #include "webrtc/voice_engine/channel.h" | 
|  | #include "webrtc/voice_engine/include/voe_errors.h" | 
|  | #include "webrtc/voice_engine/output_mixer.h" | 
|  | #include "webrtc/voice_engine/transmit_mixer.h" | 
|  | #include "webrtc/voice_engine/voice_engine_impl.h" | 
|  |  | 
|  | namespace webrtc { | 
|  |  | 
|  | VoEExternalMedia* VoEExternalMedia::GetInterface(VoiceEngine* voiceEngine) | 
|  | { | 
|  | #ifndef WEBRTC_VOICE_ENGINE_EXTERNAL_MEDIA_API | 
|  | return NULL; | 
|  | #else | 
|  | if (NULL == voiceEngine) | 
|  | { | 
|  | return NULL; | 
|  | } | 
|  | VoiceEngineImpl* s = static_cast<VoiceEngineImpl*>(voiceEngine); | 
|  | s->AddRef(); | 
|  | return s; | 
|  | #endif | 
|  | } | 
|  |  | 
|  | #ifdef WEBRTC_VOICE_ENGINE_EXTERNAL_MEDIA_API | 
|  |  | 
|  | VoEExternalMediaImpl::VoEExternalMediaImpl(voe::SharedData* shared) | 
|  | : | 
|  | #ifdef WEBRTC_VOE_EXTERNAL_REC_AND_PLAYOUT | 
|  | playout_delay_ms_(0), | 
|  | #endif | 
|  | shared_(shared) | 
|  | { | 
|  | WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(shared_->instance_id(), -1), | 
|  | "VoEExternalMediaImpl() - ctor"); | 
|  | } | 
|  |  | 
|  | VoEExternalMediaImpl::~VoEExternalMediaImpl() | 
|  | { | 
|  | WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(shared_->instance_id(), -1), | 
|  | "~VoEExternalMediaImpl() - dtor"); | 
|  | } | 
|  |  | 
|  | int VoEExternalMediaImpl::RegisterExternalMediaProcessing( | 
|  | int channel, | 
|  | ProcessingTypes type, | 
|  | VoEMediaProcess& processObject) | 
|  | { | 
|  | WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(shared_->instance_id(), -1), | 
|  | "RegisterExternalMediaProcessing(channel=%d, type=%d, " | 
|  | "processObject=0x%x)", channel, type, &processObject); | 
|  | if (!shared_->statistics().Initialized()) | 
|  | { | 
|  | shared_->SetLastError(VE_NOT_INITED, kTraceError); | 
|  | return -1; | 
|  | } | 
|  | switch (type) | 
|  | { | 
|  | case kPlaybackPerChannel: | 
|  | case kRecordingPerChannel: | 
|  | { | 
|  | voe::ChannelOwner ch = | 
|  | shared_->channel_manager().GetChannel(channel); | 
|  | voe::Channel* channelPtr = ch.channel(); | 
|  | if (channelPtr == NULL) | 
|  | { | 
|  | shared_->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, | 
|  | "RegisterExternalMediaProcessing() failed to locate " | 
|  | "channel"); | 
|  | return -1; | 
|  | } | 
|  | return channelPtr->RegisterExternalMediaProcessing(type, | 
|  | processObject); | 
|  | } | 
|  | case kPlaybackAllChannelsMixed: | 
|  | { | 
|  | return shared_->output_mixer()->RegisterExternalMediaProcessing( | 
|  | processObject); | 
|  | } | 
|  | case kRecordingAllChannelsMixed: | 
|  | case kRecordingPreprocessing: | 
|  | { | 
|  | return shared_->transmit_mixer()->RegisterExternalMediaProcessing( | 
|  | &processObject, type); | 
|  | } | 
|  | } | 
|  | return -1; | 
|  | } | 
|  |  | 
|  | int VoEExternalMediaImpl::DeRegisterExternalMediaProcessing( | 
|  | int channel, | 
|  | ProcessingTypes type) | 
|  | { | 
|  | WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(shared_->instance_id(), -1), | 
|  | "DeRegisterExternalMediaProcessing(channel=%d)", channel); | 
|  | if (!shared_->statistics().Initialized()) | 
|  | { | 
|  | shared_->SetLastError(VE_NOT_INITED, kTraceError); | 
|  | return -1; | 
|  | } | 
|  | switch (type) | 
|  | { | 
|  | case kPlaybackPerChannel: | 
|  | case kRecordingPerChannel: | 
|  | { | 
|  | voe::ChannelOwner ch = | 
|  | shared_->channel_manager().GetChannel(channel); | 
|  | voe::Channel* channelPtr = ch.channel(); | 
|  | if (channelPtr == NULL) | 
|  | { | 
|  | shared_->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, | 
|  | "RegisterExternalMediaProcessing() " | 
|  | "failed to locate channel"); | 
|  | return -1; | 
|  | } | 
|  | return channelPtr->DeRegisterExternalMediaProcessing(type); | 
|  | } | 
|  | case kPlaybackAllChannelsMixed: | 
|  | { | 
|  | return shared_->output_mixer()-> | 
|  | DeRegisterExternalMediaProcessing(); | 
|  | } | 
|  | case kRecordingAllChannelsMixed: | 
|  | case kRecordingPreprocessing: | 
|  | { | 
|  | return shared_->transmit_mixer()-> | 
|  | DeRegisterExternalMediaProcessing(type); | 
|  | } | 
|  | } | 
|  | return -1; | 
|  | } | 
|  |  | 
|  | int VoEExternalMediaImpl::GetAudioFrame(int channel, int desired_sample_rate_hz, | 
|  | AudioFrame* frame) { | 
|  | WEBRTC_TRACE(kTraceApiCall, kTraceVoice, | 
|  | VoEId(shared_->instance_id(), channel), | 
|  | "GetAudioFrame(channel=%d, desired_sample_rate_hz=%d)", | 
|  | channel, desired_sample_rate_hz); | 
|  | if (!shared_->statistics().Initialized()) | 
|  | { | 
|  | shared_->SetLastError(VE_NOT_INITED, kTraceError); | 
|  | return -1; | 
|  | } | 
|  | voe::ChannelOwner ch = shared_->channel_manager().GetChannel(channel); | 
|  | voe::Channel* channelPtr = ch.channel(); | 
|  | if (channelPtr == NULL) | 
|  | { | 
|  | shared_->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, | 
|  | "GetAudioFrame() failed to locate channel"); | 
|  | return -1; | 
|  | } | 
|  | if (!channelPtr->ExternalMixing()) { | 
|  | shared_->SetLastError(VE_INVALID_OPERATION, kTraceError, | 
|  | "GetAudioFrame() was called on channel that is not" | 
|  | " externally mixed."); | 
|  | return -1; | 
|  | } | 
|  | if (!channelPtr->Playing()) { | 
|  | shared_->SetLastError(VE_INVALID_OPERATION, kTraceError, | 
|  | "GetAudioFrame() was called on channel that is not playing."); | 
|  | return -1; | 
|  | } | 
|  | if (desired_sample_rate_hz == -1) { | 
|  | shared_->SetLastError(VE_BAD_ARGUMENT, kTraceError, | 
|  | "GetAudioFrame() was called with bad sample rate."); | 
|  | return -1; | 
|  | } | 
|  | frame->sample_rate_hz_ = desired_sample_rate_hz == 0 ? -1 : | 
|  | desired_sample_rate_hz; | 
|  | return channelPtr->GetAudioFrame(channel, *frame); | 
|  | } | 
|  |  | 
|  | int VoEExternalMediaImpl::SetExternalMixing(int channel, bool enable) { | 
|  | WEBRTC_TRACE(kTraceApiCall, kTraceVoice, | 
|  | VoEId(shared_->instance_id(), channel), | 
|  | "SetExternalMixing(channel=%d, enable=%d)", channel, enable); | 
|  | if (!shared_->statistics().Initialized()) | 
|  | { | 
|  | shared_->SetLastError(VE_NOT_INITED, kTraceError); | 
|  | return -1; | 
|  | } | 
|  | voe::ChannelOwner ch = shared_->channel_manager().GetChannel(channel); | 
|  | voe::Channel* channelPtr = ch.channel(); | 
|  | if (channelPtr == NULL) | 
|  | { | 
|  | shared_->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError, | 
|  | "SetExternalMixing() failed to locate channel"); | 
|  | return -1; | 
|  | } | 
|  | return channelPtr->SetExternalMixing(enable); | 
|  | } | 
|  |  | 
|  | #endif  // WEBRTC_VOICE_ENGINE_EXTERNAL_MEDIA_API | 
|  |  | 
|  | }  // namespace webrtc |