From d8026fb67200306c010c939a6ac27169a3cb626c Mon Sep 17 00:00:00 2001 From: Tuukka Pasanen Date: Mon, 3 Jun 2024 15:29:43 +0300 Subject: [PATCH] pulseaudio: Add function to handle Pulseaudio pa_operation Now pa_operation are handled multiple ways. Add function to make sure that they are handled always same. --- src/hostapi/pulseaudio/pa_linux_pulseaudio.c | 40 +++------ .../pulseaudio/pa_linux_pulseaudio_cb.c | 82 +++++++++---------- .../pulseaudio/pa_linux_pulseaudio_internal.h | 8 +- 3 files changed, 54 insertions(+), 76 deletions(-) diff --git a/src/hostapi/pulseaudio/pa_linux_pulseaudio.c b/src/hostapi/pulseaudio/pa_linux_pulseaudio.c index ec2fc74f5..32c22c494 100644 --- a/src/hostapi/pulseaudio/pa_linux_pulseaudio.c +++ b/src/hostapi/pulseaudio/pa_linux_pulseaudio.c @@ -51,14 +51,13 @@ */ -#include /* strlen() */ - #include "pa_linux_pulseaudio_cb_internal.h" #include "pa_linux_pulseaudio_block_internal.h" /* PulseAudio headers */ #include #include +#include #include /* This is used to identify process name for PulseAudio. */ @@ -650,12 +649,8 @@ PaError PaPulseAudio_Initialize( PaUtilHostApiRepresentation ** hostApi, PaPulseAudio_ServerInfoCb, pulseaudioHostApi ); - while( pa_operation_get_state( pulseaudioOperation ) == PA_OPERATION_RUNNING ) - { - pa_threaded_mainloop_wait( pulseaudioHostApi->mainloop ); - } - - pa_operation_unref( pulseaudioOperation ); + PaPulseAudio_ReleaseOperation( pulseaudioHostApi, + &pulseaudioOperation ); /* Add the "Default" sink at index 0 */ if( _PaPulseAudio_AddAudioDevice( pulseaudioHostApi, @@ -701,12 +696,8 @@ PaError PaPulseAudio_Initialize( PaUtilHostApiRepresentation ** hostApi, PaPulseAudio_SinkListCb, pulseaudioHostApi ); - while( pa_operation_get_state( pulseaudioOperation ) == PA_OPERATION_RUNNING ) - { - pa_threaded_mainloop_wait( pulseaudioHostApi->mainloop ); - } - - pa_operation_unref( pulseaudioOperation ); + PaPulseAudio_ReleaseOperation( pulseaudioHostApi, + &pulseaudioOperation ); /* List PulseAudio sources. If found callback: PaPulseAudio_SourceListCb */ pulseaudioOperation = @@ -714,12 +705,8 @@ PaError PaPulseAudio_Initialize( PaUtilHostApiRepresentation ** hostApi, PaPulseAudio_SourceListCb, pulseaudioHostApi ); - while( pa_operation_get_state( pulseaudioOperation ) == PA_OPERATION_RUNNING ) - { - pa_threaded_mainloop_wait( pulseaudioHostApi->mainloop ); - } - - pa_operation_unref( pulseaudioOperation ); + PaPulseAudio_ReleaseOperation( pulseaudioHostApi, + &pulseaudioOperation ); (*hostApi)->info.deviceCount = pulseaudioHostApi->deviceCount; @@ -1461,11 +1448,8 @@ PaError PaPulseAudio_RenameSource( PaStream *s, const char *streamName ) op = pa_stream_set_name( stream->inputStream, streamName, RenameStreamCb, stream ); PaPulseAudio_UnLock( stream->mainloop ); - /* Wait for completion. */ - while (pa_operation_get_state( op ) == PA_OPERATION_RUNNING) - { - pa_threaded_mainloop_wait( stream->mainloop ); - } + PaPulseAudio_ReleaseOperation( stream->hostapi, + &op ); return result; } @@ -1498,10 +1482,8 @@ PaError PaPulseAudio_RenameSink( PaStream *s, const char *streamName ) PaPulseAudio_UnLock( stream->mainloop ); /* Wait for completion. */ - while (pa_operation_get_state( op ) == PA_OPERATION_RUNNING) - { - pa_threaded_mainloop_wait( stream->mainloop ); - } + PaPulseAudio_ReleaseOperation( stream->hostapi, + &op ); return result; } diff --git a/src/hostapi/pulseaudio/pa_linux_pulseaudio_cb.c b/src/hostapi/pulseaudio/pa_linux_pulseaudio_cb.c index 3aa484a37..a715384e1 100644 --- a/src/hostapi/pulseaudio/pa_linux_pulseaudio_cb.c +++ b/src/hostapi/pulseaudio/pa_linux_pulseaudio_cb.c @@ -105,6 +105,35 @@ int PaPulseAudio_updateTimeInfo( pa_stream * s, return 0; } +/* Release pa_operation always same way */ +int PaPulseAudio_ReleaseOperation(PaPulseAudio_HostApiRepresentation *hostapi, + pa_operation **operation) +{ + unsigned int wait = 0; + pa_operation *localOperation = (*operation); + + while( pa_operation_get_state( localOperation ) == PA_OPERATION_RUNNING ) + { + pa_threaded_mainloop_wait( hostapi->mainloop ); + + wait ++; + usleep( 1000 ); + + if( wait > 2000 ) + { + printf("JEPOS\n"); + PA_DEBUG( ( "Portaudio %s: Operation still running %d!\n", + __FUNCTION__, pa_operation_get_state( localOperation ) ) ); + break; + } + } + + PaPulseAudio_Lock( hostapi->mainloop ); + pa_operation_unref( localOperation ); + operation = NULL; + PaPulseAudio_UnLock( hostapi->mainloop ); +} + /* locks the Pulse Main loop when not called from it */ void PaPulseAudio_Lock( pa_threaded_mainloop *mainloop ) @@ -488,22 +517,10 @@ PaError PaPulseAudio_CloseStreamCb( PaStream * s ) stream ); PaPulseAudio_UnLock( stream->mainloop ); - while( pa_operation_get_state( pulseaudioOperation ) == PA_OPERATION_RUNNING ) - { - pa_threaded_mainloop_wait( pulseaudioHostApi->mainloop ); - waitLoop ++; - - if(waitLoop > 256) - { - break; - } - } - - waitLoop = 0; + PaPulseAudio_ReleaseOperation( pulseaudioHostApi, + &pulseaudioOperation ); PaPulseAudio_Lock(stream->mainloop); - pa_operation_unref( pulseaudioOperation ); - pulseaudioOperation = NULL; pa_stream_disconnect( stream->outputStream ); PaPulseAudio_UnLock( stream->mainloop ); @@ -520,22 +537,10 @@ PaError PaPulseAudio_CloseStreamCb( PaStream * s ) stream ); PaPulseAudio_UnLock( stream->mainloop ); - while( pa_operation_get_state( pulseaudioOperation ) == PA_OPERATION_RUNNING ) - { - pa_threaded_mainloop_wait( pulseaudioHostApi->mainloop ); - waitLoop ++; - - if(waitLoop > 256) - { - break; - } - } - - waitLoop = 0; + PaPulseAudio_ReleaseOperation( pulseaudioHostApi, + &pulseaudioOperation ); PaPulseAudio_Lock( stream->mainloop ); - pa_operation_unref( pulseaudioOperation ); - pulseaudioOperation = NULL; /* Then we disconnect stream and wait for * Termination @@ -641,7 +646,6 @@ PaError PaPulseAudio_StartStreamCb( PaStream * s ) PaPulseAudio_HostApiRepresentation *pulseaudioHostApi = stream->hostapi; const char *pulseaudioName = NULL; pa_operation *pulseaudioOperation = NULL; - int waitLoop = 0; unsigned int pulseaudioReqFrameSize = stream->suggestedLatencyUSecs; stream->isActive = 0; @@ -769,13 +773,8 @@ PaError PaPulseAudio_StartStreamCb( PaStream * s ) stream ); PaPulseAudio_UnLock( pulseaudioHostApi->mainloop ); - while( pa_operation_get_state( pulseaudioOperation ) == PA_OPERATION_RUNNING) - { - pa_threaded_mainloop_wait( pulseaudioHostApi->mainloop ); - } - - pa_operation_unref( pulseaudioOperation ); - pulseaudioOperation = NULL; + PaPulseAudio_ReleaseOperation( pulseaudioHostApi, + &pulseaudioOperation ); } else { @@ -897,6 +896,7 @@ static PaError RequestStop( PaPulseAudio_Stream * stream, PaError ret = paNoError; PaPulseAudio_HostApiRepresentation *pulseaudioHostApi = stream->hostapi; pa_operation *pulseaudioOperation = NULL; + int waitLoop = 0; PaPulseAudio_Lock( pulseaudioHostApi->mainloop ); @@ -919,14 +919,8 @@ static PaError RequestStop( PaPulseAudio_Stream * stream, PaPulseAudio_CorkSuccessCb, stream ); - while( pa_operation_get_state( pulseaudioOperation ) == PA_OPERATION_RUNNING ) - { - pa_threaded_mainloop_wait( pulseaudioHostApi->mainloop ); - } - - pa_operation_unref( pulseaudioOperation ); - - pulseaudioOperation = NULL; + PaPulseAudio_ReleaseOperation( pulseaudioHostApi, + &pulseaudioOperation ); } requeststop_error: diff --git a/src/hostapi/pulseaudio/pa_linux_pulseaudio_internal.h b/src/hostapi/pulseaudio/pa_linux_pulseaudio_internal.h index 2d71ae412..e1386185a 100644 --- a/src/hostapi/pulseaudio/pa_linux_pulseaudio_internal.h +++ b/src/hostapi/pulseaudio/pa_linux_pulseaudio_internal.h @@ -195,11 +195,14 @@ PaPulseAudio_Stream; return errorCode; \ } \ } \ - if( !pastream->isActive || pastream->isStopped ) \ + if( !(pastream)->isActive || (pastream)->isStopped ) \ { \ - return paStreamIsStopped; \ + return paStreamIsStopped; \ } +int PaPulseAudio_ReleaseOperation(PaPulseAudio_HostApiRepresentation *hostapi, + pa_operation **pulseaudioOperation); + void PaPulseAudio_Lock( pa_threaded_mainloop *mainloop ); void PaPulseAudio_UnLock( pa_threaded_mainloop *mainloop ); @@ -225,7 +228,6 @@ PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaStreamCallback * streamCallback, void *userData ); - PaError IsStreamStopped( PaStream * s ); PaError IsStreamActive( PaStream * stream );