diff --git a/thirdparties/common/include/openssl/aes.h b/thirdparties/common/include/openssl/aes.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/asn1.h b/thirdparties/common/include/openssl/asn1.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/asn1_mac.h b/thirdparties/common/include/openssl/asn1_mac.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/asn1t.h b/thirdparties/common/include/openssl/asn1t.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/bio.h b/thirdparties/common/include/openssl/bio.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/blowfish.h b/thirdparties/common/include/openssl/blowfish.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/bn.h b/thirdparties/common/include/openssl/bn.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/buffer.h b/thirdparties/common/include/openssl/buffer.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/camellia.h b/thirdparties/common/include/openssl/camellia.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/cast.h b/thirdparties/common/include/openssl/cast.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/cmac.h b/thirdparties/common/include/openssl/cmac.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/cms.h b/thirdparties/common/include/openssl/cms.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/comp.h b/thirdparties/common/include/openssl/comp.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/conf.h b/thirdparties/common/include/openssl/conf.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/conf_api.h b/thirdparties/common/include/openssl/conf_api.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/crypto.h b/thirdparties/common/include/openssl/crypto.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/des.h b/thirdparties/common/include/openssl/des.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/des_old.h b/thirdparties/common/include/openssl/des_old.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/dh.h b/thirdparties/common/include/openssl/dh.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/dsa.h b/thirdparties/common/include/openssl/dsa.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/dso.h b/thirdparties/common/include/openssl/dso.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/dtls1.h b/thirdparties/common/include/openssl/dtls1.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/e_os2.h b/thirdparties/common/include/openssl/e_os2.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/ebcdic.h b/thirdparties/common/include/openssl/ebcdic.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/ec.h b/thirdparties/common/include/openssl/ec.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/ecdh.h b/thirdparties/common/include/openssl/ecdh.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/ecdsa.h b/thirdparties/common/include/openssl/ecdsa.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/engine.h b/thirdparties/common/include/openssl/engine.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/err.h b/thirdparties/common/include/openssl/err.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/evp.h b/thirdparties/common/include/openssl/evp.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/hmac.h b/thirdparties/common/include/openssl/hmac.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/idea.h b/thirdparties/common/include/openssl/idea.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/krb5_asn.h b/thirdparties/common/include/openssl/krb5_asn.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/kssl.h b/thirdparties/common/include/openssl/kssl.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/lhash.h b/thirdparties/common/include/openssl/lhash.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/md4.h b/thirdparties/common/include/openssl/md4.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/md5.h b/thirdparties/common/include/openssl/md5.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/mdc2.h b/thirdparties/common/include/openssl/mdc2.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/modes.h b/thirdparties/common/include/openssl/modes.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/obj_mac.h b/thirdparties/common/include/openssl/obj_mac.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/objects.h b/thirdparties/common/include/openssl/objects.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/ocsp.h b/thirdparties/common/include/openssl/ocsp.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/opensslconf.h b/thirdparties/common/include/openssl/opensslconf.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/opensslv.h b/thirdparties/common/include/openssl/opensslv.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/ossl_typ.h b/thirdparties/common/include/openssl/ossl_typ.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/pem.h b/thirdparties/common/include/openssl/pem.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/pem2.h b/thirdparties/common/include/openssl/pem2.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/pkcs12.h b/thirdparties/common/include/openssl/pkcs12.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/pkcs7.h b/thirdparties/common/include/openssl/pkcs7.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/pqueue.h b/thirdparties/common/include/openssl/pqueue.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/rand.h b/thirdparties/common/include/openssl/rand.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/rc2.h b/thirdparties/common/include/openssl/rc2.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/rc4.h b/thirdparties/common/include/openssl/rc4.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/ripemd.h b/thirdparties/common/include/openssl/ripemd.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/rsa.h b/thirdparties/common/include/openssl/rsa.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/safestack.h b/thirdparties/common/include/openssl/safestack.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/seed.h b/thirdparties/common/include/openssl/seed.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/sha.h b/thirdparties/common/include/openssl/sha.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/srp.h b/thirdparties/common/include/openssl/srp.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/srtp.h b/thirdparties/common/include/openssl/srtp.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/ssl.h b/thirdparties/common/include/openssl/ssl.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/ssl2.h b/thirdparties/common/include/openssl/ssl2.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/ssl23.h b/thirdparties/common/include/openssl/ssl23.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/ssl3.h b/thirdparties/common/include/openssl/ssl3.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/stack.h b/thirdparties/common/include/openssl/stack.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/symhacks.h b/thirdparties/common/include/openssl/symhacks.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/tls1.h b/thirdparties/common/include/openssl/tls1.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/ts.h b/thirdparties/common/include/openssl/ts.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/txt_db.h b/thirdparties/common/include/openssl/txt_db.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/ui.h b/thirdparties/common/include/openssl/ui.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/ui_compat.h b/thirdparties/common/include/openssl/ui_compat.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/whrlpool.h b/thirdparties/common/include/openssl/whrlpool.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/x509.h b/thirdparties/common/include/openssl/x509.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/x509_vfy.h b/thirdparties/common/include/openssl/x509_vfy.h old mode 100644 new mode 100755 diff --git a/thirdparties/common/include/openssl/x509v3.h b/thirdparties/common/include/openssl/x509v3.h old mode 100644 new mode 100755 diff --git a/thirdparties/iphone/lib/universal/libcrypto.a b/thirdparties/iphone/lib/universal/libcrypto.a old mode 100644 new mode 100755 diff --git a/thirdparties/iphone/lib/universal/libssl.a b/thirdparties/iphone/lib/universal/libssl.a old mode 100644 new mode 100755 diff --git a/thirdparties/mac/lib/universal/libcrypto.a b/thirdparties/mac/lib/universal/libcrypto.a old mode 100644 new mode 100755 diff --git a/thirdparties/mac/lib/universal/libssl.a b/thirdparties/mac/lib/universal/libssl.a old mode 100644 new mode 100755 diff --git a/tinyDAV/include/tinydav/audio/coreaudio/tdav_audiounit.h b/tinyDAV/include/tinydav/audio/coreaudio/tdav_audiounit.h index 3db4e6a1..20cacd1e 100755 --- a/tinyDAV/include/tinydav/audio/coreaudio/tdav_audiounit.h +++ b/tinyDAV/include/tinydav/audio/coreaudio/tdav_audiounit.h @@ -48,8 +48,8 @@ typedef void* tdav_audiounit_handle_t; tdav_audiounit_handle_t* tdav_audiounit_handle_create(uint64_t session_id); AudioComponentInstance tdav_audiounit_handle_get_instance(tdav_audiounit_handle_t* self); -int tdav_audiounit_handle_signal_consumer_prepared(tdav_audiounit_handle_t* self); -int tdav_audiounit_handle_signal_producer_prepared(tdav_audiounit_handle_t* self); +int tdav_audiounit_handle_signal_consumer_ready(tdav_audiounit_handle_t* self); +int tdav_audiounit_handle_signal_producer_ready(tdav_audiounit_handle_t* self); int tdav_audiounit_handle_start(tdav_audiounit_handle_t* self); uint32_t tdav_audiounit_handle_get_frame_duration(tdav_audiounit_handle_t* self); int tdav_audiounit_handle_configure(tdav_audiounit_handle_t* self, tsk_bool_t consumer, uint32_t ptime, AudioStreamBasicDescription* audioFormat); diff --git a/tinyDAV/include/tinydav/audio/coreaudio/tdav_consumer_audiounit.h b/tinyDAV/include/tinydav/audio/coreaudio/tdav_consumer_audiounit.h index ca48978c..6dfffbbf 100755 --- a/tinyDAV/include/tinydav/audio/coreaudio/tdav_consumer_audiounit.h +++ b/tinyDAV/include/tinydav/audio/coreaudio/tdav_consumer_audiounit.h @@ -42,6 +42,7 @@ typedef struct tdav_consumer_audiounit_s { tdav_audiounit_handle_t* audioUnitHandle; unsigned started:1; unsigned paused:1; + unsigned ready:1; struct { struct { diff --git a/tinyDAV/include/tinydav/audio/coreaudio/tdav_producer_audiounit.h b/tinyDAV/include/tinydav/audio/coreaudio/tdav_producer_audiounit.h index bcc44d7e..aa197349 100755 --- a/tinyDAV/include/tinydav/audio/coreaudio/tdav_producer_audiounit.h +++ b/tinyDAV/include/tinydav/audio/coreaudio/tdav_producer_audiounit.h @@ -41,7 +41,8 @@ typedef struct tdav_producer_audiounit_s { tdav_audiounit_handle_t* audioUnitHandle; unsigned started:1; unsigned paused:1; - unsigned muted; + unsigned ready:1; + unsigned muted:1; struct { struct { diff --git a/tinyDAV/src/audio/coreaudio/tdav_audiounit.c b/tinyDAV/src/audio/coreaudio/tdav_audiounit.c index d00f8eef..6020a32c 100755 --- a/tinyDAV/src/audio/coreaudio/tdav_audiounit.c +++ b/tinyDAV/src/audio/coreaudio/tdav_audiounit.c @@ -60,7 +60,7 @@ typedef struct tdav_audiounit_instance_s { struct { unsigned consumer:1; unsigned producer:1; - } prepared; + } ready; unsigned started:1; unsigned interrupted:1; @@ -75,7 +75,7 @@ typedef tsk_list_t tdav_audiounit_instances_L_t; static AudioComponent __audioSystem = tsk_null; static tdav_audiounit_instances_L_t* __audioUnitInstances = tsk_null; -static int _tdav_audiounit_handle_signal_xxx_prepared(tdav_audiounit_handle_t* self, tsk_bool_t consumer) +static int _tdav_audiounit_handle_signal_xxx_ready(tdav_audiounit_handle_t* self, tsk_bool_t consumer) { tdav_audiounit_instance_t* inst = (tdav_audiounit_instance_t*)self; if(!inst || !inst->audioUnit) { @@ -85,18 +85,18 @@ static int _tdav_audiounit_handle_signal_xxx_prepared(tdav_audiounit_handle_t* s tsk_safeobj_lock(inst); - if(consumer) { - inst->prepared.consumer = tsk_true; + if (consumer) { + inst->ready.consumer = tsk_true; } else { - inst->prepared.producer = tsk_true; + inst->ready.producer = tsk_true; } OSStatus status; // For iOS we are using full-duplex AudioUnit and we wait for both consumer and producer to be prepared #if TARGET_OS_IPHONE - if(inst->prepared.consumer && inst->prepared.producer) + if(inst->ready.consumer && inst->ready.producer) #endif { status = AudioUnitInitialize(inst->audioUnit); @@ -184,14 +184,14 @@ AudioComponentInstance tdav_audiounit_handle_get_instance(tdav_audiounit_handle_ return ((tdav_audiounit_instance_t*)self)->audioUnit; } -int tdav_audiounit_handle_signal_consumer_prepared(tdav_audiounit_handle_t* self) +int tdav_audiounit_handle_signal_consumer_ready(tdav_audiounit_handle_t* self) { - return _tdav_audiounit_handle_signal_xxx_prepared(self, tsk_true); + return _tdav_audiounit_handle_signal_xxx_ready(self, tsk_true); } -int tdav_audiounit_handle_signal_producer_prepared(tdav_audiounit_handle_t* self) +int tdav_audiounit_handle_signal_producer_ready(tdav_audiounit_handle_t* self) { - return _tdav_audiounit_handle_signal_xxx_prepared(self, tsk_false); + return _tdav_audiounit_handle_signal_xxx_ready(self, tsk_false); } int tdav_audiounit_handle_start(tdav_audiounit_handle_t* self) @@ -204,18 +204,23 @@ int tdav_audiounit_handle_start(tdav_audiounit_handle_t* self) } tsk_safeobj_lock(inst); - status = (OSStatus)tdav_apple_enable_audio(); - if (status == noErr) { - if ((!inst->started || inst->interrupted) && (status = AudioOutputUnitStart(inst->audioUnit))) { - TSK_DEBUG_ERROR("AudioOutputUnitStart failed with status=%ld", (signed long)status); + if (inst->ready.consumer && inst->ready.producer) { + status = (OSStatus)tdav_apple_enable_audio(); + if (status == noErr) { + if ((!inst->started || inst->interrupted) && (status = AudioOutputUnitStart(inst->audioUnit))) { + TSK_DEBUG_ERROR("AudioOutputUnitStart failed with status=%ld", (signed long)status); + } + } + else { + TSK_DEBUG_ERROR("tdav_apple_enable_audio() failed with status=%ld", (signed long)status); + } + inst->started = (status == noErr) ? tsk_true : tsk_false; + if (inst->started) { + inst->interrupted = 0; } } else { - TSK_DEBUG_ERROR("tdav_apple_enable_audio() failed with status=%ld", (signed long)status); - } - inst->started = (status == noErr) ? tsk_true : tsk_false; - if (inst->started) { - inst->interrupted = 0; + TSK_DEBUG_INFO("AudioUnit producer(%d) or consumer(%d) not ready yet ...delaying start", (int)inst->ready.producer, (int)inst->ready.consumer); } tsk_safeobj_unlock(inst); return status ? -2 : 0; @@ -223,7 +228,7 @@ int tdav_audiounit_handle_start(tdav_audiounit_handle_t* self) uint32_t tdav_audiounit_handle_get_frame_duration(tdav_audiounit_handle_t* self) { - if(self) { + if (self) { return ((tdav_audiounit_instance_t*)self)->frame_duration; } return 0; @@ -349,28 +354,30 @@ int tdav_audiounit_handle_stop(tdav_audiounit_handle_t* self) { tdav_audiounit_instance_t* inst = (tdav_audiounit_instance_t*)self; OSStatus status = noErr; - if(!inst || (inst->started && !inst->audioUnit)) { + if (!inst || (inst->started && !inst->audioUnit)) { TSK_DEBUG_ERROR("Invalid parameter"); return -1; } tsk_safeobj_lock(inst); - if(inst->started && (status = AudioOutputUnitStop(inst->audioUnit))) { + if (inst->started && (status = AudioOutputUnitStop(inst->audioUnit))) { TSK_DEBUG_ERROR("AudioOutputUnitStop failed with status=%ld", (signed long)status); } inst->started = (status == noErr ? tsk_false : tsk_true); + inst->ready.consumer = tsk_false; + inst->ready.producer = tsk_false; tsk_safeobj_unlock(inst); return (status != noErr) ? -2 : 0; } int tdav_audiounit_handle_destroy(tdav_audiounit_handle_t** self) { - if(!self || !*self) { + if (!self || !*self) { TSK_DEBUG_ERROR("Invalid parameter"); return -1; } tsk_list_lock(__audioUnitInstances); - if(tsk_object_get_refcount(*self)==1) { + if (tsk_object_get_refcount(*self)==1) { tsk_list_remove_item_by_data(__audioUnitInstances, *self); } else { diff --git a/tinyDAV/src/audio/coreaudio/tdav_consumer_audiounit.c b/tinyDAV/src/audio/coreaudio/tdav_consumer_audiounit.c index 6cbe2b51..86d5c580 100755 --- a/tinyDAV/src/audio/coreaudio/tdav_consumer_audiounit.c +++ b/tinyDAV/src/audio/coreaudio/tdav_consumer_audiounit.c @@ -39,6 +39,8 @@ static tsk_size_t tdav_consumer_audiounit_get(tdav_consumer_audiounit_t* self, void* data, tsk_size_t size); static int tdav_consumer_audiounit_pause(tmedia_consumer_t* self); static int tdav_consumer_audiounit_resume(tmedia_consumer_t* self); +static int tdav_consumer_audiounit_init(tmedia_consumer_t* self); +static int tdav_consumer_audiounit_deinit(tmedia_consumer_t* self); static OSStatus __handle_output_buffer(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, @@ -122,167 +124,23 @@ int tdav_consumer_audiounit_set(tmedia_consumer_t* self, const tmedia_param_t* p static int tdav_consumer_audiounit_prepare(tmedia_consumer_t* self, const tmedia_codec_t* codec) { - static UInt32 flagOne = 1; - AudioStreamBasicDescription audioFormat; -#define kOutputBus 0 - tdav_consumer_audiounit_t* consumer = (tdav_consumer_audiounit_t*)self; - OSStatus status = noErr; - - if(!consumer || !codec || !codec->plugin) { + + if (!consumer || !codec || !codec->plugin) { TSK_DEBUG_ERROR("Invalid parameter"); return -1; } - if(!consumer->audioUnitHandle) { - if(!(consumer->audioUnitHandle = tdav_audiounit_handle_create(TMEDIA_CONSUMER(consumer)->session_id))) { - TSK_DEBUG_ERROR("Failed to get audio unit instance for session with id=%lld", TMEDIA_CONSUMER(consumer)->session_id); - return -3; - } - } - - // enable - status = AudioUnitSetProperty(tdav_audiounit_handle_get_instance(consumer->audioUnitHandle), - kAudioOutputUnitProperty_EnableIO, - kAudioUnitScope_Output, - kOutputBus, - &flagOne, - sizeof(flagOne)); - if(status) { - TSK_DEBUG_ERROR("AudioUnitSetProperty(kAudioOutputUnitProperty_EnableIO) failed with status=%d", (int32_t)status); - return -4; - } - else { - -#if !TARGET_OS_IPHONE // strange: TARGET_OS_MAC is equal to '1' on Smulator - UInt32 param; - - // disable input - param = 0; - status = AudioUnitSetProperty(tdav_audiounit_handle_get_instance(consumer->audioUnitHandle), kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, ¶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 outputDeviceID; - status = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, ¶m, &outputDeviceID); - if(status != noErr) { - TSK_DEBUG_ERROR("AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice) 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(consumer->audioUnitHandle), - kAudioOutputUnitProperty_CurrentDevice, - kAudioUnitScope_Global, - 0, - &outputDeviceID, - sizeof(AudioDeviceID)); - if(status != noErr) { - TSK_DEBUG_ERROR("AudioUnitSetProperty(kAudioOutputUnitProperty_CurrentDevice) failed with status=%ld", (signed long)status); - return -4; - } - -#endif - - TMEDIA_CONSUMER(consumer)->audio.ptime = TMEDIA_CODEC_PTIME_AUDIO_DECODING(codec); - TMEDIA_CONSUMER(consumer)->audio.in.channels = TMEDIA_CODEC_CHANNELS_AUDIO_DECODING(codec); - TMEDIA_CONSUMER(consumer)->audio.in.rate = TMEDIA_CODEC_RATE_DECODING(codec); - - TSK_DEBUG_INFO("AudioUnit consumer: in.channels=%d, out.channles=%d, in.rate=%d, out.rate=%d, ptime=%d", - TMEDIA_CONSUMER(consumer)->audio.in.channels, - TMEDIA_CONSUMER(consumer)->audio.out.channels, - TMEDIA_CONSUMER(consumer)->audio.in.rate, - TMEDIA_CONSUMER(consumer)->audio.out.rate, - TMEDIA_CONSUMER(consumer)->audio.ptime); - - audioFormat.mSampleRate = TMEDIA_CONSUMER(consumer)->audio.out.rate ? TMEDIA_CONSUMER(consumer)->audio.out.rate : TMEDIA_CONSUMER(consumer)->audio.in.rate; - audioFormat.mFormatID = kAudioFormatLinearPCM; - audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; - audioFormat.mChannelsPerFrame = TMEDIA_CONSUMER(consumer)->audio.in.channels; - audioFormat.mFramesPerPacket = 1; - audioFormat.mBitsPerChannel = TMEDIA_CONSUMER(consumer)->audio.bits_per_sample; - audioFormat.mBytesPerPacket = audioFormat.mBitsPerChannel / 8 * audioFormat.mChannelsPerFrame; - audioFormat.mBytesPerFrame = audioFormat.mBytesPerPacket; - audioFormat.mReserved = 0; - status = AudioUnitSetProperty(tdav_audiounit_handle_get_instance(consumer->audioUnitHandle), - kAudioUnitProperty_StreamFormat, - kAudioUnitScope_Input, - kOutputBus, - &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(consumer->audioUnitHandle, tsk_true, TMEDIA_CONSUMER(consumer)->audio.ptime, &audioFormat)) { - TSK_DEBUG_ERROR("tdav_audiounit_handle_set_rate(%d) failed", TMEDIA_CONSUMER(consumer)->audio.out.rate); - return -4; - } - - // set callback function - AURenderCallbackStruct callback; - callback.inputProc = __handle_output_buffer; - callback.inputProcRefCon = consumer; - status = AudioUnitSetProperty(tdav_audiounit_handle_get_instance(consumer->audioUnitHandle), - kAudioUnitProperty_SetRenderCallback, - kAudioUnitScope_Input, - kOutputBus, - &callback, - sizeof(callback)); - if(status) { - TSK_DEBUG_ERROR("AudioUnitSetProperty(kAudioOutputUnitProperty_SetInputCallback) failed with status=%ld", (signed long)status); - return -6; - } - } - } - - // allocate the chunck buffer and create the ring - consumer->ring.chunck.size = (TMEDIA_CONSUMER(consumer)->audio.ptime * audioFormat.mSampleRate * audioFormat.mBytesPerFrame) / 1000; - consumer->ring.size = kRingPacketCount * consumer->ring.chunck.size; - if(!(consumer->ring.chunck.buffer = tsk_realloc(consumer->ring.chunck.buffer, consumer->ring.chunck.size))) { - TSK_DEBUG_ERROR("Failed to allocate new buffer"); - return -7; - } - if(!consumer->ring.buffer) { - consumer->ring.buffer = speex_buffer_init((int)consumer->ring.size); - } - else { - int ret; - if((ret = (int)speex_buffer_resize(consumer->ring.buffer, (int)consumer->ring.size)) < 0) { - TSK_DEBUG_ERROR("speex_buffer_resize(%d) failed with error code=%d", (int)consumer->ring.size, ret); - return ret; - } - } - if(!consumer->ring.buffer) { - TSK_DEBUG_ERROR("Failed to create a new ring buffer with size = %d", (int)consumer->ring.size); - return -8; - } - if(!consumer->ring.mutex && !(consumer->ring.mutex = tsk_mutex_create_2(tsk_false))) { - TSK_DEBUG_ERROR("Failed to create mutex"); - return -9; - } - - // set maximum frames per slice as buffer size - //UInt32 numFrames = (UInt32)consumer->ring.chunck.size; - //status = AudioUnitSetProperty(tdav_audiounit_handle_get_instance(consumer->audioUnitHandle), - // kAudioUnitProperty_MaximumFramesPerSlice, - // kAudioUnitScope_Global, - // 0, - // &numFrames, - // sizeof(numFrames)); - //if(status){ - // TSK_DEBUG_ERROR("AudioUnitSetProperty(kAudioUnitProperty_MaximumFramesPerSlice, %u) failed with status=%d", (unsigned)numFrames, (int32_t)status); - // return -6; - //} - - TSK_DEBUG_INFO("AudioUnit consumer prepared"); - return tdav_audiounit_handle_signal_consumer_prepared(consumer->audioUnitHandle); + + // Initialize the decoder parameters without allocating AudioUnit resourses + TMEDIA_CONSUMER(consumer)->audio.ptime = TMEDIA_CODEC_PTIME_AUDIO_DECODING(codec); + TMEDIA_CONSUMER(consumer)->audio.in.channels = TMEDIA_CODEC_CHANNELS_AUDIO_DECODING(codec); + TMEDIA_CONSUMER(consumer)->audio.in.rate = TMEDIA_CODEC_RATE_DECODING(codec); + + TSK_DEBUG_INFO("AudioUnit consumer prepared (ptime=%d, channels=%d, rate=%d)", + (int)TMEDIA_CONSUMER(consumer)->audio.ptime, + (int)TMEDIA_CONSUMER(consumer)->audio.in.channels, + (int)TMEDIA_CONSUMER(consumer)->audio.in.rate); + return 0; } static int tdav_consumer_audiounit_start(tmedia_consumer_t* self) @@ -293,16 +151,28 @@ static int tdav_consumer_audiounit_start(tmedia_consumer_t* self) TSK_DEBUG_ERROR("Invalid parameter"); return -1; } - if(consumer->paused) { + if (consumer->paused) { consumer->paused = tsk_false; } - if(consumer->started) { + if (consumer->started) { TSK_DEBUG_WARN("Already started"); return 0; } else { - int ret = tdav_audiounit_handle_start(consumer->audioUnitHandle); - if(ret) { + int ret; + // Initialize the consumer if not already done + if (!consumer->ready) { + ret = tdav_consumer_audiounit_init(self); + if (ret) { + tdav_consumer_audiounit_deinit(self); + TSK_DEBUG_ERROR("tdav_consumer_audiounit_init failed with error code=%d", ret); + return ret; + } + } + // Start the handle (will wait until producer is ready) + ret = tdav_audiounit_handle_start(consumer->audioUnitHandle); + if (ret) { + tdav_consumer_audiounit_deinit(self); TSK_DEBUG_ERROR("tdav_audiounit_handle_start failed with error code=%d", ret); return ret; } @@ -344,14 +214,8 @@ static int tdav_consumer_audiounit_pause(tmedia_consumer_t* self) return -1; } if (!consumer->paused) { + tdav_consumer_audiounit_deinit(self); consumer->paused = tsk_true; - if (consumer->started) { - int ret = tdav_audiounit_handle_stop(consumer->audioUnitHandle); - if(ret) { - TSK_DEBUG_ERROR("tdav_audiounit_handle_stop failed with error code=%d", ret); - } - consumer->started = false; - } } TSK_DEBUG_INFO("AudioUnit consumer paused"); @@ -366,13 +230,13 @@ static int tdav_consumer_audiounit_resume(tmedia_consumer_t* self) return -1; } if (consumer->paused) { - consumer->paused = tsk_false; + consumer->paused = tsk_false; // *must* be before start() if (!consumer->started) { - int ret = tdav_audiounit_handle_start(consumer->audioUnitHandle); - if(ret) { - TSK_DEBUG_ERROR("tdav_audiounit_handle_start failed with error code=%d", ret); + int ret = tdav_consumer_audiounit_start(self); + if (ret) { + TSK_DEBUG_ERROR("Failed to stop the consumer"); + return ret; } - consumer->started = true; } } @@ -382,34 +246,218 @@ static int tdav_consumer_audiounit_resume(tmedia_consumer_t* self) static int tdav_consumer_audiounit_stop(tmedia_consumer_t* self) { - tdav_consumer_audiounit_t* consumer = (tdav_consumer_audiounit_t*)self; + int ret = tdav_consumer_audiounit_deinit(self); + if (ret) { + TSK_DEBUG_ERROR("Failed to stop the consumer"); + return ret; + } + TSK_DEBUG_INFO("AudioUnit consumer stoppped"); + return 0; +} +static int tdav_consumer_audiounit_init(tmedia_consumer_t* self) +{ + static UInt32 flagOne = 1; + AudioStreamBasicDescription audioFormat; +#define kOutputBus 0 + + tdav_consumer_audiounit_t* consumer = (tdav_consumer_audiounit_t*)self; + OSStatus status = noErr; + + if (!consumer) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + if (consumer->ready) { + TSK_DEBUG_INFO("AudioUnit consumer already initialized"); + return 0; + } + + // create handle if not already done + if (!consumer->audioUnitHandle) { + if(!(consumer->audioUnitHandle = tdav_audiounit_handle_create(TMEDIA_CONSUMER(consumer)->session_id))) { + TSK_DEBUG_ERROR("Failed to get audio unit instance for session with id=%lld", TMEDIA_CONSUMER(consumer)->session_id); + return -2; + } + } + + // enable + status = AudioUnitSetProperty(tdav_audiounit_handle_get_instance(consumer->audioUnitHandle), + kAudioOutputUnitProperty_EnableIO, + kAudioUnitScope_Output, + kOutputBus, + &flagOne, + sizeof(flagOne)); + if(status) { + TSK_DEBUG_ERROR("AudioUnitSetProperty(kAudioOutputUnitProperty_EnableIO) failed with status=%d", (int32_t)status); + return -4; + } + else { + +#if !TARGET_OS_IPHONE // strange: TARGET_OS_MAC is equal to '1' on Smulator + UInt32 param; + + // disable input + param = 0; + status = AudioUnitSetProperty(tdav_audiounit_handle_get_instance(consumer->audioUnitHandle), kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, ¶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 outputDeviceID; + status = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, ¶m, &outputDeviceID); + if(status != noErr) { + TSK_DEBUG_ERROR("AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice) 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(consumer->audioUnitHandle), + kAudioOutputUnitProperty_CurrentDevice, + kAudioUnitScope_Global, + 0, + &outputDeviceID, + sizeof(AudioDeviceID)); + if(status != noErr) { + TSK_DEBUG_ERROR("AudioUnitSetProperty(kAudioOutputUnitProperty_CurrentDevice) failed with status=%ld", (signed long)status); + return -4; + } + +#endif + + TSK_DEBUG_INFO("AudioUnit consumer: in.channels=%d, out.channles=%d, in.rate=%d, out.rate=%d, ptime=%d", + TMEDIA_CONSUMER(consumer)->audio.in.channels, + TMEDIA_CONSUMER(consumer)->audio.out.channels, + TMEDIA_CONSUMER(consumer)->audio.in.rate, + TMEDIA_CONSUMER(consumer)->audio.out.rate, + TMEDIA_CONSUMER(consumer)->audio.ptime); + + audioFormat.mSampleRate = TMEDIA_CONSUMER(consumer)->audio.out.rate ? TMEDIA_CONSUMER(consumer)->audio.out.rate : TMEDIA_CONSUMER(consumer)->audio.in.rate; + audioFormat.mFormatID = kAudioFormatLinearPCM; + audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; + audioFormat.mChannelsPerFrame = TMEDIA_CONSUMER(consumer)->audio.in.channels; + audioFormat.mFramesPerPacket = 1; + audioFormat.mBitsPerChannel = TMEDIA_CONSUMER(consumer)->audio.bits_per_sample; + audioFormat.mBytesPerPacket = audioFormat.mBitsPerChannel / 8 * audioFormat.mChannelsPerFrame; + audioFormat.mBytesPerFrame = audioFormat.mBytesPerPacket; + audioFormat.mReserved = 0; + status = AudioUnitSetProperty(tdav_audiounit_handle_get_instance(consumer->audioUnitHandle), + kAudioUnitProperty_StreamFormat, + kAudioUnitScope_Input, + kOutputBus, + &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(consumer->audioUnitHandle, tsk_true, TMEDIA_CONSUMER(consumer)->audio.ptime, &audioFormat)) { + TSK_DEBUG_ERROR("tdav_audiounit_handle_set_rate(%d) failed", TMEDIA_CONSUMER(consumer)->audio.out.rate); + return -4; + } + + // set callback function + AURenderCallbackStruct callback; + callback.inputProc = __handle_output_buffer; + callback.inputProcRefCon = consumer; + status = AudioUnitSetProperty(tdav_audiounit_handle_get_instance(consumer->audioUnitHandle), + kAudioUnitProperty_SetRenderCallback, + kAudioUnitScope_Input, + kOutputBus, + &callback, + sizeof(callback)); + if(status) { + TSK_DEBUG_ERROR("AudioUnitSetProperty(kAudioOutputUnitProperty_SetInputCallback) failed with status=%ld", (signed long)status); + return -6; + } + } + } + + // allocate the chunck buffer and create the ring + consumer->ring.chunck.size = (TMEDIA_CONSUMER(consumer)->audio.ptime * audioFormat.mSampleRate * audioFormat.mBytesPerFrame) / 1000; + consumer->ring.size = kRingPacketCount * consumer->ring.chunck.size; + if(!(consumer->ring.chunck.buffer = tsk_realloc(consumer->ring.chunck.buffer, consumer->ring.chunck.size))) { + TSK_DEBUG_ERROR("Failed to allocate new buffer"); + return -7; + } + if(!consumer->ring.buffer) { + consumer->ring.buffer = speex_buffer_init((int)consumer->ring.size); + } + else { + int ret; + if((ret = (int)speex_buffer_resize(consumer->ring.buffer, (int)consumer->ring.size)) < 0) { + TSK_DEBUG_ERROR("speex_buffer_resize(%d) failed with error code=%d", (int)consumer->ring.size, ret); + return ret; + } + } + if(!consumer->ring.buffer) { + TSK_DEBUG_ERROR("Failed to create a new ring buffer with size = %d", (int)consumer->ring.size); + return -8; + } + if(!consumer->ring.mutex && !(consumer->ring.mutex = tsk_mutex_create_2(tsk_false))) { + TSK_DEBUG_ERROR("Failed to create mutex"); + return -9; + } + + // set maximum frames per slice as buffer size + //UInt32 numFrames = (UInt32)consumer->ring.chunck.size; + //status = AudioUnitSetProperty(tdav_audiounit_handle_get_instance(consumer->audioUnitHandle), + // kAudioUnitProperty_MaximumFramesPerSlice, + // kAudioUnitScope_Global, + // 0, + // &numFrames, + // sizeof(numFrames)); + //if(status){ + // TSK_DEBUG_ERROR("AudioUnitSetProperty(kAudioUnitProperty_MaximumFramesPerSlice, %u) failed with status=%d", (unsigned)numFrames, (int32_t)status); + // return -6; + //} + + if (tdav_audiounit_handle_signal_consumer_ready(consumer->audioUnitHandle)) { + TSK_DEBUG_ERROR("tdav_audiounit_handle_signal_consumer_ready failed"); + return -10; + } + + consumer->ready = tsk_true; + + TSK_DEBUG_INFO("AudioUnit consumer initialized and ready"); + return 0; +} + +int tdav_consumer_audiounit_deinit(tmedia_consumer_t* self) +{ + tdav_consumer_audiounit_t* consumer = (tdav_consumer_audiounit_t*)self; if(!consumer) { TSK_DEBUG_ERROR("Invalid parameter"); return -1; } - if(!consumer->started) { - TSK_DEBUG_INFO("Not started"); - return 0; - } - else { + // Stop + if (consumer->started) { int ret = tdav_audiounit_handle_stop(consumer->audioUnitHandle); - if(ret) { + if (ret) { TSK_DEBUG_ERROR("tdav_audiounit_handle_stop failed with error code=%d", ret); - return ret; } + consumer->started = tsk_false; } + // Destroy handle (will be re-created by the next start) #if TARGET_OS_IPHONE //https://devforums.apple.com/thread/118595 - if(consumer->audioUnitHandle) { + if (consumer->audioUnitHandle) { tdav_audiounit_handle_destroy(&consumer->audioUnitHandle); } #endif - - consumer->started = tsk_false; - TSK_DEBUG_INFO("AudioUnit consumer stoppped"); + consumer->ready = tsk_false; + consumer->paused = tsk_false; + + TSK_DEBUG_INFO("AudioUnit consumer deinitialized"); + return 0; - } // @@ -432,14 +480,7 @@ static tsk_object_t* tdav_consumer_audiounit_dtor(tsk_object_t * self) tdav_consumer_audiounit_t *consumer = self; if(consumer) { /* deinit self */ - // Stop the consumer if not done - if(consumer->started) { - tdav_consumer_audiounit_stop(self); - } - // destroy handle - if(consumer->audioUnitHandle) { - tdav_audiounit_handle_destroy(&consumer->audioUnitHandle); - } + tdav_consumer_audiounit_deinit(TMEDIA_CONSUMER(self)); TSK_FREE(consumer->ring.chunck.buffer); if(consumer->ring.buffer) { speex_buffer_destroy(consumer->ring.buffer); diff --git a/tinyDAV/src/audio/coreaudio/tdav_producer_audiounit.c b/tinyDAV/src/audio/coreaudio/tdav_producer_audiounit.c index b2b60f74..3f037c8e 100755 --- a/tinyDAV/src/audio/coreaudio/tdav_producer_audiounit.c +++ b/tinyDAV/src/audio/coreaudio/tdav_producer_audiounit.c @@ -37,6 +37,8 @@ static int tdav_producer_audiounit_pause(tmedia_producer_t* self); static int tdav_producer_audiounit_resume(tmedia_producer_t* self); +static int tdav_producer_audiounit_init(tmedia_producer_t* self); +static int tdav_producer_audiounit_deinit(tmedia_producer_t* self); static OSStatus __handle_input_buffer(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, @@ -104,28 +106,146 @@ int tdav_producer_audiounit_set(tmedia_producer_t* self, const tmedia_param_t* p } static int tdav_producer_audiounit_prepare(tmedia_producer_t* self, const tmedia_codec_t* codec) +{ + tdav_producer_audiounit_t* producer = (tdav_producer_audiounit_t*)self; + if (!producer || !codec || !codec->plugin) { + TSK_DEBUG_ERROR("Invalid parameter"); + return -1; + } + + 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 prepared(channels=%d, rate=%d, ptime=%d)", + (int)TMEDIA_PRODUCER(producer)->audio.channels, + (int)TMEDIA_PRODUCER(producer)->audio.rate, + (int)TMEDIA_PRODUCER(producer)->audio.ptime); + return 0; +} + +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 { + // Initialize the consumer if not already done + if (!producer->ready) { + ret = tdav_producer_audiounit_init(self); + if (ret) { + tdav_producer_audiounit_deinit(self); + TSK_DEBUG_ERROR("tdav_producer_audiounit_init failed with error code=%d", ret); + return ret; + } + } + // Start handle + 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; +} + +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; + } + if (!producer->paused) { + tdav_producer_audiounit_deinit(self); + producer->paused = tsk_true; + } + + TSK_DEBUG_INFO("AudioUnit producer paused"); + return 0; +} + +static int tdav_producer_audiounit_resume(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; // *must* be before start() + if (!producer->started) { + int ret = tdav_producer_audiounit_start(self); + if (ret) { + TSK_DEBUG_ERROR("Failed to stop the consumer"); + return ret; + } + } + } + + TSK_DEBUG_INFO("AudioUnit producer resumed"); + return 0; +} + +static int tdav_producer_audiounit_stop(tmedia_producer_t* self) +{ + int ret = tdav_producer_audiounit_deinit(self); + if (ret) { + TSK_DEBUG_ERROR("Failed to stop the consumer"); + return ret; + } + TSK_DEBUG_INFO("AudioUnit producer stoppped"); + return 0; +} + +static int tdav_producer_audiounit_init(tmedia_producer_t* self) { 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) { + + if (!producer) { TSK_DEBUG_ERROR("Invalid parameter"); return -1; } - if(!producer->audioUnitHandle) { + + if (producer->ready) { + TSK_DEBUG_INFO("AudioUnit consumer already initialized"); + return 0; + } + + 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, @@ -133,7 +253,7 @@ static int tdav_producer_audiounit_prepare(tmedia_producer_t* self, const tmedia kInputBus, &flagOne, sizeof(flagOne)); - if(status != noErr) { + if (status != noErr) { TSK_DEBUG_ERROR("AudioUnitSetProperty(kAudioOutputUnitProperty_EnableIO) failed with status=%ld", (signed long)status); return -4; } @@ -151,7 +271,7 @@ static int tdav_producer_audiounit_prepare(tmedia_producer_t* self, const tmedia TSK_DEBUG_ERROR("AudioUnitSetProperty(kAudioOutputUnitProperty_EnableIO) failed with status=%ld", (signed long)status); return -4; } - + // set default audio device param = sizeof(AudioDeviceID); AudioDeviceID inputDeviceID; @@ -160,7 +280,7 @@ static int tdav_producer_audiounit_prepare(tmedia_producer_t* self, const tmedia 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, @@ -173,17 +293,12 @@ static int tdav_producer_audiounit_prepare(tmedia_producer_t* self, const tmedia 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); - + 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), @@ -199,7 +314,7 @@ static int tdav_producer_audiounit_prepare(tmedia_producer_t* self, const tmedia TMEDIA_PRODUCER(producer)->audio.rate = deviceFormat.mSampleRate; #endif } - + // set format audioFormat.mSampleRate = TMEDIA_PRODUCER(producer)->audio.rate; audioFormat.mFormatID = kAudioFormatLinearPCM; @@ -224,13 +339,13 @@ static int tdav_producer_audiounit_prepare(tmedia_producer_t* self, const tmedia return -5; } else { - + // configure - if(tdav_audiounit_handle_configure(producer->audioUnitHandle, tsk_false, TMEDIA_PRODUCER(producer)->audio.ptime, &audioFormat)) { + 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; @@ -253,7 +368,7 @@ static int tdav_producer_audiounit_prepare(tmedia_producer_t* self, const tmedia // 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))) { @@ -267,7 +382,7 @@ static int tdav_producer_audiounit_prepare(tmedia_producer_t* self, const tmedia } else { int ret; - if((ret = speex_buffer_resize(producer->ring.buffer, producer->ring.size)) < 0) { + if((ret = speex_buffer_resize(producer->ring.buffer, (int)producer->ring.size)) < 0) { TSK_DEBUG_ERROR("speex_buffer_resize(%d) failed with error code=%d", (int)producer->ring.size, ret); return ret; } @@ -277,119 +392,48 @@ static int tdav_producer_audiounit_prepare(tmedia_producer_t* self, const tmedia 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 (tdav_audiounit_handle_signal_producer_ready(producer->audioUnitHandle)) { + TSK_DEBUG_ERROR("tdav_audiounit_handle_signal_producer_ready failed"); + return -10; } - 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"); + + producer->ready = tsk_true; + + TSK_DEBUG_INFO("AudioUnit producer initialized"); return 0; } -static int tdav_producer_audiounit_pause(tmedia_producer_t* self) +static int tdav_producer_audiounit_deinit(tmedia_producer_t* self) { tdav_producer_audiounit_t* producer = (tdav_producer_audiounit_t*)self; - if(!producer) { + if (!producer) { TSK_DEBUG_ERROR("Invalid parameter"); return -1; } - if (!producer->paused) { - producer->paused = tsk_true; - if (producer->started) { - 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! - } - producer->started = false; - } - } - TSK_DEBUG_INFO("AudioUnit producer paused"); - return 0; -} - -static int tdav_producer_audiounit_resume(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) { - if (!producer->started) { - int ret = tdav_audiounit_handle_start(producer->audioUnitHandle); - if(ret) { - TSK_DEBUG_ERROR("tdav_audiounit_handle_start failed with error code=%d", ret); - // do not return even if failed => we MUST stop the thread! - } - } - producer->paused = false; - producer->started = true; - } - TSK_DEBUG_INFO("AudioUnit producer resumed"); - 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 { + // Stop + if (producer->started) { int ret = tdav_audiounit_handle_stop(producer->audioUnitHandle); - if(ret) { + 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); - } -#endif + producer->started = tsk_false; } - producer->started = tsk_false; - TSK_DEBUG_INFO("AudioUnit producer stoppped"); + // Destroy handle (will be re-created by the next start) +#if TARGET_OS_IPHONE + //https://devforums.apple.com/thread/118595 + if (producer->audioUnitHandle) { + tdav_audiounit_handle_destroy(&producer->audioUnitHandle); + } +#endif + producer->ready = tsk_false; + producer->paused = tsk_false; + + TSK_DEBUG_INFO("AudioUnit producer deinitialized"); + return 0; } @@ -413,15 +457,7 @@ 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 - if (producer->audioUnitHandle) { - tdav_audiounit_handle_destroy(&producer->audioUnitHandle); - } + tdav_producer_audiounit_deinit(TMEDIA_PRODUCER(self)); TSK_FREE(producer->ring.chunck.buffer); if(producer->ring.buffer) { speex_buffer_destroy(producer->ring.buffer);