Implement non-destructive box editing and enhance decoder documentation#7
Merged
Conversation
Supersedes the PR #5 splice-based prototype with an extent-tree design whose two correctness gaps (stale ancestor sizes, heuristic chunk-offset fixup) are impossible by construction. Design: - edit/tree.rs: the file parses into a tree where unmodified boxes are byte-range references into the source, not copies. Container prefix bytes (stsd entry_count, sample-entry fixed headers), padding, and original header forms (compact/largesize/to-EOF) are preserved. Serialization streams extents in chunks (mdat never held in memory) and recomputes box sizes bottom-up, so every ancestor of an edited box is correct by construction. Invariant: serializing an unedited tree reproduces the source byte for byte. - edit/fixup.rs: layout produces an exact old->new extent map; each stco/co64 entry is remapped through the extent containing it. No heuristics: unmoved data keeps its offsets, moved data shifts by exactly its extent's delta. Entries pointing at removed data are left unchanged and reported. - edit/fields.rs: Set patches named fields (mvhd/tkhd/mdhd timestamps, timescale, duration, rate, volume, track_id, layer, width/height, language) in place with version-aware offsets; matrices, reserved regions, and unknown bytes are untouched — no re-encoding. - edit/mod.rs + tags.rs: Editor with Remove/RemoveAll/Insert/Replace/ Set/SetTag commands; slash paths with [n] indexing and © fourccs; SetTag creates the moov/udta/meta/ilst chain (ffmpeg-compatible hdlr) when missing. Fragmented and HEIF files (moof/sidx/iloc) are refused with a clear error since their internal offsets are not yet covered by fixup; no-op pass-through still works. Packaging: "edit" cargo feature (on by default; disable for a parse-only build), mp4edit binary (--remove/--remove-all/--insert/ --replace/--set/--tag), and examples/edit.rs. Tests (tests/edit_roundtrip.rs): byte-identical zero-edit round-trips on synthetic and real files; removal before mdat shifts stco entries by exactly the removed size while removal after mdat leaves them untouched; samples still resolve to identical media bytes after every edit; ancestor sizes re-tile the file with no gaps; Set changes only the addressed bytes; tag create/replace; fragmented-file guard. Verified on a real file with ffprobe/ffmpeg: tags readable, all 2336 chunk offsets adjusted, zero decode errors.
The extension point already existed (get_boxes_with_registry + Registry::with_decoder) but was invisible enough that PR #3 was opened to add what was already there. No new functionality: - add a worked doc example on get_boxes_with_registry showing the intended pattern: extend the default registry with a custom decoder (default_registry().with_decoder(...)) rather than replace it - re-export default_registry at the crate root - add an integration test proving a custom decoder fires through get_boxes_with_registry alongside the built-in decoders Supersedes PR #3.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.