aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/tests
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-node/tests')
-rw-r--r--packages/meshbay-node/tests/test_stream_seek_reports_the_keyframe.py51
1 files changed, 36 insertions, 15 deletions
diff --git a/packages/meshbay-node/tests/test_stream_seek_reports_the_keyframe.py b/packages/meshbay-node/tests/test_stream_seek_reports_the_keyframe.py
index acd2ebb..9aea2b4 100644
--- a/packages/meshbay-node/tests/test_stream_seek_reports_the_keyframe.py
+++ b/packages/meshbay-node/tests/test_stream_seek_reports_the_keyframe.py
@@ -9,16 +9,24 @@ further along than it did.
That was a wrong label while only the scrubber read it. It became a wrong
*answer* when subtitles arrived: their cues carry the source's own absolute
-timestamps, so the mismatch put every line on screen a GOP before it was
-spoken. Measured on a real H264 title, seeking to 600 s, 2650 s and 5000 s
-landed on keyframes 0.82 s, 1.56 s and 4.64 s earlier.
+timestamps, so the mismatch put every line on screen before it was spoken.
-**The assertion is on the decoded picture, not on the number.** A test that
-only compared `stream_init["start"]` against an expected keyframe would agree
-with the implementation by construction — both would be reading the same
-ffprobe. The first frame delivered is decoded and matched against the source
-frame at the position the node claims, which is a statement about what was
-served rather than about what was computed.
+**Where the seek lands is measured, not predicted, and that distinction is
+this module's subject.** The first attempt scanned ffprobe's key frames and
+took the last one at or before the request. It was wrong twice: Matroska's
+Cues index only some keyframes, so the seek backs off to an indexed one that
+can be much earlier, and the landing point moves with **which streams are
+mapped**, because the container is positioned where every mapped stream has
+data. On a real title, one seek answered 4909.863 s from the frame list and
+delivered 4907.236 s — 2.65 s of subtitles standing away from the voice, which
+is what a viewer reported after the first fix.
+
+**The assertion is therefore on the decoded picture, not on the number.** A
+test comparing `stream_init["start"]` against an expected keyframe would agree
+with the implementation by construction, both reading the same probe. The
+first frame delivered is decoded and matched against the source frame at the
+position the node claims, which is a statement about what was served rather
+than about what was computed.
"""
import shutil
@@ -33,7 +41,7 @@ from meshbay_common.webcrypto import chunk_key_aes, decrypt_chunk_aes
from meshbay_node.indexer.group_index import GroupIndex
from meshbay_node.transport.webrtc_server import (
WebRTCPeerSession,
- _keyframe_at_or_before,
+ _seek_lands_at,
)
from conftest import needs_subprocess, one_root
@@ -121,17 +129,30 @@ def _frame_md5(path: Path, at: float | None = None) -> str:
return hashlib.md5(proc.stdout).hexdigest()
+_MAPS = ["-map", "0:v:0", "-map", "0:a:0"]
+
+
@pytest.mark.asyncio
-async def test_the_lookup_finds_the_keyframe_the_seek_will_land_on(tmp_path):
+async def test_the_probe_measures_where_the_seek_lands(tmp_path):
+ """Measured with the mapping the stream will use, never predicted.
+
+ A scan of ffprobe's key frames answers a different question: Matroska
+ indexes only some keyframes, and the landing point also moves with which
+ audio track is mapped, because the container is positioned where every
+ mapped stream has data. On a real title those two answers were 4909.863
+ and 4907.236 — 2.65 s of subtitles standing away from the voice.
+ """
clip = tmp_path / "clip.mp4"
_make_h264_clip(clip)
- assert await _keyframe_at_or_before(clip, _SEEK_TO) == pytest.approx(
+ assert await _seek_lands_at(clip, _SEEK_TO, _MAPS) == pytest.approx(
_EXPECTED_KEYFRAME, abs=0.05)
# A position that *is* a keyframe answers itself, not the one before.
- assert await _keyframe_at_or_before(clip, 20.0) == pytest.approx(20.0, abs=0.05)
- # Before the first one there is nothing earlier to find.
- assert await _keyframe_at_or_before(clip, 0) == 0.0
+ assert await _seek_lands_at(clip, 20.0, _MAPS) == pytest.approx(20.0, abs=0.05)
+ # A seek never lands after what was asked for.
+ for t in (7.0, 15.0, 23.0):
+ landed = await _seek_lands_at(clip, t, _MAPS)
+ assert landed is not None and landed <= t + 0.05, (t, landed)
@pytest.mark.asyncio