mirror of https://github.com/mpv-player/mpv
Fix dead lock when changing and restoring stream format for digital output,
replaced with lockless code. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@25008 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
4ab4cd3dcd
commit
894000c434
|
@ -44,9 +44,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <pthread.h>
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/time.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@ -857,21 +855,16 @@ static int AudioStreamChangeFormat( AudioStreamID i_stream_id, AudioStreamBasicD
|
||||||
UInt32 i_param_size = 0;
|
UInt32 i_param_size = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
struct timeval now;
|
static volatile int stream_format_changed;
|
||||||
struct timespec timeout;
|
stream_format_changed = 0;
|
||||||
struct { pthread_mutex_t lock; pthread_cond_t cond; } w;
|
|
||||||
|
|
||||||
print_format(MSGL_V, "setting stream format:", &change_format);
|
print_format(MSGL_V, "setting stream format:", &change_format);
|
||||||
|
|
||||||
/* Condition because SetProperty is asynchronious. */
|
|
||||||
pthread_cond_init(&w.cond, NULL);
|
|
||||||
pthread_mutex_init(&w.lock, NULL);
|
|
||||||
pthread_mutex_lock(&w.lock);
|
|
||||||
|
|
||||||
/* Install the callback. */
|
/* Install the callback. */
|
||||||
err = AudioStreamAddPropertyListener(i_stream_id, 0,
|
err = AudioStreamAddPropertyListener(i_stream_id, 0,
|
||||||
kAudioStreamPropertyPhysicalFormat,
|
kAudioStreamPropertyPhysicalFormat,
|
||||||
StreamListener, (void *)&w);
|
StreamListener,
|
||||||
|
(void *)&stream_format_changed);
|
||||||
if (err != noErr)
|
if (err != noErr)
|
||||||
{
|
{
|
||||||
ao_msg(MSGT_AO, MSGL_WARN, "AudioStreamAddPropertyListener failed: [%4.4s]\n", (char *)&err);
|
ao_msg(MSGT_AO, MSGL_WARN, "AudioStreamAddPropertyListener failed: [%4.4s]\n", (char *)&err);
|
||||||
|
@ -889,19 +882,19 @@ static int AudioStreamChangeFormat( AudioStreamID i_stream_id, AudioStreamBasicD
|
||||||
return CONTROL_FALSE;
|
return CONTROL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The AudioStreamSetProperty is not only asynchronious (requiring the locks),
|
/* The AudioStreamSetProperty is not only asynchronious,
|
||||||
* it is also not Atomic, in its behaviour.
|
* it is also not Atomic, in its behaviour.
|
||||||
* Therefore we check 5 times before we really give up.
|
* Therefore we check 5 times before we really give up.
|
||||||
* FIXME: failing isn't actually implemented yet. */
|
* FIXME: failing isn't actually implemented yet. */
|
||||||
for (i = 0; i < 5; ++i)
|
for (i = 0; i < 5; ++i)
|
||||||
{
|
{
|
||||||
AudioStreamBasicDescription actual_format;
|
AudioStreamBasicDescription actual_format;
|
||||||
|
int j;
|
||||||
gettimeofday(&now, NULL);
|
for (j = 0; !stream_format_changed && j < 50; ++j)
|
||||||
timeout.tv_sec = now.tv_sec;
|
usec_sleep(10000);
|
||||||
timeout.tv_nsec = (now.tv_usec + 500000) * 1000;
|
if (stream_format_changed)
|
||||||
|
stream_format_changed = 0;
|
||||||
if (pthread_cond_timedwait(&w.cond, &w.lock, &timeout))
|
else
|
||||||
ao_msg(MSGT_AO, MSGL_V, "reached timeout\n" );
|
ao_msg(MSGT_AO, MSGL_V, "reached timeout\n" );
|
||||||
|
|
||||||
i_param_size = sizeof(AudioStreamBasicDescription);
|
i_param_size = sizeof(AudioStreamBasicDescription);
|
||||||
|
@ -931,11 +924,6 @@ static int AudioStreamChangeFormat( AudioStreamID i_stream_id, AudioStreamBasicD
|
||||||
return CONTROL_FALSE;
|
return CONTROL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Destroy the lock and condition. */
|
|
||||||
pthread_mutex_unlock(&w.lock);
|
|
||||||
pthread_mutex_destroy(&w.lock);
|
|
||||||
pthread_cond_destroy(&w.cond);
|
|
||||||
|
|
||||||
return CONTROL_TRUE;
|
return CONTROL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1144,17 +1132,12 @@ static OSStatus StreamListener( AudioStreamID inStream,
|
||||||
AudioDevicePropertyID inPropertyID,
|
AudioDevicePropertyID inPropertyID,
|
||||||
void * inClientData )
|
void * inClientData )
|
||||||
{
|
{
|
||||||
struct { pthread_mutex_t lock; pthread_cond_t cond; } * w = inClientData;
|
|
||||||
|
|
||||||
switch (inPropertyID)
|
switch (inPropertyID)
|
||||||
{
|
{
|
||||||
case kAudioStreamPropertyPhysicalFormat:
|
case kAudioStreamPropertyPhysicalFormat:
|
||||||
if (NULL!=w)
|
ao_msg(MSGT_AO, MSGL_V, "got notify kAudioStreamPropertyPhysicalFormat changed.\n");
|
||||||
{
|
if (inClientData)
|
||||||
pthread_mutex_lock(&w->lock);
|
*(volatile int *)inClientData = 1;
|
||||||
pthread_cond_signal(&w->cond);
|
|
||||||
pthread_mutex_unlock(&w->lock);
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue