Files
Sylpheed/docs/re/data/ffmpeg-container-seek-trap.txt
sylph-decoder 72f0f7fcea re: reproduce the container-seek trap on this disc, and clear the Explorer of it
sylpheed-port asked whether my capture or extraction paths seek with -ss before -i.
Reproduced on this disc's own movies: a 4.0 s audio request returns 4.597 s (ADV)
and 4.256 s (S00A), with correlations of -0.03 and -0.34 at zero shift, so the
windows are different content rather than shifted. The 4.597 matches their 4.6.

But the VIDEO seek here is exact -- container-seek frame at 20.0 s is byte-identical
to the frame from a full decode with no seek. So the trap is a property of the audio
stream, not of -ss placement as such.

The Explorer has two -ss sites, both video, and its audio path (decode_audio_wav)
never seeks -- so it is not affected. Read only; the viewer is the human's tool and
was not modified.

My own instrument failed twice first: a vstats line read as a timestamp, then
showinfo reporting frames from before an output-side -ss discard. The pixel
comparison needed no interpretation and settled it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v
2026-08-30 23:36:42 +00:00

56 lines
3.1 KiB
Plaintext

# `-ss` BEFORE `-i` is a container seek -- reproduced on this disc, and checked
# against the Explorer. 2026-08-30.
#
# sylpheed-port hit this implementing AUDIO-VERIFICATION §1's transcode check: a
# 4.0 s request returned 4.6 s on a WMA Pro source, so their two comparison
# windows covered different stretches and no shift could align them. They flagged
# it because it is indistinguishable from the alignment trap that page already
# names, and asked whether my capture or extraction paths seek that way.
#
################################################################################
# ✅ REPRODUCED INDEPENDENTLY, on this disc's own movies. Request 4.0 s, ask for
# 4.0 s of audio, container seek (-ss before -i) versus decoder seek (-ss after):
#
# ADV BEFORE -i: 4.597 s AFTER -i: 4.000 s correlation at zero shift -0.0274
# S00A BEFORE -i: 4.256 s AFTER -i: 4.000 s correlation at zero shift -0.3366
#
# The 4.597 s matches the 4.6 s they measured. The near-zero and NEGATIVE
# correlations say the two windows are not the same audio offset by a shift --
# they are different content.
#
# ❌ BUT THE VIDEO SEEK ON THIS DISC IS EXACT. Container-seek frame at 20.0 s
# versus the frame taken by full decode with no seek at all:
# ADV 0.00 % of pixels differ, rmse 0.00
# S00A 0.00 % of pixels differ, rmse 0.00
# Byte-identical. So the trap is a property of the AUDIO stream here, not of
# `-ss` before `-i` as such.
#
################################################################################
# ✅ THE EXPLORER IS NOT AFFECTED -- checked, not assumed, and NOT modified.
# `crates/sylpheed-viewer` is the human's tool and off limits; this is a read.
#
# iso_loader.rs:2053 spawn_video_decoder -- `-ss` BEFORE `-i`, video
# iso_loader.rs:2131 grab_one_frame -- `-ss` BEFORE `-i`, video
# iso_loader.rs:2017 decode_audio_wav -- NO `-ss` at all, whole track
#
# Both seek sites are video, where the seek is exact on these files; the audio
# path never seeks. ⚠️ Worth noting anyway: spawn_video_decoder's comment says
# "output pts re-base to 0, so we add `start` back to each frame's timestamp",
# which ASSUMES the seek landed exactly. It does here. It would be silently wrong
# on a source where it did not, which is the shape of the trap rather than an
# instance of it.
#
# ⚠️ FOR ANYONE EXTRACTING MOVIE AUDIO FROM THIS DISC: put `-ss` AFTER `-i`.
# A window taken with a container seek is up to 0.6 s of different content, and
# nothing about the output says so.
#
################################################################################
# 🔴 AND MY OWN INSTRUMENT FAILED TWICE BEFORE THE ANSWER CAME OUT.
# attempt 1: read a "timestamp" that was ffmpeg's -vstats output, not a pts;
# attempt 2: `showinfo` with an output-side `-ss`, which reports frames from
# BEFORE the discard, so the column read 0 for every case.
# Both produced confident-looking tables. What worked was dropping timestamp
# semantics entirely and comparing PIXELS, which needs no interpretation.
# ⚠️ When two attempts at a measurement disagree with each other, the third
# should change the KIND of quantity measured, not the parsing.