[vlc-commits] [Git][videolan/vlc][master] 3 commits: aout: account for drained filter samples
Jean-Baptiste Kempf (@jbk)
gitlab at videolan.org
Sun Oct 11 17:39:13 UTC 2026
Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC
Commits:
8b56c478 by Thomas Guillem at 2026-10-11T19:22:43+02:00
aout: account for drained filter samples
Also take into account drained samples from stream_GetDelay().
- - - - -
486fbfbe by Thomas Guillem at 2026-10-11T19:22:43+02:00
aout: fix the stream delay at rate != 1
At rate != 1, stream_GetDelay() mixed output samples, counted after the
rate filter, with stream-time timestamps: at a constant rate, the delay
was off by (1/rate - 1) times the output submitted since the last
flush.
Outputs without a drain callback (wasapi, coreaudio, avsamplebuffer,
AudioTrack) wait for this delay at EOF: with adummy, playing 4 s of
audio took 16.0 s at x0.5 and 1.6 s at x2, cutting the end (8.1 s and
2.2 s now). With --clock-master=monotonic, the audio inserted silence
every 100 ms at x2.5 and flushed its buffers every 5 s at x0.5.
- - - - -
38022073 by Thomas Guillem at 2026-10-11T19:22:43+02:00
test: player: check that EOF waits for the audio at rate != 1
Without the stream delay fix, EOF stopped the test output at least
180 ms before its last sample at x2, and up to 95 ms before at x4.
- - - - -
4 changed files:
- src/audio_output/dec.c
- test/src/player/common.h
- test/src/player/eof.c
- test/src/player/modules.c
Changes:
=====================================
src/audio_output/dec.c
=====================================
@@ -150,8 +150,7 @@ static int stream_GetDelay(vlc_aout_stream *stream, vlc_tick_t *delay)
* coefficient is 1.0 (audio at the same speed than the monotonic
* clock) since the calculation is done on a very small interval
* (generally less than 2 seconds). */
- vlc_tick_t play_date = (last_pts - audio_ts) / (double) stream->sync.rate
- + system_ts;
+ vlc_tick_t play_date = last_pts - audio_ts + system_ts;
*delay = play_date - system_now;
return 0;
}
@@ -773,6 +772,10 @@ void vlc_aout_stream_NotifyTiming(vlc_aout_stream *stream, vlc_tick_t system_ts,
vlc_tick_t rate_audio_ts = stream->timing.rate_audio_ts;
vlc_tick_t rate_system_ts = stream->timing.rate_system_ts;
+ /* audio_ts is the output position: at rate != 1, it advances with the
+ * output samples, like played_samples, not with the stream timestamps
+ * of the clock. */
+ vlc_tick_t clock_audio_ts = audio_ts;
if (rate_audio_ts != VLC_TICK_INVALID)
{
/* Drop timing updates that comes before the rate change */
@@ -783,8 +786,8 @@ void vlc_aout_stream_NotifyTiming(vlc_aout_stream *stream, vlc_tick_t system_ts,
}
/* Fix the audio timestamp with the rate */
- audio_ts = rate_audio_ts + (system_ts - rate_system_ts)
- * stream->timing.rate;
+ clock_audio_ts = rate_audio_ts + (system_ts - rate_system_ts)
+ * stream->timing.rate;
}
stream->timing.system_ts = system_ts;
@@ -792,7 +795,7 @@ void vlc_aout_stream_NotifyTiming(vlc_aout_stream *stream, vlc_tick_t system_ts,
vlc_clock_Lock(stream->sync.clock);
stream->timing.last_drift =
vlc_clock_Update(stream->sync.clock, system_ts,
- audio_ts, stream->timing.rate);
+ clock_audio_ts, stream->timing.rate);
vlc_clock_Unlock(stream->sync.clock);
vlc_mutex_unlock(&stream->timing.lock);
}
@@ -1049,6 +1052,7 @@ void vlc_aout_stream_Drain(vlc_aout_stream *stream)
if (block)
{
assert (block->i_pts != VLC_TICK_INVALID);
+ stream->timing.played_samples += block->i_nb_samples;
aout->play(aout, block, vlc_tick_now());
}
}
=====================================
test/src/player/common.h
=====================================
@@ -146,8 +146,15 @@ struct report_aout_first_pts
vlc_tick_t first_pts;
};
+struct report_aout_stop
+{
+ vlc_tick_t date;
+ vlc_tick_t end_date;
+};
+
#define REPORT_LIST \
X(vlc_tick_t, on_aout_first_pts) \
+ X(struct report_aout_stop, on_aout_stop) \
#define X(type, name) typedef struct VLC_VECTOR(type) vec_##name;
PLAYER_REPORT_LIST
=====================================
test/src/player/eof.c
=====================================
@@ -62,6 +62,32 @@ test_repeat(struct ctx *ctx)
test_end(ctx);
}
+static void
+test_audio_end(struct ctx *ctx, float rate)
+{
+ test_log("audio_end: rate %f\n", rate);
+
+ vlc_player_t *player = ctx->player;
+
+ struct media_params params = DEFAULT_MEDIA_PARAMS(VLC_TICK_FROM_SEC(1));
+ params.track_count[VIDEO_ES] = 0;
+ params.track_count[SPU_ES] = 0;
+ player_set_next_mock_media(ctx, "media1", ¶ms);
+ player_set_rate(ctx, rate);
+ player_start(ctx);
+
+ wait_state(ctx, VLC_PLAYER_STATE_STOPPED);
+
+ /* The test aout has no drain callback: EOF waits for the play date of its
+ * last sample, computed by the core from two clock reads. */
+ vec_on_aout_stop *vec = &ctx->report.on_aout_stop;
+ assert(vec->size > 0);
+ struct report_aout_stop report = VEC_LAST(vec);
+ assert(report.date >= report.end_date - VLC_TICK_FROM_MS(10));
+
+ test_end(ctx);
+}
+
int
main(void)
{
@@ -69,6 +95,8 @@ main(void)
ctx_init(&ctx, 0);
test_play_pause(&ctx);
test_repeat(&ctx);
+ test_audio_end(&ctx, 2.f);
+ test_audio_end(&ctx, 4.f);
ctx_destroy(&ctx);
return 0;
}
=====================================
test/src/player/modules.c
=====================================
@@ -51,6 +51,27 @@ static void aout_Flush(audio_output_t *aout)
sys->first_pts = sys->first_play_date = VLC_TICK_INVALID;
}
+static void aout_Stop(audio_output_t *aout)
+{
+ struct aout_sys *sys = aout->sys;
+
+ if (sys->first_play_date != VLC_TICK_INVALID)
+ {
+ /* Same dates as the timing reports from Play() */
+ struct report_aout_stop report = {
+ .date = vlc_tick_now(),
+ .end_date = sys->first_play_date + sys->pos - VLC_TICK_0,
+ };
+
+ struct ctx *ctx = sys->ctx;
+ vlc_player_Lock(ctx->player);
+ VEC_PUSH(on_aout_stop, report);
+ vlc_player_Unlock(ctx->player);
+ }
+
+ aout_Flush(aout);
+}
+
static void aout_Pause(audio_output_t *aout, bool pause, vlc_tick_t date)
{
(void) date;
@@ -84,7 +105,7 @@ static int aout_Open(vlc_object_t *obj)
aout->play = aout_Play;
aout->pause = aout_Pause;
aout->flush = aout_Flush;
- aout->stop = aout_Flush;
+ aout->stop = aout_Stop;
aout->volume_set = NULL;
aout->mute_set = NULL;
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/a40028950c3a7d017049d961345414925af00908...38022073f64ca9321766117d7a402e1e3f5ed8fa
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/a40028950c3a7d017049d961345414925af00908...38022073f64ca9321766117d7a402e1e3f5ed8fa
You're receiving this email because of your account on code.videolan.org. Manage all notifications: https://code.videolan.org/-/profile/notifications | Help: https://code.videolan.org/help
More information about the vlc-commits
mailing list