mirror of
https://projects.vdr-developer.org/git/vdr-plugin-softhddevice.git
synced 2023-10-10 19:16:51 +02:00
Fix audio thread close race condition.
This commit is contained in:
parent
8b7402a397
commit
a3c0052c4b
@ -1,6 +1,7 @@
|
|||||||
User johns
|
User johns
|
||||||
Date:
|
Date:
|
||||||
|
|
||||||
|
Fix audio thread close race condition.
|
||||||
Support ffmpeg new AVFrame API in the audio codec.
|
Support ffmpeg new AVFrame API in the audio codec.
|
||||||
Config for automatic AES parameters.
|
Config for automatic AES parameters.
|
||||||
Use GCC built-in functions for atomic operations.
|
Use GCC built-in functions for atomic operations.
|
||||||
|
29
audio.c
29
audio.c
@ -149,6 +149,7 @@ static int AudioBufferTime = 336; ///< audio buffer time in ms
|
|||||||
static pthread_t AudioThread; ///< audio play thread
|
static pthread_t AudioThread; ///< audio play thread
|
||||||
static pthread_mutex_t AudioMutex; ///< audio condition mutex
|
static pthread_mutex_t AudioMutex; ///< audio condition mutex
|
||||||
static pthread_cond_t AudioStartCond; ///< condition variable
|
static pthread_cond_t AudioStartCond; ///< condition variable
|
||||||
|
static char AudioThreadStop; ///< stop audio thread
|
||||||
#else
|
#else
|
||||||
static const int AudioThread; ///< dummy audio thread
|
static const int AudioThread; ///< dummy audio thread
|
||||||
#endif
|
#endif
|
||||||
@ -942,7 +943,6 @@ static int AlsaThread(void)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
for (;;) {
|
for (;;) {
|
||||||
pthread_testcancel();
|
|
||||||
if (AudioPaused) {
|
if (AudioPaused) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1216,7 +1216,8 @@ static int AlsaSetup(int *freq, int *channels, int passthrough)
|
|||||||
snd_pcm_t *handle;
|
snd_pcm_t *handle;
|
||||||
|
|
||||||
handle = AlsaPCMHandle;
|
handle = AlsaPCMHandle;
|
||||||
// FIXME: need lock
|
// no lock needed, thread exit in main loop only
|
||||||
|
//Debug(3, "audio: %s [\n", __FUNCTION__);
|
||||||
AlsaPCMHandle = NULL; // other threads should check handle
|
AlsaPCMHandle = NULL; // other threads should check handle
|
||||||
snd_pcm_close(handle);
|
snd_pcm_close(handle);
|
||||||
if (AudioAlsaCloseOpenDelay) {
|
if (AudioAlsaCloseOpenDelay) {
|
||||||
@ -1227,6 +1228,7 @@ static int AlsaSetup(int *freq, int *channels, int passthrough)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
AlsaPCMHandle = handle;
|
AlsaPCMHandle = handle;
|
||||||
|
//Debug(3, "audio: %s ]\n", __FUNCTION__);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -1548,7 +1550,6 @@ static int OssThread(void)
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
struct pollfd fds[1];
|
struct pollfd fds[1];
|
||||||
|
|
||||||
pthread_testcancel();
|
|
||||||
if (AudioPaused) {
|
if (AudioPaused) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -2050,6 +2051,12 @@ static void *AudioPlayHandlerThread(void *dummy)
|
|||||||
{
|
{
|
||||||
Debug(3, "audio: play thread started\n");
|
Debug(3, "audio: play thread started\n");
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
// check if we should stop the thread
|
||||||
|
if (AudioThreadStop) {
|
||||||
|
Debug(3, "audio: play thread stopped\n");
|
||||||
|
return PTHREAD_CANCELED;
|
||||||
|
}
|
||||||
|
|
||||||
Debug(3, "audio: wait on start condition\n");
|
Debug(3, "audio: wait on start condition\n");
|
||||||
pthread_mutex_lock(&AudioMutex);
|
pthread_mutex_lock(&AudioMutex);
|
||||||
AudioRunning = 0;
|
AudioRunning = 0;
|
||||||
@ -2072,6 +2079,11 @@ static void *AudioPlayHandlerThread(void *dummy)
|
|||||||
int err;
|
int err;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
// check if we should stop the thread
|
||||||
|
if (AudioThreadStop) {
|
||||||
|
Debug(3, "audio: play thread stopped\n");
|
||||||
|
return PTHREAD_CANCELED;
|
||||||
|
}
|
||||||
// look if there is a flush command in the queue
|
// look if there is a flush command in the queue
|
||||||
flush = 0;
|
flush = 0;
|
||||||
filled = atomic_read(&AudioRingFilled);
|
filled = atomic_read(&AudioRingFilled);
|
||||||
@ -2156,6 +2168,7 @@ static void *AudioPlayHandlerThread(void *dummy)
|
|||||||
*/
|
*/
|
||||||
static void AudioInitThread(void)
|
static void AudioInitThread(void)
|
||||||
{
|
{
|
||||||
|
AudioThreadStop = 0;
|
||||||
pthread_mutex_init(&AudioMutex, NULL);
|
pthread_mutex_init(&AudioMutex, NULL);
|
||||||
pthread_cond_init(&AudioStartCond, NULL);
|
pthread_cond_init(&AudioStartCond, NULL);
|
||||||
pthread_create(&AudioThread, NULL, AudioPlayHandlerThread, NULL);
|
pthread_create(&AudioThread, NULL, AudioPlayHandlerThread, NULL);
|
||||||
@ -2169,10 +2182,12 @@ static void AudioExitThread(void)
|
|||||||
{
|
{
|
||||||
void *retval;
|
void *retval;
|
||||||
|
|
||||||
|
Debug(3, "audio: %s\n", __FUNCTION__);
|
||||||
|
|
||||||
if (AudioThread) {
|
if (AudioThread) {
|
||||||
if (pthread_cancel(AudioThread)) {
|
AudioThreadStop = 1;
|
||||||
Error(_("audio: can't queue cancel play thread\n"));
|
AudioRunning = 1; // wakeup thread, if needed
|
||||||
}
|
pthread_cond_signal(&AudioStartCond);
|
||||||
if (pthread_join(AudioThread, &retval) || retval != PTHREAD_CANCELED) {
|
if (pthread_join(AudioThread, &retval) || retval != PTHREAD_CANCELED) {
|
||||||
Error(_("audio: can't cancel play thread\n"));
|
Error(_("audio: can't cancel play thread\n"));
|
||||||
}
|
}
|
||||||
@ -2994,6 +3009,8 @@ void AudioExit(void)
|
|||||||
{
|
{
|
||||||
const AudioModule *module;
|
const AudioModule *module;
|
||||||
|
|
||||||
|
Debug(3, "audio: %s\n", __FUNCTION__);
|
||||||
|
|
||||||
#ifdef USE_AUDIO_THREAD
|
#ifdef USE_AUDIO_THREAD
|
||||||
if (AudioUsedModule->Thread) { // supports threads
|
if (AudioUsedModule->Thread) { // supports threads
|
||||||
AudioExitThread();
|
AudioExitThread();
|
||||||
|
Loading…
Reference in New Issue
Block a user