wai identify: what any file is, from its bytes alone #589
463 changed files with 31782 additions and 11 deletions
30
.github/workflows/wai-conformance.yml
vendored
30
.github/workflows/wai-conformance.yml
vendored
|
|
@ -316,6 +316,9 @@ on:
|
|||
# format-probes' tables; and the registry's wire identifiers test reads projection.md,
|
||||
# loc-carriage.md and delivery-telemetry.md (whose §6.6 cmsd_read_verify.py reads).
|
||||
- 'wai/extensions/format-probes.md'
|
||||
# tests/identify.rs requires media-identify §6 and §7 to list the reference's signatures,
|
||||
# and identify_verify.py reads those tables and the capabilities of its §5.1.
|
||||
- 'wai/extensions/media-identify.md'
|
||||
- 'wai/extensions/projection.md'
|
||||
- 'wai/extensions/loc-carriage.md'
|
||||
- 'wai/extensions/delivery-telemetry.md'
|
||||
|
|
@ -589,7 +592,7 @@ jobs:
|
|||
working-directory: wai/wai-rs
|
||||
run: |
|
||||
set -euo pipefail
|
||||
for f in neural_int video_int audio_int splat_int staged stage_measure telemetry http format_probe; do
|
||||
for f in neural_int video_int audio_int splat_int staged stage_measure telemetry http format_probe identify; do
|
||||
cargo check --lib --no-default-features --features "$f"
|
||||
done
|
||||
# The decode bench prints its machine line from bench_env; no other step builds it.
|
||||
|
|
@ -606,6 +609,8 @@ jobs:
|
|||
cargo build --lib --target wasm32-unknown-unknown --no-default-features --features telemetry
|
||||
# And the header probes: a browser reads a payload's parameters the same way.
|
||||
cargo build --lib --target wasm32-unknown-unknown --no-default-features --features format_probe
|
||||
# And identification: a browser says what a dropped file is the same way.
|
||||
cargo build --lib --target wasm32-unknown-unknown --no-default-features --features identify
|
||||
# carriage: every registered capability round-trips byte-exact. cli_wrap_intent and
|
||||
# cli_registry run the `wai` binary, which builds without the codecs feature: the
|
||||
# intent rule of `wai wrap`, its refusal of candidate capabilities (SPEC §5), its media
|
||||
|
|
@ -1182,7 +1187,7 @@ jobs:
|
|||
# No debuginfo, for the reason given at cargo-classes: this job ran out of the VM's disk
|
||||
# mid-link beside two others (#550).
|
||||
CARGO_PROFILE_DEV_DEBUG: '0'
|
||||
WAI_FEATURES: key_discovery,http,video_manifest,stage_measure,live_events,live_room,capture_take,live_compose,live_record,timed_text,access_services,live_metering,energy_steering,live_moderation,dred_exact,live_ads,live_provenance,synthesis,synthesis_mark,neural_int,exact_upscale,robustness,ai_usage,contribution,settlement,browser_sink,receipt_claims,takedown,influence,direction,co_performance,age_assurance,bearer_receipts,exploration,co_watch,telemetry_aggregate,exact_tonemap,splat_exact,live_watermark,derive_edge,sink_energy,key_release,stitched_presentation,prior_wire,scene_map,avatar_face,receipt_ledger,stream_audit,fleet,native_sink,platform_encode,remote_desktop,stream_termination,live_world,format_probe,live_messaging,conform_result,revenue_share,opportunity_report,channel_lineup,route_record
|
||||
WAI_FEATURES: key_discovery,http,video_manifest,stage_measure,live_events,live_room,capture_take,live_compose,live_record,timed_text,access_services,live_metering,energy_steering,live_moderation,dred_exact,live_ads,live_provenance,synthesis,synthesis_mark,neural_int,exact_upscale,robustness,ai_usage,contribution,settlement,browser_sink,receipt_claims,takedown,influence,direction,co_performance,age_assurance,bearer_receipts,exploration,co_watch,telemetry_aggregate,exact_tonemap,splat_exact,live_watermark,derive_edge,sink_energy,key_release,stitched_presentation,prior_wire,scene_map,avatar_face,receipt_ledger,stream_audit,fleet,native_sink,platform_encode,remote_desktop,stream_termination,live_world,format_probe,identify,live_messaging,conform_result,revenue_share,opportunity_report,channel_lineup,route_record
|
||||
WAI_PQ_FEATURES: synthesis,pq_signatures
|
||||
WAI_RELEASE_FEATURES: dred_exact,synthesis_mark,robustness,avatar_face
|
||||
steps:
|
||||
|
|
@ -1252,12 +1257,12 @@ jobs:
|
|||
--bin wai_http_vectors --bin wai_stage_measure --bin wai_browser_sink_vectors \
|
||||
--bin wai_claim_vectors --bin wai_jwp_vectors --bin wai_signer_vectors \
|
||||
--bin wai_sink_energy_vectors --bin wai_stitched_presentation \
|
||||
--bin wai_stream_termination_vectors --bin wai_format_probe --bin wai_conform_result_vectors \
|
||||
--bin wai_stream_termination_vectors --bin wai_format_probe --bin wai_identify_vectors --bin wai_conform_result_vectors \
|
||||
--bin wai_channel_lineup_vectors
|
||||
for b in wai_http_vectors wai_stage_measure wai_browser_sink_vectors \
|
||||
wai_claim_vectors wai_jwp_vectors wai_signer_vectors \
|
||||
wai_sink_energy_vectors wai_stitched_presentation \
|
||||
wai_stream_termination_vectors wai_format_probe wai_conform_result_vectors \
|
||||
wai_stream_termination_vectors wai_format_probe wai_identify_vectors wai_conform_result_vectors \
|
||||
wai_channel_lineup_vectors; do
|
||||
cp "${CARGO_TARGET_DIR:-target}/debug/$b" "$RUNNER_TEMP/wai-bins/union/"
|
||||
done
|
||||
|
|
@ -1278,7 +1283,7 @@ jobs:
|
|||
--test derive_edge --test det_cost_bin --test sink_energy --test key_release \
|
||||
--test stitched_presentation --test prior_wire --test scene_map --test receipt_ledger \
|
||||
--test stream_audit --test fleet --test native_sink --test platform_encode --test remote_desktop \
|
||||
--test stream_termination --test live_world --test format_probe --test live_messaging \
|
||||
--test stream_termination --test live_world --test format_probe --test identify --test live_messaging \
|
||||
--test conform_result --test revenue_share --test opportunity_report --test channel_lineup --test route_record
|
||||
cargo test --release --no-run --no-default-features --features "$WAI_RELEASE_FEATURES" \
|
||||
--test dred_exact --test dred_exact_measure --test synthesis_mark --test robustness \
|
||||
|
|
@ -2729,6 +2734,21 @@ jobs:
|
|||
bash format-probe-conformance/fetch.sh "$fetched"
|
||||
(cd wai-rs && "$RUNNER_TEMP/wai-bins/union/wai_format_probe" verify ../format-probe-conformance --fetched "$fetched")
|
||||
python3 -I format-probe-conformance/format_probe_verify.py format-probe-conformance --fetched "$fetched"
|
||||
# Media identification (extensions/media-identify.md): wai-rs's unit tests (hostile bytes
|
||||
# through every walk, what a file reads as its bytes) and tests/identify.rs (the corpus
|
||||
# regenerates byte for byte with every result; the extension's tables; `wai identify`); then
|
||||
# identify_verify.py, written from the text and sharing no code with wai-rs but
|
||||
# format_probe_verify.py's probes, which gives every file its whole result, holds ext/ to
|
||||
# what an independent prober read of it, and requires every mutated copy to fail.
|
||||
- name: media identification · wai-rs and identify_verify.py
|
||||
working-directory: wai
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --lib identify::)
|
||||
(cd wai-rs && cargo test --no-default-features --features "$WAI_FEATURES" --test identify)
|
||||
(cd wai-rs && "$RUNNER_TEMP/wai-bins/union/wai_identify_vectors" verify ../identify-conformance)
|
||||
python3 -I identify-conformance/identify_verify.py identify-conformance
|
||||
# CMSD reading (extensions/delivery-telemetry.md §6.6): the second implementation, written
|
||||
# from that text and RFC 9651 with its own field parser, reads every field of
|
||||
# telemetry-conformance/cmsd-read/ and every field expected/cmsd.json states, and requires
|
||||
|
|
|
|||
|
|
@ -6,6 +6,21 @@ wire format may change and such changes are recorded here.
|
|||
|
||||
## Unreleased
|
||||
|
||||
### What any file is, from its bytes alone
|
||||
|
||||
- **`wai identify <file>`** (operation `media.inspect`, [extensions/media-identify.md](extensions/media-identify.md)): the
|
||||
formats a file's bytes fit, each with the offsets that say so and how far its structure was followed; a container's
|
||||
tracks with their codec, size and protection as it states them; the registered capabilities they map to; signatures
|
||||
found inside it; and, where no format is recognised, measures that still hold: how its values are spread and the lags at
|
||||
which it repeats. `verdict` is `identified`, `ambiguous`, `signature_only` or `unknown`, and there is no confidence
|
||||
figure: a candidate's strength says what was checked. Nothing is decoded and no protected track is opened. It reads ISO
|
||||
media, Matroska, transport streams, Ogg, FLAC, RIFF, MPEG audio, ADTS, PNG, JPEG, GIF, IVF, YUV4MPEG2, FLV, AV1 OBU and
|
||||
Annex B streams and HLS and DASH text, and knows many more by signature. Any size of file costs a bounded amount, and
|
||||
every walk has been given hostile bytes. It is in the agent door as `media_inspect`, its results marked
|
||||
`untrusted_content`, because a file's author chooses the strings in it.
|
||||
- The corpus [`identify-conformance/`](identify-conformance/) holds files from real muxers and encoders, with what an
|
||||
independent prober reads of them, and negative controls; `identify_verify.py` is a second implementation.
|
||||
|
||||
### A probe no longer panics on two adjacent start codes
|
||||
|
||||
- `wai.video.avs3` and `wai.audio.avs3`: a payload with a start code prefix directly after another (`00 00 01 00 00 01`)
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ operation of the toolchain, named by it with `_` for the dot, and the tools come
|
|||
|
||||
| Toolset | Tools |
|
||||
|---|---|
|
||||
| `core` (the default) | `envelope_inspect`, `registry_list`, `registry_show`, `receipt_verify`, `envelope_wrap`, `conformance_list`, `conformance_run`, `docs_search` |
|
||||
| `core` (the default) | `envelope_inspect`, `media_inspect`, `registry_list`, `registry_show`, `receipt_verify`, `envelope_wrap`, `conformance_list`, `conformance_run`, `docs_search` |
|
||||
| `dev` | `dev_start`, `dev_stop`, `room_grant`, `room_join`, `room_leave`, `session_show` |
|
||||
| `app` (a build with the feature `app`) | `app_guide`, `app_check`, `app_stream`, `app_export`: Create's, below |
|
||||
|
||||
|
|
|
|||
|
|
@ -2203,7 +2203,9 @@ above).
|
|||
`wai.video.avs3` and `wai.audio.avs3` (and for `wai.image.jxs`, `wai.video.jxs`,
|
||||
`wai.image.ieee1857_11` and `wai.meta.projection`): it identifies a payload as the format its
|
||||
capability names and reads the parameters its headers state, or refuses it with a code. A
|
||||
probe decodes no sample, so it does not change any class above.
|
||||
probe decodes no sample, so it does not change any class above. Where the capability is not known,
|
||||
[media-identify](extensions/media-identify.md) says what a file is from its bytes alone, with the
|
||||
offsets that say so, and runs these probes among its readings.
|
||||
|
||||
**One Opus packet.** A `wai.audio.opus.packet` payload is one Opus packet (RFC
|
||||
6716 §3), its TOC byte first, with no container: the per-packet form streaming
|
||||
|
|
|
|||
|
|
@ -1000,6 +1000,74 @@
|
|||
"sdk": "wai.media.generate"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "media.inspect",
|
||||
"summary": "What a file is, from its bytes alone: the formats they fit with the bytes that say so, its tracks, its protection, and measures where no format is recognised",
|
||||
"cli": "wai identify",
|
||||
"aliases": [],
|
||||
"usage": [
|
||||
"wai identify <file> [--json] any file, not only an envelope (extensions/media-identify.md); unknown stays unknown"
|
||||
],
|
||||
"placement": "local",
|
||||
"effect": "reads",
|
||||
"dry_run": false,
|
||||
"confirm": "never",
|
||||
"route": null,
|
||||
"doors": {
|
||||
"cli": true,
|
||||
"mcp": true,
|
||||
"http": false
|
||||
},
|
||||
"toolset": "core",
|
||||
"stability": "stable",
|
||||
"input": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": "string",
|
||||
"format": "path",
|
||||
"description": "Any file.",
|
||||
"x-cli": {
|
||||
"positional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"path"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"output": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"format",
|
||||
"size",
|
||||
"verdict",
|
||||
"candidates",
|
||||
"probes_accepted",
|
||||
"embedded",
|
||||
"embedded_capped",
|
||||
"measures"
|
||||
],
|
||||
"description": "The formats the bytes fit, each with the bytes that say so and how far they were followed; what a probe accepted; signatures found inside; and measures that hold whatever the bytes are"
|
||||
},
|
||||
"stream": null,
|
||||
"since": "0.3.0",
|
||||
"deprecated": null,
|
||||
"receipt": false,
|
||||
"needs": {
|
||||
"all": [
|
||||
"identify"
|
||||
]
|
||||
},
|
||||
"names": {
|
||||
"cli": "wai media inspect",
|
||||
"mcp": "media_inspect",
|
||||
"c": "wai_media_inspect",
|
||||
"rust": "wai::media::inspect",
|
||||
"sdk": "wai.media.inspect"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "media.upscale",
|
||||
"summary": "Upscale a PNG exactly, by an integer network under a pinned prior, with a signed record a verifier recomputes",
|
||||
|
|
|
|||
689
wai/extensions/media-identify.md
Normal file
689
wai/extensions/media-identify.md
Normal file
|
|
@ -0,0 +1,689 @@
|
|||
# WAI Extension: Media Identification
|
||||
|
||||
> Status: Draft. What a file is, from its bytes alone: the formats they fit, each with the bytes
|
||||
> that say so and how far they were followed; what a registered probe reads of it; signatures
|
||||
> found inside it; and measures that hold when no format is recognised. It decodes nothing, and
|
||||
> what it does not establish it leaves out. The reference implementation is the `identify` module
|
||||
> of `wai-rs` (feature `identify`), which `wai identify` runs (operation `media.inspect`); the
|
||||
> corpus is [`identify-conformance/`](../identify-conformance/), and its second implementation is
|
||||
> `identify-conformance/identify_verify.py`.
|
||||
> Keywords **MUST**, **MUST NOT**, **SHOULD**, **MAY** are RFC 2119/8174.
|
||||
|
||||
## 1. Scope
|
||||
|
||||
§1.1 `wai inspect` reads what an envelope holds. Most files a toolchain meets are not envelopes,
|
||||
and the first question about one is what it is. Identification answers that for any file, and
|
||||
it is the first step of working out how a piece of media was made.
|
||||
|
||||
§1.2 A result states only what the bytes establish. A claim comes with the offsets of the bytes
|
||||
that make it, and a walk says where it stopped and why. A format is never guessed from a file
|
||||
name, and no confidence figure is given: a result has a strength (§4), which says what was
|
||||
checked. Where the bytes fit no format, the verdict is `unknown` and the measures (§8) are what
|
||||
is known.
|
||||
|
||||
§1.3 What a container states is not what its samples hold. A track row (§5.1) reports what the file
|
||||
says of a track, and no sample is read to confirm it. No payload is decrypted, and a protected track
|
||||
is reported as protected and no further.
|
||||
|
||||
§1.4 This extension adds no capability and changes no dispatch (SPEC §4). A capability in a result
|
||||
is the registered capability whose payload a format or track is: it says what `wai wrap` would
|
||||
carry it under, not that a decoder here accepts it.
|
||||
|
||||
## 2. The result
|
||||
|
||||
§2.1 A result is a JSON object:
|
||||
|
||||
| member | value |
|
||||
|---|---|
|
||||
| `format` | `wai.identify/1` |
|
||||
| `size` | the file's length in bytes |
|
||||
| `verdict` | `identified`, `ambiguous`, `signature_only` or `unknown` (§4.2) |
|
||||
| `candidates` | the formats the bytes fit, in the order of §4.3 |
|
||||
| `probes_accepted` | the capabilities whose probe accepted the bytes (§3.5) |
|
||||
| `embedded` | signatures found inside the file (§7), each `{at, id}` |
|
||||
| `embedded_capped` | whether more were found than `embedded` holds |
|
||||
| `measures` | §8 |
|
||||
|
||||
§2.2 A candidate is a JSON object:
|
||||
|
||||
| member | value |
|
||||
|---|---|
|
||||
| `id` | the format, as §5 and §6 name it, or the capability a probe alone accepted (§3.5) |
|
||||
| `kind` | `wai`, `container`, `audio`, `image`, `elementary`, `playlist`, `text`, `compression` or `capture` |
|
||||
| `strength` | `signature`, `structure` or `parameters` (§4.1) |
|
||||
| `evidence` | the first 8 bytes-that-say-so, each `{at, len, is}`: `len` bytes at offset `at`, which read as `is` |
|
||||
| `walked_to` | the offset a walk of the file's structures reached, or `null` where the format has no such walk |
|
||||
| `stopped` | `null`, or `{at, why}`: where a walk stopped before the file's end (§3.3) |
|
||||
| `facts` | what the format's headers state, by the section that defines it |
|
||||
| `tracks` | §5.1 |
|
||||
| `capabilities` | the capabilities it maps to (§1.4), sorted |
|
||||
|
||||
## 3. Common rules
|
||||
|
||||
§3.1 Integers are read as each section says. `u8`, `be16`, `be24`, `be32` and `be64` are big-endian,
|
||||
`le16` and `le32` little-endian. All arithmetic of a result is integer arithmetic, but for the
|
||||
sample
|
||||
rate of §5.4; two implementations give the same result for the same bytes on any machine.
|
||||
|
||||
§3.2 **What is read.** The **head** is the first 1 MiB of the file (1,048,576 bytes), or all of it
|
||||
if
|
||||
shorter. The walks of §5.5, §5.9, §5.10, §5.13, §5.17, §5.18, §5.19 and §5.20, the table of §6 and
|
||||
the
|
||||
probes read the head alone. The other walks read the file where their lengths lead. The **scan** is
|
||||
the first 16 MiB of the file (16,777,216 bytes), or all of it if shorter: §7 and §8 read it.
|
||||
|
||||
§3.3 **Walks.** A walk reads a format's structures in order and is bounded: at most 4,096 structures
|
||||
(§5.6: 256), and 64 tracks. A walk that stops before the file's end says why, in `stopped`:
|
||||
|
||||
| `why` | meaning |
|
||||
|---|---|
|
||||
| `overrun` | a structure declares, or needs, more than the file holds |
|
||||
| `invalid` | a structure's bytes are not what the format allows there |
|
||||
| `crc` | a checksum the format defines does not hold |
|
||||
| `limit` | the walk reached a bound of this extension, or the end of the head where it reads no further |
|
||||
| `unknown_size` | a structure of unknown size, whose end only reading it would find (§5.4) |
|
||||
|
||||
`walked_to` and a stop's `at` are never past the end of the file: an offset past it is taken as the
|
||||
file's length. A walk that reads the head alone and reaches its end while the file goes on has
|
||||
stopped
|
||||
there, `limit`.
|
||||
|
||||
§3.4 **Strings.** A string read from the file enters a result only through this filter: its first
|
||||
64 bytes, each of 0x20 to 0x7E but `\` as itself, and any other byte as `\xNN` in lowercase
|
||||
hexadecimal.
|
||||
A file is untrusted input: a reader **MUST** treat these strings as data, and a tool that gives a
|
||||
result to an agent **MUST** mark it as holding them.
|
||||
|
||||
§3.5 **Probes.** The probes of the table of [format-probes](format-probes.md) §2 that can name a
|
||||
format from the bytes (`wai.image.jxs`, `wai.video.jxs`, `wai.video.hevc`, `wai.video.mvhevc`,
|
||||
`wai.video.vvc`, `wai.video.lcevc`, `wai.audio.mpegh`, `wai.video.avs3`, `wai.audio.avs3`, in that
|
||||
order) each read the head. The other two read a payload declared to be theirs, have no signature,
|
||||
and say nothing of a file they are merely given, so they are not run. For each probe, in order:
|
||||
|
||||
- Where it accepts, the capability joins `probes_accepted`. The first candidate of kind `elementary`
|
||||
that maps to that capability (or, for `wai.video.mvhevc`, to `wai.video.hevc`) has its strength
|
||||
raised
|
||||
to `parameters`, the capability added to its `capabilities`, and the probe's result set in its
|
||||
`facts.probe` under the capability. With no such candidate, a candidate of kind `elementary` is
|
||||
added
|
||||
whose `id` is the capability, of strength `parameters`, with evidence `{at: 0, len: <head's
|
||||
length>,
|
||||
is: "probe"}`, that capability and the same `facts.probe`.
|
||||
- Where it refuses with `no_signature`, nothing is recorded.
|
||||
- Where it refuses otherwise, and a candidate of kind `elementary` already maps to that capability,
|
||||
its
|
||||
`facts.probe_refused` holds the code under the capability.
|
||||
|
||||
## 4. Strength and verdict
|
||||
|
||||
§4.1 **Strength** says how far a candidate's bytes were followed:
|
||||
|
||||
- `signature`: a format's fixed bytes are where the format puts them. Nothing else was checked, and
|
||||
short ones occur by chance: `evidence` shows how many bytes it was.
|
||||
- `structure`: what follows the signature is what the format's section requires of it.
|
||||
- `parameters`: a probe of format-probes read the format's headers and accepted them.
|
||||
|
||||
§4.2 **The verdict** comes from the candidates at the highest strength present: `unknown` if there
|
||||
are
|
||||
no candidates; `ambiguous` if more than one; `signature_only` if one, of strength `signature`; else
|
||||
`identified`. Two formats that both fit are both reported, and no ranking between them is invented.
|
||||
|
||||
§4.3 **Order.** Candidates are in order of strength, strongest first. Within a strength they keep
|
||||
the
|
||||
order of the sections that define them: §5.2 to §5.20, then §6's table in its order, then those a
|
||||
probe alone added, in the order of §3.5.
|
||||
|
||||
## 5. Walks
|
||||
|
||||
§5.1 **Tracks.** A row of `tracks` holds `track` (the identifier the container gives, or `null`),
|
||||
`media` (`video`, `audio`, `text` or `other`), `stated` (what the container calls it, through §3.4),
|
||||
`codec` (the name of the table below, or `null` where this extension has no name for it), and
|
||||
`width`,
|
||||
`height`, `channels`, `sample_rate` and `protected`, each `null` where not stated. `protected`, on a
|
||||
track the container says is protected, is `{scheme, original}`, each `null` where not stated.
|
||||
|
||||
A row's codec adds to its candidate's `capabilities` the capability of this table, where it has one:
|
||||
|
||||
| codec | capability |
|
||||
|---|---|
|
||||
| `avc` | `wai.video.avc` |
|
||||
| `hevc` | `wai.video.hevc` |
|
||||
| `vvc` | `wai.video.vvc` |
|
||||
| `av1` | `wai.video.av1` |
|
||||
| `vp8` | `wai.video.vp8` |
|
||||
| `vp9` | `wai.video.vp9` |
|
||||
| `evc` | `wai.video.evc` |
|
||||
| `lcevc` | `wai.video.lcevc` |
|
||||
| `jpeg-xs` | `wai.video.jxs` |
|
||||
| `jpeg2000` | `wai.video.j2k` |
|
||||
| `aac` | `wai.audio.aac` |
|
||||
| `opus` | `wai.audio.opus` |
|
||||
| `flac` | `wai.audio.flac` |
|
||||
| `ac4` | `wai.audio.ac4` |
|
||||
| `mpegh` | `wai.audio.mpegh` |
|
||||
| `iamf` | `wai.audio.iamf` |
|
||||
|
||||
The names `mp3`, `vorbis`, `theora`, `speex`, `ac3`, `eac3`, `webvtt` and `ttml` map to none.
|
||||
|
||||
§5.2 **WAI envelopes** (`wai`, kind `wai`). The head begins `WAI1` or `WAI2`: evidence `magic:WAI1`
|
||||
or
|
||||
`magic:WAI2`, 4 bytes at 0, and `facts.version`. `le32` at 4 is the manifest's length. If it is
|
||||
absent
|
||||
the walk stops at 0 (`overrun`). If it exceeds 1 MiB the walk stops at 8 (`limit`); if the file
|
||||
holds
|
||||
less the walk stops at 8 (`overrun`); if the manifest is not JSON, at 8 (`invalid`). Evidence
|
||||
`manifest`. For `WAI1`: `facts.capability` is `model_requirement.capability`, and `le32` after the
|
||||
manifest is the payload's length, with evidence `payload_length`; where it or the payload does not
|
||||
fit
|
||||
the walk stops there (`overrun`) with `walked_to` there too, else `walked_to` is past the payload.
|
||||
For
|
||||
`WAI2`: `le16` after the manifest is `facts.renditions`, evidence `rendition_count`, and `walked_to`
|
||||
is
|
||||
past it. A walk that reaches this is `structure`. `wai inspect` reads the rest.
|
||||
|
||||
§5.3 **ISO base media** (`isobmff`, kind `container`). The four bytes at 4 are one of `ftyp`,
|
||||
`styp`,
|
||||
`moov`, `mdat`, `moof`, `free`, `skip`, `wide`, `sidx` or `pnot`. Boxes are walked from 0 to the end
|
||||
of
|
||||
the file. A box: `be32` size and four bytes of type. Every type byte is 0x20 to 0x7E or 0xA9, else
|
||||
`invalid`. Size 0 runs to the end of the file; size 1 means `be64` at 8 is the size, which must be
|
||||
at
|
||||
least 16; any other size below 8 is `invalid`. Fewer bytes than a header needs is `overrun`. Each
|
||||
box whose header
|
||||
reads gives evidence `box:<type>`, 4 bytes at its offset plus 4, and its type joins `facts.boxes`
|
||||
(distinct, first 16); a box that does not end within the file stops the walk there (`overrun`).
|
||||
`moof`
|
||||
boxes are counted in `facts.fragments`, present when there are any.
|
||||
|
||||
`ftyp` that fits: fewer than 8 content bytes is `invalid`; else `facts.major_brand` is its first
|
||||
four,
|
||||
and `facts.compatible_brands` the first 16 of the four-byte brands from its ninth. A major or
|
||||
compatible brand `avif` or `avis` (among its first 4096 bytes) adds `wai.image.avif`.
|
||||
|
||||
`moov` that fits and is at most 64 MiB is read for `trak` boxes (above that, `facts.moov_not_read`
|
||||
is
|
||||
`true`). Inside a box, children are read as the top level is, stopping at the first that does not
|
||||
fit.
|
||||
A track needs `mdia`, and in it `hdlr` (the handler type is at content offset 8) and
|
||||
`minf`/`stbl`/`stsd`
|
||||
with a first entry (the entries start at content offset 8), else it has no row. `track` is from
|
||||
`tkhd`:
|
||||
`be32` at content offset 12 if its first byte is 0, else at 20. `media` from the handler: `vide`,
|
||||
`auxv`,
|
||||
`pict` is `video`; `soun` is `audio`; `text`, `subt`, `sbtl`, `clcp` is `text`; else `other`.
|
||||
`stated` is the
|
||||
entry's type. For `video`: `width` `be16` at entry content 24, `height` at 26, child boxes from 78.
|
||||
For
|
||||
`audio`: `channels` `be16` at 16, `sample_rate` `be32` at 24 shifted right 16, and, where `be16` at
|
||||
8 is
|
||||
0, child boxes from 28.
|
||||
|
||||
An entry of type `encv`, `enca`, `enct` or `encs` is protected: `protected.scheme` is from
|
||||
`sinf`/`schm`
|
||||
(content bytes 4 to 8) and `protected.original` from `sinf`/`frma` (its first four), and the codec
|
||||
is
|
||||
named from `original` where it is present. `mp4a` is named from its `esds`: `aac` for object type
|
||||
0x40,
|
||||
0x66, 0x67 or 0x68, `mp3` for 0x69 or 0x6B, else `null`. The object type is reached as MPEG-4
|
||||
Systems
|
||||
lays it out: after four version bytes, tag 3 and its size (one to four bytes of 7 bits, high bit set
|
||||
on
|
||||
all but the last); two bytes of identifier and one of flags, then 2 bytes if flag 0x80, a length
|
||||
byte
|
||||
and that many if 0x40, and 2 bytes if 0x20; tag 4 and its size; the next byte. Other entry types:
|
||||
|
||||
| entry | codec | entry | codec |
|
||||
|---|---|---|---|
|
||||
| `avc1` `avc2` `avc3` `avc4` `dvav` `dva1` | `avc` | `hvc1` `hev1` `dvh1` `dvhe` | `hevc` |
|
||||
| `vvc1` `vvi1` | `vvc` | `av01` `dav1` | `av1` |
|
||||
| `vp08` | `vp8` | `vp09` | `vp9` |
|
||||
| `evc1` | `evc` | `lvc1` | `lcevc` |
|
||||
| `jxsm` | `jpeg-xs` | `mjp2` | `jpeg2000` |
|
||||
| `Opus` | `opus` | `fLaC` | `flac` |
|
||||
| `ac-3` | `ac3` | `ec-3` | `eac3` |
|
||||
| `ac-4` | `ac4` | `mhm1` `mhm2` `mha1` `mha2` | `mpegh` |
|
||||
| `iamf` | `iamf` | `wvtt` | `webvtt` |
|
||||
| `stpp` | `ttml` | | |
|
||||
|
||||
`structure`: at least two box headers read.
|
||||
|
||||
§5.4 **Matroska and WebM** (`matroska`, kind `container`). The head begins `1A 45 DF A3`: evidence
|
||||
`ebml`, 4 bytes at 0. An element is an identifier of 1 to 4 bytes (its length in the leading zeros
|
||||
of
|
||||
its first byte, the marker kept) and a size of 1 to 8 bytes (the same, the marker removed; all ones
|
||||
is unknown). The header must read in the head, with a known size: else the walk stops at 0
|
||||
(`invalid` for an
|
||||
element that does not parse, `overrun` for one that does not fit). `facts.doc_type` is its 0x4282,
|
||||
through
|
||||
§3.4, and `facts.doc_type_version` its 0x4287. The next element must be the Segment, 0x18538067:
|
||||
evidence
|
||||
`segment`; else the walk stops there, `overrun` if fewer than 5 bytes remain and `invalid`
|
||||
otherwise. A
|
||||
Segment with a known size that passes the file's end sets `facts.segment_overruns_by`, and the walk
|
||||
ends at
|
||||
the file's end.
|
||||
|
||||
Its children are walked to its end. A child that does not parse stops the walk (`overrun` if fewer
|
||||
than 12
|
||||
bytes remain, else `invalid`); an unknown size, `unknown_size`; a child that passes the file's end,
|
||||
`overrun`.
|
||||
Clusters (0x1F43B675) are counted in `facts.clusters`, present when there are any, one that passes
|
||||
the file's
|
||||
end included. Tracks (0x1654AE6B) of at most 1 MiB gives evidence `tracks` and a row for each 0xAE:
|
||||
`track` 0xD7;
|
||||
`media` from 0x83: 1 `video`, 2 `audio`, 17 `text`, else `other`; `stated` and `codec` from 0x86;
|
||||
`width` and
|
||||
`height` 0xB0 and 0xBA in 0xE0; `channels` 0x9F and `sample_rate` 0xB5 in 0xE1, an IEEE float of 4
|
||||
or 8 bytes
|
||||
taken toward zero; `protected` where 0x6D80 holds 0x6240 holding 0x5035. Unsigned values are
|
||||
big-endian, of 1 to
|
||||
8 bytes. The codec is `aac` for an identifier beginning `A_AAC`, else:
|
||||
|
||||
| identifier | codec | identifier | codec |
|
||||
|---|---|---|---|
|
||||
| `V_MPEG4/ISO/AVC` | `avc` | `V_MPEGH/ISO/HEVC` | `hevc` |
|
||||
| `V_MPEGI/ISO/VVC` | `vvc` | `V_AV1` | `av1` |
|
||||
| `V_VP8` | `vp8` | `V_VP9` | `vp9` |
|
||||
| `A_OPUS` | `opus` | `A_FLAC` | `flac` |
|
||||
| `A_VORBIS` | `vorbis` | `A_AC3` | `ac3` |
|
||||
| `A_EAC3` | `eac3` | `A_MPEG/L3` | `mp3` |
|
||||
| `S_TEXT/WEBVTT` | `webvtt` | | |
|
||||
|
||||
`structure`: at least one child read.
|
||||
|
||||
§5.5 **MPEG transport streams** (`mpeg-ts`, kind `container`). For each layout in order, packet size
|
||||
and sync
|
||||
offset (188, 0), (192, 4), (204, 0), and for each start from 0 below the packet size: 0x47 at the
|
||||
sync offset of
|
||||
five packets from there. The first that holds is the layout: evidence `sync`, 1 byte at its first
|
||||
sync,
|
||||
`facts.packet_size`. Packets are read while 188 bytes from a sync offset lie in the head. A packet
|
||||
whose sync byte
|
||||
is not 0x47 stops the walk (`invalid`), at the offset of that byte. PID is 13 bits from byte 1;
|
||||
`facts.scrambled_packets`
|
||||
counts those whose byte 3 has either of its top two bits set. With an adaptation field (byte 3 bit
|
||||
0x20), the payload
|
||||
is past its length byte and its length. With a payload (bit 0x10), PID 0 and each PID the program
|
||||
table names are
|
||||
gathered: a packet with the start bit (byte 1 bit 0x40) begins a section after its pointer field,
|
||||
and a section's
|
||||
length is 3 plus the 12 bits from its second byte. A section is used only if at least 12 bytes long
|
||||
and its MPEG-2
|
||||
checksum (polynomial 0x04C11DB7, from all ones, not reflected, over the section and its checksum) is
|
||||
0.
|
||||
|
||||
The first section of table 0 on PID 0 is the program table: evidence `pat`, each entry of 4 bytes
|
||||
from offset 8 to 4 from
|
||||
its end (the first 64), with program number from the first two bytes and PID from the next 13 bits,
|
||||
program 0 not being
|
||||
counted. `facts.programs` is the number of programs. The first section of table 2 on each such PID:
|
||||
evidence `pmt`.
|
||||
Program information of the 12 bits from offset 10 starts at 12; streams follow, each a type byte, 13
|
||||
bits of PID at the
|
||||
next two bytes and 12 bits of descriptor length at the next two, then that many bytes of
|
||||
descriptors. A row for each,
|
||||
after the last packet: `track` the PID, `stated` `stream_type:0x<two lowercase hexadecimal digits>`,
|
||||
`protected` where a
|
||||
descriptor with tag 9 is among the program's or the stream's (then `{scheme: null, original:
|
||||
null}`). Codec and media:
|
||||
|
||||
| type | codec | media | type | codec | media |
|
||||
|---|---|---|---|---|---|
|
||||
| 0x1B | `avc` | video | 0x24 | `hevc` | video |
|
||||
| 0x33 | `vvc` | video | 0x0F 0x11 | `aac` | audio |
|
||||
| 0x03 0x04 | `mp3` | audio | 0x81 | `ac3` | audio |
|
||||
| 0x87 | `eac3` | audio | 0x01 0x02 0x10 | `null` | video |
|
||||
|
||||
Any other type has codec `null` and media `other`. `facts.packets_read` counts the packets. If no
|
||||
sync byte stopped it,
|
||||
and the walk's end is before the file's: `limit` if the head is shorter than the file, else
|
||||
`overrun`. Always `structure`.
|
||||
|
||||
§5.6 **Ogg** (`ogg`, kind `container`). The head begins `OggS` and a zero byte. Pages from 0: a
|
||||
27-byte header beginning the
|
||||
same, a table of as many bytes as its byte 26, and a body of as many bytes as that table sums to. A
|
||||
page that does not fit is
|
||||
`overrun`; a header that does not begin so, `invalid`; a checksum (`le32` at 22) that does not hold
|
||||
over the page with its checksum
|
||||
bytes zero, under the polynomial 0x04C11DB7 from zero, not reflected, `crc`. At most 256 pages. Each
|
||||
gives evidence `page`, 1 page
|
||||
long, at its offset. Byte 5 bit 0x02 starts a stream: a row with `track` `le32` at 14, read from the
|
||||
body: `OpusHead` (`stated`
|
||||
`OpusHead`, `opus`, audio, `channels` byte 9, `sample_rate` `le32` at 12); `\x01vorbis` (`stated`
|
||||
`vorbis`, `vorbis`, audio, `channels` byte
|
||||
11, `sample_rate` `le32` at 12); `\x7fFLAC` (`stated` `FLAC`, `flac`, audio); `\x80theora` (`stated`
|
||||
`theora`, `theora`, video);
|
||||
`Speex` and three spaces (`stated` `Speex`, `speex`, audio); else `stated` is its first 8 bytes,
|
||||
media `other`. `facts.pages_read`.
|
||||
`structure`: two pages, or one that ends at the file's end.
|
||||
|
||||
§5.7 **ID3 and FLAC** (`flac`, kind `audio`). An **ID3v2 tag** at 0, for this and §5.9: `ID3`, ten
|
||||
header bytes, bytes 3 and 4 not 0xFF,
|
||||
and bytes 6 to 9 each below 0x80. Its length is 10 plus those four as 7 bits each, plus 10 where
|
||||
byte 5 has bit 0x10. A head that begins
|
||||
`ID3` with a header that is not one means neither walk applies. `fLaC` at 0, or after the tag:
|
||||
evidence `fLaC`, and `wai.audio.flac`.
|
||||
Blocks follow: a byte (bit 0x80: last; low 7 bits: type), then `be24` length. The first must be type
|
||||
0 of length 34, else `invalid`:
|
||||
evidence `streaminfo`, 34 bytes at its body, and `facts.sample_rate` (20 bits from body byte 10),
|
||||
`facts.channels` (3 bits, plus 1),
|
||||
`facts.bits_per_sample` (5 bits, plus 1) and `facts.samples` (36 bits). A block past the file's end
|
||||
is `overrun`. After the last block, 2 bytes
|
||||
0xFF and 0xF8 or 0xF9 are a frame's sync: evidence `frame_sync`, and `structure`. Other bytes there
|
||||
stop the walk (`invalid`), and no bytes
|
||||
(`overrun`). `walked_to` is the offset after the last block read.
|
||||
|
||||
§5.8 **RIFF** (kind per form). The head begins `RIFF`, with at least 12 bytes. The form at 8: `WAVE`
|
||||
is `wave`, audio; `AVI ` is `avi`, container;
|
||||
`WEBP` is `webp`, image; any other is `riff`, container. Evidence `form:<form>`, 4 bytes at 8, and
|
||||
`facts.form`. The declared end is `le32` at 4 plus 8,
|
||||
in `facts.declared_size` where it is not the file's size; the walk ends at the lesser of it and the
|
||||
file's size. Chunks from 12: four bytes of
|
||||
type and `le32` length, padded to an even length. A header past the end stops the walk (`overrun`)
|
||||
unless the walk is exactly at the end or beyond it;
|
||||
each header read gives evidence `chunk:<type>`, and its type joins `facts.chunks` (distinct, first
|
||||
16). A chunk's content past the end stops the walk there
|
||||
(`overrun`).
|
||||
|
||||
For `wave`: `fmt ` gives, from at most its first 64 bytes, `facts.format_tag` `le16` at 0 (where
|
||||
that is 0xFFFE, `le16` at 24 instead),
|
||||
`facts.channels` `le16` at 2, `facts.sample_rate` `le32` at 4 and `facts.bits_per_sample` `le16` at
|
||||
14, each `null` where absent; `data` gives `facts.data_bytes`.
|
||||
For `webp`: `VP8 ` with bytes 3 to 5 `9D 01 2A` gives `facts.coding` `lossy`, `facts.width` and
|
||||
`facts.height` from `le16` at 6 and 8 in their low 14 bits;
|
||||
`VP8L` with first byte 0x2F and 5 bytes gives `lossless`, and, in `le32` at 1, `width` its low 14
|
||||
bits plus 1 and `height` the next 14 plus 1; `VP8X` with 10 bytes gives
|
||||
`extended`, and `width` and `height` the 24-bit little-endian values at 4 and 7, each plus 1.
|
||||
`walked_to` is the walk's end, at most the end above. `structure`: one chunk read.
|
||||
|
||||
§5.9 **MPEG audio** (`mpeg-audio`, kind `audio`). From 0 or after an ID3v2 tag (§5.7). A frame:
|
||||
0xFF; 3 high bits of the next byte set; version 2 bits (0: 2.5, 2: 2,
|
||||
3: 1), layer 2 bits (1: III, 2: II, 3: I), the bitrate index in byte 2's high 4 bits (not 0 or 15),
|
||||
rate index in the next 2 (not 3), padding the next bit; byte 3's high 2 bits are
|
||||
the channel mode. The version value 1 and layer value 0 are not a frame. Rate is 44100, 48000 or
|
||||
32000 by index, halved for version 2 and quartered for 2.5. The bitrate in kbit/s, by
|
||||
index from 1:
|
||||
|
||||
| | indexes 1 to 14 |
|
||||
|---|---|
|
||||
| version 1, layer I | 32 64 96 128 160 192 224 256 288 320 352 384 416 448 |
|
||||
| version 1, layer II | 32 48 56 64 80 96 112 128 160 192 224 256 320 384 |
|
||||
| version 1, layer III | 32 40 48 56 64 80 96 112 128 160 192 224 256 320 |
|
||||
| version 2 or 2.5, layer I | 32 48 56 64 80 96 112 128 144 160 176 192 224 256 |
|
||||
| version 2 or 2.5, layers II and III | 8 16 24 32 40 48 56 64 80 96 112 128 144 160 |
|
||||
|
||||
Frame length: layer I, (12000 × kbit/s ÷ rate + padding) × 4; layer III of version 2 or 2.5, 72000 ×
|
||||
kbit/s ÷ rate + padding; otherwise 144000 × kbit/s ÷ rate + padding; division
|
||||
is integer division. Nothing is a candidate unless the first bytes are a frame and at least one
|
||||
whole frame is walked. Evidence `id3v2`, 3 bytes at 0, where a tag is there; `frame_header`, 4 bytes
|
||||
at the first
|
||||
frame. `facts.version` (`1`, `2` or `2.5`), `facts.layer`, `facts.bitrate_kbps`, `facts.sample_rate`
|
||||
and `facts.channels` (1 for channel mode 3, else 2), of the first frame. Frames walk through the
|
||||
head. A frame must
|
||||
keep the first's version, layer and rate, else the walk stops there (`overrun` if fewer than 4 bytes
|
||||
remain, else `invalid`). Exactly 128 bytes left beginning `TAG`: evidence `id3v1`, 3 bytes, and the
|
||||
walk ends after them. A frame past the
|
||||
file's end is `overrun`, past the head's alone `limit`. `facts.frames_read`. `structure`: three
|
||||
frames.
|
||||
|
||||
§5.10 **ADTS** (`adts`, kind `audio`). A frame: 0xFF; byte 1 with `byte & 0xF6 == 0xF0`; byte 2's
|
||||
high 2 bits plus 1 the audio object type, its next 4 the rate index (below 13: 96000, 88200, 64000,
|
||||
48000, 44100, 32000, 24000, 22050,
|
||||
16000, 12000, 11025, 8000, 7350), and channel configuration from its low bit and byte 3's high 2;
|
||||
frame length 13 bits from byte 3's low 2, at least 7. Nothing is a candidate unless the head begins
|
||||
with a frame and at least one whole
|
||||
frame is walked. Evidence `frame_header`, 7 bytes at 0, `wai.audio.aac`, and
|
||||
`facts.audio_object_type`, `facts.sample_rate`, `facts.channel_configuration` of the first. Frames
|
||||
walk as §5.9's do, keeping type and rate (`overrun` under 7 bytes), and with
|
||||
the same limits. `facts.frames_read`. `structure`: three frames.
|
||||
|
||||
§5.11 **PNG** (`png`, kind `image`). The head begins `89 50 4E 47 0D 0A 1A 0A`: evidence
|
||||
`signature`, and `wai.image.png`. Chunks from 8: `be32` length, four ASCII letters of type (else
|
||||
`invalid`), data, 4-byte checksum. The first must be `IHDR` of length 13, else
|
||||
`invalid`; its checksum (polynomial 0xEDB88320 reflected, from all ones, inverted at the end; over
|
||||
type and data) must hold, else `crc`. Then evidence `ihdr`, 25 bytes, `facts.width`, `facts.height`,
|
||||
`facts.bit_depth`, `facts.colour_type`, `facts.interlace`, and `structure`.
|
||||
`acTL` sets `facts.animated`; `cICP` with 4 bytes readable sets `facts.cicp` to them as a list. A
|
||||
chunk past the file's end, or the end of the file before `IEND`, is `overrun`. `IEND` gives evidence
|
||||
`iend`, 12 bytes at its offset, and the walk ends after it. `facts.chunks_read`.
|
||||
Only `IHDR`'s checksum is computed.
|
||||
|
||||
§5.12 **JPEG** (`jpeg`, kind `image`). The head begins `FF D8 FF`: evidence `soi`, 2 bytes at 0, and
|
||||
`wai.image.jpeg`. Markers from 2: 0xFF and a code, a code of 0xFF being a fill byte that advances
|
||||
one. Fewer than 2 bytes is `overrun`; a first byte not 0xFF is `invalid`. A code of 0xDA gives
|
||||
evidence `sos`, 2 bytes, and ends the walk there. Others: `be16` length, at least 2 (else
|
||||
`invalid`), `overrun` if it does not read or the segment passes the file's end. 0xE0 to 0xEF name an
|
||||
application segment from its first 32 bytes: `JFIF\0` `jfif`, `Exif\0\0` `exif`, `ICC_PROFILE\0`
|
||||
`icc`, `MPF\0` `mpf`,
|
||||
the XMP namespace (`http://ns.adobe.com/xap/1.0/\0`) `xmp`, `Adobe` `adobe`, else `other`; <!-- allow-name: the APP14 segment's identifier and the XMP namespace, byte signatures a JPEG carries -->
|
||||
`facts.applications` holds them, distinct, first 8. Codes 0xC0 to 0xC3, 0xC5 to 0xC7, 0xC9 to 0xCB
|
||||
and 0xCD to 0xCF are a frame header, needing 6 bytes (else `overrun`): evidence `sof`, the segment's
|
||||
bytes, `facts.process` (0xC0
|
||||
`baseline`, 0xC1 `extended`, 0xC2 `progressive`, 0xC3 `lossless`, 0xC9 to 0xCB `arithmetic`, else
|
||||
`hierarchical`), `facts.precision`, `facts.height`, `facts.width`, `facts.components`, and
|
||||
`structure`.
|
||||
|
||||
§5.13 **GIF** (`gif`, kind `image`). The head begins `GIF87a` or `GIF89a`: evidence
|
||||
`signature:<it>`, 6 bytes. Fewer than 13 bytes stops the walk at 6. `facts.width` and `facts.height`
|
||||
from `le16` at 6 and 8; a global table of 3 × 2^(n+1) bytes follows byte 10 flag 0x80 (n its low 3
|
||||
bits). Blocks from there: 0x3B the
|
||||
trailer (evidence `trailer`, 1 byte, and the walk ends after it); 0x21 an extension, sub-blocks from
|
||||
2 on; 0x2C an image, 10 bytes (a local table likewise from its byte 9), one more byte, then
|
||||
sub-blocks, evidence `image`, 10 bytes, for the first; any other byte is `invalid`. Sub-blocks: a
|
||||
count byte and that many, ending after a count
|
||||
of 0. Bytes not in the head stop the walk: `limit` where the head is shorter than the file, else
|
||||
`overrun`. `facts.frames_read`. `structure`: one image, or the trailer.
|
||||
|
||||
§5.14 **IVF** (`ivf`, kind `container`). The head begins `DKIF`: evidence `dkif`, 4 bytes. Under 12
|
||||
bytes stops at 0 (`overrun`); a version (`le16` at 4) not 0 or a header length (`le16` at 6) under
|
||||
32 stops at 0 (`invalid`). A row: media `video`, `stated` the four bytes at 8, codec `av1` for
|
||||
`AV01`, `vp9` for `VP90`, `vp8` for
|
||||
`VP80`, `width` and `height` `le16` at 12 and 14. Frames from the header length: `le32` size, 8
|
||||
bytes of time, then that many. `overrun` where one does not fit. `facts.frames_read`. `structure`:
|
||||
one frame.
|
||||
|
||||
§5.15 **YUV4MPEG2** (`y4m`, kind `elementary`). The head begins `YUV4MPEG2 `: evidence `signature`,
|
||||
10 bytes. A line feed must end the header within 256 bytes: else stop at 0 (`overrun` if the file
|
||||
ends sooner, else `invalid`). Space-separated tokens: `W` width, `H` height, `C` colour (default
|
||||
`420`), `F` frame rate; `facts.width`, `facts.height`, `facts.colour`
|
||||
and `facts.frame_rate`. A colour is a base, and optionally `p` and a decimal depth, 2 bytes a sample
|
||||
above 8. Bases: `420`, `420jpeg`, `420mpeg2`, `420paldv` (w·h + 2·⌈w/2⌉·⌈h/2⌉ samples a frame);
|
||||
`422` (w·h + 2·⌈w/2⌉·h); `444` (3·w·h); `mono` (w·h). Any other stops the walk (`invalid`), as do
|
||||
absent dimensions. Frames: a line beginning `FRAME`, within 256 bytes, then a frame's bytes.
|
||||
`facts.frames_read`.
|
||||
`structure`: one frame.
|
||||
|
||||
§5.16 **FLV** (`flv`, kind `container`). The head begins `FLV` and 0x01: evidence `signature`, 4
|
||||
bytes. `be32` at 5, the data offset, must be at least 9, else stop at 0 (`overrun` under 9 bytes,
|
||||
else `invalid`). Tags from that offset plus 4: 11 header bytes (type in byte 0's low 5 bits, one of
|
||||
8, 9 or 18, else `invalid`; `be24` length at 1), then the body, then a `be32` that must be 11 plus
|
||||
the length (else `invalid`; absent, `overrun`).
|
||||
The first audio tag (type 8, with a body) gives a row: media `audio`, `stated` `sound_format:<n>`
|
||||
for its first body byte's high 4 bits, codec `mp3` for 2 and `aac` for 10. The first video tag (type
|
||||
9, with a body) gives a row: where its first body byte has bit 0x80, `stated` is the next four
|
||||
bytes, with codec `avc` for `avc1`, `hevc` for `hvc1`, `av1` for `av01`, `vp9` for `vp09`; otherwise
|
||||
`stated` is `codec_id:<n>` for that byte's low 4 bits, with `avc` for 7. The video row comes first.
|
||||
`facts.tags_read`. `structure`: one tag.
|
||||
|
||||
§5.17 **AV1 OBU streams** (`av1-obu`, kind `elementary`). An OBU: a header byte with bits 0x81 clear
|
||||
and 0x02 set; type its bits 3 to 6, one of 1 to 8 or 15; an extension byte where bit 0x04 is set; a
|
||||
LEB128 size of at most 8 bytes; that many bytes. The first must be type 1 or 2. They are walked
|
||||
through the head. A header that does not parse stops the walk at it (`limit` if the head is shorter
|
||||
than the file and fewer than 8 bytes remain, else `invalid`); one past the file's end, `overrun`;
|
||||
one past the head's alone, `limit`. The first type 1 gives evidence `sequence_header`, and is read
|
||||
as AV1 §5.5: `facts.profile`, `facts.level` (the first operating point's `seq_level_idx`),
|
||||
`facts.width` and `facts.height` (`max_frame_width_minus_1` and `max_frame_height_minus_1`, plus 1).
|
||||
`facts.units_read`, and `wai.video.av1`. A candidate only if a sequence header reads and at least
|
||||
two OBUs were walked, and then `structure`: two bytes that merely fit are no claim of AV1.
|
||||
|
||||
§5.18 **HLS** (`hls`, kind `playlist`). After an optional UTF-8 byte order mark, `#EXTM3U` and a
|
||||
line end or the end of the head: evidence `extm3u`, 7 bytes at it. Lines (ended by a line feed, less
|
||||
a final carriage return) are read: any beginning `#EXT-X-` is a tag; `#EXT-X-STREAM-INF:` counts
|
||||
`facts.variants`, and the first with `CODECS="` gives `facts.codecs`; `#EXTINF:` counts
|
||||
`facts.segments`; `#EXT-X-MAP:` counts `facts.maps`; `#EXT-X-ENDLIST` sets `facts.ended`;
|
||||
`#EXT-X-VERSION:` gives `facts.version` where it is a decimal integer; and the first `#EXT-X-KEY:`
|
||||
or `#EXT-X-SESSION-KEY:` whose `METHOD=` (to the next comma) is not `NONE` gives `facts.key_method`.
|
||||
`facts.playlist` is `multivariant` with variants, else `media` with segments, else `other`. Every
|
||||
one of these facts is present; `structure`: at least one tag.
|
||||
|
||||
§5.19 **DASH** (`dash`, kind `playlist`). After an optional byte order mark and any white space,
|
||||
`<?...?>` and `<!--...-->`, then `<MPD` and white space or `>`: evidence `mpd`, 4 bytes at it.
|
||||
`urn:mpeg:dash:schema:mpd:2011` anywhere in the head gives evidence `namespace` and `structure`.
|
||||
`facts.type` is the value of ` type="` in the root tag up to its first `>`. `facts.periods`,
|
||||
`facts.adaptation_sets`, `facts.representations` and `facts.content_protection` count `<Period`,
|
||||
`<AdaptationSet`, `<Representation` and `<ContentProtection`; `facts.codecs` holds the distinct
|
||||
values of `codecs="`, the first 16. It is no XML parser: these are substrings.
|
||||
|
||||
§5.20 **Annex B streams** (kind `elementary`). The head holds at least two zero bytes, then 0x01,
|
||||
and nothing before them. Units are split as format-probes §2 (its Annex B byte streams) does, the
|
||||
first 4,096 (trailing zero bytes removed). If the byte after the first prefix is 0xBA or 0xB3, §6
|
||||
has the format, and no reading applies. Each reading below needs every unit's header to hold and its
|
||||
parameter sets in order, each before the first coded picture of that reading; a stream two readings
|
||||
fit is reported as both, and no reading is preferred. A reading is `structure`, with
|
||||
`facts.units_read`. Where the head is shorter than the file, or 4,096 units were read, it stops at
|
||||
the last unit (`limit`). `walked_to` is `null`.
|
||||
|
||||
- `avc-annexb`: one header byte, bit 0x80 clear, type its low 5 bits and 1 to 21; types 5, 7 and 8
|
||||
have nonzero bits 0x60. Order 7, 8; coded pictures are types 1 to 5. Its first type 7 is read as
|
||||
ITU-T H.264 §7.3.2.1.1, with emulation prevention removed: a `profile_idc` other than 66, 77, 88,
|
||||
100, 110, 122, 244, 44, 83, 86, 118, 128, 138, 139, 134 or 135 or a failed reading rules the
|
||||
reading out. Evidence `nal:sps`; facts `profile_idc`, `constraint_flags`, `level_idc`,
|
||||
`chroma_format_idc`, `width` and `height` less cropping; `wai.video.avc`.
|
||||
- `hevc-annexb`: two header bytes, bit 0x80 of the first clear, the low 3 bits of the second not
|
||||
zero, type the first's bits 1 to 6 and one of 0 to 9, 16 to 21 or 32 to 40. Order 32, 33, 34;
|
||||
coded pictures are types 0 to 9 and 16 to 21. Evidence `nal:sps`; `wai.video.hevc`.
|
||||
- `vvc-annexb`: two header bytes, bits 0xC0 of the first clear, the low 3 bits of the second not
|
||||
zero, type the second's high 5 bits and at most 25. Order 15, 16; coded pictures are types 0 to
|
||||
10. Evidence `nal:sps`; `wai.video.vvc`.
|
||||
|
||||
## 6. Formats known by their signature
|
||||
|
||||
§6.1 A format of this table is a candidate where every one of its fixed bytes is at its offset in
|
||||
the head: `strength` `signature`, evidence `signature` for each, and the capabilities it names.
|
||||
Bytes are in hexadecimal, each group at the offset before its colon. A format with two rows is
|
||||
either.
|
||||
|
||||
| id | kind | bytes | capability |
|
||||
|---|---|---|---|
|
||||
| `aiff` | audio | `0:464f524d 8:41494646` | |
|
||||
| `aiff` | audio | `0:464f524d 8:41494643` | |
|
||||
| `caf` | audio | `0:636166660001` | |
|
||||
| `wavpack` | audio | `0:7776706b` | |
|
||||
| `amr` | audio | `0:2321414d520a` | |
|
||||
| `amr-wb` | audio | `0:2321414d522d57420a` | |
|
||||
| `jpegxl` | image | `0:ff0a` | `wai.image.jxl` |
|
||||
| `jpegxl` | image | `0:0000000c4a584c200d0a870a` | `wai.image.jxl` |
|
||||
| `jp2` | image | `0:0000000c6a5020200d0a870a` | `wai.image.jp2` |
|
||||
| `j2k` | image | `0:ff4fff51` | `wai.image.jp2` |
|
||||
| `tiff` | image | `0:49492a00` | |
|
||||
| `tiff` | image | `0:4d4d002a` | |
|
||||
| `bigtiff` | image | `0:49492b00` | |
|
||||
| `bigtiff` | image | `0:4d4d002b` | |
|
||||
| `openexr` | image | `0:762f3101` | |
|
||||
| `dpx` | image | `0:53445058` | |
|
||||
| `dpx` | image | `0:58504453` | |
|
||||
| `radiance` | image | `0:233f52414449414e43450a` | |
|
||||
| `radiance` | image | `0:233f524742450a` | |
|
||||
| `mxf` | container | `0:060e2b34020501010d0102` | |
|
||||
| `asf` | container | `0:3026b2758e66cf11a6d900aa0062ce6c` | |
|
||||
| `mpeg-ps` | container | `0:000001ba` | |
|
||||
| `mpeg-video` | elementary | `0:000001b3` | |
|
||||
| `webvtt` | text | `0:574542565454` | |
|
||||
| `gzip` | compression | `0:1f8b08` | |
|
||||
| `zstd` | compression | `0:28b52ffd` | |
|
||||
| `xz` | compression | `0:fd377a585a00` | |
|
||||
| `bzip2` | compression | `0:425a68` | |
|
||||
| `zip` | compression | `0:504b0304` | |
|
||||
| `tar` | compression | `257:7573746172` | |
|
||||
| `pcap` | capture | `0:d4c3b2a1` | |
|
||||
| `pcap` | capture | `0:a1b2c3d4` | |
|
||||
| `pcap` | capture | `0:4d3cb2a1` | |
|
||||
| `pcap` | capture | `0:a1b23c4d` | |
|
||||
| `pcapng` | capture | `0:0a0d0d0a` | |
|
||||
|
||||
## 7. Signatures inside a file
|
||||
|
||||
§7.1 A reverse engineer's first question about a blob is what it holds. The scan is searched for
|
||||
each of these fixed bytes, none shorter than 8 bytes, so that one in 16 MiB of noise is improbable;
|
||||
each hit past the file's beginning gives `{at, id}`, `at` being where its structure begins, `back`
|
||||
bytes before them. A hit whose structure would begin at or before the file's beginning is not
|
||||
reported. Hits are in the order their bytes are found, and within one offset in this table's order.
|
||||
At most 32 are reported, and `embedded_capped` says whether another was found. A hit says only that
|
||||
the bytes are there.
|
||||
|
||||
| id | bytes | back |
|
||||
|---|---|---|
|
||||
| `png` | `89504e470d0a1a0a` | 0 |
|
||||
| `jp2` | `0000000c6a5020200d0a870a` | 0 |
|
||||
| `jpegxl` | `0000000c4a584c200d0a870a` | 0 |
|
||||
| `mxf` | `060e2b34020501010d0102` | 0 |
|
||||
| `asf` | `3026b2758e66cf11a6d900aa0062ce6c` | 0 |
|
||||
| `ogg` | `4f67675300020000000000000000` | 0 |
|
||||
| `flac` | `664c614300000022` | 0 |
|
||||
| `flac` | `664c614380000022` | 0 |
|
||||
| `isobmff` | `6674797069736f6d` | 4 |
|
||||
| `isobmff` | `6674797069736f32` | 4 |
|
||||
| `isobmff` | `6674797069736f35` | 4 |
|
||||
| `isobmff` | `6674797069736f36` | 4 |
|
||||
| `isobmff` | `667479706d703431` | 4 |
|
||||
| `isobmff` | `667479706d703432` | 4 |
|
||||
| `isobmff` | `667479704d344120` | 4 |
|
||||
| `isobmff` | `667479704d345620` | 4 |
|
||||
| `isobmff` | `6674797071742020` | 4 |
|
||||
| `isobmff` | `6674797061766966` | 4 |
|
||||
| `isobmff` | `6674797068656963` | 4 |
|
||||
| `isobmff` | `66747970636d6663` | 4 |
|
||||
| `isobmff` | `6674797064617368` | 4 |
|
||||
| `isobmff` | `667479706d736468` | 4 |
|
||||
|
||||
## 8. Measures
|
||||
|
||||
§8.1 `measures` holds, over the scan: `scanned`, its length; `distinct_bytes`, how many of the 256
|
||||
values occur; `zero_bytes`, how many are zero; `chi_square`, the floor of `256 · Σc² / n` less `n`,
|
||||
where `c` are the counts of the values and `n` the length, and 0 for an empty scan; `text` (§8.2);
|
||||
`windows` and `uniform_windows` (§8.3); and `periods` (§8.4).
|
||||
|
||||
§8.2 `text` is true where the scan is not empty, is valid UTF-8 (a sequence the scan's end cuts
|
||||
short allowed), and holds no byte below 0x20 but 0x09, 0x0A, 0x0C and 0x0D, and no 0x7F.
|
||||
|
||||
§8.3 A **window** is each whole 4096 bytes of the scan from its start. One is **uniform** when the
|
||||
sum of its counts squared is at most 70,496: its chi-square against a uniform spread is then at most
|
||||
310, about the 99th percentile for 255 degrees of freedom. A compressed payload and an encrypted one
|
||||
both tend to be uniform; this measure cannot tell them apart, and says only that the bytes show no
|
||||
structure in their values.
|
||||
|
||||
§8.4 **Repeats.** Over the first 256 KiB of the scan (`n` bytes), for each lag `l` from 1 to `L +
|
||||
1`, where `L` is the lesser of 4096 and `⌊n/4⌋`: `m = n − l`; `matches` counts the `i` below `m`
|
||||
with byte `i` equal to byte `i + l`; `expected` is the floor of `m · Σc² / n²`, at least 1, over
|
||||
this sample's counts; the excess `e` is `matches − expected`; and `z` is, where `e` is positive, the
|
||||
floor of the square root of the floor of `e² / expected`, otherwise 0. With `L` below 2 there are no
|
||||
periods.
|
||||
|
||||
The floor is 8 times the median of `|e|` over those lags, the element at index `⌊k/2⌋` of the `k` of
|
||||
them sorted: data that repeats exactly is not independent from lag to lag, and its noise is many
|
||||
times what `z` assumes. A lag from 2 to `L`, in increasing order, is reported as `{lag, z}` where
|
||||
all of these hold, at most 8: `z` is at least 8; `e` is at least the floor; `e` exceeds twice the
|
||||
greatest of its neighbours' excess and 0; if `2l ≤ L + 1`, `z` at `2l` is at least 8; and it is no
|
||||
multiple of a lag already reported. A repeat is a record size, a sample width or a table's stride,
|
||||
found with no knowledge of the format.
|
||||
|
||||
## 9. Security
|
||||
|
||||
§9.1 Identification reads files nobody vouches for. A conforming implementation **MUST NOT** panic,
|
||||
read outside the file, allocate more than the file's bounded windows and a bounded number of
|
||||
structures, or follow a URI in a playlist. The bounds of §3 are what make the cost of a hostile file
|
||||
bounded.
|
||||
|
||||
§9.2 A result can hold strings a file's author chose (§3.4). The operation's agent door marks its
|
||||
results `untrusted_content`.
|
||||
|
||||
§9.3 An implementation **MUST NOT** decrypt, or try to recover the keys of, a protected track. It
|
||||
reports the scheme the file states and stops.
|
||||
|
||||
## 10. Conformance
|
||||
|
||||
§10.1 The corpus [`identify-conformance/`](../identify-conformance/) holds files written by real
|
||||
muxers and encoders from synthetic inputs (`ext/`), generated cases and negative controls (`gen/`),
|
||||
and `vectors.json`, each file's digest and whole result. `prober.json` is what an independent media
|
||||
prober reads of `ext/`, the reference checked against it wherever both state a value. A conforming
|
||||
implementation gives each file its result exactly.
|
||||
21
wai/identify-conformance/README.md
Normal file
21
wai/identify-conformance/README.md
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
# identify-conformance — media identification
|
||||
|
||||
The corpus of [`extensions/media-identify.md`](../extensions/media-identify.md) §10.
|
||||
|
||||
**Feature equivalence.** A conforming implementation, given a vector's file, gives the whole result
|
||||
`vectors.json` states for it: every candidate with its evidence, where its walk stopped and why, its
|
||||
facts, tracks and capabilities; what was embedded; and the measures. A vector with `repeat` is its
|
||||
file that many times over, for what happens past the head and past the scan (§3.2).
|
||||
|
||||
- `ext/` — files written by real muxers and encoders, from test patterns and sine waves. The
|
||||
protected file uses an all-zero test key.
|
||||
- `gen/` — what `wai_identify_vectors gen` writes: generated cases and negative controls, each saying
|
||||
in `vectors.json` what it tests, many of them a change to a file of `ext/`.
|
||||
- `vectors.json` — every vector's file, SHA-256, origin and whole result.
|
||||
- `prober.json` — what an independent media prober reads of `ext/`: each file's format and streams.
|
||||
`identify_verify.py` holds the result to it wherever both state a value, so the reference and the
|
||||
second implementation agreeing is not all that is checked.
|
||||
- `identify_verify.py` — the second implementation, written from the extension.
|
||||
|
||||
**Provenance.** `ext/` and `prober.json` are written by `tools/make_external.sh`, with open tools; it
|
||||
is not run in CI, because it needs them. `tools/oracle.py` writes `prober.json`.
|
||||
BIN
wai/identify-conformance/ext/a.aac
Normal file
BIN
wai/identify-conformance/ext/a.aac
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/a.aiff
Normal file
BIN
wai/identify-conformance/ext/a.aiff
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/a.caf
Normal file
BIN
wai/identify-conformance/ext/a.caf
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/a.flac
Normal file
BIN
wai/identify-conformance/ext/a.flac
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/a.mp3
Normal file
BIN
wai/identify-conformance/ext/a.mp3
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/a.wav
Normal file
BIN
wai/identify-conformance/ext/a.wav
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/a.wav.gz
Normal file
BIN
wai/identify-conformance/ext/a.wav.gz
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/a.wav.zst
Normal file
BIN
wai/identify-conformance/ext/a.wav.zst
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/av1.ivf
Normal file
BIN
wai/identify-conformance/ext/av1.ivf
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/av1.mp4
Normal file
BIN
wai/identify-conformance/ext/av1.mp4
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/av1.obu
Normal file
BIN
wai/identify-conformance/ext/av1.obu
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/avc-aac.flv
Normal file
BIN
wai/identify-conformance/ext/avc-aac.flv
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/avc-aac.mp4
Normal file
BIN
wai/identify-conformance/ext/avc-aac.mp4
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/avc-aac.ts
Normal file
BIN
wai/identify-conformance/ext/avc-aac.ts
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/avc-protected.mp4
Normal file
BIN
wai/identify-conformance/ext/avc-protected.mp4
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/avc.h264
Normal file
BIN
wai/identify-conformance/ext/avc.h264
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/avc.m2ts
Normal file
BIN
wai/identify-conformance/ext/avc.m2ts
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/container.jxl
Normal file
BIN
wai/identify-conformance/ext/container.jxl
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/flac.mp4
Normal file
BIN
wai/identify-conformance/ext/flac.mp4
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/hevc-flac.mkv
Normal file
BIN
wai/identify-conformance/ext/hevc-flac.mkv
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/hevc-fragmented.mp4
Normal file
BIN
wai/identify-conformance/ext/hevc-fragmented.mp4
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/hevc-hvc1.mp4
Normal file
BIN
wai/identify-conformance/ext/hevc-hvc1.mp4
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/hevc.h265
Normal file
BIN
wai/identify-conformance/ext/hevc.h265
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/hevc.ts
Normal file
BIN
wai/identify-conformance/ext/hevc.ts
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/id3.mp3
Normal file
BIN
wai/identify-conformance/ext/id3.mp3
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/lossless.webp
Normal file
BIN
wai/identify-conformance/ext/lossless.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 234 B |
BIN
wai/identify-conformance/ext/lossy.webp
Normal file
BIN
wai/identify-conformance/ext/lossy.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 214 B |
26
wai/identify-conformance/ext/manifest.mpd
Normal file
26
wai/identify-conformance/ext/manifest.mpd
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="urn:mpeg:dash:schema:mpd:2011"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd"
|
||||
profiles="urn:mpeg:dash:profile:isoff-live:2011"
|
||||
type="static"
|
||||
mediaPresentationDuration="PT0.3S"
|
||||
maxSegmentDuration="PT5.0S"
|
||||
minBufferTime="PT0.6S">
|
||||
<ProgramInformation>
|
||||
</ProgramInformation>
|
||||
<ServiceDescription id="0">
|
||||
</ServiceDescription>
|
||||
<Period id="0" start="PT0.0S">
|
||||
<AdaptationSet id="0" contentType="video" startWithSAP="1" segmentAlignment="true" bitstreamSwitching="true" frameRate="10/1" maxWidth="32" maxHeight="32" par="1:1">
|
||||
<Representation id="0" mimeType="video/mp4" codecs="avc1.42c00a" bandwidth="60373" width="32" height="32" sar="1:1">
|
||||
<SegmentTemplate timescale="10240" initialization="i.m4s" media="s.m4s" startNumber="1">
|
||||
<SegmentTimeline>
|
||||
<S t="0" d="3072" />
|
||||
</SegmentTimeline>
|
||||
</SegmentTemplate>
|
||||
</Representation>
|
||||
</AdaptationSet>
|
||||
</Period>
|
||||
</MPD>
|
||||
8
wai/identify-conformance/ext/media.m3u8
Normal file
8
wai/identify-conformance/ext/media.m3u8
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#EXTM3U
|
||||
#EXT-X-VERSION:3
|
||||
#EXT-X-TARGETDURATION:0
|
||||
#EXT-X-MEDIA-SEQUENCE:0
|
||||
#EXT-X-PLAYLIST-TYPE:VOD
|
||||
#EXTINF:0.300000,
|
||||
s0.ts
|
||||
#EXT-X-ENDLIST
|
||||
BIN
wai/identify-conformance/ext/mpeg2.m2v
Normal file
BIN
wai/identify-conformance/ext/mpeg2.m2v
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/mpeg2.mpg
Normal file
BIN
wai/identify-conformance/ext/mpeg2.mpg
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/opus.m4a
Normal file
BIN
wai/identify-conformance/ext/opus.m4a
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/opus.ogg
Normal file
BIN
wai/identify-conformance/ext/opus.ogg
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/p.avif
Normal file
BIN
wai/identify-conformance/ext/p.avif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
BIN
wai/identify-conformance/ext/p.gif
Normal file
BIN
wai/identify-conformance/ext/p.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1,010 B |
BIN
wai/identify-conformance/ext/p.j2k
Normal file
BIN
wai/identify-conformance/ext/p.j2k
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/p.jp2
Normal file
BIN
wai/identify-conformance/ext/p.jp2
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/p.jpg
Normal file
BIN
wai/identify-conformance/ext/p.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 720 B |
BIN
wai/identify-conformance/ext/p.jxl
Normal file
BIN
wai/identify-conformance/ext/p.jxl
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/p.png
Normal file
BIN
wai/identify-conformance/ext/p.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 344 B |
BIN
wai/identify-conformance/ext/p.tif
Normal file
BIN
wai/identify-conformance/ext/p.tif
Normal file
Binary file not shown.
4
wai/identify-conformance/ext/t.vtt
Normal file
4
wai/identify-conformance/ext/t.vtt
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
WEBVTT
|
||||
|
||||
00:00.000 --> 00:01.000
|
||||
A line.
|
||||
5
wai/identify-conformance/ext/v.y4m
Normal file
5
wai/identify-conformance/ext/v.y4m
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
YUV4MPEG2 W16 H16 F10:1 Ip A1:1 C420jpeg XYSCSS=420JPEG
|
||||
FRAME
|
||||
JJJJJJJJ))))jjェェJJJJJJJJ))))jjェェJJ&&66JJ&&66JJ&&66JJ&&66JJ鋳鋳&&鋳JJ鋳鋳&鋳6QQ 鋳@@鋳鋳66QQ 鋳@@鋳鋳66QQ 鋳@鋳鋳鋳6嘆Q 鋳@鋳鋳鋳6嘆Q 鋳@@鋳鋳66QQ 鋳@@鋳鋳66QQ 0鋳@鋳&鋳6QQ 00鋳鋳&&鋳ンンンン<EFBE9D>ハヲン覧梨恍貨覧梨恍貨<E6818D>MOボJZw5d<35>55瓜w5Li55_Zw5d<35>55瓜w`AOボJヲヲヲヲnn゙ヲ演榎|妖ヲ演榎|妖ヲ於ウー困ェ<E59BB0>チлチチd<EFBE81>チ」榁チ挺愧лチチd<EFBE81>イー困ェFRAME
|
||||
JJJJJJJJ))))jjェェJJJJJJJJ))))jjェェJJ&&66JJ&&66JJ&&66JJ&&66JJ鋳鋳&&鋳JJ鋳鋳&鋳6QQ 鋳@@鋳鋳66QQ 鋳@@鋳鋳66QQ 鋳@鋳鋳鋳6嘆Q 鋳@鋳鋳鋳6嘆Q 鋳@@鋳鋳66QQ 鋳@@鋳鋳66QQ 0鋳@鋳&鋳6QQ 00鋳鋳&&鋳ンンンン<EFBE9D>ハヲン覧梨恍貨覧梨恍貨<E6818D>MOボJZw5d<35>55瓜w5Li55_Zw5d<35>55瓜w`AOボJヲヲヲヲnn゙ヲ演榎|妖ヲ演榎|妖ヲ於ウー困ェ<E59BB0>チлチチd<EFBE81>チ」榁チ挺愧лチチd<EFBE81>イー困ェFRAME
|
||||
JJJJJJJJ))))jjェェJJJJJJJJ))))jjェェJJ&&66JJ&&66JJ&&66JJ&&66JJ鋳鋳&&鋳JJ鋳鋳&鋳6QQ 鋳@@鋳鋳66QQ 鋳@@鋳鋳66QQ 鋳@鋳鋳鋳6嘆Q 鋳@鋳鋳鋳6嘆Q 鋳@@鋳鋳66QQ 鋳@@鋳鋳66QQ 0鋳@鋳&鋳6QQ 00鋳鋳&&鋳ンンンン<EFBE9D>ハヲン覧梨恍貨覧梨恍貨<E6818D>MOボJZw5d<35>55瓜w5Li55_Zw5d<35>55瓜w`AOボJヲヲヲヲnn゙ヲ演榎|妖ヲ演榎|妖ヲ於ウー困ェ<E59BB0>チлチチd<EFBE81>チ」榁チ挺愧лチチd<EFBE81>イー困ェ
|
||||
BIN
wai/identify-conformance/ext/vorbis.ogg
Normal file
BIN
wai/identify-conformance/ext/vorbis.ogg
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/vp9-opus.webm
Normal file
BIN
wai/identify-conformance/ext/vp9-opus.webm
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/vp9.ivf
Normal file
BIN
wai/identify-conformance/ext/vp9.ivf
Normal file
Binary file not shown.
BIN
wai/identify-conformance/ext/vp9.mp4
Normal file
BIN
wai/identify-conformance/ext/vp9.mp4
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/adts-bad-len.bin
Normal file
BIN
wai/identify-conformance/gen/adts-bad-len.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/adts-bad-rate.bin
Normal file
BIN
wai/identify-conformance/gen/adts-bad-rate.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/adts-frame.bin
Normal file
BIN
wai/identify-conformance/gen/adts-frame.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/adts-inside.bin
Normal file
BIN
wai/identify-conformance/gen/adts-inside.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/adts-junk.bin
Normal file
BIN
wai/identify-conformance/gen/adts-junk.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/adts-many.bin
Normal file
BIN
wai/identify-conformance/gen/adts-many.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/adts-other-rate.bin
Normal file
BIN
wai/identify-conformance/gen/adts-other-rate.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/adts-past.bin
Normal file
BIN
wai/identify-conformance/gen/adts-past.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/adts-rate13.bin
Normal file
BIN
wai/identify-conformance/gen/adts-rate13.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/adts-six.bin
Normal file
BIN
wai/identify-conformance/gen/adts-six.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/adts-tail.bin
Normal file
BIN
wai/identify-conformance/gen/adts-tail.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/annexb-02.bin
Normal file
BIN
wai/identify-conformance/gen/annexb-02.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/annexb-all-zero.bin
Normal file
BIN
wai/identify-conformance/gen/annexb-all-zero.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/annexb-empty-unit.bin
Normal file
BIN
wai/identify-conformance/gen/annexb-empty-unit.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/annexb-first-empty.bin
Normal file
BIN
wai/identify-conformance/gen/annexb-first-empty.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/annexb-one-byte.bin
Normal file
BIN
wai/identify-conformance/gen/annexb-one-byte.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/annexb-one-zero.bin
Normal file
BIN
wai/identify-conformance/gen/annexb-one-zero.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/av1-bad-seq.bin
Normal file
BIN
wai/identify-conformance/gen/av1-bad-seq.bin
Normal file
Binary file not shown.
2
wai/identify-conformance/gen/av1-cut-size.bin
Normal file
2
wai/identify-conformance/gen/av1-cut-size.bin
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
<EFBFBD>
|
||||
BIN
wai/identify-conformance/gen/av1-ext.bin
Normal file
BIN
wai/identify-conformance/gen/av1-ext.bin
Normal file
Binary file not shown.
2
wai/identify-conformance/gen/av1-first-other.bin
Normal file
2
wai/identify-conformance/gen/av1-first-other.bin
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
2
|
||||
<1D>葮
|
||||
BIN
wai/identify-conformance/gen/av1-forbidden.bin
Normal file
BIN
wai/identify-conformance/gen/av1-forbidden.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/av1-full.bin
Normal file
BIN
wai/identify-conformance/gen/av1-full.bin
Normal file
Binary file not shown.
2
wai/identify-conformance/gen/av1-leb8.bin
Normal file
2
wai/identify-conformance/gen/av1-leb8.bin
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
<1D><><EFBFBD>22<><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
BIN
wai/identify-conformance/gen/av1-level7.bin
Normal file
BIN
wai/identify-conformance/gen/av1-level7.bin
Normal file
Binary file not shown.
2
wai/identify-conformance/gen/av1-long-size.bin
Normal file
2
wai/identify-conformance/gen/av1-long-size.bin
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
<1D>葮22<><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
BIN
wai/identify-conformance/gen/av1-long-uvlc.bin
Normal file
BIN
wai/identify-conformance/gen/av1-long-uvlc.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/av1-many.bin
Normal file
BIN
wai/identify-conformance/gen/av1-many.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/av1-no-seq.bin
Normal file
BIN
wai/identify-conformance/gen/av1-no-seq.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/av1-no-size.bin
Normal file
BIN
wai/identify-conformance/gen/av1-no-size.bin
Normal file
Binary file not shown.
2
wai/identify-conformance/gen/av1-only-seq.bin
Normal file
2
wai/identify-conformance/gen/av1-only-seq.bin
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
<1D>葮
|
||||
BIN
wai/identify-conformance/gen/av1-past.bin
Normal file
BIN
wai/identify-conformance/gen/av1-past.bin
Normal file
Binary file not shown.
2
wai/identify-conformance/gen/av1-reduced.bin
Normal file
2
wai/identify-conformance/gen/av1-reduced.bin
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
<1D>葮2
|
||||
BIN
wai/identify-conformance/gen/av1-reserved.bin
Normal file
BIN
wai/identify-conformance/gen/av1-reserved.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/av1-unit.bin
Normal file
BIN
wai/identify-conformance/gen/av1-unit.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/avc-444-crop.bin
Normal file
BIN
wai/identify-conformance/gen/avc-444-crop.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/avc-444-separate.bin
Normal file
BIN
wai/identify-conformance/gen/avc-444-separate.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/avc-adjacent.bin
Normal file
BIN
wai/identify-conformance/gen/avc-adjacent.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/avc-bad-profile.bin
Normal file
BIN
wai/identify-conformance/gen/avc-bad-profile.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/avc-chroma.bin
Normal file
BIN
wai/identify-conformance/gen/avc-chroma.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/avc-chroma4-full.bin
Normal file
BIN
wai/identify-conformance/gen/avc-chroma4-full.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/avc-crop.bin
Normal file
BIN
wai/identify-conformance/gen/avc-crop.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/avc-cut-sps.bin
Normal file
BIN
wai/identify-conformance/gen/avc-cut-sps.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/avc-end-start.bin
Normal file
BIN
wai/identify-conformance/gen/avc-end-start.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/avc-escape-run.bin
Normal file
BIN
wai/identify-conformance/gen/avc-escape-run.bin
Normal file
Binary file not shown.
BIN
wai/identify-conformance/gen/avc-escaped.bin
Normal file
BIN
wai/identify-conformance/gen/avc-escaped.bin
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue