diff options
Diffstat (limited to 'plugins/audio_webrtc')
-rwxr-xr-x | plugins/audio_webrtc/audio_webrtc.cxx | 858 | ||||
-rwxr-xr-x | plugins/audio_webrtc/audio_webrtc.h | 6 | ||||
-rwxr-xr-x | plugins/audio_webrtc/audio_webrtc_config.h | 52 | ||||
-rwxr-xr-x | plugins/audio_webrtc/audio_webrtc_consumer.cxx | 309 | ||||
-rwxr-xr-x | plugins/audio_webrtc/audio_webrtc_consumer.h | 8 | ||||
-rwxr-xr-x | plugins/audio_webrtc/audio_webrtc_producer.cxx | 315 | ||||
-rwxr-xr-x | plugins/audio_webrtc/audio_webrtc_producer.h | 6 | ||||
-rwxr-xr-x | plugins/audio_webrtc/audio_webrtc_transport.cxx | 34 | ||||
-rwxr-xr-x | plugins/audio_webrtc/audio_webrtc_transport.h | 57 | ||||
-rwxr-xr-x | plugins/audio_webrtc/dllmain.cxx | 25 |
10 files changed, 828 insertions, 842 deletions
diff --git a/plugins/audio_webrtc/audio_webrtc.cxx b/plugins/audio_webrtc/audio_webrtc.cxx index 167166d..b604d49 100755 --- a/plugins/audio_webrtc/audio_webrtc.cxx +++ b/plugins/audio_webrtc/audio_webrtc.cxx @@ -1,17 +1,17 @@ /* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -37,99 +37,93 @@ using namespace webrtc; #if DOUBANGO_AUDIO_WEBRTC_UNDER_ANDROID // https://groups.google.com/group/android-ndk/browse_thread/thread/a1667f28162cf69b/8ef3a171df7f8dfe -extern "C" -{ - void *__dso_handle = NULL; -} +extern "C" +{ + void *__dso_handle = NULL; +} #endif -typedef enum PLUGIN_INDEX_E -{ - PLUGIN_INDEX_AUDIO_CONSUMER, - PLUGIN_INDEX_AUDIO_PRODUCER, - PLUGIN_INDEX_COUNT +typedef enum PLUGIN_INDEX_E { + PLUGIN_INDEX_AUDIO_CONSUMER, + PLUGIN_INDEX_AUDIO_PRODUCER, + PLUGIN_INDEX_COUNT } PLUGIN_INDEX_T; int __plugin_get_def_count() { - return PLUGIN_INDEX_COUNT; + return PLUGIN_INDEX_COUNT; } tsk_plugin_def_type_t __plugin_get_def_type_at(int index) { - switch(index){ - case PLUGIN_INDEX_AUDIO_CONSUMER: return tsk_plugin_def_type_consumer; - case PLUGIN_INDEX_AUDIO_PRODUCER: return tsk_plugin_def_type_producer; - default: - { - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("No plugin at index %d", index); - return tsk_plugin_def_type_none; - } - } + switch(index) { + case PLUGIN_INDEX_AUDIO_CONSUMER: + return tsk_plugin_def_type_consumer; + case PLUGIN_INDEX_AUDIO_PRODUCER: + return tsk_plugin_def_type_producer; + default: { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("No plugin at index %d", index); + return tsk_plugin_def_type_none; + } + } } tsk_plugin_def_media_type_t __plugin_get_def_media_type_at(int index) { - switch(index){ - case PLUGIN_INDEX_AUDIO_CONSUMER: - case PLUGIN_INDEX_AUDIO_PRODUCER: - { - return tsk_plugin_def_media_type_audio; - } - default: - { - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("No plugin at index %d", index); - return tsk_plugin_def_media_type_none; - } - } + switch(index) { + case PLUGIN_INDEX_AUDIO_CONSUMER: + case PLUGIN_INDEX_AUDIO_PRODUCER: { + return tsk_plugin_def_media_type_audio; + } + default: { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("No plugin at index %d", index); + return tsk_plugin_def_media_type_none; + } + } } tsk_plugin_def_ptr_const_t __plugin_get_def_at(int index) { - switch(index){ - case PLUGIN_INDEX_AUDIO_CONSUMER: - { - return audio_consumer_webrtc_plugin_def_t; - } - case PLUGIN_INDEX_AUDIO_PRODUCER: - { - return audio_producer_webrtc_plugin_def_t; - } - default: - { - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("No plugin at index %d", index); - return tsk_null; - } - } + switch(index) { + case PLUGIN_INDEX_AUDIO_CONSUMER: { + return audio_consumer_webrtc_plugin_def_t; + } + case PLUGIN_INDEX_AUDIO_PRODUCER: { + return audio_producer_webrtc_plugin_def_t; + } + default: { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("No plugin at index %d", index); + return tsk_null; + } + } } // // WebRTC AudioInstance // -typedef struct audio_webrtc_instance_s -{ - TSK_DECLARE_OBJECT; - - uint64_t sessionId; - - bool isStarted; - - bool isConsumerPrepared; - bool isConsumerStarted; - bool isProducerPrepared; - bool isProducerStarted; - - bool isSpeakerAvailable; - bool isPlayoutAvailable; - bool isRecordingAvailable; - - AudioDeviceModule* device; - AudioTransportImpl* transport; - - TSK_DECLARE_SAFEOBJ; +typedef struct audio_webrtc_instance_s { + TSK_DECLARE_OBJECT; + + uint64_t sessionId; + + bool isStarted; + + bool isConsumerPrepared; + bool isConsumerStarted; + bool isProducerPrepared; + bool isProducerStarted; + + bool isSpeakerAvailable; + bool isPlayoutAvailable; + bool isRecordingAvailable; + + AudioDeviceModule* device; + AudioTransportImpl* transport; + + TSK_DECLARE_SAFEOBJ; } audio_webrtc_instance_t; typedef tsk_list_t audio_webrtc_instances_L_t; @@ -138,425 +132,425 @@ static audio_webrtc_instances_L_t* __audioInstances = tsk_null; static tsk_object_t* audio_webrtc_instance_ctor(tsk_object_t * self, va_list * app) { - audio_webrtc_instance_t* audioInstance = (audio_webrtc_instance_t*)self; - if(audioInstance){ - tsk_safeobj_init(audioInstance); - } - return self; + audio_webrtc_instance_t* audioInstance = (audio_webrtc_instance_t*)self; + if(audioInstance) { + tsk_safeobj_init(audioInstance); + } + return self; } static tsk_object_t* audio_webrtc_instance_dtor(tsk_object_t * self) -{ - DOUBANGO_AUDIO_WEBRTC_DEBUG_INFO("Audio Instance destroyed"); - audio_webrtc_instance_t* audioInstance = (audio_webrtc_instance_t*)self; - if(audioInstance){ +{ + DOUBANGO_AUDIO_WEBRTC_DEBUG_INFO("Audio Instance destroyed"); + audio_webrtc_instance_t* audioInstance = (audio_webrtc_instance_t*)self; + if(audioInstance) { tsk_safeobj_lock(audioInstance); - if(audioInstance->device){ - audioInstance->device->RegisterAudioCallback(tsk_null); - audioInstance->device->Terminate(); - audioInstance->device->Release();//FIXME: must be deleted? - audioInstance->device = tsk_null; - } - if(audioInstance->transport){ - delete audioInstance->transport; - audioInstance->transport = tsk_null; - } + if(audioInstance->device) { + audioInstance->device->RegisterAudioCallback(tsk_null); + audioInstance->device->Terminate(); + audioInstance->device->Release();//FIXME: must be deleted? + audioInstance->device = tsk_null; + } + if(audioInstance->transport) { + delete audioInstance->transport; + audioInstance->transport = tsk_null; + } tsk_safeobj_unlock(audioInstance); - - tsk_safeobj_deinit(audioInstance); - } - return self; + + tsk_safeobj_deinit(audioInstance); + } + return self; } static int audio_webrtc_instance_cmp(const tsk_object_t *_ai1, const tsk_object_t *_ai2) { - return ((int)_ai1 - (int)_ai2); + return ((int)_ai1 - (int)_ai2); } -static const tsk_object_def_t audio_webrtc_instance_def_s = -{ - sizeof(audio_webrtc_instance_t), - audio_webrtc_instance_ctor, - audio_webrtc_instance_dtor, - audio_webrtc_instance_cmp, +static const tsk_object_def_t audio_webrtc_instance_def_s = { + sizeof(audio_webrtc_instance_t), + audio_webrtc_instance_ctor, + audio_webrtc_instance_dtor, + audio_webrtc_instance_cmp, }; const tsk_object_def_t *audio_webrtc_instance_def_t = &audio_webrtc_instance_def_s; audio_webrtc_instance_handle_t* audio_webrtc_instance_create(uint64_t sessionId) { - audio_webrtc_instance_t* audioInstance = tsk_null; - - // create list used to hold instances - if(!__audioInstances && !(__audioInstances = tsk_list_create())){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Failed to create new list"); - return tsk_null; - } - - //= lock the list - tsk_list_lock(__audioInstances); - - // find the instance from the list - const tsk_list_item_t* item; - tsk_list_foreach(item, __audioInstances){ - if(((audio_webrtc_instance_t*)item->data)->sessionId == sessionId){ - audioInstance = (audio_webrtc_instance_t*)tsk_object_ref(item->data); - break; - } - } - - if(!audioInstance){ - audio_webrtc_instance_t* _audioInstance; - if(!(_audioInstance = (audio_webrtc_instance_t*)tsk_object_new(&audio_webrtc_instance_def_s))){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Failed to create new audio instance"); - goto done; - } - - if(!(_audioInstance->device = AudioDeviceModuleImpl::Create(kAudioDeviceModuleId))){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Failed to create audio device"); - TSK_OBJECT_SAFE_FREE(_audioInstance); - goto done; - } - _audioInstance->device->AddRef(); - - if(!(_audioInstance->transport = new AudioTransportImpl(_audioInstance->device))){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Failed to create audio transport"); - TSK_OBJECT_SAFE_FREE(_audioInstance); - goto done; - } - if((_audioInstance->device->RegisterAudioCallback(_audioInstance->transport))){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("AudioDeviceModule::RegisterAudioCallback() failed"); - TSK_OBJECT_SAFE_FREE(_audioInstance); - goto done; - } - - if((_audioInstance->device->Init())){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("AudioDeviceModule::Init() failed"); - TSK_OBJECT_SAFE_FREE(_audioInstance); - goto done; - } - - _audioInstance->sessionId = sessionId; - audioInstance = _audioInstance; - tsk_list_push_back_data(__audioInstances, (void**)&_audioInstance); - } + audio_webrtc_instance_t* audioInstance = tsk_null; + + // create list used to hold instances + if(!__audioInstances && !(__audioInstances = tsk_list_create())) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Failed to create new list"); + return tsk_null; + } + + //= lock the list + tsk_list_lock(__audioInstances); + + // find the instance from the list + const tsk_list_item_t* item; + tsk_list_foreach(item, __audioInstances) { + if(((audio_webrtc_instance_t*)item->data)->sessionId == sessionId) { + audioInstance = (audio_webrtc_instance_t*)tsk_object_ref(item->data); + break; + } + } + + if(!audioInstance) { + audio_webrtc_instance_t* _audioInstance; + if(!(_audioInstance = (audio_webrtc_instance_t*)tsk_object_new(&audio_webrtc_instance_def_s))) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Failed to create new audio instance"); + goto done; + } + + if(!(_audioInstance->device = AudioDeviceModuleImpl::Create(kAudioDeviceModuleId))) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Failed to create audio device"); + TSK_OBJECT_SAFE_FREE(_audioInstance); + goto done; + } + _audioInstance->device->AddRef(); + + if(!(_audioInstance->transport = new AudioTransportImpl(_audioInstance->device))) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Failed to create audio transport"); + TSK_OBJECT_SAFE_FREE(_audioInstance); + goto done; + } + if((_audioInstance->device->RegisterAudioCallback(_audioInstance->transport))) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("AudioDeviceModule::RegisterAudioCallback() failed"); + TSK_OBJECT_SAFE_FREE(_audioInstance); + goto done; + } + + if((_audioInstance->device->Init())) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("AudioDeviceModule::Init() failed"); + TSK_OBJECT_SAFE_FREE(_audioInstance); + goto done; + } + + _audioInstance->sessionId = sessionId; + audioInstance = _audioInstance; + tsk_list_push_back_data(__audioInstances, (void**)&_audioInstance); + } done: - //= unlock the list - tsk_list_unlock(__audioInstances); + //= unlock the list + tsk_list_unlock(__audioInstances); - return audioInstance; + return audioInstance; } int audio_webrtc_instance_prepare_consumer(audio_webrtc_instance_handle_t* _self, tmedia_consumer_t** _consumer) { - audio_webrtc_instance_t* self = (audio_webrtc_instance_t*)_self; - if(!self || !self->device || !self->transport || !_consumer || !*_consumer){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("invalid parameter"); - return -1; - } - - if(self->isConsumerPrepared){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_WARN("Consumer already prepared"); - return 0; - } - - int ret; - bool _bool; - - tsk_safeobj_lock(self); - - self->transport->SetConsumer((const struct audio_consumer_webrtc_s*)*_consumer); - - if((ret = self->device->SetPlayoutDevice(DOUBANGO_AUDIO_WEBRTC_DEVICE_DEFAULT))){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("AudioDeviceModule->SetPlayoutDevice(%d) failed", DOUBANGO_AUDIO_WEBRTC_DEVICE_DEFAULT); - } - - if((ret = self->device->SpeakerIsAvailable(&_bool))){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("SpeakerIsAvailable() failed with error code=%d", ret); - } - else{ - if(!_bool){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("SpeakerIsAvailable() returned false"); - } - self->isSpeakerAvailable = _bool; - } - - if((ret = self->device->InitSpeaker())){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("InitSpeaker() failed with error code=%d", ret); - } - - if((ret = self->device->PlayoutIsAvailable(&_bool))){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("PlayoutIsAvailable() failed with error code =%d", ret); - } - else{ - if(!_bool){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("PlayoutIsAvailable() returned false"); - } - self->isPlayoutAvailable = _bool; - } - - if((ret = self->device->SetStereoPlayout(((*_consumer)->audio.in.channels == 2)))){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("SetStereoPlayout(%d==2) failed with error code=%d", (*_consumer)->audio.in.channels, ret); - } - - //if((ret = self->device->SetPlayoutBuffer(AudioDeviceModule::kFixedBufferSize, (*_consumer)->audio.ptime))){ - // DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("SetPlayoutBuffer(%d ms) failed with error code=%d", (*_consumer)->audio.ptime, ret); - //} - // always request 10ms buffers. In all cases WebRTC don't support anything else - if((ret = self->device->SetPlayoutBuffer(AudioDeviceModule::kFixedBufferSize, 10))){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("SetPlayoutBuffer(%d ms) failed with error code=%d", 10, ret); - } - - uint32_t playoutSampleRate = (*_consumer)->audio.out.rate ? (*_consumer)->audio.out.rate : (*_consumer)->audio.in.rate; - if((ret = self->device->SetPlayoutSampleRate(playoutSampleRate))){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("SetPlayoutSampleRate(%d) failed with error code=%d", playoutSampleRate, ret); - } - - if((ret = self->device->InitPlayout())){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("AudioDeviceModule::InitPlayout() failed with error code = %d", ret); - goto done; - } - - // init output parameters - if((ret = self->device->StereoPlayout(&_bool))){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("StereoPlayout() failed with error code=%d", ret); - } - else{ - (*_consumer)->audio.out.channels = (_bool ? 2 : 1); - } - if((ret = self->device->PlayoutSampleRate(&playoutSampleRate))){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("PlayoutSampleRate() failed with error code=%d", ret); - } - else{ - (*_consumer)->audio.out.rate = playoutSampleRate; - } + audio_webrtc_instance_t* self = (audio_webrtc_instance_t*)_self; + if(!self || !self->device || !self->transport || !_consumer || !*_consumer) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("invalid parameter"); + return -1; + } + + if(self->isConsumerPrepared) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_WARN("Consumer already prepared"); + return 0; + } + + int ret; + bool _bool; + + tsk_safeobj_lock(self); + + self->transport->SetConsumer((const struct audio_consumer_webrtc_s*)*_consumer); + + if((ret = self->device->SetPlayoutDevice(DOUBANGO_AUDIO_WEBRTC_DEVICE_DEFAULT))) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("AudioDeviceModule->SetPlayoutDevice(%d) failed", DOUBANGO_AUDIO_WEBRTC_DEVICE_DEFAULT); + } + + if((ret = self->device->SpeakerIsAvailable(&_bool))) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("SpeakerIsAvailable() failed with error code=%d", ret); + } + else { + if(!_bool) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("SpeakerIsAvailable() returned false"); + } + self->isSpeakerAvailable = _bool; + } + + if((ret = self->device->InitSpeaker())) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("InitSpeaker() failed with error code=%d", ret); + } + + if((ret = self->device->PlayoutIsAvailable(&_bool))) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("PlayoutIsAvailable() failed with error code =%d", ret); + } + else { + if(!_bool) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("PlayoutIsAvailable() returned false"); + } + self->isPlayoutAvailable = _bool; + } + + if((ret = self->device->SetStereoPlayout(((*_consumer)->audio.in.channels == 2)))) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("SetStereoPlayout(%d==2) failed with error code=%d", (*_consumer)->audio.in.channels, ret); + } + + //if((ret = self->device->SetPlayoutBuffer(AudioDeviceModule::kFixedBufferSize, (*_consumer)->audio.ptime))){ + // DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("SetPlayoutBuffer(%d ms) failed with error code=%d", (*_consumer)->audio.ptime, ret); + //} + // always request 10ms buffers. In all cases WebRTC don't support anything else + if((ret = self->device->SetPlayoutBuffer(AudioDeviceModule::kFixedBufferSize, 10))) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("SetPlayoutBuffer(%d ms) failed with error code=%d", 10, ret); + } + + uint32_t playoutSampleRate = (*_consumer)->audio.out.rate ? (*_consumer)->audio.out.rate : (*_consumer)->audio.in.rate; + if((ret = self->device->SetPlayoutSampleRate(playoutSampleRate))) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("SetPlayoutSampleRate(%d) failed with error code=%d", playoutSampleRate, ret); + } + + if((ret = self->device->InitPlayout())) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("AudioDeviceModule::InitPlayout() failed with error code = %d", ret); + goto done; + } + + // init output parameters + if((ret = self->device->StereoPlayout(&_bool))) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("StereoPlayout() failed with error code=%d", ret); + } + else { + (*_consumer)->audio.out.channels = (_bool ? 2 : 1); + } + if((ret = self->device->PlayoutSampleRate(&playoutSampleRate))) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("PlayoutSampleRate() failed with error code=%d", ret); + } + else { + (*_consumer)->audio.out.rate = playoutSampleRate; + } done: - tsk_safeobj_unlock(self); + tsk_safeobj_unlock(self); - self->isConsumerPrepared = (ret == 0); + self->isConsumerPrepared = (ret == 0); - return ret; + return ret; } int audio_webrtc_instance_prepare_producer(audio_webrtc_instance_handle_t* _self, tmedia_producer_t** _producer) { - audio_webrtc_instance_t* self = (audio_webrtc_instance_t*)_self; - if(!self || !self->device || !self->transport || !_producer || !*_producer){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("invalid parameter"); - return -1; - } - - if(self->isProducerPrepared){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_WARN("Producer already prepared"); - return 0; - } - - int ret; - bool _bool; - - tsk_safeobj_lock(self); - - self->transport->SetProducer((const struct audio_producer_webrtc_s*)*_producer); - - if((ret = self->device->SetRecordingDevice(DOUBANGO_AUDIO_WEBRTC_DEVICE_DEFAULT))){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("AudioDeviceModule->SetRecordingDevice(%d) failed", DOUBANGO_AUDIO_WEBRTC_DEVICE_DEFAULT); - } - - if((ret = self->device->RecordingIsAvailable(&_bool))){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("RecordingIsAvailable() failed with error code =%d", ret); - } - else{ - if(!_bool){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("RecordingIsAvailable() returned false"); - } - self->isRecordingAvailable = _bool; - } - - if((ret = self->device->MicrophoneIsAvailable(&_bool))){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("MicrophoneIsAvailable() failed with error code =%d", ret); - } - else{ - if(!_bool){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("MicrophoneIsAvailable() returned false"); - } - else{ - if((ret = self->device->InitMicrophone())){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("InitMicrophone() failed with error code =%d", ret); - } - } - } - - if((ret = self->device->SetStereoRecording(((*_producer)->audio.channels == 2)))){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("SetStereoRecording(%d==2) failed with error code=%d", (*_producer)->audio.channels, ret); - } - - uint32_t recordingSampleRate = (*_producer)->audio.rate; - if((ret = self->device->SetRecordingSampleRate(recordingSampleRate))){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("SetRecordingSampleRate(%d) failed with error code=%d", recordingSampleRate, ret); - } - - if((ret = self->device->InitRecording())){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("AudioDeviceModule::InitRecording() failed with error code = %d", ret); - goto done; - } - - // init output parameters - if((ret = self->device->StereoRecording(&_bool))){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("StereoRecording() failed with error code=%d", ret); - } - else{ - (*_producer)->audio.channels = (_bool ? 2 : 1); - } - if((ret = self->device->RecordingSampleRate(&recordingSampleRate))){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("RecordingSampleRate() failed with error code=%d", ret); - } - else{ - (*_producer)->audio.rate = recordingSampleRate; - } + audio_webrtc_instance_t* self = (audio_webrtc_instance_t*)_self; + if(!self || !self->device || !self->transport || !_producer || !*_producer) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("invalid parameter"); + return -1; + } + + if(self->isProducerPrepared) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_WARN("Producer already prepared"); + return 0; + } + + int ret; + bool _bool; + + tsk_safeobj_lock(self); + + self->transport->SetProducer((const struct audio_producer_webrtc_s*)*_producer); + + if((ret = self->device->SetRecordingDevice(DOUBANGO_AUDIO_WEBRTC_DEVICE_DEFAULT))) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("AudioDeviceModule->SetRecordingDevice(%d) failed", DOUBANGO_AUDIO_WEBRTC_DEVICE_DEFAULT); + } + + if((ret = self->device->RecordingIsAvailable(&_bool))) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("RecordingIsAvailable() failed with error code =%d", ret); + } + else { + if(!_bool) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("RecordingIsAvailable() returned false"); + } + self->isRecordingAvailable = _bool; + } + + if((ret = self->device->MicrophoneIsAvailable(&_bool))) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("MicrophoneIsAvailable() failed with error code =%d", ret); + } + else { + if(!_bool) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("MicrophoneIsAvailable() returned false"); + } + else { + if((ret = self->device->InitMicrophone())) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("InitMicrophone() failed with error code =%d", ret); + } + } + } + + if((ret = self->device->SetStereoRecording(((*_producer)->audio.channels == 2)))) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("SetStereoRecording(%d==2) failed with error code=%d", (*_producer)->audio.channels, ret); + } + + uint32_t recordingSampleRate = (*_producer)->audio.rate; + if((ret = self->device->SetRecordingSampleRate(recordingSampleRate))) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("SetRecordingSampleRate(%d) failed with error code=%d", recordingSampleRate, ret); + } + + if((ret = self->device->InitRecording())) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("AudioDeviceModule::InitRecording() failed with error code = %d", ret); + goto done; + } + + // init output parameters + if((ret = self->device->StereoRecording(&_bool))) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("StereoRecording() failed with error code=%d", ret); + } + else { + (*_producer)->audio.channels = (_bool ? 2 : 1); + } + if((ret = self->device->RecordingSampleRate(&recordingSampleRate))) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("RecordingSampleRate() failed with error code=%d", ret); + } + else { + (*_producer)->audio.rate = recordingSampleRate; + } done: - tsk_safeobj_unlock(self); + tsk_safeobj_unlock(self); - self->isProducerPrepared = (ret == 0); + self->isProducerPrepared = (ret == 0); - return ret; + return ret; } int audio_webrtc_instance_start_consumer(audio_webrtc_instance_handle_t* _self) { - audio_webrtc_instance_t* self = (audio_webrtc_instance_t*)_self; - if(!self || !self->device || !self->transport){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("invalid parameter"); - return -1; - } - - tsk_safeobj_lock(self); - if(!self->isConsumerPrepared){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Consumer not prepared"); - goto done; - } - - if(self->isConsumerStarted){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_WARN("Consumer already started"); - goto done; - } - - if(self->isPlayoutAvailable){ - int ret; - if((ret = self->device->StartPlayout())){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("StartPlayout() failed with error code = %d", ret); - } - - self->isConsumerStarted = self->device->Playing(); - DOUBANGO_AUDIO_WEBRTC_DEBUG_INFO("isPlaying=%s", (self->isConsumerPrepared ? "true" : "false")); - } + audio_webrtc_instance_t* self = (audio_webrtc_instance_t*)_self; + if(!self || !self->device || !self->transport) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("invalid parameter"); + return -1; + } + + tsk_safeobj_lock(self); + if(!self->isConsumerPrepared) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Consumer not prepared"); + goto done; + } + + if(self->isConsumerStarted) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_WARN("Consumer already started"); + goto done; + } + + if(self->isPlayoutAvailable) { + int ret; + if((ret = self->device->StartPlayout())) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("StartPlayout() failed with error code = %d", ret); + } + + self->isConsumerStarted = self->device->Playing(); + DOUBANGO_AUDIO_WEBRTC_DEBUG_INFO("isPlaying=%s", (self->isConsumerPrepared ? "true" : "false")); + } done: - tsk_safeobj_unlock(self); - return (self->isConsumerStarted ? 0 : -1); + tsk_safeobj_unlock(self); + return (self->isConsumerStarted ? 0 : -1); } int audio_webrtc_instance_start_producer(audio_webrtc_instance_handle_t* _self) { - audio_webrtc_instance_t* self = (audio_webrtc_instance_t*)_self; - if(!self || !self->device || !self->transport){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("invalid parameter"); - return -1; - } - - tsk_safeobj_lock(self); - if(!self->isProducerPrepared){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Producer not prepared"); - goto done; - } - - if(self->isProducerStarted){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_WARN("Consumer already started"); - goto done; - } - - if(self->isRecordingAvailable){ - int ret; - if((ret = self->device->StartRecording())){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("StartRecording() failed with error code = %d", ret); - } - - self->isProducerStarted = self->device->Recording(); - DOUBANGO_AUDIO_WEBRTC_DEBUG_INFO("isRecording=%s", (self->isProducerStarted ? "true" : "false")); - } + audio_webrtc_instance_t* self = (audio_webrtc_instance_t*)_self; + if(!self || !self->device || !self->transport) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("invalid parameter"); + return -1; + } + + tsk_safeobj_lock(self); + if(!self->isProducerPrepared) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Producer not prepared"); + goto done; + } + + if(self->isProducerStarted) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_WARN("Consumer already started"); + goto done; + } + + if(self->isRecordingAvailable) { + int ret; + if((ret = self->device->StartRecording())) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("StartRecording() failed with error code = %d", ret); + } + + self->isProducerStarted = self->device->Recording(); + DOUBANGO_AUDIO_WEBRTC_DEBUG_INFO("isRecording=%s", (self->isProducerStarted ? "true" : "false")); + } done: - tsk_safeobj_unlock(self); - return (self->isProducerStarted ? 0 : -1); - return 0; + tsk_safeobj_unlock(self); + return (self->isProducerStarted ? 0 : -1); + return 0; } int audio_webrtc_instance_stop_consumer(audio_webrtc_instance_handle_t* _self) { - audio_webrtc_instance_t* self = (audio_webrtc_instance_t*)_self; - if(!self || !self->device || !self->transport){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("invalid parameter"); - return -1; - } - - tsk_safeobj_lock(self); - - if(!self->isConsumerStarted){ - goto done; - } - - int ret; - if((ret = self->device->StopPlayout())){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("StopPlayout() failed with error code = %d", ret); - } - else{ - self->isConsumerStarted = self->device->Playing(); - } + audio_webrtc_instance_t* self = (audio_webrtc_instance_t*)_self; + if(!self || !self->device || !self->transport) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("invalid parameter"); + return -1; + } + + tsk_safeobj_lock(self); + + if(!self->isConsumerStarted) { + goto done; + } + + int ret; + if((ret = self->device->StopPlayout())) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("StopPlayout() failed with error code = %d", ret); + } + else { + self->isConsumerStarted = self->device->Playing(); + } done: - tsk_safeobj_unlock(self); - return (self->isConsumerStarted ? -1 : 0); + tsk_safeobj_unlock(self); + return (self->isConsumerStarted ? -1 : 0); } int audio_webrtc_instance_stop_producer(audio_webrtc_instance_handle_t* _self) { - audio_webrtc_instance_t* self = (audio_webrtc_instance_t*)_self; - if(!self || !self->device || !self->transport){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("invalid parameter"); - return -1; - } - - tsk_safeobj_lock(self); - - if(!self->isProducerStarted){ - goto done; - } - - int ret; - if((ret = self->device->StopRecording())){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("StopRecording() failed with error code = %d", ret); - } - else{ - self->isProducerStarted = self->device->Recording(); - } + audio_webrtc_instance_t* self = (audio_webrtc_instance_t*)_self; + if(!self || !self->device || !self->transport) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("invalid parameter"); + return -1; + } + + tsk_safeobj_lock(self); + + if(!self->isProducerStarted) { + goto done; + } + + int ret; + if((ret = self->device->StopRecording())) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("StopRecording() failed with error code = %d", ret); + } + else { + self->isProducerStarted = self->device->Recording(); + } done: - tsk_safeobj_unlock(self); - return (self->isProducerStarted ? -1 : 0); + tsk_safeobj_unlock(self); + return (self->isProducerStarted ? -1 : 0); } -int audio_webrtc_instance_destroy(audio_webrtc_instance_handle_t** _self){ - if(!_self || !*_self){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Invalid parameter"); - return -1; - } - tsk_list_lock(__audioInstances); - if(tsk_object_get_refcount(*_self)==1){ - tsk_list_remove_item_by_data(__audioInstances, *_self); - } - else { - tsk_object_unref(*_self); - } - tsk_list_unlock(__audioInstances); - *_self = tsk_null; - return 0; +int audio_webrtc_instance_destroy(audio_webrtc_instance_handle_t** _self) +{ + if(!_self || !*_self) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Invalid parameter"); + return -1; + } + tsk_list_lock(__audioInstances); + if(tsk_object_get_refcount(*_self)==1) { + tsk_list_remove_item_by_data(__audioInstances, *_self); + } + else { + tsk_object_unref(*_self); + } + tsk_list_unlock(__audioInstances); + *_self = tsk_null; + return 0; } diff --git a/plugins/audio_webrtc/audio_webrtc.h b/plugins/audio_webrtc/audio_webrtc.h index 115a243..070d2fb 100755 --- a/plugins/audio_webrtc/audio_webrtc.h +++ b/plugins/audio_webrtc/audio_webrtc.h @@ -1,17 +1,17 @@ /* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ diff --git a/plugins/audio_webrtc/audio_webrtc_config.h b/plugins/audio_webrtc/audio_webrtc_config.h index dc7c1fd..d441703 100755 --- a/plugins/audio_webrtc/audio_webrtc_config.h +++ b/plugins/audio_webrtc/audio_webrtc_config.h @@ -1,17 +1,17 @@ /* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -72,13 +72,13 @@ # define DOUBANGO_AUDIO_WEBRTC_BEGIN_DECLS extern "C" { # define DOUBANGO_AUDIO_WEBRTC_END_DECLS } #else -# define DOUBANGO_AUDIO_WEBRTC_BEGIN_DECLS +# define DOUBANGO_AUDIO_WEBRTC_BEGIN_DECLS # define DOUBANGO_AUDIO_WEBRTC_END_DECLS #endif #ifdef _MSC_VER #if HAVE_FFMPEG // FFMPeg warnings (treated as errors) -# pragma warning (disable:4244) +# pragma warning (disable:4244) #endif # define inline __inline # define _CRT_SECURE_NO_WARNINGS @@ -96,7 +96,7 @@ #endif #if HAVE_CONFIG_H - #include "../config.h" +#include "../config.h" #endif #if DOUBANGO_AUDIO_WEBRTC_UNDER_WINDOWS @@ -113,22 +113,30 @@ #define ANDROID_DEBUG_TAG "plugin_audio_webrtc" // DDMS log tag when using eclise static void DOUBANGO_AUDIO_WEBRTC_DEBUG_ANY(int level, const char* fmt, ...) { - char* message = tsk_null; - va_list ap; - va_start(ap, fmt); - tsk_sprintf_2(&message, fmt, &ap); - - if(message){ - switch(level){ - case DEBUG_LEVEL_INFO: __android_log_write(ANDROID_LOG_INFO, ANDROID_DEBUG_TAG, message); break; - case DEBUG_LEVEL_WARN: __android_log_write(ANDROID_LOG_WARN, ANDROID_DEBUG_TAG, message); break; - case DEBUG_LEVEL_ERROR: __android_log_write(ANDROID_LOG_ERROR, ANDROID_DEBUG_TAG, message); break; - case DEBUG_LEVEL_FATAL: __android_log_write(ANDROID_LOG_FATAL, ANDROID_DEBUG_TAG, message); break; - } - TSK_FREE(message); - } - - va_end(ap); + char* message = tsk_null; + va_list ap; + va_start(ap, fmt); + tsk_sprintf_2(&message, fmt, &ap); + + if(message) { + switch(level) { + case DEBUG_LEVEL_INFO: + __android_log_write(ANDROID_LOG_INFO, ANDROID_DEBUG_TAG, message); + break; + case DEBUG_LEVEL_WARN: + __android_log_write(ANDROID_LOG_WARN, ANDROID_DEBUG_TAG, message); + break; + case DEBUG_LEVEL_ERROR: + __android_log_write(ANDROID_LOG_ERROR, ANDROID_DEBUG_TAG, message); + break; + case DEBUG_LEVEL_FATAL: + __android_log_write(ANDROID_LOG_FATAL, ANDROID_DEBUG_TAG, message); + break; + } + TSK_FREE(message); + } + + va_end(ap); } #define DOUBANGO_AUDIO_WEBRTC_DEBUG_INFO(FMT, ...) DOUBANGO_AUDIO_WEBRTC_DEBUG_ANY(DEBUG_LEVEL_INFO, FMT, ##__VA_ARGS__) #define DOUBANGO_AUDIO_WEBRTC_DEBUG_WARN(FMT, ...) DOUBANGO_AUDIO_WEBRTC_DEBUG_ANY(DEBUG_LEVEL_WARN, FMT, ##__VA_ARGS__) diff --git a/plugins/audio_webrtc/audio_webrtc_consumer.cxx b/plugins/audio_webrtc/audio_webrtc_consumer.cxx index e55097b..8762a2d 100755 --- a/plugins/audio_webrtc/audio_webrtc_consumer.cxx +++ b/plugins/audio_webrtc/audio_webrtc_consumer.cxx @@ -1,17 +1,17 @@ /* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -24,153 +24,152 @@ #include "tsk_memory.h" #include "tsk_debug.h" -typedef struct audio_consumer_webrtc_s -{ - TDAV_DECLARE_CONSUMER_AUDIO; - audio_webrtc_instance_handle_t* audioInstHandle; - struct{ - void* ptr; - bool isFull; - int size; - int index; - } buffer; +typedef struct audio_consumer_webrtc_s { + TDAV_DECLARE_CONSUMER_AUDIO; + audio_webrtc_instance_handle_t* audioInstHandle; + struct { + void* ptr; + bool isFull; + int size; + int index; + } buffer; } audio_consumer_webrtc_t; int audio_consumer_webrtc_get_data_10ms(const audio_consumer_webrtc_t* _self, void* audioSamples, int nSamples, int nBytesPerSample, int nChannels, int samplesPerSec, uint32_t &nSamplesOut) { - nSamplesOut = 0; - if(!_self || !audioSamples || !nSamples){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if((nSamples != (samplesPerSec / 100))){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Not producing 10ms samples (nSamples=%d, samplesPerSec=%d)", nSamples, samplesPerSec); - return -2; - } - if((nBytesPerSample != (TMEDIA_CONSUMER(_self)->audio.bits_per_sample >> 3))){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("%d not valid bytes/samples", nBytesPerSample); - return -3; - } - if((nChannels != TMEDIA_CONSUMER(_self)->audio.out.channels)){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("%d not the expected number of channels", nChannels); - return -4; - } - - audio_consumer_webrtc_t* self = const_cast<audio_consumer_webrtc_t*>(_self); - - if(self->buffer.index == self->buffer.size){ - tdav_consumer_audio_tick(TDAV_CONSUMER_AUDIO(self)); - self->buffer.index = 0; - if((tdav_consumer_audio_get(TDAV_CONSUMER_AUDIO(self), self->buffer.ptr, self->buffer.size)) != self->buffer.size){ - nSamplesOut = 0; - return 0; - } - } - - int nSamplesInBits = (nSamples * nBytesPerSample); - if(_self->buffer.index + nSamplesInBits <= _self->buffer.size){ - memcpy(audioSamples, (((uint8_t*)self->buffer.ptr) + self->buffer.index), nSamplesInBits); - } - self->buffer.index += nSamplesInBits; - TSK_CLAMP(0, self->buffer.index, self->buffer.size); - nSamplesOut = nSamples; - - return 0; + nSamplesOut = 0; + if(!_self || !audioSamples || !nSamples) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if((nSamples != (samplesPerSec / 100))) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Not producing 10ms samples (nSamples=%d, samplesPerSec=%d)", nSamples, samplesPerSec); + return -2; + } + if((nBytesPerSample != (TMEDIA_CONSUMER(_self)->audio.bits_per_sample >> 3))) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("%d not valid bytes/samples", nBytesPerSample); + return -3; + } + if((nChannels != TMEDIA_CONSUMER(_self)->audio.out.channels)) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("%d not the expected number of channels", nChannels); + return -4; + } + + audio_consumer_webrtc_t* self = const_cast<audio_consumer_webrtc_t*>(_self); + + if(self->buffer.index == self->buffer.size) { + tdav_consumer_audio_tick(TDAV_CONSUMER_AUDIO(self)); + self->buffer.index = 0; + if((tdav_consumer_audio_get(TDAV_CONSUMER_AUDIO(self), self->buffer.ptr, self->buffer.size)) != self->buffer.size) { + nSamplesOut = 0; + return 0; + } + } + + int nSamplesInBits = (nSamples * nBytesPerSample); + if(_self->buffer.index + nSamplesInBits <= _self->buffer.size) { + memcpy(audioSamples, (((uint8_t*)self->buffer.ptr) + self->buffer.index), nSamplesInBits); + } + self->buffer.index += nSamplesInBits; + TSK_CLAMP(0, self->buffer.index, self->buffer.size); + nSamplesOut = nSamples; + + return 0; } /* ============ Media Consumer Interface ================= */ static int audio_consumer_webrtc_set(tmedia_consumer_t* self, const tmedia_param_t* param) { - audio_consumer_webrtc_t* webrtc = (audio_consumer_webrtc_t*)self; - int ret = tdav_consumer_audio_set(TDAV_CONSUMER_AUDIO(self), param); + audio_consumer_webrtc_t* webrtc = (audio_consumer_webrtc_t*)self; + int ret = tdav_consumer_audio_set(TDAV_CONSUMER_AUDIO(self), param); - if(ret == 0){ - if(tsk_striequals(param->key, "volume")){ - - } - } + if(ret == 0) { + if(tsk_striequals(param->key, "volume")) { - return ret; + } + } + + return ret; } static int audio_consumer_webrtc_prepare(tmedia_consumer_t* _self, const tmedia_codec_t* codec) { - audio_consumer_webrtc_t* self = (audio_consumer_webrtc_t*)_self; - if(!self){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - // create audio instance - if(!(self->audioInstHandle = audio_webrtc_instance_create(TMEDIA_CONSUMER(self)->session_id))){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Failed to create audio instance handle"); - return -1; - } - - // initialize input parameters from the codec information - TMEDIA_CONSUMER(self)->audio.ptime = codec->plugin->audio.ptime; - TMEDIA_CONSUMER(self)->audio.in.channels = codec->plugin->audio.channels; - TMEDIA_CONSUMER(self)->audio.in.rate = codec->plugin->rate; - - // prepare playout device and update output parameters - int ret = audio_webrtc_instance_prepare_consumer(self->audioInstHandle, &_self); - - // now that the producer is prepared we can initialize internal buffer using device caps - if(ret == 0){ - // allocate buffer - int xsize = ((TMEDIA_CONSUMER(self)->audio.ptime * TMEDIA_CONSUMER(self)->audio.out.rate) / 1000) * (TMEDIA_CONSUMER(self)->audio.bits_per_sample >> 3); - if(!(self->buffer.ptr = tsk_realloc(self->buffer.ptr, xsize))){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Failed to allocate buffer with size = %d", xsize); - self->buffer.size = 0; - return -1; - } - memset(self->buffer.ptr, 0, xsize); - self->buffer.size = xsize; - self->buffer.index = 0; - self->buffer.isFull = false; - } - return ret; + audio_consumer_webrtc_t* self = (audio_consumer_webrtc_t*)_self; + if(!self) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + // create audio instance + if(!(self->audioInstHandle = audio_webrtc_instance_create(TMEDIA_CONSUMER(self)->session_id))) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Failed to create audio instance handle"); + return -1; + } + + // initialize input parameters from the codec information + TMEDIA_CONSUMER(self)->audio.ptime = codec->plugin->audio.ptime; + TMEDIA_CONSUMER(self)->audio.in.channels = codec->plugin->audio.channels; + TMEDIA_CONSUMER(self)->audio.in.rate = codec->plugin->rate; + + // prepare playout device and update output parameters + int ret = audio_webrtc_instance_prepare_consumer(self->audioInstHandle, &_self); + + // now that the producer is prepared we can initialize internal buffer using device caps + if(ret == 0) { + // allocate buffer + int xsize = ((TMEDIA_CONSUMER(self)->audio.ptime * TMEDIA_CONSUMER(self)->audio.out.rate) / 1000) * (TMEDIA_CONSUMER(self)->audio.bits_per_sample >> 3); + if(!(self->buffer.ptr = tsk_realloc(self->buffer.ptr, xsize))) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Failed to allocate buffer with size = %d", xsize); + self->buffer.size = 0; + return -1; + } + memset(self->buffer.ptr, 0, xsize); + self->buffer.size = xsize; + self->buffer.index = 0; + self->buffer.isFull = false; + } + return ret; } static int audio_consumer_webrtc_start(tmedia_consumer_t* _self) { - audio_consumer_webrtc_t* self = (audio_consumer_webrtc_t*)_self; - if(!self){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Invalid parameter"); - return -1; - } + audio_consumer_webrtc_t* self = (audio_consumer_webrtc_t*)_self; + if(!self) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Invalid parameter"); + return -1; + } - return audio_webrtc_instance_start_consumer(self->audioInstHandle); + return audio_webrtc_instance_start_consumer(self->audioInstHandle); } static int audio_consumer_webrtc_consume(tmedia_consumer_t* _self, const void* buffer, tsk_size_t size, const tsk_object_t* proto_hdr) { - audio_consumer_webrtc_t* self = (audio_consumer_webrtc_t*)_self; - if(!self || !buffer || !size){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("1Invalid parameter"); - return -1; - } - /* buffer is already decoded */ - return tdav_consumer_audio_put(TDAV_CONSUMER_AUDIO(self), buffer, size, proto_hdr); + audio_consumer_webrtc_t* self = (audio_consumer_webrtc_t*)_self; + if(!self || !buffer || !size) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("1Invalid parameter"); + return -1; + } + /* buffer is already decoded */ + return tdav_consumer_audio_put(TDAV_CONSUMER_AUDIO(self), buffer, size, proto_hdr); } static int audio_consumer_webrtc_pause(tmedia_consumer_t* self) { - return 0; + return 0; } static int audio_consumer_webrtc_stop(tmedia_consumer_t* _self) { - audio_consumer_webrtc_t* self = (audio_consumer_webrtc_t*)_self; - if(!self){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Invalid parameter"); - return -1; - } + audio_consumer_webrtc_t* self = (audio_consumer_webrtc_t*)_self; + if(!self) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Invalid parameter"); + return -1; + } - return audio_webrtc_instance_stop_consumer(self->audioInstHandle); + return audio_webrtc_instance_stop_consumer(self->audioInstHandle); } @@ -180,54 +179,52 @@ static int audio_consumer_webrtc_stop(tmedia_consumer_t* _self) /* constructor */ static tsk_object_t* audio_consumer_webrtc_ctor(tsk_object_t *_self, va_list * app) { - audio_consumer_webrtc_t *self = (audio_consumer_webrtc_t *)_self; - if(self){ - /* init base */ - tdav_consumer_audio_init(TDAV_CONSUMER_AUDIO(self)); - /* init self */ - - } - return self; + audio_consumer_webrtc_t *self = (audio_consumer_webrtc_t *)_self; + if(self) { + /* init base */ + tdav_consumer_audio_init(TDAV_CONSUMER_AUDIO(self)); + /* init self */ + + } + return self; } /* destructor */ static tsk_object_t* audio_consumer_webrtc_dtor(tsk_object_t *_self) -{ - audio_consumer_webrtc_t *self = (audio_consumer_webrtc_t *)_self; - if(self){ - /* stop */ - audio_consumer_webrtc_stop(TMEDIA_CONSUMER(self)); - /* deinit self */ - if(self->audioInstHandle){ - audio_webrtc_instance_destroy(&self->audioInstHandle); - } - TSK_FREE(self->buffer.ptr); - /* deinit base */ - tdav_consumer_audio_deinit(TDAV_CONSUMER_AUDIO(self)); - } - - return self; +{ + audio_consumer_webrtc_t *self = (audio_consumer_webrtc_t *)_self; + if(self) { + /* stop */ + audio_consumer_webrtc_stop(TMEDIA_CONSUMER(self)); + /* deinit self */ + if(self->audioInstHandle) { + audio_webrtc_instance_destroy(&self->audioInstHandle); + } + TSK_FREE(self->buffer.ptr); + /* deinit base */ + tdav_consumer_audio_deinit(TDAV_CONSUMER_AUDIO(self)); + } + + return self; } /* object definition */ -static const tsk_object_def_t audio_consumer_webrtc_def_s = -{ - sizeof(audio_consumer_webrtc_t), - audio_consumer_webrtc_ctor, - audio_consumer_webrtc_dtor, - tdav_consumer_audio_cmp, +static const tsk_object_def_t audio_consumer_webrtc_def_s = { + sizeof(audio_consumer_webrtc_t), + audio_consumer_webrtc_ctor, + audio_consumer_webrtc_dtor, + tdav_consumer_audio_cmp, }; /* plugin definition*/ -static const tmedia_consumer_plugin_def_t audio_consumer_webrtc_plugin_def_s = -{ - &audio_consumer_webrtc_def_s, - - tmedia_audio, - "WebRTC audio consumer", - - audio_consumer_webrtc_set, - audio_consumer_webrtc_prepare, - audio_consumer_webrtc_start, - audio_consumer_webrtc_consume, - audio_consumer_webrtc_pause, - audio_consumer_webrtc_stop +static const tmedia_consumer_plugin_def_t audio_consumer_webrtc_plugin_def_s = { + &audio_consumer_webrtc_def_s, + + tmedia_audio, + "WebRTC audio consumer", + + audio_consumer_webrtc_set, + audio_consumer_webrtc_prepare, + audio_consumer_webrtc_start, + audio_consumer_webrtc_consume, + audio_consumer_webrtc_pause, + audio_consumer_webrtc_stop }; const tmedia_consumer_plugin_def_t *audio_consumer_webrtc_plugin_def_t = &audio_consumer_webrtc_plugin_def_s; diff --git a/plugins/audio_webrtc/audio_webrtc_consumer.h b/plugins/audio_webrtc/audio_webrtc_consumer.h index 9dc7dd1..8874f6d 100755 --- a/plugins/audio_webrtc/audio_webrtc_consumer.h +++ b/plugins/audio_webrtc/audio_webrtc_consumer.h @@ -1,17 +1,17 @@ /* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -22,7 +22,7 @@ DOUBANGO_AUDIO_WEBRTC_BEGIN_DECLS -extern const struct tmedia_consumer_plugin_def_s *audio_consumer_webrtc_plugin_def_t; +extern const struct tmedia_consumer_plugin_def_s *audio_consumer_webrtc_plugin_def_t; int audio_consumer_webrtc_get_data_10ms(const struct audio_consumer_webrtc_s* self, void* audioSamples, int nSamples, int nBytesPerSample, int nChannels, int samplesPerSec, uint32_t &nSamplesOut); diff --git a/plugins/audio_webrtc/audio_webrtc_producer.cxx b/plugins/audio_webrtc/audio_webrtc_producer.cxx index 02c5aeb..3d95d06 100755 --- a/plugins/audio_webrtc/audio_webrtc_producer.cxx +++ b/plugins/audio_webrtc/audio_webrtc_producer.cxx @@ -1,17 +1,17 @@ /* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -24,147 +24,146 @@ #include "tsk_memory.h" #include "tsk_debug.h" -typedef struct audio_producer_webrtc_s -{ - TDAV_DECLARE_PRODUCER_AUDIO; - - bool isMuted; - audio_webrtc_instance_handle_t* audioInstHandle; - struct{ - void* ptr; - int size; - int index; - } buffer; +typedef struct audio_producer_webrtc_s { + TDAV_DECLARE_PRODUCER_AUDIO; + + bool isMuted; + audio_webrtc_instance_handle_t* audioInstHandle; + struct { + void* ptr; + int size; + int index; + } buffer; } audio_producer_webrtc_t; int audio_producer_webrtc_handle_data_10ms(const audio_producer_webrtc_t* _self, const void* audioSamples, int nSamples, int nBytesPerSample, int samplesPerSec, int nChannels) { - if(!_self || !audioSamples || !nSamples){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if((nSamples != (samplesPerSec / 100))){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Not producing 10ms samples (nSamples=%d, samplesPerSec=%d)", nSamples, samplesPerSec); - return -2; - } - if((nBytesPerSample != (TMEDIA_PRODUCER(_self)->audio.bits_per_sample >> 3))){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("%d not valid bytes/samples", nBytesPerSample); - return -3; - } - if((nChannels != TMEDIA_PRODUCER(_self)->audio.channels)){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("%d not the expected number of channels", nChannels); - return -4; - } - - int nSamplesInBits = (nSamples * nBytesPerSample); - if(_self->buffer.index + nSamplesInBits > _self->buffer.size){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Buffer overflow"); - return -5; - } - - audio_producer_webrtc_t* self = const_cast<audio_producer_webrtc_t*>(_self); - - memcpy((((uint8_t*)self->buffer.ptr) + self->buffer.index), audioSamples, nSamplesInBits); - self->buffer.index += nSamplesInBits; - - if(self->buffer.index == self->buffer.size){ - self->buffer.index = 0; - if(TMEDIA_PRODUCER(self)->enc_cb.callback){ - if(self->isMuted){ - memset(self->buffer.ptr, 0, self->buffer.size); - } - TMEDIA_PRODUCER(self)->enc_cb.callback(TMEDIA_PRODUCER(self)->enc_cb.callback_data, self->buffer.ptr, self->buffer.size); - } - } - - return 0; + if(!_self || !audioSamples || !nSamples) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if((nSamples != (samplesPerSec / 100))) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Not producing 10ms samples (nSamples=%d, samplesPerSec=%d)", nSamples, samplesPerSec); + return -2; + } + if((nBytesPerSample != (TMEDIA_PRODUCER(_self)->audio.bits_per_sample >> 3))) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("%d not valid bytes/samples", nBytesPerSample); + return -3; + } + if((nChannels != TMEDIA_PRODUCER(_self)->audio.channels)) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("%d not the expected number of channels", nChannels); + return -4; + } + + int nSamplesInBits = (nSamples * nBytesPerSample); + if(_self->buffer.index + nSamplesInBits > _self->buffer.size) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Buffer overflow"); + return -5; + } + + audio_producer_webrtc_t* self = const_cast<audio_producer_webrtc_t*>(_self); + + memcpy((((uint8_t*)self->buffer.ptr) + self->buffer.index), audioSamples, nSamplesInBits); + self->buffer.index += nSamplesInBits; + + if(self->buffer.index == self->buffer.size) { + self->buffer.index = 0; + if(TMEDIA_PRODUCER(self)->enc_cb.callback) { + if(self->isMuted) { + memset(self->buffer.ptr, 0, self->buffer.size); + } + TMEDIA_PRODUCER(self)->enc_cb.callback(TMEDIA_PRODUCER(self)->enc_cb.callback_data, self->buffer.ptr, self->buffer.size); + } + } + + return 0; } /* ============ Media Producer Interface ================= */ static int audio_producer_webrtc_set(tmedia_producer_t* _self, const tmedia_param_t* param) -{ - audio_producer_webrtc_t* self = (audio_producer_webrtc_t*)_self; - if(param->plugin_type == tmedia_ppt_producer){ - if(param->value_type == tmedia_pvt_int32){ - if(tsk_striequals(param->key, "mute")){ - self->isMuted = (TSK_TO_INT32((uint8_t*)param->value) != 0); - return 0; - } - } - } - return tdav_producer_audio_set(TDAV_PRODUCER_AUDIO(self), param); +{ + audio_producer_webrtc_t* self = (audio_producer_webrtc_t*)_self; + if(param->plugin_type == tmedia_ppt_producer) { + if(param->value_type == tmedia_pvt_int32) { + if(tsk_striequals(param->key, "mute")) { + self->isMuted = (TSK_TO_INT32((uint8_t*)param->value) != 0); + return 0; + } + } + } + return tdav_producer_audio_set(TDAV_PRODUCER_AUDIO(self), param); } static int audio_producer_webrtc_prepare(tmedia_producer_t* _self, const tmedia_codec_t* codec) { - audio_producer_webrtc_t* self = (audio_producer_webrtc_t*)_self; - if(!self || !codec){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Invalid parameter"); - return -1; - } - - // create audio instance - if(!(self->audioInstHandle = audio_webrtc_instance_create(TMEDIA_PRODUCER(self)->session_id))){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Failed to create audio instance handle"); - return -2; - } - - // check that ptime is mutiple of 10 - if((codec->plugin->audio.ptime % 10)){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("ptime=%d not multiple of 10", codec->plugin->audio.ptime); - return -3; - } - - // init input parameters from the codec - TMEDIA_PRODUCER(self)->audio.channels = codec->plugin->audio.channels; - TMEDIA_PRODUCER(self)->audio.rate = codec->plugin->rate; - TMEDIA_PRODUCER(self)->audio.ptime = codec->plugin->audio.ptime; - - // prepare playout device and update output parameters - int ret; - ret = audio_webrtc_instance_prepare_producer(self->audioInstHandle, &_self); - - // now that the producer is prepared we can initialize internal buffer using device caps - if(ret == 0){ - // allocate buffer - int xsize = ((TMEDIA_PRODUCER(self)->audio.ptime * TMEDIA_PRODUCER(self)->audio.rate) / 1000) * (TMEDIA_PRODUCER(self)->audio.bits_per_sample >> 3); - if(!(self->buffer.ptr = tsk_realloc(self->buffer.ptr, xsize))){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Failed to allocate buffer with size = %d", xsize); - self->buffer.size = 0; - return -1; - } - self->buffer.size = xsize; - self->buffer.index = 0; - } - return ret; + audio_producer_webrtc_t* self = (audio_producer_webrtc_t*)_self; + if(!self || !codec) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + // create audio instance + if(!(self->audioInstHandle = audio_webrtc_instance_create(TMEDIA_PRODUCER(self)->session_id))) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Failed to create audio instance handle"); + return -2; + } + + // check that ptime is mutiple of 10 + if((codec->plugin->audio.ptime % 10)) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("ptime=%d not multiple of 10", codec->plugin->audio.ptime); + return -3; + } + + // init input parameters from the codec + TMEDIA_PRODUCER(self)->audio.channels = codec->plugin->audio.channels; + TMEDIA_PRODUCER(self)->audio.rate = codec->plugin->rate; + TMEDIA_PRODUCER(self)->audio.ptime = codec->plugin->audio.ptime; + + // prepare playout device and update output parameters + int ret; + ret = audio_webrtc_instance_prepare_producer(self->audioInstHandle, &_self); + + // now that the producer is prepared we can initialize internal buffer using device caps + if(ret == 0) { + // allocate buffer + int xsize = ((TMEDIA_PRODUCER(self)->audio.ptime * TMEDIA_PRODUCER(self)->audio.rate) / 1000) * (TMEDIA_PRODUCER(self)->audio.bits_per_sample >> 3); + if(!(self->buffer.ptr = tsk_realloc(self->buffer.ptr, xsize))) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Failed to allocate buffer with size = %d", xsize); + self->buffer.size = 0; + return -1; + } + self->buffer.size = xsize; + self->buffer.index = 0; + } + return ret; } static int audio_producer_webrtc_start(tmedia_producer_t* _self) { - audio_producer_webrtc_t* self = (audio_producer_webrtc_t*)_self; - if(!self){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Invalid parameter"); - return -1; - } + audio_producer_webrtc_t* self = (audio_producer_webrtc_t*)_self; + if(!self) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Invalid parameter"); + return -1; + } - return audio_webrtc_instance_start_producer(self->audioInstHandle); + return audio_webrtc_instance_start_producer(self->audioInstHandle); } static int audio_producer_webrtc_pause(tmedia_producer_t* self) { - return 0; + return 0; } static int audio_producer_webrtc_stop(tmedia_producer_t* _self) { - audio_producer_webrtc_t* self = (audio_producer_webrtc_t*)_self; - if(!self){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Invalid parameter"); - return -1; - } + audio_producer_webrtc_t* self = (audio_producer_webrtc_t*)_self; + if(!self) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("Invalid parameter"); + return -1; + } - return audio_webrtc_instance_stop_producer(self->audioInstHandle); + return audio_webrtc_instance_stop_producer(self->audioInstHandle); } @@ -174,54 +173,52 @@ static int audio_producer_webrtc_stop(tmedia_producer_t* _self) /* constructor */ static tsk_object_t* audio_producer_webrtc_ctor(tsk_object_t *_self, va_list * app) { - audio_producer_webrtc_t *self = (audio_producer_webrtc_t *)_self; - if(self){ - /* init base */ - tdav_producer_audio_init(TDAV_PRODUCER_AUDIO(self)); - /* init self */ - - } - return self; + audio_producer_webrtc_t *self = (audio_producer_webrtc_t *)_self; + if(self) { + /* init base */ + tdav_producer_audio_init(TDAV_PRODUCER_AUDIO(self)); + /* init self */ + + } + return self; } /* destructor */ static tsk_object_t* audio_producer_webrtc_dtor(tsk_object_t *_self) -{ - audio_producer_webrtc_t *self = (audio_producer_webrtc_t *)_self; - if(self){ - /* stop */ - audio_producer_webrtc_stop(TMEDIA_PRODUCER(self)); - /* deinit self */ - if(self->audioInstHandle){ - audio_webrtc_instance_destroy(&self->audioInstHandle); - } - TSK_FREE(self->buffer.ptr); - - /* deinit base */ - tdav_producer_audio_deinit(TDAV_PRODUCER_AUDIO(self)); - } - - return self; +{ + audio_producer_webrtc_t *self = (audio_producer_webrtc_t *)_self; + if(self) { + /* stop */ + audio_producer_webrtc_stop(TMEDIA_PRODUCER(self)); + /* deinit self */ + if(self->audioInstHandle) { + audio_webrtc_instance_destroy(&self->audioInstHandle); + } + TSK_FREE(self->buffer.ptr); + + /* deinit base */ + tdav_producer_audio_deinit(TDAV_PRODUCER_AUDIO(self)); + } + + return self; } /* object definition */ -static const tsk_object_def_t audio_producer_webrtc_def_s = -{ - sizeof(audio_producer_webrtc_t), - audio_producer_webrtc_ctor, - audio_producer_webrtc_dtor, - tdav_producer_audio_cmp, +static const tsk_object_def_t audio_producer_webrtc_def_s = { + sizeof(audio_producer_webrtc_t), + audio_producer_webrtc_ctor, + audio_producer_webrtc_dtor, + tdav_producer_audio_cmp, }; /* plugin definition*/ -static const tmedia_producer_plugin_def_t audio_producer_webrtc_plugin_def_s = -{ - &audio_producer_webrtc_def_s, - - tmedia_audio, - "WebRTC audio producer", - - audio_producer_webrtc_set, - audio_producer_webrtc_prepare, - audio_producer_webrtc_start, - audio_producer_webrtc_pause, - audio_producer_webrtc_stop +static const tmedia_producer_plugin_def_t audio_producer_webrtc_plugin_def_s = { + &audio_producer_webrtc_def_s, + + tmedia_audio, + "WebRTC audio producer", + + audio_producer_webrtc_set, + audio_producer_webrtc_prepare, + audio_producer_webrtc_start, + audio_producer_webrtc_pause, + audio_producer_webrtc_stop }; const tmedia_producer_plugin_def_t *audio_producer_webrtc_plugin_def_t = &audio_producer_webrtc_plugin_def_s;
\ No newline at end of file diff --git a/plugins/audio_webrtc/audio_webrtc_producer.h b/plugins/audio_webrtc/audio_webrtc_producer.h index 49adf0d..0e1defd 100755 --- a/plugins/audio_webrtc/audio_webrtc_producer.h +++ b/plugins/audio_webrtc/audio_webrtc_producer.h @@ -1,17 +1,17 @@ /* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ diff --git a/plugins/audio_webrtc/audio_webrtc_transport.cxx b/plugins/audio_webrtc/audio_webrtc_transport.cxx index 470e4e7..a9b50ed 100755 --- a/plugins/audio_webrtc/audio_webrtc_transport.cxx +++ b/plugins/audio_webrtc/audio_webrtc_transport.cxx @@ -1,17 +1,17 @@ /* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -33,15 +33,15 @@ AudioTransportImpl::AudioTransportImpl(AudioDeviceModule* audioDevice) : _microphoneBoost(false), _microphoneAGC(false), _loopBackMeasurements(false), - _consumer(tsk_null), - _producer(tsk_null) + _consumer(tsk_null), + _producer(tsk_null) { - + } AudioTransportImpl::~AudioTransportImpl() { - + } void AudioTransportImpl::SetFullDuplex(bool enable) @@ -60,11 +60,11 @@ WebRtc_Word32 AudioTransportImpl::RecordedDataIsAvailable( const WebRtc_UWord32 currentMicLevel, WebRtc_UWord32& newMicLevel) { - if(!_producer){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("No wrapped producer"); - return 0; - } - return audio_producer_webrtc_handle_data_10ms(_producer, audioSamples, nSamples, nBytesPerSample, samplesPerSec, nChannels); + if(!_producer) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("No wrapped producer"); + return 0; + } + return audio_producer_webrtc_handle_data_10ms(_producer, audioSamples, nSamples, nBytesPerSample, samplesPerSec, nChannels); } @@ -76,9 +76,9 @@ WebRtc_Word32 AudioTransportImpl::NeedMorePlayData( void* audioSamples, WebRtc_UWord32& nSamplesOut) { - if(!_consumer){ - DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("No wrapped consumer"); - return 0; - } - return audio_consumer_webrtc_get_data_10ms(_consumer, audioSamples, nSamples, nBytesPerSample, nChannels, samplesPerSec, nSamplesOut); + if(!_consumer) { + DOUBANGO_AUDIO_WEBRTC_DEBUG_ERROR("No wrapped consumer"); + return 0; + } + return audio_consumer_webrtc_get_data_10ms(_consumer, audioSamples, nSamples, nBytesPerSample, nChannels, samplesPerSec, nSamplesOut); }
\ No newline at end of file diff --git a/plugins/audio_webrtc/audio_webrtc_transport.h b/plugins/audio_webrtc/audio_webrtc_transport.h index 6d98ab5..07e5ac8 100755 --- a/plugins/audio_webrtc/audio_webrtc_transport.h +++ b/plugins/audio_webrtc/audio_webrtc_transport.h @@ -1,17 +1,17 @@ /* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -26,15 +26,15 @@ class AudioTransportImpl: public webrtc::AudioTransport { public: virtual WebRtc_Word32 - RecordedDataIsAvailable(const void* audioSamples, - const WebRtc_UWord32 nSamples, - const WebRtc_UWord8 nBytesPerSample, - const WebRtc_UWord8 nChannels, - const WebRtc_UWord32 samplesPerSec, - const WebRtc_UWord32 totalDelayMS, - const WebRtc_Word32 clockDrift, - const WebRtc_UWord32 currentMicLevel, - WebRtc_UWord32& newMicLevel); + RecordedDataIsAvailable(const void* audioSamples, + const WebRtc_UWord32 nSamples, + const WebRtc_UWord8 nBytesPerSample, + const WebRtc_UWord8 nChannels, + const WebRtc_UWord32 samplesPerSec, + const WebRtc_UWord32 totalDelayMS, + const WebRtc_Word32 clockDrift, + const WebRtc_UWord32 currentMicLevel, + WebRtc_UWord32& newMicLevel); virtual WebRtc_Word32 NeedMorePlayData(const WebRtc_UWord32 nSamples, const WebRtc_UWord8 nBytesPerSample, @@ -43,63 +43,54 @@ public: void* audioSamples, WebRtc_UWord32& nSamplesOut); - AudioTransportImpl(webrtc::AudioDeviceModule* audioDevice); + AudioTransportImpl(webrtc::AudioDeviceModule* audioDevice); ~AudioTransportImpl(); public: void SetFullDuplex(bool enable); - void SetSpeakerVolume(bool enable) - { + void SetSpeakerVolume(bool enable) { _speakerVolume = enable; } ; - void SetSpeakerMute(bool enable) - { + void SetSpeakerMute(bool enable) { _speakerMute = enable; } ; - void SetMicrophoneMute(bool enable) - { + void SetMicrophoneMute(bool enable) { _microphoneMute = enable; } ; - void SetMicrophoneVolume(bool enable) - { + void SetMicrophoneVolume(bool enable) { _microphoneVolume = enable; } ; - void SetMicrophoneBoost(bool enable) - { + void SetMicrophoneBoost(bool enable) { _microphoneBoost = enable; } ; - void SetLoopbackMeasurements(bool enable) - { + void SetLoopbackMeasurements(bool enable) { _loopBackMeasurements = enable; } ; - void SetMicrophoneAGC(bool enable) - { + void SetMicrophoneAGC(bool enable) { _microphoneAGC = enable; } ; - void SetConsumer(const struct audio_consumer_webrtc_s* consumer) - { + void SetConsumer(const struct audio_consumer_webrtc_s* consumer) { _consumer = consumer; } ; - void SetProducer(const struct audio_producer_webrtc_s* producer) - { + void SetProducer(const struct audio_producer_webrtc_s* producer) { _producer = producer; } ; private: webrtc::AudioDeviceModule* _audioDevice; - const struct audio_consumer_webrtc_s* _consumer; // mut be const and must not take reference - const struct audio_producer_webrtc_s* _producer; // mut be const and must not take reference + const struct audio_consumer_webrtc_s* _consumer; // mut be const and must not take reference + const struct audio_producer_webrtc_s* _producer; // mut be const and must not take reference bool _fullDuplex; bool _speakerVolume; diff --git a/plugins/audio_webrtc/dllmain.cxx b/plugins/audio_webrtc/dllmain.cxx index 8a319bc..06fc5ff 100755 --- a/plugins/audio_webrtc/dllmain.cxx +++ b/plugins/audio_webrtc/dllmain.cxx @@ -1,17 +1,17 @@ /* Copyright (C) 2012 Doubango Telecom <http://www.doubango.org> -* +* * This file is part of Open Source Doubango Framework. * * DOUBANGO is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. -* +* * DOUBANGO is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. -* +* * You should have received a copy of the GNU General Public License * along with DOUBANGO. */ @@ -24,16 +24,15 @@ BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved - ) + ) { - switch (ul_reason_for_call) - { - case DLL_PROCESS_ATTACH: - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - case DLL_PROCESS_DETACH: - break; - } - return TRUE; + switch (ul_reason_for_call) { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; } |