*/
int snd_pcm_wait(snd_pcm_t *pcm, int timeout)
{
- if (snd_pcm_mmap_avail(pcm) >= pcm->avail_min) {
+ if (!snd_pcm_may_wait_for_avail_min(pcm, snd_pcm_mmap_avail(pcm))) {
/* check more precisely */
switch (snd_pcm_state(pcm)) {
case SND_PCM_STATE_XRUN:
goto _end;
}
if ((state == SND_PCM_STATE_RUNNING &&
- (snd_pcm_uframes_t)avail < pcm->avail_min &&
- size > (snd_pcm_uframes_t)avail)) {
+ size > (snd_pcm_uframes_t)avail &&
+ snd_pcm_may_wait_for_avail_min(pcm, avail))) {
if (pcm->mode & SND_PCM_NONBLOCK) {
err = -EAGAIN;
goto _end;
}
- err = snd_pcm_wait(pcm, -1);
+ err = snd_pcm_wait_nocheck(pcm, -1);
if (err < 0)
break;
goto _again;
return snd_pcm_set_chmap(generic->slave, map);
}
+int snd_pcm_generic_may_wait_for_avail_min(snd_pcm_t *pcm, snd_pcm_uframes_t avail ATTRIBUTE_UNUSED)
+{
+ snd_pcm_generic_t *generic = pcm->private_data;
+ return snd_pcm_may_wait_for_avail_min(generic->slave, snd_pcm_mmap_avail(generic->slave));
+}
+
#endif /* DOC_HIDDEN */
snd1_pcm_generic_get_chmap
#define snd_pcm_generic_set_chmap \
snd1_pcm_generic_set_chmap
+#define snd_pcm_generic_may_wait_for_avail_min \
+ snd1_pcm_generic_may_wait_for_avail_min
int snd_pcm_generic_close(snd_pcm_t *pcm);
int snd_pcm_generic_nonblock(snd_pcm_t *pcm, int nonblock);
snd_pcm_chmap_query_t **snd_pcm_generic_query_chmaps(snd_pcm_t *pcm);
snd_pcm_chmap_t *snd_pcm_generic_get_chmap(snd_pcm_t *pcm);
int snd_pcm_generic_set_chmap(snd_pcm_t *pcm, const snd_pcm_chmap_t *map);
-
+int snd_pcm_generic_may_wait_for_avail_min(snd_pcm_t *pcm, snd_pcm_uframes_t avail);
.poll_descriptors_count = snd_pcm_generic_poll_descriptors_count,
.poll_descriptors = snd_pcm_generic_poll_descriptors,
.poll_revents = snd_pcm_generic_poll_revents,
+ .may_wait_for_avail_min = snd_pcm_generic_may_wait_for_avail_min,
};
/**
int (*poll_descriptors_count)(snd_pcm_t *pcm);
int (*poll_descriptors)(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space);
int (*poll_revents)(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
+ int (*may_wait_for_avail_min)(snd_pcm_t *pcm, snd_pcm_uframes_t avail);
} snd_pcm_fast_ops_t;
struct _snd_pcm {
snd_pcm_chmap_t *
_snd_pcm_choose_fixed_chmap(snd_pcm_t *pcm, snd_pcm_chmap_query_t * const *maps);
+/* return true if the PCM stream may wait to get avail_min space */
+static inline int snd_pcm_may_wait_for_avail_min(snd_pcm_t *pcm, snd_pcm_uframes_t avail)
+{
+ if (avail >= pcm->avail_min)
+ return 0;
+ if (pcm->fast_ops->may_wait_for_avail_min)
+ return pcm->fast_ops->may_wait_for_avail_min(pcm, avail);
+ return 1;
+}
+
.poll_descriptors_count = snd_pcm_generic_poll_descriptors_count,
.poll_descriptors = snd_pcm_generic_poll_descriptors,
.poll_revents = snd_pcm_generic_poll_revents,
+ .may_wait_for_avail_min = snd_pcm_generic_may_wait_for_avail_min,
};
/**
.poll_descriptors = snd_pcm_generic_poll_descriptors,
.poll_descriptors_count = snd_pcm_generic_poll_descriptors_count,
.poll_revents = snd_pcm_generic_poll_revents,
+ .may_wait_for_avail_min = snd_pcm_generic_may_wait_for_avail_min,
};
#ifndef DOC_HIDDEN
return 0;
}
+static int snd_pcm_multi_may_wait_for_avail_min(snd_pcm_t *pcm, snd_pcm_uframes_t avail)
+{
+ snd_pcm_multi_t *multi = pcm->private_data;
+ snd_pcm_t *slave = multi->slaves[multi->master_slave].pcm;
+ return snd_pcm_may_wait_for_avail_min(slave, snd_pcm_mmap_avail(slave));
+}
+
static snd_pcm_chmap_query_t **snd_pcm_multi_query_chmaps(snd_pcm_t *pcm)
{
snd_pcm_multi_t *multi = pcm->private_data;
.poll_descriptors_count = snd_pcm_multi_poll_descriptors_count,
.poll_descriptors = snd_pcm_multi_poll_descriptors,
.poll_revents = snd_pcm_multi_poll_revents,
+ .may_wait_for_avail_min = snd_pcm_multi_may_wait_for_avail_min,
};
/**
.poll_descriptors_count = snd_pcm_generic_poll_descriptors_count,
.poll_descriptors = snd_pcm_generic_poll_descriptors,
.poll_revents = snd_pcm_generic_poll_revents,
+ .may_wait_for_avail_min = snd_pcm_generic_may_wait_for_avail_min,
};
#endif
.poll_descriptors_count = snd_pcm_generic_poll_descriptors_count,
.poll_descriptors = snd_pcm_generic_poll_descriptors,
.poll_revents = snd_pcm_rate_poll_revents,
+ .may_wait_for_avail_min = snd_pcm_generic_may_wait_for_avail_min,
};
static const snd_pcm_ops_t snd_pcm_rate_ops = {