@@ -219,6 +219,8 @@ PulseAudioPlayer::PulseAudioPlayer(agi::AudioProvider *provider) : AudioPlayer(p
219219 if (pa_threaded_mainloop_start (mainloop.get ()))
220220 throw AudioPlayerOpenError (" Failed to start PulseAudio threaded mainloop" );
221221
222+ PAThreadedMainloopLock lock{mainloop.get ()};
223+
222224 // Create context
223225 context.reset (pa_context_new (pa_threaded_mainloop_get_api (mainloop.get ()), " Aegisub" ), mainloop.get ());
224226 if (!context.get ())
@@ -283,14 +285,15 @@ PulseAudioPlayer::PulseAudioPlayer(agi::AudioProvider *provider) : AudioPlayer(p
283285
284286PulseAudioPlayer::~PulseAudioPlayer ()
285287{
288+ PAThreadedMainloopLock lock{mainloop.get ()};
286289 if (is_playing) Stop ();
287290}
288291
289292void PulseAudioPlayer::Play (int64_t start,int64_t count)
290293{
294+ PAThreadedMainloopLock lock{mainloop.get ()};
291295 if (is_playing) {
292296 // If we're already playing, do a quick "reset"
293- PAThreadedMainloopLock lock{mainloop.get ()};
294297 is_playing = false ;
295298
296299 PAOperation op{pa_stream_flush (stream.get (), (pa_stream_success_cb_t )PAStreamSuccessCB, this )};
@@ -311,15 +314,11 @@ void PulseAudioPlayer::Play(int64_t start,int64_t count)
311314 is_playing = true ;
312315
313316 play_start_time = 0 ;
314- {
315- PAThreadedMainloopLock lock{mainloop.get ()};
316- if (int paerror = pa_stream_get_time (stream.get (), (pa_usec_t *) &play_start_time))
317- LOG_E (" audio/player/pulse" ) << " Error getting stream time: " << pa_strerror (paerror) << " (" << paerror << " )" ;
318- }
317+ if (int paerror = pa_stream_get_time (stream.get (), (pa_usec_t *) &play_start_time))
318+ LOG_E (" audio/player/pulse" ) << " Error getting stream time: " << pa_strerror (paerror) << " (" << paerror << " )" ;
319319
320320 PulseAudioPlayer::PAStreamWriteCB (stream.get (), pa_stream_writable_size (stream.get ()), this );
321321
322- PAThreadedMainloopLock lock{mainloop.get ()};
323322 PAOperation op{pa_stream_trigger (stream.get (), (pa_stream_success_cb_t )PAStreamSuccessCB, this )};
324323
325324 while (pa_operation_get_state (op.get ()) == PA_OPERATION_RUNNING )
@@ -333,6 +332,7 @@ void PulseAudioPlayer::Play(int64_t start,int64_t count)
333332
334333void PulseAudioPlayer::Stop ()
335334{
335+ PAThreadedMainloopLock lock{mainloop.get ()};
336336 if (!is_playing) return ;
337337
338338 is_playing = false ;
@@ -342,7 +342,6 @@ void PulseAudioPlayer::Stop()
342342 end_frame = 0 ;
343343
344344 // Flush the stream of data
345- PAThreadedMainloopLock lock{mainloop.get ()};
346345 PAOperation op{pa_stream_flush (stream.get (), (pa_stream_success_cb_t )PAStreamSuccessCB, this )};
347346
348347 while (pa_operation_get_state (op.get ()) == PA_OPERATION_RUNNING )
@@ -356,11 +355,14 @@ void PulseAudioPlayer::Stop()
356355
357356void PulseAudioPlayer::SetEndPosition (int64_t pos)
358357{
358+ PAThreadedMainloopLock lock{mainloop.get ()};
359359 end_frame = pos;
360360}
361361
362362int64_t PulseAudioPlayer::GetCurrentPosition ()
363363{
364+ PAThreadedMainloopLock lock{mainloop.get ()};
365+
364366 if (!is_playing) return 0 ;
365367
366368 // FIXME: this should be based on not duration played but actual sample being heard
0 commit comments