/* Read up to len frames */ static snd_pcm_sframes_t readbuf(snd_pcm_t *handle, char *buf, long len) { snd_pcm_sframes_t r; snd_pcm_uframes_t frames; snd_pcm_htimestamp(handle, &frames, ×tamp); r = snd_pcm_readi(handle, buf, len); if (r < 0 && r != -EAGAIN) { r = snd_pcm_recover(handle, r, 0); if (r < 0) fprintf(error_fp, "alsa: overrun recover error: %s\n", snd_strerror(r)); } return r; }
static void *peeper(void *data) { int thread_no = (long)data; snd_pcm_sframes_t val; snd_pcm_status_t *stat; snd_htimestamp_t tstamp; int mode = running_mode, err; snd_pcm_status_alloca(&stat); while (running) { if (running_mode == MODE_RANDOM) mode = rand() % MODE_RANDOM; switch (mode) { case MODE_AVAIL_UPDATE: val = snd_pcm_avail_update(pcm); err = 0; break; case MODE_STATUS: err = snd_pcm_status(pcm, stat); val = snd_pcm_status_get_avail(stat); break; case MODE_HWSYNC: err = snd_pcm_hwsync(pcm); break; case MODE_TIMESTAMP: err = snd_pcm_htimestamp(pcm, (snd_pcm_uframes_t *)&val, &tstamp); break; default: err = snd_pcm_delay(pcm, &val); break; } if (quiet) continue; if (running_mode == MODE_RANDOM) { fprintf(stderr, "%d%c%s", thread_no, mode_suffix[mode], err ? "!" : ""); } else { if (show_value && mode != MODE_HWSYNC) fprintf(stderr, "\r%d ", (int)val); else fprintf(stderr, "%d%s", thread_no, err ? "!" : ""); } } return NULL; }
static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt) { AlsaData *s = s1->priv_data; AVStream *st = s1->streams[0]; int res; snd_htimestamp_t timestamp; snd_pcm_uframes_t ts_delay; if (av_new_packet(pkt, s->period_size) < 0) { return AVERROR(EIO); } while ((res = snd_pcm_readi(s->h, pkt->data, pkt->size / s->frame_size)) < 0) { if (res == -EAGAIN) { av_free_packet(pkt); return AVERROR(EAGAIN); } if (ff_alsa_xrun_recover(s1, res) < 0) { av_log(s1, AV_LOG_ERROR, "ALSA read error: %s\n", snd_strerror(res)); av_free_packet(pkt); return AVERROR(EIO); } } snd_pcm_htimestamp(s->h, &ts_delay, ×tamp); ts_delay += res; pkt->pts = timestamp.tv_sec * 1000000LL + (timestamp.tv_nsec * st->codec->sample_rate - ts_delay * 1000000000LL + st->codec->sample_rate * 500LL) / (st->codec->sample_rate * 1000LL); pkt->size = res * s->frame_size; return 0; }
int snd_pcm_generic_htimestamp(snd_pcm_t *pcm, snd_pcm_uframes_t *avail, snd_htimestamp_t *tstamp) { snd_pcm_generic_t *generic = pcm->private_data; return snd_pcm_htimestamp(generic->slave, avail, tstamp); }