aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Grossman <johngro@google.com>2012-04-03 16:37:38 -0700
committerSimon Wilson <simonwilson@google.com>2012-05-04 16:33:59 -0700
commitb6db70a16026bfc226a200a4382d04e2d15d84a1 (patch)
tree3c48e38fcaa9b0885abe11b530fc13babc2bce8a
parent6a52f2cbad1f191f3f14fbb0da6951ab2e0be5ca (diff)
pcm: Add PCM_NORESTART flag
Add a flag which can be passed to pcm_open (called PCM_NORESTART). When set on a playback stream, calls to pcm_write will not automatically attempt to restart an ALSA device in the case of an underflow. Instead, it will propagate the first EPIPE error up to the application to allow it to handle the underflow situation. Subsequent calls to pcm_write will attempt to start the pipeline.
-rw-r--r--include/tinyalsa/asoundlib.h9
-rw-r--r--pcm.c6
2 files changed, 14 insertions, 1 deletions
diff --git a/include/tinyalsa/asoundlib.h b/include/tinyalsa/asoundlib.h
index 704354e..e65403e 100644
--- a/include/tinyalsa/asoundlib.h
+++ b/include/tinyalsa/asoundlib.h
@@ -45,6 +45,15 @@ struct pcm;
#define PCM_IN 0x10000000
#define PCM_MMAP 0x00000001
#define PCM_NOIRQ 0x00000002
+#define PCM_NORESTART 0x00000004 /* PCM_NORESTART - when set, calls to
+ * pcm_write for a playback stream will not
+ * attempt to restart the stream in the case
+ * of an underflow, but will return -EPIPE
+ * instead. After the first -EPIPE error, the
+ * stream is considered to be stopped, and a
+ * second call to pcm_write will attempt to
+ * restart the stream.
+ */
/* PCM runtime states */
#define PCM_STATE_OPEN 0
diff --git a/pcm.c b/pcm.c
index d253433..2dca157 100644
--- a/pcm.c
+++ b/pcm.c
@@ -378,8 +378,12 @@ int pcm_write(struct pcm *pcm, const void *data, unsigned int count)
if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_WRITEI_FRAMES, &x)) {
pcm->running = 0;
if (errno == EPIPE) {
- /* we failed to make our window -- try to restart */
+ /* we failed to make our window -- try to restart if we are
+ * allowed to do so. Otherwise, simply allow the EPIPE error to
+ * propagate up to the app level */
pcm->underruns++;
+ if (pcm->flags & PCM_NORESTART)
+ return -EPIPE;
continue;
}
return oops(pcm, errno, "cannot write stream data");