11 releases (4 breaking)
0.5.1 | Oct 31, 2023 |
---|---|
0.5.0 | Oct 22, 2023 |
0.4.0 | Oct 17, 2023 |
0.3.1 | May 16, 2023 |
0.1.2 | Mar 21, 2023 |
#58 in Video
4,733 downloads per month
135KB
3K
SLoC
mp4san
A Rust MP4 format "sanitizer".
Currently the sanitizer is capable of:
- Returning all presentation metadata present in the input as a self-contained contiguous byte array.
- Finding and returning a pointer to the span in the input containing the (contiguous) media data.
"Presentation" metadata means any metadata which is required by an MP4 player to play the file. "Self-contained and contiguous" means that the returned metadata can be concatenated with the media data to form a valid MP4 file.
Unsupported MP4 features
The sanitizer does not currently support:
- "Fragmented" MP4 files, which are mostly used for adaptive-bitrate streaming.
- Discontiguous media data, i.e. media data (
mdat
) boxes interspersed with presentation metadata (moov
). - Media data references (
dref
) pointing to separate files. - Any similar format, e.g. Quicktime File Format (
mov
) or the legacy MP4 version 1, which does not contain theisom
compatible brand in its file type header (ftyp
).
Usage
The main entry points to the sanitizer are sanitize
/sanitize_async
, which take a Read
+ Skip
input. The
Skip
trait represents a subset of the Seek
trait; an input stream which can be skipped forward, but not
necessarily seeked to arbitrary positions.
use mp4san_test::{example_ftyp, example_mdat, example_moov};
let example_input = [example_ftyp(), example_mdat(), example_moov()].concat();
let sanitized = mp4san::sanitize(std::io::Cursor::new(example_input)).unwrap();
assert_eq!(sanitized.metadata, Some([example_ftyp(), example_moov()].concat()));
assert_eq!(sanitized.data.offset, example_ftyp().len() as u64);
assert_eq!(sanitized.data.len, example_mdat().len() as u64);
The parse
module also contains a less stable and undocumented API which can be used to parse individual MP4 box
types.
API Documentation
Private Documentation
Contributing Bug Reports
GitHub is the project's bug tracker. Please search for similar existing issues before submitting a new one.
Testing
FFMpeg and GPAC-based verification of mp4san output can be enabled using the features mp4san-test/ffmpeg
and
mp4san-test/gpac
.
The mp4san-test/ffmpeg
feature requires the following FFMpeg libraries and their headers to be installed:
libavcodec
libavformat
libavutil
libswresample
libswscale
The mp4san-test/gpac
feature requires libgpac >= 2.2
and its headers to be installed.
The test_data
integration test runs on sample data files in the private
test-data
submodule. If you have access to this repo, you may check out the submodule manually:
$ git submodule update --init --checkout
Integration tests on sample data files can be processed through mp4san-test-gen
before being added to the
mp4san-test-data
repo. This removes any actual media data from the sample file, since it's not read by mp4san
anyway, leaving only metadata for testing purposes. This allows even very large media files to be gzipped to very small
sizes.
$ cargo run --bin mp4san-test-gen -- test-sample.mp4 test-data/test-sample.mp4.gz
Fuzz Testing
Fuzz testing via both cargo afl
and cargo fuzz
is supported. See the Rust Fuzz Book for more details. To run AFL-based fuzzing:
$ cargo install cargo-afl
$ cd fuzz-afl
$ ./fuzz $num_cpus
To run libFuzzer-based fuzzing:
$ cargo +nightly install cargo-fuzz
$ cargo +nightly fuzz run sanitize -- -dict=fuzz/mp4.dict -seed_inputs=fuzz/input/ffmpeg-black-1f.mp4,fuzz/input/ffmpeg-smptebars-30f.mp4
OSS-Fuzz
Continuous fuzz testing is also provided by OSS-Fuzz.
Build Status
Code Coverage
Bugs Found
License
Licensed under MIT.
Dependencies
~3.5MB
~75K SLoC