PR #25139 opened by whatisyourname0 URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25139 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25139.patch
# Summary of changes ALSA capture can assemble a packet from several successful reads, including reads separated by EAGAIN. `audio_read_packet()` currently uses the final read's frame count when calculating PTS and updating `last_period`. Earlier reads in the same packet are omitted from both calculations. Use the completed packet's frame count for both. At 48 kHz, a 7680-frame packet assembled from two 3840-frame reads otherwise receives its first PTS about 80 ms late. Single-read packets keep the same calculation. ## Reproduction and validation The attached reproducer contains a hardware-free regression test and an optional real ALSA experiment, with build and execution instructions in `README.md`. - The regression test calls the FFmpeg ALSA demuxer and time filter, using GNU ld wrappers for ALSA reads and the clock. All 24 cases pass across 44.1, 48, 96 and 192 kHz, covering sample order, partial reads, EAGAIN, PTS and XRUN recovery. Short-read timestamp assertions fail on the parent revision. - Under ARM64 QEMU, half-period priming followed by nonblocking reads or SIGALRM produces actual ALSA short returns. These tests leave read return values unchanged. Eighteen before/after runs observed 48 short returns. Split packets had a first-PTS error of 79.976–79.996 ms before the fix and 5–15 us of observation overhead afterwards. - The ALSA-enabled minimal build passes FATE (302 test entries). GNU patcheck was reviewed: its `res` warnings are diff-only false positives; `res` remains assigned and used in the read loop. The minor-fix Changelog hint was reviewed. - Consumer-stall XRUN recovery and reopen tests passed. QEMU KASAN/lockdep logs showed no diagnostics in those experiments. Runtime validation used base `3e6cd5e7603cb81b028b9c17530697b8986bf69a` plus signed commit `2d1cf34a9d11a83c9063bc1ac36a45b638e1d7bc`. This PR applies the same diff to master `b7e835e069`; the ALSA source is byte-identical to the tested version, and the stable patch IDs match. ALSA/timefilter sources have not changed since the tested base. The device experiment used silent virtual input. Physical-device behavior and how often short reads occur in field recordings remain unmeasured. This fix does not reconstruct samples lost to XRUN or add timestamps to raw PCM output. The standalone regression test is supplied for review and is not integrated into FATE. ## Previous email submission The patch and reproducer were initially sent before list subscription and held for moderation. This PR replaces that submission. The two original Message-IDs are: - `<[email protected]>` - `<[email protected]>` I have asked `[email protected]` to discard both held messages. The withdrawal request was accepted by Gmail SMTP; moderator confirmation is pending. Please use this PR for review. From d06b18f53f59506d8a5a5247115c84dd752e5dff Mon Sep 17 00:00:00 2001 From: whatisyourname0 <[email protected]> Date: Sat, 17 Oct 2026 04:17:44 +0000 Subject: [PATCH] fix(avdevice/alsa): timestamp the complete capture packet after short reads ALSA capture can assemble a packet from multiple successful reads, possibly across EAGAIN returns. The timestamp calculation still uses the frame count from the final read, so it subtracts too little audio time. The same count also supplies the wrong interval to the next time-filter update. Use the completed packet's frame count for both calculations. A 7680-frame packet assembled from two 3840-frame reads at 48 kHz otherwise receives a first PTS 80 ms too late. Single-read packets retain the same calculation. Reproduced with real ALSA short returns under ARM64 QEMU: a capture PCM was primed by half a period, then read in nonblocking mode or interrupted by SIGALRM while waiting for the remainder. No read return values were changed in those tests. The fix also passes deterministic sample-order, PTS, EAGAIN and XRUN recovery checks at 44.1, 48, 96 and 192 kHz. Signed-off-by: Joonho Lee <[email protected]> --- libavdevice/alsa_dec.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libavdevice/alsa_dec.c b/libavdevice/alsa_dec.c index 7411fcc5fb..78ced66de9 100644 --- a/libavdevice/alsa_dec.c +++ b/libavdevice/alsa_dec.c @@ -106,7 +106,7 @@ fail: static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt) { AlsaData *s = s1->priv_data; - int res; + int res, frames; int64_t dts; snd_pcm_sframes_t delay = 0; @@ -134,11 +134,13 @@ static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt) } while (s->pkt->size < s->period_size * s->frame_size); av_packet_move_ref(pkt, s->pkt); + /* A packet may have been assembled from multiple short reads. */ + frames = pkt->size / s->frame_size; dts = av_gettime(); snd_pcm_delay(s->h, &delay); - dts -= av_rescale(delay + res, 1000000, s->sample_rate); + dts -= av_rescale(delay + frames, 1000000, s->sample_rate); pkt->pts = ff_timefilter_update(s->timefilter, dts, s->last_period); - s->last_period = res; + s->last_period = frames; return 0; } -- 2.54.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
