diff options
Diffstat (limited to 'libavdevice/alsa_dec.c')
-rw-r--r-- | libavdevice/alsa_dec.c | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/libavdevice/alsa_dec.c b/libavdevice/alsa_dec.c index 36494e9..902fba3 100644 --- a/libavdevice/alsa_dec.c +++ b/libavdevice/alsa_dec.c @@ -104,6 +104,7 @@ static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt) int res; int64_t dts; snd_pcm_sframes_t delay = 0; + snd_pcm_audio_tstamp_config_t tstamp_config; if (av_new_packet(pkt, s->period_size * s->frame_size) < 0) { return AVERROR(EIO); @@ -125,8 +126,29 @@ static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt) ff_timefilter_reset(s->timefilter); } - dts = av_gettime(); - snd_pcm_delay(s->h, &delay); + dts = 0; + if (s->use_driver_timestamps) { + tstamp_config.type_requested = 1; + tstamp_config.report_delay = 1; + snd_pcm_status_set_audio_htstamp_config(s->st, &tstamp_config); + if (snd_pcm_status(s->h, s->st) >= 0) { + struct timespec ts; + snd_pcm_status_get_driver_htstamp(s->st, &ts); + if ((ts.tv_sec == 0) && (ts.tv_nsec == 0)) { + // Try alternate access method + snd_pcm_status_get_htstamp(s->st, &ts); + } + dts = (int64_t)ts.tv_sec * 1000000 + ts.tv_nsec / 1000; + delay = snd_pcm_status_get_delay(s->st); + } + } + if (dts == 0) { + // Driver timestamps not supported + // Fall back to system timestamps + dts = av_gettime(); + snd_pcm_delay(s->h, &delay); + } + dts -= av_rescale(delay + res, 1000000, s->sample_rate); pkt->pts = ff_timefilter_update(s->timefilter, dts, s->last_period); s->last_period = res; |