fix(video): recover periodic rational H264 composition offsets (#409 follow-up) - #419
fix(video): recover periodic rational H264 composition offsets (#409 follow-up)#419orut34iop wants to merge 2 commits into
Conversation
|
The retest diagnosis is right, and it is what the fix is built on. Thank you for going back to the asset and coming back with the measurement instead of a symptom. Reproduced here before touching anything, on a purpose-built twin pair with the reported shape ( One line in this PR was worth more than the rest of the review put together:
My first cut derived the phase from the reorder delay. It reproduced both of my own fixtures bit-exactly, and it would have missed the reporting asset, because phase 2 is not The engine fix is #427, merged as Packet placement should not require the ladder to sit on the lattice. In this PR every packet is placed by reading its own timestamp back into an ordinal, so a packet more than a tolerated tick off the lattice, or ambiguously on it, is emitted with its raw timestamps. That is the defect returning in the middle of a file, on the axis a consumer is already reading. In #427 the lattice is consulted once per coded video sequence, at its IDR; the pictures inside it are placed by rank, and a sequence whose IDR cannot be read back onto the lattice falls back to the rounded step anchored on the container's own timestamp, which describes the stream to within a tick and cannot drift because it re-anchors at every IDR. Nothing is ever handed on in decode order because an arithmetic path did not close, and there is a test that says so. The same holds for the container index. This PR maps each index entry through the lattice and omits the entries it cannot place. The rationale in the comment is sound as far as it goes, but a keyframe silently leaving the segment plan changes where segments are cut, and nothing downstream can see that it happened. #427 keeps the index folded by the one constant the packets themselves move by, so an entry cannot disagree with the packet it points at, and none can go missing. Those two together are what removes the need for the ordinal bookkeeping, the resynchronisation rules and the full-stream drift proof, and the change comes to about 180 lines rather than 1327. That is the reason this PR is being closed rather than merged and hardened: the difference is architectural, not a list of findings. Two things from your work stay in the repo: the diagnosis above, and the fixtures from #411, which are still the regression test for the whole-tick half of this and now sit next to a fractional pair built the same way: 33 packets, three coded video sequences, both writer shapes, from the head and after a seek: every repaired packet carries the healthy twin's PTS and DTS exactly. |
Summary
Retesting the released #413 + #415 implementation on the original reporting asset still showed continuous judder from the first frame, without seeking. Its decode ladder is constant-rate but periodically quantized, so the current uniform-integer-step classifier fails closed and repairs no packets.
This follow-up recovers the exact rational cadence and sampling phase from the observed repeated DTS cycle while leaving ambiguous, malformed, aliased, and genuinely variable timing untouched.
Closes #409
What changed
avg_frame_rateas the stronger whole-stream corroboration andr_frame_rateonly as its fallback, so an exact nominal short-period alias cannot override contradictory average-rate evidence.AVStream.nb_framesspan and prove with exact integer arithmetic that the cadence error cannot accumulate beyond half a tick across the complete stream. Missing span, overflow, or excessive drift fails closed.The physical signature is
PTS == DTSfor 12/12 sampled packets,video_delay=1,time_base=1/1200000, and the repeating DTS-step cycle40040,40041,40040,40040,40041. The recovered cadence is200202/5; the nominal30000/1001coded rate rounds to an integer 40040-tick cadence, while the average rate corroborates the recovered cadence within the full-stream half-tick bound.Test plan
ctts/ SDR; audio was not involved in the defect.stream_frames=261363, classified the source asrepairing, and repaired all 12 sampled packets with 0 unrepaired. Direct playback remained smooth; scrubbing and release resumed playback and remained smooth; a separate unaffected video remained unchanged.DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer xcrun swift build --target AetherEnginepassed.PublicAPIDocumentationTests: 4/4 passed.No source URL, media identity, request headers, device identifier, or raw device log is included.
Checklist
CHANGELOG.mdupdated