From e80f5c2cd31f1f5c238b6a82849bd31b64107e7b Mon Sep 17 00:00:00 2001 From: Seungbae Shin Date: Tue, 7 Nov 2017 19:00:37 +0900 Subject: [PATCH] Enable dummy write on streamCb only for async mode backward compatibility set started/underflow for playback debugging purpose [Version] 0.4.5 [Issue Type] Bug Fix Change-Id: I1c39d76895f93c6a6719d719c3382342f84be4d8 (cherry picked from commit 2f28d6f49ca602993014f849835865757e1f02b9) --- include/CPulseAudioClient.h | 2 ++ packaging/capi-media-audio-io.spec | 2 +- src/cpp/CAudioOutput.cpp | 9 ++------- src/cpp/CPulseAudioClient.cpp | 38 +++++++++++++++++++++++++++++--------- 4 files changed, 34 insertions(+), 17 deletions(-) diff --git a/include/CPulseAudioClient.h b/include/CPulseAudioClient.h index 277e99f..d68e02c 100644 --- a/include/CPulseAudioClient.h +++ b/include/CPulseAudioClient.h @@ -113,6 +113,8 @@ namespace tizen_media_audio { static void __streamCaptureCb(pa_stream* s, size_t length, void* user_data); static void __streamPlaybackCb(pa_stream* s, size_t length, void* user_data); static void __streamLatencyUpdateCb(pa_stream* s, void* user_data); + static void __streamStartedCb(pa_stream* s, void* user_data); + static void __streamUnderflowCb(pa_stream* s, void* user_data); static void __streamEventCb(pa_stream* s, const char *name, pa_proplist *pl, void *user_data); static void __successStreamCb(pa_stream* s, int success, void* user_data); static void __successDrainCb(pa_stream* s, int success, void* user_data); diff --git a/packaging/capi-media-audio-io.spec b/packaging/capi-media-audio-io.spec index 4d2976b..5fb9918 100644 --- a/packaging/capi-media-audio-io.spec +++ b/packaging/capi-media-audio-io.spec @@ -1,6 +1,6 @@ Name: capi-media-audio-io Summary: An Audio Input & Audio Output library in Tizen Native API -Version: 0.4.4 +Version: 0.4.5 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/cpp/CAudioOutput.cpp b/src/cpp/CAudioOutput.cpp index b4aeb8a..f96f78f 100644 --- a/src/cpp/CAudioOutput.cpp +++ b/src/cpp/CAudioOutput.cpp @@ -224,9 +224,7 @@ void CAudioOutput::unprepare() { try { if (mpAudioSessionHandler->getId() >= 0 && !mIsInterrupted) { if (isForceIgnore() == false && mpAudioSessionHandler->isSkipSession() == false) { - CPulseStreamSpec::EStreamLatency streamSpec; - streamSpec = mpPulseAudioClient->getStreamSpec().getStreamLatency(); - if (CPulseStreamSpec::EStreamLatency::STREAM_LATENCY_OUTPUT_DEFAULT_ASYNC != streamSpec) + if (mStreamCallback.onStream == NULL) CAudioIO::drain(); } } @@ -305,15 +303,12 @@ void CAudioOutput::resume() { } void CAudioOutput::drain() { - CPulseStreamSpec::EStreamLatency streamSpec; - if (__IsInit() == false || __IsReady() == false) { THROW_ERROR_MSG(CAudioError::EError::ERROR_NOT_INITIALIZED, "Did not initialize or prepare CAudioOutput"); } - streamSpec = mpPulseAudioClient->getStreamSpec().getStreamLatency(); - if (CPulseStreamSpec::EStreamLatency::STREAM_LATENCY_OUTPUT_DEFAULT_ASYNC == streamSpec) + if (mStreamCallback.onStream) THROW_ERROR_MSG(CAudioError::EError::ERROR_INVALID_OPERATION, "async type don't support drain"); try { diff --git a/src/cpp/CPulseAudioClient.cpp b/src/cpp/CPulseAudioClient.cpp index 50ce02e..bd123bb 100644 --- a/src/cpp/CPulseAudioClient.cpp +++ b/src/cpp/CPulseAudioClient.cpp @@ -195,18 +195,16 @@ void CPulseAudioClient::__streamPlaybackCb(pa_stream* s, size_t length, void* us pClient->__mpListener->onStream(pClient, length); +#ifndef DISABLE_MOBILE_BACK_COMP /* If stream is not written in first callback during prepare, then write dummy data to ensure the start */ - if (pClient->__mIsFirstStream) { - AUDIO_IO_LOGD("Write dummy, length [%d]", length); - - char* dummy = new char[length]; - memset(dummy, 0, length); - pa_stream_write(s, dummy, length, NULL, 0LL, PA_SEEK_RELATIVE); - delete [] dummy; - + if (pClient->__mSpec.getStreamLatency() == CPulseStreamSpec::EStreamLatency::STREAM_LATENCY_OUTPUT_DEFAULT_ASYNC && + pClient->__mIsFirstStream) { + AUDIO_IO_LOGW("[async] Write dummy of length[%d] since not written in first callback during prepare", length); + __dummy_write(s, length); pClient->__mIsFirstStream = false; } +#endif } void CPulseAudioClient::__streamLatencyUpdateCb(pa_stream* s, void* user_data) { @@ -218,6 +216,24 @@ void CPulseAudioClient::__streamLatencyUpdateCb(pa_stream* s, void* user_data) { pa_threaded_mainloop_signal(pClient->__mpMainloop, 0); } +void CPulseAudioClient::__streamStartedCb(pa_stream* s, void* user_data) { + assert(s); + assert(user_data); + + CPulseAudioClient* pClient = static_cast(user_data); + + AUDIO_IO_LOGD("stream %p started.", pClient); +} + +void CPulseAudioClient::__streamUnderflowCb(pa_stream* s, void* user_data) { + assert(s); + assert(user_data); + + CPulseAudioClient* pClient = static_cast(user_data); + + AUDIO_IO_LOGD("stream %p UnderFlow...", pClient); +} + void CPulseAudioClient::__streamEventCb(pa_stream* s, const char *name, pa_proplist *pl, void *user_data) { assert(s); assert(user_data); @@ -360,6 +376,10 @@ void CPulseAudioClient::initialize() { pa_stream_set_write_callback(__mpStream, __streamPlaybackCb, this); pa_stream_set_latency_update_callback(__mpStream, __streamLatencyUpdateCb, this); pa_stream_set_event_callback(__mpStream, __streamEventCb, this); + if (__mDirection == EStreamDirection::STREAM_DIRECTION_PLAYBACK) { + pa_stream_set_started_callback(__mpStream, __streamStartedCb, this); + pa_stream_set_underflow_callback(__mpStream, __streamUnderflowCb, this); + } // Connect stream with PA Server @@ -658,7 +678,7 @@ int CPulseAudioClient::write(const void* data, size_t length) { int ret = 0; #ifdef _AUDIO_IO_DEBUG_TIMING_ - AUDIO_IO_LOGD("data[%p], length[%d]", data, length); + AUDIO_IO_LOGD("data[%p], length[%d], First[%d]", data, length, __mIsFirstStream); #endif if (pa_stream_is_corked(__mpStream)) { AUDIO_IO_LOGW("stream is corked...do uncork here first!!!!"); -- 2.7.4