mirror of
https://github.com/mpv-player/mpv
synced 2025-01-13 18:45:25 +00:00
ao_alsa: do not call snd_pcm_delay() when paused
This causes trouble when a hw device is used:
pcm_hw.c:514:(snd_pcm_hw_delay) SNDRV_PCM_IOCTL_DELAY failed (-77): File descriptor in bad state
when running mpv test.mkv --ao=alsa:device=iec958,alsa and pausing
during playback.
Historically, mplayer usually did not call snd_pcm_delay() (which is
called by get_delay()) while paused, so this problem never showed up.
But at least mpv has changes that cause get_delay() to be called when
updating the status line (see commit 3f949cf
).
It's possible that calling snd_pcm_delay() is not always legal when the
audio is paused, and at least fails with the error message mentioned
above is the device is a hardware device. Change get_delay() to return
the last delay before the audio was paused. The intention is to get a
continuous playback status display, even when pausing or frame stepping,
otherwise we could just return the audio buffer fill status in
get_delay() or even just 0 when paused.
This commit is contained in:
parent
67ee79283b
commit
9b3bf76d27
@ -69,6 +69,7 @@ static size_t bytes_per_sample;
|
||||
|
||||
static int alsa_can_pause;
|
||||
static snd_pcm_sframes_t prepause_frames;
|
||||
static float delay_before_pause;
|
||||
|
||||
#define ALSA_DEVICE_SIZE 256
|
||||
|
||||
@ -354,6 +355,7 @@ static int init(int rate_hz, int channels, int format, int flags)
|
||||
mp_msg(MSGT_AO,MSGL_V,"alsa-init: using ALSA %s\n", snd_asoundlib_version());
|
||||
|
||||
prepause_frames = 0;
|
||||
delay_before_pause = 0;
|
||||
|
||||
snd_lib_error_set_handler(alsa_error_handler);
|
||||
|
||||
@ -703,6 +705,7 @@ static void audio_pause(void)
|
||||
int err;
|
||||
|
||||
if (alsa_can_pause) {
|
||||
delay_before_pause = get_delay();
|
||||
if ((err = snd_pcm_pause(alsa_handler, 1)) < 0)
|
||||
{
|
||||
mp_tmsg(MSGT_AO,MSGL_ERR,"[AO_ALSA] pcm pause error: %s\n", snd_strerror(err));
|
||||
@ -713,6 +716,7 @@ static void audio_pause(void)
|
||||
if (snd_pcm_delay(alsa_handler, &prepause_frames) < 0
|
||||
|| prepause_frames < 0)
|
||||
prepause_frames = 0;
|
||||
delay_before_pause = prepause_frames / (float)ao_data.samplerate;
|
||||
|
||||
if ((err = snd_pcm_drop(alsa_handler)) < 0)
|
||||
{
|
||||
@ -757,6 +761,7 @@ static void reset(void)
|
||||
int err;
|
||||
|
||||
prepause_frames = 0;
|
||||
delay_before_pause = 0;
|
||||
if ((err = snd_pcm_drop(alsa_handler)) < 0)
|
||||
{
|
||||
mp_tmsg(MSGT_AO,MSGL_ERR,"[AO_ALSA] pcm prepare error: %s\n", snd_strerror(err));
|
||||
@ -847,6 +852,9 @@ static float get_delay(void)
|
||||
if (alsa_handler) {
|
||||
snd_pcm_sframes_t delay;
|
||||
|
||||
if (snd_pcm_state(alsa_handler) == SND_PCM_STATE_PAUSED)
|
||||
return delay_before_pause;
|
||||
|
||||
if (snd_pcm_delay(alsa_handler, &delay) < 0)
|
||||
return 0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user