From cb2cb331e0ed61b64f85547feb27730185beeeac Mon Sep 17 00:00:00 2001 From: Seungbae Shin Date: Wed, 11 Nov 2020 19:24:06 +0900 Subject: [PATCH] Wait for accept when signaling stream ready connection to sync callback sequence + add/revise some logs for debugging convenience [Version] 0.5.35 [Issue Type] Bug Change-Id: Icb7320014b569ef4dbd6656482974e17da53400e --- packaging/capi-media-audio-io.spec | 2 +- src/cpp/CAudioOutput.cpp | 3 +++ src/cpp/CPulseAudioClient.cpp | 46 ++++++++++++++++++++++++++++---------- 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/packaging/capi-media-audio-io.spec b/packaging/capi-media-audio-io.spec index 0b6de5d..bca194b 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.5.34 +Version: 0.5.35 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/cpp/CAudioOutput.cpp b/src/cpp/CAudioOutput.cpp index 4ae30f7..29c3729 100644 --- a/src/cpp/CAudioOutput.cpp +++ b/src/cpp/CAudioOutput.cpp @@ -149,9 +149,12 @@ void CAudioOutput::prepare() { mpPulseAudioClient = new CPulseAudioClient(CPulseAudioClient::EStreamDirection::STREAM_DIRECTION_PLAYBACK, spec, this); mpPulseAudioClient->initialize(); + AUDIO_IO_LOGD("pClient:[%p] initialized done", mpPulseAudioClient); #ifndef DISABLE_MOBILE_BACK_COMP /* Uncork stream which is created with CORKED flag */ + /* FIXME : following uncork may move into initialize() for mainloop lock */ mpPulseAudioClient->cork(false); + AUDIO_IO_LOGD("pClient:[%p] corked done", mpPulseAudioClient); #endif CAudioIO::prepare(); diff --git a/src/cpp/CPulseAudioClient.cpp b/src/cpp/CPulseAudioClient.cpp index 57750e4..e5b3f88 100644 --- a/src/cpp/CPulseAudioClient.cpp +++ b/src/cpp/CPulseAudioClient.cpp @@ -135,39 +135,55 @@ void CPulseAudioClient::__streamStateChangeCb(pa_stream* s, void* user_data) { assert(user_data); auto pClient = static_cast(user_data); + pa_stream_state_t state = pa_stream_get_state(s); + + switch (state) { + case PA_STREAM_UNCONNECTED: + break; + + case PA_STREAM_CREATING: + break; - switch (pa_stream_get_state(s)) { case PA_STREAM_READY: - AUDIO_IO_LOGD("The pa_stream[%p] is ready", s); + AUDIO_IO_LOGD("pClient[%p] pa_stream[%p] is READY[%d]", pClient, s, PA_STREAM_READY); pClient->__mpListener->setState(CAudioInfo::EAudioIOState::AUDIO_IO_STATE_RUNNING); pClient->__mpListener->onStateChanged(CAudioInfo::EAudioIOState::AUDIO_IO_STATE_RUNNING); if (pClient->__mDirection == EStreamDirection::STREAM_DIRECTION_PLAYBACK) pClient->__mIsFirstStream = true; pClient->__mIsInit = true; - pa_threaded_mainloop_signal(pClient->__mpMainloop, 0); + + AUDIO_IO_LOGD("pClient[%p] pa_stream[%p] now signaling...", pClient, s); + pa_threaded_mainloop_signal(pClient->__mpMainloop, 1); + AUDIO_IO_LOGD("pClient[%p] pa_stream[%p] signal accepted", pClient, s); break; //LCOV_EXCL_START case PA_STREAM_FAILED: - AUDIO_IO_LOGD("The pa_stream[%p] is failed", s); + AUDIO_IO_LOGD("pClient[%p] pa_stream[%p] is FAILED[%d]", pClient, s, PA_STREAM_FAILED); pClient->__mpListener->setState(CAudioInfo::EAudioIOState::AUDIO_IO_STATE_IDLE); pClient->__mpListener->onStateChanged(CAudioInfo::EAudioIOState::AUDIO_IO_STATE_IDLE, __is_microphone_restricted()); + + AUDIO_IO_LOGD("pClient[%p] pa_stream[%p] now signaling...", pClient, s); pa_threaded_mainloop_signal(pClient->__mpMainloop, 0); break; //LCOV_EXCL_STOP case PA_STREAM_TERMINATED: - AUDIO_IO_LOGD("The pa_stream[%p] is terminated", s); + AUDIO_IO_LOGD("pClient[%p] pa_stream[%p] is TERMINATED[%d]", pClient, s, PA_STREAM_TERMINATED); pClient->__mpListener->setState(CAudioInfo::EAudioIOState::AUDIO_IO_STATE_IDLE); pClient->__mpListener->onStateChanged(CAudioInfo::EAudioIOState::AUDIO_IO_STATE_IDLE); + + AUDIO_IO_LOGD("pClient[%p] pa_stream[%p] now signaling...", pClient, s); pa_threaded_mainloop_signal(pClient->__mpMainloop, 0); break; - case PA_STREAM_UNCONNECTED: - case PA_STREAM_CREATING: + default: + AUDIO_IO_LOGW("Unexpected state[%d]", state); break; } + + AUDIO_IO_LOGD("pClient[%p] pa_stream[%p] state[%d] done", pClient, s, state); } void CPulseAudioClient::__streamCaptureCb(pa_stream* s, size_t length, void* user_data) { @@ -283,7 +299,7 @@ void CPulseAudioClient::__successStreamCb(pa_stream* s, int success, void* user_ pClient->__mIsOperationSuccess = static_cast(success); - /* FIXME : verify following action without any waitings */ + /* FIXME : verify following action without any waiting */ pa_threaded_mainloop_signal(pClient->__mpMainloop, 0); } @@ -392,6 +408,8 @@ void CPulseAudioClient::initialize() { pa_threaded_mainloop_wait(__mpMainloop); } + AUDIO_IO_LOGD("pa_context[%p] now ready", __mpContext); + // Allocates PA stream pa_sample_spec ss = __mSpec.getSampleSpec(); pa_channel_map map = __mSpec.getChannelMap(); @@ -437,7 +455,6 @@ void CPulseAudioClient::initialize() { ret = pa_stream_connect_record(__mpStream, NULL, NULL, flags); } - if (ret != 0) { //LCOV_EXCL_START err = pa_context_errno(__mpContext); @@ -446,13 +463,14 @@ void CPulseAudioClient::initialize() { //LCOV_EXCL_STOP } + AUDIO_IO_LOGD("pa_stream[%p] now wait for stream ready...", __mpStream); + while (true) { pa_stream_state_t state = pa_stream_get_state(__mpStream); + AUDIO_IO_LOGD("pa_stream[%p] current state[%d]", __mpStream, state); - if (state == PA_STREAM_READY) { - AUDIO_IO_LOGD("STREAM READY"); + if (state == PA_STREAM_READY) break; - } if (!PA_STREAM_IS_GOOD(state)) { err = pa_context_errno(__mpContext); @@ -465,8 +483,11 @@ void CPulseAudioClient::initialize() { } /* Wait until the stream is ready */ + AUDIO_IO_LOGD("pa_mainloop[%p] signal wait...", __mpMainloop); pa_threaded_mainloop_wait(__mpMainloop); + AUDIO_IO_LOGD("pa_mainloop[%p] signal wait done", __mpMainloop); } + pa_threaded_mainloop_accept(__mpMainloop); // __mIsInit = true; // Moved to __streamStateChangeCb() } catch (const CAudioError& e) { @@ -748,6 +769,7 @@ void CPulseAudioClient::cork(bool cork) { /* FIXME: wait for completion like drain? */ pa_operation_unref(pa_stream_cork(__mpStream, static_cast(cork), __successStreamCb, this)); + AUDIO_IO_LOGD("cork[%d] done", cork); } bool CPulseAudioClient::isCorked() { -- 2.7.4