From 50dfb4359619563012997bc3ddafb7667741066c Mon Sep 17 00:00:00 2001 From: Mamadou DIOP Date: Tue, 23 Feb 2016 22:00:35 +0100 Subject: Add new QoS implementation Code formatting --- .../src/audio/coreaudio/tdav_producer_audiounit.c | 627 ++++++++++----------- 1 file changed, 313 insertions(+), 314 deletions(-) (limited to 'tinyDAV/src/audio/coreaudio/tdav_producer_audiounit.c') diff --git a/tinyDAV/src/audio/coreaudio/tdav_producer_audiounit.c b/tinyDAV/src/audio/coreaudio/tdav_producer_audiounit.c index a88261e..7f8af7e 100755 --- a/tinyDAV/src/audio/coreaudio/tdav_producer_audiounit.c +++ b/tinyDAV/src/audio/coreaudio/tdav_producer_audiounit.c @@ -2,19 +2,19 @@ * Copyright (C) 2010-2011 Mamadou Diop. * * Contact: Mamadou Diop - * + * * 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. * @@ -35,322 +35,323 @@ #define kRingPacketCount 10 -static OSStatus __handle_input_buffer(void *inRefCon, - AudioUnitRenderActionFlags *ioActionFlags, - const AudioTimeStamp *inTimeStamp, - UInt32 inBusNumber, - UInt32 inNumberFrames, - AudioBufferList *ioData) { - OSStatus status = noErr; - tdav_producer_audiounit_t* producer = (tdav_producer_audiounit_t*)inRefCon; - - // holder - AudioBuffer buffer; - buffer.mData = tsk_null; - buffer.mDataByteSize = 0; - buffer.mNumberChannels = TMEDIA_PRODUCER(producer)->audio.channels; - - // list of holders - AudioBufferList buffers; - buffers.mNumberBuffers = 1; - buffers.mBuffers[0] = buffer; - - // render to get frames from the system - status = AudioUnitRender(tdav_audiounit_handle_get_instance(producer->audioUnitHandle), - ioActionFlags, - inTimeStamp, - inBusNumber, - inNumberFrames, - &buffers); - if(status == 0){ +static OSStatus __handle_input_buffer(void *inRefCon, + AudioUnitRenderActionFlags *ioActionFlags, + const AudioTimeStamp *inTimeStamp, + UInt32 inBusNumber, + UInt32 inNumberFrames, + AudioBufferList *ioData) +{ + OSStatus status = noErr; + tdav_producer_audiounit_t* producer = (tdav_producer_audiounit_t*)inRefCon; + + // holder + AudioBuffer buffer; + buffer.mData = tsk_null; + buffer.mDataByteSize = 0; + buffer.mNumberChannels = TMEDIA_PRODUCER(producer)->audio.channels; + + // list of holders + AudioBufferList buffers; + buffers.mNumberBuffers = 1; + buffers.mBuffers[0] = buffer; + + // render to get frames from the system + status = AudioUnitRender(tdav_audiounit_handle_get_instance(producer->audioUnitHandle), + ioActionFlags, + inTimeStamp, + inBusNumber, + inNumberFrames, + &buffers); + if(status == 0) { // must not be done on async thread: doing it gives bad audio quality when audio+video call is done with CPU consuming codec (e.g. speex or g729) - speex_buffer_write(producer->ring.buffer, buffers.mBuffers[0].mData, buffers.mBuffers[0].mDataByteSize); + speex_buffer_write(producer->ring.buffer, buffers.mBuffers[0].mData, buffers.mBuffers[0].mDataByteSize); int avail = speex_buffer_get_available(producer->ring.buffer); while (producer->started && avail >= producer->ring.chunck.size) { avail -= speex_buffer_read(producer->ring.buffer, (void*)producer->ring.chunck.buffer, (int)producer->ring.chunck.size); TMEDIA_PRODUCER(producer)->enc_cb.callback(TMEDIA_PRODUCER(producer)->enc_cb.callback_data, - producer->ring.chunck.buffer, producer->ring.chunck.size); + producer->ring.chunck.buffer, producer->ring.chunck.size); } - } - + } + return status; } /* ============ Media Producer Interface ================= */ int tdav_producer_audiounit_set(tmedia_producer_t* self, const tmedia_param_t* param) -{ +{ tdav_producer_audiounit_t* producer = (tdav_producer_audiounit_t*)self; - if(param->plugin_type == tmedia_ppt_producer){ - if(param->value_type == tmedia_pvt_int32){ - if (tsk_striequals(param->key, "mute")) { - producer->muted = TSK_TO_INT32((uint8_t*)param->value); - return tdav_audiounit_handle_mute(((tdav_producer_audiounit_t*)self)->audioUnitHandle, producer->muted); - } + if(param->plugin_type == tmedia_ppt_producer) { + if(param->value_type == tmedia_pvt_int32) { + if (tsk_striequals(param->key, "mute")) { + producer->muted = TSK_TO_INT32((uint8_t*)param->value); + return tdav_audiounit_handle_mute(((tdav_producer_audiounit_t*)self)->audioUnitHandle, producer->muted); + } else if (tsk_striequals(param->key, "interrupt")) { - int32_t interrupt = *((uint8_t*)param->value) ? 1 : 0; + int32_t interrupt = *((uint8_t*)param->value) ? 1 : 0; return tdav_audiounit_handle_interrupt(producer->audioUnitHandle, interrupt); } - } - } - return tdav_producer_audio_set(TDAV_PRODUCER_AUDIO(self), param); + } + } + return tdav_producer_audio_set(TDAV_PRODUCER_AUDIO(self), param); } static int tdav_producer_audiounit_prepare(tmedia_producer_t* self, const tmedia_codec_t* codec) { - static UInt32 flagOne = 1; - UInt32 param; - // static UInt32 flagZero = 0; + static UInt32 flagOne = 1; + UInt32 param; + // static UInt32 flagZero = 0; #define kInputBus 1 - - tdav_producer_audiounit_t* producer = (tdav_producer_audiounit_t*)self; - OSStatus status = noErr; - AudioStreamBasicDescription audioFormat; - AudioStreamBasicDescription deviceFormat; - - if(!producer || !codec || !codec->plugin){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if(!producer->audioUnitHandle){ - if(!(producer->audioUnitHandle = tdav_audiounit_handle_create(TMEDIA_PRODUCER(producer)->session_id))){ - TSK_DEBUG_ERROR("Failed to get audio unit instance for session with id=%lld", TMEDIA_PRODUCER(producer)->session_id); - return -3; - } - } - - // enable - status = AudioUnitSetProperty(tdav_audiounit_handle_get_instance(producer->audioUnitHandle), - kAudioOutputUnitProperty_EnableIO, - kAudioUnitScope_Input, - kInputBus, - &flagOne, - sizeof(flagOne)); - if(status != noErr){ - TSK_DEBUG_ERROR("AudioUnitSetProperty(kAudioOutputUnitProperty_EnableIO) failed with status=%ld", (signed long)status); - return -4; - } - else { + + tdav_producer_audiounit_t* producer = (tdav_producer_audiounit_t*)self; + OSStatus status = noErr; + AudioStreamBasicDescription audioFormat; + AudioStreamBasicDescription deviceFormat; + + if(!producer || !codec || !codec->plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if(!producer->audioUnitHandle) { + if(!(producer->audioUnitHandle = tdav_audiounit_handle_create(TMEDIA_PRODUCER(producer)->session_id))) { + TSK_DEBUG_ERROR("Failed to get audio unit instance for session with id=%lld", TMEDIA_PRODUCER(producer)->session_id); + return -3; + } + } + + // enable + status = AudioUnitSetProperty(tdav_audiounit_handle_get_instance(producer->audioUnitHandle), + kAudioOutputUnitProperty_EnableIO, + kAudioUnitScope_Input, + kInputBus, + &flagOne, + sizeof(flagOne)); + if(status != noErr) { + TSK_DEBUG_ERROR("AudioUnitSetProperty(kAudioOutputUnitProperty_EnableIO) failed with status=%ld", (signed long)status); + return -4; + } + else { #if !TARGET_OS_IPHONE // strange: TARGET_OS_MAC is equal to '1' on Smulator - // disable output - param = 0; - status = AudioUnitSetProperty(tdav_audiounit_handle_get_instance(producer->audioUnitHandle), - kAudioOutputUnitProperty_EnableIO, - kAudioUnitScope_Output, - 0, - ¶m, - sizeof(UInt32)); - if(status != noErr){ - TSK_DEBUG_ERROR("AudioUnitSetProperty(kAudioOutputUnitProperty_EnableIO) failed with status=%ld", (signed long)status); - return -4; - } - - // set default audio device - param = sizeof(AudioDeviceID); - AudioDeviceID inputDeviceID; - status = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, ¶m, &inputDeviceID); - if(status != noErr){ - TSK_DEBUG_ERROR("AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice) failed with status=%ld", (signed long)status); - return -4; - } - - // set the current device to the default input unit - status = AudioUnitSetProperty(tdav_audiounit_handle_get_instance(producer->audioUnitHandle), - kAudioOutputUnitProperty_CurrentDevice, - kAudioUnitScope_Output, - 0, - &inputDeviceID, - sizeof(AudioDeviceID)); - if(status != noErr){ - TSK_DEBUG_ERROR("AudioUnitSetProperty(kAudioOutputUnitProperty_CurrentDevice) failed with status=%ld", (signed long)status); - return -4; - } + // disable output + param = 0; + status = AudioUnitSetProperty(tdav_audiounit_handle_get_instance(producer->audioUnitHandle), + kAudioOutputUnitProperty_EnableIO, + kAudioUnitScope_Output, + 0, + ¶m, + sizeof(UInt32)); + if(status != noErr) { + TSK_DEBUG_ERROR("AudioUnitSetProperty(kAudioOutputUnitProperty_EnableIO) failed with status=%ld", (signed long)status); + return -4; + } + + // set default audio device + param = sizeof(AudioDeviceID); + AudioDeviceID inputDeviceID; + status = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, ¶m, &inputDeviceID); + if(status != noErr) { + TSK_DEBUG_ERROR("AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice) failed with status=%ld", (signed long)status); + return -4; + } + + // set the current device to the default input unit + status = AudioUnitSetProperty(tdav_audiounit_handle_get_instance(producer->audioUnitHandle), + kAudioOutputUnitProperty_CurrentDevice, + kAudioUnitScope_Output, + 0, + &inputDeviceID, + sizeof(AudioDeviceID)); + if(status != noErr) { + TSK_DEBUG_ERROR("AudioUnitSetProperty(kAudioOutputUnitProperty_CurrentDevice) failed with status=%ld", (signed long)status); + return -4; + } #endif /* TARGET_OS_MAC */ - - /* codec should have ptime */ - TMEDIA_PRODUCER(producer)->audio.channels = TMEDIA_CODEC_CHANNELS_AUDIO_ENCODING(codec); - TMEDIA_PRODUCER(producer)->audio.rate = TMEDIA_CODEC_RATE_ENCODING(codec); - TMEDIA_PRODUCER(producer)->audio.ptime = TMEDIA_CODEC_PTIME_AUDIO_ENCODING(codec); + + /* codec should have ptime */ + TMEDIA_PRODUCER(producer)->audio.channels = TMEDIA_CODEC_CHANNELS_AUDIO_ENCODING(codec); + TMEDIA_PRODUCER(producer)->audio.rate = TMEDIA_CODEC_RATE_ENCODING(codec); + TMEDIA_PRODUCER(producer)->audio.ptime = TMEDIA_CODEC_PTIME_AUDIO_ENCODING(codec); TSK_DEBUG_INFO("AudioUnit producer: channels=%d, rate=%d, ptime=%d", TMEDIA_PRODUCER(producer)->audio.channels, TMEDIA_PRODUCER(producer)->audio.rate, TMEDIA_PRODUCER(producer)->audio.ptime); - - // get device format - param = sizeof(AudioStreamBasicDescription); - status = AudioUnitGetProperty(tdav_audiounit_handle_get_instance(producer->audioUnitHandle), - kAudioUnitProperty_StreamFormat, - kAudioUnitScope_Input, - kInputBus, - &deviceFormat, ¶m); - if(status == noErr && deviceFormat.mSampleRate){ + + // get device format + param = sizeof(AudioStreamBasicDescription); + status = AudioUnitGetProperty(tdav_audiounit_handle_get_instance(producer->audioUnitHandle), + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Input, + kInputBus, + &deviceFormat, ¶m); + if(status == noErr && deviceFormat.mSampleRate) { #if TARGET_OS_IPHONE - // iOS support 8Khz, 16kHz and 32kHz => do not override the sampleRate + // iOS support 8Khz, 16kHz and 32kHz => do not override the sampleRate #elif TARGET_OS_MAC - // For example, iSight supports only 48kHz - TMEDIA_PRODUCER(producer)->audio.rate = deviceFormat.mSampleRate; + // For example, iSight supports only 48kHz + TMEDIA_PRODUCER(producer)->audio.rate = deviceFormat.mSampleRate; #endif - } - - // set format - audioFormat.mSampleRate = TMEDIA_PRODUCER(producer)->audio.rate; - audioFormat.mFormatID = kAudioFormatLinearPCM; - audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked | kAudioFormatFlagIsNonInterleaved; - audioFormat.mChannelsPerFrame = TMEDIA_PRODUCER(producer)->audio.channels; - audioFormat.mFramesPerPacket = 1; - audioFormat.mBitsPerChannel = TMEDIA_PRODUCER(producer)->audio.bits_per_sample; - audioFormat.mBytesPerPacket = audioFormat.mBitsPerChannel / 8 * audioFormat.mChannelsPerFrame; - audioFormat.mBytesPerFrame = audioFormat.mBytesPerPacket; - audioFormat.mReserved = 0; - if(audioFormat.mFormatID == kAudioFormatLinearPCM && audioFormat.mChannelsPerFrame == 1){ - audioFormat.mFormatFlags &= ~kLinearPCMFormatFlagIsNonInterleaved; - } - status = AudioUnitSetProperty(tdav_audiounit_handle_get_instance(producer->audioUnitHandle), - kAudioUnitProperty_StreamFormat, - kAudioUnitScope_Output, - kInputBus, - &audioFormat, - sizeof(audioFormat)); - if(status){ - TSK_DEBUG_ERROR("AudioUnitSetProperty(kAudioUnitProperty_StreamFormat) failed with status=%ld", (signed long)status); - return -5; - } - else { - - // configure - if(tdav_audiounit_handle_configure(producer->audioUnitHandle, tsk_false, TMEDIA_PRODUCER(producer)->audio.ptime, &audioFormat)){ - TSK_DEBUG_ERROR("tdav_audiounit_handle_set_rate(%d) failed", TMEDIA_PRODUCER(producer)->audio.rate); - return -4; - } - - // set callback function - AURenderCallbackStruct callback; - callback.inputProc = __handle_input_buffer; - callback.inputProcRefCon = producer; - status = AudioUnitSetProperty(tdav_audiounit_handle_get_instance(producer->audioUnitHandle), - kAudioOutputUnitProperty_SetInputCallback, - kAudioUnitScope_Output, - kInputBus, - &callback, - sizeof(callback)); - if(status){ - TSK_DEBUG_ERROR("AudioUnitSetProperty(kAudioOutputUnitProperty_SetInputCallback) failed with status=%ld", (signed long)status); - return -6; - } - else { - // disbale buffer allocation as we will provide ours - //status = AudioUnitSetProperty(tdav_audiounit_handle_get_instance(producer->audioUnitHandle), - // kAudioUnitProperty_ShouldAllocateBuffer, - // kAudioUnitScope_Output, - // kInputBus, - // &flagZero, - // sizeof(flagZero)); - - producer->ring.chunck.size = (TMEDIA_PRODUCER(producer)->audio.ptime * audioFormat.mSampleRate * audioFormat.mBytesPerFrame) / 1000; - // allocate our chunck buffer - if(!(producer->ring.chunck.buffer = tsk_realloc(producer->ring.chunck.buffer, producer->ring.chunck.size))){ - TSK_DEBUG_ERROR("Failed to allocate new buffer"); - return -7; - } - // create ringbuffer - producer->ring.size = kRingPacketCount * producer->ring.chunck.size; - if(!producer->ring.buffer){ - producer->ring.buffer = speex_buffer_init((int)producer->ring.size); - } - else { - int ret; - if((ret = speex_buffer_resize(producer->ring.buffer, producer->ring.size)) < 0){ - TSK_DEBUG_ERROR("speex_buffer_resize(%d) failed with error code=%d", (int)producer->ring.size, ret); - return ret; - } - } - if(!producer->ring.buffer){ - TSK_DEBUG_ERROR("Failed to create a new ring buffer with size = %d", (int)producer->ring.size); - return -9; - } - } - - } - } - - TSK_DEBUG_INFO("AudioUnit producer prepared"); - return tdav_audiounit_handle_signal_producer_prepared(producer->audioUnitHandle);; + } + + // set format + audioFormat.mSampleRate = TMEDIA_PRODUCER(producer)->audio.rate; + audioFormat.mFormatID = kAudioFormatLinearPCM; + audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked | kAudioFormatFlagIsNonInterleaved; + audioFormat.mChannelsPerFrame = TMEDIA_PRODUCER(producer)->audio.channels; + audioFormat.mFramesPerPacket = 1; + audioFormat.mBitsPerChannel = TMEDIA_PRODUCER(producer)->audio.bits_per_sample; + audioFormat.mBytesPerPacket = audioFormat.mBitsPerChannel / 8 * audioFormat.mChannelsPerFrame; + audioFormat.mBytesPerFrame = audioFormat.mBytesPerPacket; + audioFormat.mReserved = 0; + if(audioFormat.mFormatID == kAudioFormatLinearPCM && audioFormat.mChannelsPerFrame == 1) { + audioFormat.mFormatFlags &= ~kLinearPCMFormatFlagIsNonInterleaved; + } + status = AudioUnitSetProperty(tdav_audiounit_handle_get_instance(producer->audioUnitHandle), + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Output, + kInputBus, + &audioFormat, + sizeof(audioFormat)); + if(status) { + TSK_DEBUG_ERROR("AudioUnitSetProperty(kAudioUnitProperty_StreamFormat) failed with status=%ld", (signed long)status); + return -5; + } + else { + + // configure + if(tdav_audiounit_handle_configure(producer->audioUnitHandle, tsk_false, TMEDIA_PRODUCER(producer)->audio.ptime, &audioFormat)) { + TSK_DEBUG_ERROR("tdav_audiounit_handle_set_rate(%d) failed", TMEDIA_PRODUCER(producer)->audio.rate); + return -4; + } + + // set callback function + AURenderCallbackStruct callback; + callback.inputProc = __handle_input_buffer; + callback.inputProcRefCon = producer; + status = AudioUnitSetProperty(tdav_audiounit_handle_get_instance(producer->audioUnitHandle), + kAudioOutputUnitProperty_SetInputCallback, + kAudioUnitScope_Output, + kInputBus, + &callback, + sizeof(callback)); + if(status) { + TSK_DEBUG_ERROR("AudioUnitSetProperty(kAudioOutputUnitProperty_SetInputCallback) failed with status=%ld", (signed long)status); + return -6; + } + else { + // disbale buffer allocation as we will provide ours + //status = AudioUnitSetProperty(tdav_audiounit_handle_get_instance(producer->audioUnitHandle), + // kAudioUnitProperty_ShouldAllocateBuffer, + // kAudioUnitScope_Output, + // kInputBus, + // &flagZero, + // sizeof(flagZero)); + + producer->ring.chunck.size = (TMEDIA_PRODUCER(producer)->audio.ptime * audioFormat.mSampleRate * audioFormat.mBytesPerFrame) / 1000; + // allocate our chunck buffer + if(!(producer->ring.chunck.buffer = tsk_realloc(producer->ring.chunck.buffer, producer->ring.chunck.size))) { + TSK_DEBUG_ERROR("Failed to allocate new buffer"); + return -7; + } + // create ringbuffer + producer->ring.size = kRingPacketCount * producer->ring.chunck.size; + if(!producer->ring.buffer) { + producer->ring.buffer = speex_buffer_init((int)producer->ring.size); + } + else { + int ret; + if((ret = speex_buffer_resize(producer->ring.buffer, producer->ring.size)) < 0) { + TSK_DEBUG_ERROR("speex_buffer_resize(%d) failed with error code=%d", (int)producer->ring.size, ret); + return ret; + } + } + if(!producer->ring.buffer) { + TSK_DEBUG_ERROR("Failed to create a new ring buffer with size = %d", (int)producer->ring.size); + return -9; + } + } + + } + } + + TSK_DEBUG_INFO("AudioUnit producer prepared"); + return tdav_audiounit_handle_signal_producer_prepared(producer->audioUnitHandle);; } static int tdav_producer_audiounit_start(tmedia_producer_t* self) { - tdav_producer_audiounit_t* producer = (tdav_producer_audiounit_t*)self; - - if(!producer){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if(producer->paused){ - producer->paused = tsk_false; - return tsk_false; - } - - int ret; - if(producer->started){ - TSK_DEBUG_WARN("Already started"); - return 0; - } - else { - ret = tdav_audiounit_handle_start(producer->audioUnitHandle); - if(ret){ - TSK_DEBUG_ERROR("tdav_audiounit_handle_start failed with error code=%d", ret); - return ret; - } - } - producer->started = tsk_true; - + tdav_producer_audiounit_t* producer = (tdav_producer_audiounit_t*)self; + + if(!producer) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if(producer->paused) { + producer->paused = tsk_false; + return tsk_false; + } + + int ret; + if(producer->started) { + TSK_DEBUG_WARN("Already started"); + return 0; + } + else { + ret = tdav_audiounit_handle_start(producer->audioUnitHandle); + if(ret) { + TSK_DEBUG_ERROR("tdav_audiounit_handle_start failed with error code=%d", ret); + return ret; + } + } + producer->started = tsk_true; + // apply parameters (because could be lost when the producer is restarted -handle recreated-) ret = tdav_audiounit_handle_mute(producer->audioUnitHandle, producer->muted); - TSK_DEBUG_INFO("AudioUnit producer started"); - return 0; + TSK_DEBUG_INFO("AudioUnit producer started"); + return 0; } static int tdav_producer_audiounit_pause(tmedia_producer_t* self) { tdav_producer_audiounit_t* producer = (tdav_producer_audiounit_t*)self; - if(!producer){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - producer->paused = tsk_true; - TSK_DEBUG_INFO("AudioUnit producer paused"); - return 0; + if(!producer) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + producer->paused = tsk_true; + TSK_DEBUG_INFO("AudioUnit producer paused"); + return 0; } static int tdav_producer_audiounit_stop(tmedia_producer_t* self) { tdav_producer_audiounit_t* producer = (tdav_producer_audiounit_t*)self; - - if(!producer){ - TSK_DEBUG_ERROR("Invalid parameter"); - return -1; - } - if(!producer->started){ - TSK_DEBUG_INFO("Not started"); - return 0; - } - else { - int ret = tdav_audiounit_handle_stop(producer->audioUnitHandle); - if(ret){ - TSK_DEBUG_ERROR("tdav_audiounit_handle_stop failed with error code=%d", ret); - // do not return even if failed => we MUST stop the thread! - } + + if(!producer) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + if(!producer->started) { + TSK_DEBUG_INFO("Not started"); + return 0; + } + else { + int ret = tdav_audiounit_handle_stop(producer->audioUnitHandle); + if(ret) { + TSK_DEBUG_ERROR("tdav_audiounit_handle_stop failed with error code=%d", ret); + // do not return even if failed => we MUST stop the thread! + } #if TARGET_OS_IPHONE - //https://devforums.apple.com/thread/118595 - if(producer->audioUnitHandle){ - tdav_audiounit_handle_destroy(&producer->audioUnitHandle); - } + //https://devforums.apple.com/thread/118595 + if(producer->audioUnitHandle) { + tdav_audiounit_handle_destroy(&producer->audioUnitHandle); + } #endif - } - producer->started = tsk_false; - TSK_DEBUG_INFO("AudioUnit producer stoppped"); - return 0; + } + producer->started = tsk_false; + TSK_DEBUG_INFO("AudioUnit producer stoppped"); + return 0; } @@ -360,61 +361,59 @@ static int tdav_producer_audiounit_stop(tmedia_producer_t* self) /* constructor */ static tsk_object_t* tdav_producer_audiounit_ctor(tsk_object_t * self, va_list * app) { - tdav_producer_audiounit_t *producer = self; - if(producer){ - /* init base */ - tdav_producer_audio_init(TDAV_PRODUCER_AUDIO(producer)); - /* init self */ - } - return self; + tdav_producer_audiounit_t *producer = self; + if(producer) { + /* init base */ + tdav_producer_audio_init(TDAV_PRODUCER_AUDIO(producer)); + /* init self */ + } + return self; } /* destructor */ static tsk_object_t* tdav_producer_audiounit_dtor(tsk_object_t * self) -{ - tdav_producer_audiounit_t *producer = self; - if(producer){ - // Stop the producer if not done - if(producer->started){ - tdav_producer_audiounit_stop(self); - } - - // Free all buffers and dispose the queue +{ + tdav_producer_audiounit_t *producer = self; + if(producer) { + // Stop the producer if not done + if(producer->started) { + tdav_producer_audiounit_stop(self); + } + + // Free all buffers and dispose the queue if (producer->audioUnitHandle) { - tdav_audiounit_handle_destroy(&producer->audioUnitHandle); + tdav_audiounit_handle_destroy(&producer->audioUnitHandle); } TSK_FREE(producer->ring.chunck.buffer); - if(producer->ring.buffer){ - speex_buffer_destroy(producer->ring.buffer); - } - /* deinit base */ - tdav_producer_audio_deinit(TDAV_PRODUCER_AUDIO(producer)); - + if(producer->ring.buffer) { + speex_buffer_destroy(producer->ring.buffer); + } + /* deinit base */ + tdav_producer_audio_deinit(TDAV_PRODUCER_AUDIO(producer)); + TSK_DEBUG_INFO("*** AudioUnit Producer destroyed ***"); - } - - return self; + } + + return self; } /* object definition */ -static const tsk_object_def_t tdav_producer_audiounit_def_s = -{ - sizeof(tdav_producer_audiounit_t), - tdav_producer_audiounit_ctor, - tdav_producer_audiounit_dtor, - tdav_producer_audio_cmp, +static const tsk_object_def_t tdav_producer_audiounit_def_s = { + sizeof(tdav_producer_audiounit_t), + tdav_producer_audiounit_ctor, + tdav_producer_audiounit_dtor, + tdav_producer_audio_cmp, }; /* plugin definition*/ -static const tmedia_producer_plugin_def_t tdav_producer_audiounit_plugin_def_s = -{ - &tdav_producer_audiounit_def_s, - - tmedia_audio, - "Apple CoreAudio producer (AudioUnit)", - - tdav_producer_audiounit_set, - tdav_producer_audiounit_prepare, - tdav_producer_audiounit_start, - tdav_producer_audiounit_pause, - tdav_producer_audiounit_stop +static const tmedia_producer_plugin_def_t tdav_producer_audiounit_plugin_def_s = { + &tdav_producer_audiounit_def_s, + + tmedia_audio, + "Apple CoreAudio producer (AudioUnit)", + + tdav_producer_audiounit_set, + tdav_producer_audiounit_prepare, + tdav_producer_audiounit_start, + tdav_producer_audiounit_pause, + tdav_producer_audiounit_stop }; const tmedia_producer_plugin_def_t *tdav_producer_audiounit_plugin_def_t = &tdav_producer_audiounit_plugin_def_s; -- cgit v1.1