Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pulseaudio: Rework stopping code that it should prevent artifacts #965

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 48 additions & 25 deletions src/hostapi/pulseaudio/pa_linux_pulseaudio_cb.c
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Github won't let me add a comment to an unchanged line, but at line 429 call to pa_steam_write, nothing has been copied to bufferData yet. Furthermore, bufferData memory is invalidated by the call (see https://freedesktop.org/software/pulseaudio/doxygen/stream_8h.html#a4fc69dec0cc202fcc174125dc88dada7 ) so subsequent calls to the buffer processor may crash.

I suggest moving the calls to PaUtil_EndBufferProcessing and PaUtil_EndCpuLoadMeasurement prior to the call to pa_stream_write.

Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,37 @@ void _PaPulseAudio_Read( PaPulseAudio_Stream *stream,

}

static int _PaPulseaudio_WriteZero(PaPulseAudio_Stream *stream,
int32_t length)
{
size_t tmpSize = length;
int ret = paContinue;
void *bufferData = NULL;

if( length <= 0)
{
return ret;
}

/* Allocate memory to make it faster to output stuff */
if( pa_stream_begin_write( stream->outputStream, &bufferData, &tmpSize ) )
{
PA_DEBUG( ("Portaudio %s: Can't output to stream!\n",
__FUNCTION__) );
return paInsufficientMemory;
}

memset( bufferData, 0x00, tmpSize);

pa_stream_write( stream->outputStream,
bufferData,
tmpSize,
NULL,
0,
PA_SEEK_RELATIVE );
return ret;
}

static int _PaPulseAudio_ProcessAudio(PaPulseAudio_Stream *stream,
size_t length)
{
Expand All @@ -233,6 +264,7 @@ static int _PaPulseAudio_ProcessAudio(PaPulseAudio_Stream *stream,
int ret = paContinue;
void *bufferData = NULL;
size_t pulseaudioOutputWritten = 0;
size_t pulseaudioLength = length;

/* If there is no specified per host buffer then
* just generate one or but correct one in place
Expand Down Expand Up @@ -293,19 +325,10 @@ static int _PaPulseAudio_ProcessAudio(PaPulseAudio_Stream *stream,
pulseaudioInputBytes /= 2;
}

if( !stream->isActive && stream->pulseaudioIsActive && stream->outputStream)
if( !stream->isActive && stream->outputStream)
{
bufferData = pulseaudioSampleBuffer;
memset( bufferData, 0x00, length);

pa_stream_write( stream->outputStream,
bufferData,
length,
NULL,
0,
PA_SEEK_RELATIVE );

return paContinue;
return _PaPulseaudio_WriteZero( stream,
pulseaudioLength );
}


Expand Down Expand Up @@ -388,13 +411,10 @@ static int _PaPulseAudio_ProcessAudio(PaPulseAudio_Stream *stream,
size_t tmpSize = pulseaudioOutputBytes;

/* Allocate memory to make it faster to output stuff */
pa_stream_begin_write( stream->outputStream, &bufferData, &tmpSize );

/* If bufferData is NULL then output is not ready
* and we have to wait for it
*/
if(!bufferData)
if( pa_stream_begin_write( stream->outputStream, &bufferData, &tmpSize ) )
{
PA_DEBUG( ("Portaudio %s: Can't output to stream!\n",
__FUNCTION__) )
return paNotInitialized;
}

Expand Down Expand Up @@ -426,6 +446,13 @@ static int _PaPulseAudio_ProcessAudio(PaPulseAudio_Stream *stream,

PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer,
hostFrameCount );

if( ret )
{
stream->isActive = 0;
return _PaPulseaudio_WriteZero( stream,
(length - pulseaudioOutputWritten) );
}
}

return ret;
Expand Down Expand Up @@ -518,8 +545,6 @@ PaError PaPulseAudio_CloseStreamCb( PaStream * s )
/* Wait for stream to be stopped */
stream->isActive = 0;
stream->isStopped = 1;
stream->pulseaudioIsActive = 0;
stream->pulseaudioIsStopped = 1;

if( stream->outputStream != NULL
&& PA_STREAM_IS_GOOD( pa_stream_get_state( stream->outputStream ) ) )
Expand All @@ -536,7 +561,6 @@ PaError PaPulseAudio_CloseStreamCb( PaStream * s )
&pulseaudioOperation );

PaPulseAudio_Lock(stream->mainloop);

pa_stream_disconnect( stream->outputStream );
PaPulseAudio_UnLock( stream->mainloop );
}
Expand Down Expand Up @@ -598,6 +622,9 @@ PaError PaPulseAudio_CloseStreamCb( PaStream * s )
usleep(10000);
}

stream->pulseaudioIsActive = 0;
stream->pulseaudioIsStopped = 1;

PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );

Expand Down Expand Up @@ -917,8 +944,6 @@ static PaError RequestStop( PaPulseAudio_Stream * stream,
/* Wait for stream to be stopped */
stream->isActive = 0;
stream->isStopped = 1;
stream->pulseaudioIsActive = 0;
stream->pulseaudioIsStopped = 1;

stream->missedBytes = 0;

Expand All @@ -941,8 +966,6 @@ static PaError RequestStop( PaPulseAudio_Stream * stream,

requeststop_error:
PaPulseAudio_UnLock( pulseaudioHostApi->mainloop );
stream->isActive = 0;
stream->isStopped = 1;
stream->pulseaudioIsActive = 0;
stream->pulseaudioIsStopped = 1;

Expand Down
Loading