When seeking backward or jumping around in a video that has TrueHD audio track selected, audio can suddenly go silent - padding_remaining can evaluate to negative or exceed max_padding_per_packet. Previously, spdifenc clamped padding_remaining to 0 and requested a sample, leaving truehd_output_timing_valid intact and retaining the partially filled hd_buf_filled buffer.
This desynchronizes subsequent 61,440-byte IEC 61937 MAT burst boundaries, causing AV receivers to lose framing sync and mute audio until playback is restarted. Fix this by flushing any partial MAT burst buffer (hd_buf_filled = 0) and re-anchoring the timing counters to the incoming access unit upon encountering an un-bridgeable timeline discontinuity. To test this, play a video with TrueHD selected (preferably a lossless track to increase chance of a framing desync) and jump around the video. Big chapter jumps and little 5 second or 10 second jumps, forwards and backwards. There should be no loss of audio at any point. Signed-off-by: Max <[email protected]> --- v2: - Add missing Signed-off-by line. libavformat/spdifenc.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/libavformat/spdifenc.c b/libavformat/spdifenc.c index 0b8d8c5886..04f58ee557 100644 --- a/libavformat/spdifenc.c +++ b/libavformat/spdifenc.c @@ -632,15 +632,22 @@ static int spdif_header_truehd(AVFormatContext *s, AVPacket *pkt) padding_remaining = prev_padding + discontinuity_padding; if (padding_remaining < 0 || padding_remaining > max_padding_per_packet) { - avpriv_request_sample(s, - "Unusual TrueHD output_timing discontinuity: " - "expected %"PRIu16" got %"PRIu16", " - "timing delta %d => %d, prev padding %d, " - "discontinuity padding %d, " - "total padding %d ignored", - ctx->truehd_output_timing, au.output_timing, - previous_oi_delta, current_oi_delta, prev_padding, - discontinuity_padding, padding_remaining); + av_log(s, AV_LOG_DEBUG, + "TrueHD output_timing discontinuity: %d bytes (timing %u -> %u), resetting MAT burst\n", + padding_remaining, input_timing, au.output_timing); + + /* Un-bridgeable timeline discontinuity (e.g. seek). + * Flush any incomplete partial frame in the active MAT buffer + * so the new AU starts cleanly aligned to a fresh burst. */ + ctx->hd_buf_filled = 0; + + /* Reset timing state so the incoming access unit re-seeds the baseline */ + ctx->truehd_prev_size = 0; + ctx->truehd_prev_time = input_timing; + ctx->truehd_output_timing = au.output_timing; + ctx->truehd_oi_delta = current_oi_delta; + ctx->truehd_output_timing_valid = 1; + padding_remaining = 0; } else { av_log(s, AV_LOG_VERBOSE, -- 2.39.5 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
