Takashi Iwai
41fbdd9151
OBS-URL: https://build.opensuse.org/package/show/multimedia:libs/alsa?expand=0&rev=53
149 lines
3.4 KiB
Diff
149 lines
3.4 KiB
Diff
From 2e48439ad93f6c8d99a2d72928ac71285b5211bb Mon Sep 17 00:00:00 2001
|
|
From: Jaroslav Kysela <perex@perex.cz>
|
|
Date: Sun, 31 Jan 2010 09:40:08 +0100
|
|
Subject: [PATCH] pcm: fix read_areas and write_areas
|
|
|
|
The stream state was wrongly updated and handled.
|
|
|
|
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
|
|
---
|
|
src/pcm/pcm.c | 87 +++++++++++++++++++++++++++++++-------------------------
|
|
1 files changed, 48 insertions(+), 39 deletions(-)
|
|
|
|
diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c
|
|
index 06d674f..f910189 100644
|
|
--- a/src/pcm/pcm.c
|
|
+++ b/src/pcm/pcm.c
|
|
@@ -6528,46 +6528,51 @@ snd_pcm_sframes_t snd_pcm_read_areas(snd_pcm_t *pcm, const snd_pcm_channel_area_
|
|
{
|
|
snd_pcm_uframes_t xfer = 0;
|
|
snd_pcm_sframes_t err = 0;
|
|
- snd_pcm_state_t state = snd_pcm_state(pcm);
|
|
+ snd_pcm_state_t state;
|
|
|
|
if (size == 0)
|
|
return 0;
|
|
|
|
- switch (state) {
|
|
- case SND_PCM_STATE_PREPARED:
|
|
- err = snd_pcm_start(pcm);
|
|
- if (err < 0)
|
|
- goto _end;
|
|
- break;
|
|
- case SND_PCM_STATE_DRAINING:
|
|
- case SND_PCM_STATE_RUNNING:
|
|
- break;
|
|
- case SND_PCM_STATE_XRUN:
|
|
- return -EPIPE;
|
|
- case SND_PCM_STATE_SUSPENDED:
|
|
- return -ESTRPIPE;
|
|
- case SND_PCM_STATE_DISCONNECTED:
|
|
- return -ENODEV;
|
|
- default:
|
|
- return -EBADFD;
|
|
- }
|
|
-
|
|
while (size > 0) {
|
|
snd_pcm_uframes_t frames;
|
|
snd_pcm_sframes_t avail;
|
|
_again:
|
|
- if (state == SND_PCM_STATE_RUNNING) {
|
|
+ state = snd_pcm_state(pcm);
|
|
+ switch (state) {
|
|
+ case SND_PCM_STATE_PREPARED:
|
|
+ err = snd_pcm_start(pcm);
|
|
+ if (err < 0)
|
|
+ goto _end;
|
|
+ break;
|
|
+ case SND_PCM_STATE_RUNNING:
|
|
err = snd_pcm_hwsync(pcm);
|
|
if (err < 0)
|
|
goto _end;
|
|
+ break;
|
|
+ case SND_PCM_STATE_DRAINING:
|
|
+ case SND_PCM_STATE_PAUSED:
|
|
+ break;
|
|
+ case SND_PCM_STATE_XRUN:
|
|
+ err = -EPIPE;
|
|
+ goto _end;
|
|
+ case SND_PCM_STATE_SUSPENDED:
|
|
+ err = -ESTRPIPE;
|
|
+ goto _end;
|
|
+ case SND_PCM_STATE_DISCONNECTED:
|
|
+ err = -ENODEV;
|
|
+ goto _end;
|
|
+ default:
|
|
+ err = -EBADFD;
|
|
+ goto _end;
|
|
}
|
|
avail = snd_pcm_avail_update(pcm);
|
|
if (avail < 0) {
|
|
err = avail;
|
|
goto _end;
|
|
}
|
|
- if ((snd_pcm_uframes_t)avail < pcm->avail_min &&
|
|
- size > (snd_pcm_uframes_t)avail) {
|
|
+ if (avail == 0) {
|
|
+ if (state == SND_PCM_STATE_DRAINING)
|
|
+ goto _end;
|
|
if (pcm->mode & SND_PCM_NONBLOCK) {
|
|
err = -EAGAIN;
|
|
goto _end;
|
|
@@ -6602,33 +6607,37 @@ snd_pcm_sframes_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area
|
|
{
|
|
snd_pcm_uframes_t xfer = 0;
|
|
snd_pcm_sframes_t err = 0;
|
|
- snd_pcm_state_t state = snd_pcm_state(pcm);
|
|
+ snd_pcm_state_t state;
|
|
|
|
if (size == 0)
|
|
return 0;
|
|
|
|
- switch (state) {
|
|
- case SND_PCM_STATE_PREPARED:
|
|
- case SND_PCM_STATE_RUNNING:
|
|
- break;
|
|
- case SND_PCM_STATE_XRUN:
|
|
- return -EPIPE;
|
|
- case SND_PCM_STATE_SUSPENDED:
|
|
- return -ESTRPIPE;
|
|
- case SND_PCM_STATE_DISCONNECTED:
|
|
- return -ENODEV;
|
|
- default:
|
|
- return -EBADFD;
|
|
- }
|
|
-
|
|
while (size > 0) {
|
|
snd_pcm_uframes_t frames;
|
|
snd_pcm_sframes_t avail;
|
|
_again:
|
|
- if (state == SND_PCM_STATE_RUNNING) {
|
|
+ state = snd_pcm_state(pcm);
|
|
+ switch (state) {
|
|
+ case SND_PCM_STATE_PREPARED:
|
|
+ case SND_PCM_STATE_PAUSED:
|
|
+ break;
|
|
+ case SND_PCM_STATE_RUNNING:
|
|
err = snd_pcm_hwsync(pcm);
|
|
if (err < 0)
|
|
goto _end;
|
|
+ break;
|
|
+ case SND_PCM_STATE_XRUN:
|
|
+ err = -EPIPE;
|
|
+ goto _end;
|
|
+ case SND_PCM_STATE_SUSPENDED:
|
|
+ err = -ESTRPIPE;
|
|
+ goto _end;
|
|
+ case SND_PCM_STATE_DISCONNECTED:
|
|
+ err = -ENODEV;
|
|
+ goto _end;
|
|
+ default:
|
|
+ err = -EBADFD;
|
|
+ goto _end;
|
|
}
|
|
avail = snd_pcm_avail_update(pcm);
|
|
if (avail < 0) {
|
|
--
|
|
1.7.0.1
|
|
|