510 lines
34 KiB
Markdown
510 lines
34 KiB
Markdown
# WAI Extension: Format Probes
|
||
|
||
> Status: Draft. A **header probe** for each sink-supplied format the registry names whose
|
||
> payload WAI does not decode itself: it identifies a payload as the format its capability
|
||
> names and reads the parameters the format's headers state, or refuses it with one of the
|
||
> codes of §12. No probe decodes a picture or a sound. Probes are defined for JPEG XS
|
||
> (`wai.image.jxs`, `wai.video.jxs`), H.265 and MV-HEVC (`wai.video.hevc`,
|
||
> `wai.video.mvhevc`), H.266 (`wai.video.vvc`), LCEVC (`wai.video.lcevc`), MPEG-H 3D Audio
|
||
> (`wai.audio.mpegh`), AVS3 video and audio (`wai.video.avs3`, `wai.audio.avs3`), the picture
|
||
> header of IEEE 1857.11 (`wai.image.ieee1857_11`, a candidate) and the projection descriptor
|
||
> (`wai.meta.projection`, [projection](projection.md)). §3.5 maps a JPEG XS payload onto the
|
||
> media-type parameters of RFC 9134 and the constant-rate carriage of SMPTE ST 2110-22. The
|
||
> reference implementation is the `format_probe` module of `wai-rs` (feature
|
||
> `format_probe`) and its tool `wai_format_probe`; the corpus is
|
||
> [`format-probe-conformance/`](../format-probe-conformance/), and its second implementation
|
||
> is `format-probe-conformance/format_probe_verify.py`.
|
||
> Keywords **MUST**, **MUST NOT**, **SHOULD**, **MAY** are RFC 2119/8174.
|
||
>
|
||
> Texts read for this revision: ITU-T H.265 (V11, 01/2026) and ITU-T H.266 (V4, 01/2026),
|
||
> whole; ITU-T H.273 and ITU-T H.274 (V4, 01/2026) §8.15; RFC 9134; SMPTE ST 2110-22:2022; the
|
||
> public previews of ISO/IEC 21122-2:2022/Amd 1:2022 (Tables A.7 and A.16) and ISO/IEC
|
||
> 21122-4:2022 (§6.3, Annex B.2); ATSC A/342-3:2024-04 §5.2; ETSI TS 101 154 V2.10.1 §5.16.2 and
|
||
> §6.10.2. Not openly readable, and so not read: ISO/IEC 21122-1, ISO/IEC 23094-2, ISO/IEC
|
||
> 23008-3, T/AI 109.2, T/AI 109.3 and IEEE 1857.11-2024. For those formats §3 to §10 say where
|
||
> each layout was read instead.
|
||
|
||
## 1. Scope
|
||
|
||
§1.1 A probe reads a payload's headers. It identifies the format by the bytes the format
|
||
begins with, where it has such bytes (§2.4), reads the parameters its headers state, and checks
|
||
the structure the probe reads: the order of the format's required structures, the lengths they
|
||
declare, and the values the format forbids or reserves among the fields read. It reads no
|
||
coded sample data: a payload a probe accepts is not shown to decode, and a probe that accepts a
|
||
payload says nothing of the pictures or sounds in it.
|
||
|
||
§1.2 What a probe gives is used to describe a payload without decoding it: in a catalogue, in a
|
||
manifest a packager writes, in the `codecs` string or media-type parameters a delivery binding
|
||
states (§3.5), and to refuse a payload that does not hold the format its capability names before
|
||
any decoder sees it.
|
||
|
||
§1.3 An encoder **MUST NOT** emit, under a capability whose probe has basis `standard` or `wai`
|
||
(§2.3), a payload that probe refuses; it **SHOULD NOT** emit one that a probe of basis
|
||
`implementation` refuses. A sink **MAY** probe a payload before it dispatches it (SPEC §4); a
|
||
sink that probes and gets a refusal does not dispatch the payload under that capability, and
|
||
may still take dispatch step 5 with a fallback. A probe's refusal is not a statement that the
|
||
payload does not conform to its format's standard: a probe of basis `implementation` reads the
|
||
layout its sources give, and §12's `outside_probe` names payloads it cannot read at all.
|
||
|
||
§1.4 This extension adds no capability. It completes the registrations of `wai.video.vvc`,
|
||
`wai.video.lcevc`, `wai.audio.mpegh`, `wai.video.avs3` and `wai.audio.avs3`, which were
|
||
registered with no probe, and gives the registrations of `wai.image.jxs`, `wai.video.jxs`,
|
||
`wai.video.mvhevc`, `wai.image.ieee1857_11` and `wai.meta.projection` (SPEC §5) theirs.
|
||
|
||
## 2. Common rules
|
||
|
||
§2.1 A probe's result is a JSON object whose members each section names; a member the payload
|
||
does not state is `null`. Integers are JSON numbers, flags JSON booleans. The probe reports the
|
||
first refusal its reading meets, in the order each section reads.
|
||
|
||
§2.2 A bit reader reads most significant bit first. `u(n)` is an `n`-bit unsigned integer;
|
||
`ue(v)` is the Exp-Golomb code of ITU-T H.265 §9.2, and one with more than 31 leading zero bits
|
||
is `reserved_value`. Reading past the payload's end is `truncated`.
|
||
|
||
§2.3 Every probe has a **basis**: `standard`, where its format's own text is openly readable and
|
||
was read; `implementation`, where it is not and the layout was read from open implementations,
|
||
each section naming which agree; `wai`, for a format this specification defines.
|
||
|
||
§2.4 The probes, in order:
|
||
|
||
| capability | basis | section |
|
||
|---|---|---|
|
||
| `wai.image.jxs` | implementation | §3 |
|
||
| `wai.video.jxs` | implementation | §3.3 |
|
||
| `wai.video.hevc` | standard | §4 |
|
||
| `wai.video.mvhevc` | standard | §4 |
|
||
| `wai.video.vvc` | standard | §5 |
|
||
| `wai.video.lcevc` | implementation | §6 |
|
||
| `wai.audio.mpegh` | implementation | §7 |
|
||
| `wai.video.avs3` | implementation | §8 |
|
||
| `wai.audio.avs3` | implementation | §9 |
|
||
| `wai.image.ieee1857_11` | implementation | §10 |
|
||
| `wai.meta.projection` | wai | §11 |
|
||
|
||
Any other capability has no probe: `no_probe`.
|
||
|
||
§2.5 **Annex B byte streams.** A payload of H.265, H.266 or LCEVC is a byte stream: after any
|
||
zero bytes, it begins with the start code prefix `0x000001`, and otherwise is `no_signature`
|
||
(one zero byte before the prefix is not enough: at least two). A NAL unit is the bytes after a
|
||
prefix up to the next prefix, less the zero bytes that end it. Its payload is read with every
|
||
emulation-prevention byte removed: the `0x03` of every `0x000003` (ITU-T H.265 §7.4.2).
|
||
|
||
## 3. JPEG XS
|
||
|
||
§3.1 **Sources.** ISO/IEC 21122-1 is not openly readable. The marker codes, the segment
|
||
layouts and the order of §3.2 are those two independent open implementations of the codestream
|
||
agree on, a decoder and encoder under BSD-2-Clause-Patent and a decoder under MIT, at the
|
||
revisions `format-probe-conformance/tools/make_external.sh` pins. The profile codes are ISO/IEC
|
||
21122-2:2022/Amd 1:2022 Table A.7, and the sublevel codes its Table A.16, read in the
|
||
amendment's public preview. Level codes are named only where the two open readings agree
|
||
(§3.4).
|
||
|
||
§3.2 **The codestream.** A `wai.image.jxs` payload is one codestream. A probe reads, in order:
|
||
|
||
1. `SOC`, `0xFF10`, as the first two bytes; otherwise `no_signature`.
|
||
2. `CAP`, `0xFF50`, immediately after, and otherwise `out_of_order`; its length `Lcap`, a
|
||
big-endian `u16` of at least 2 (else `length_mismatch`), counts itself and `Lcap − 2` bytes of
|
||
capability bits, read most significant bit first: bit `i` set is reported in `cap_bits`.
|
||
3. `PIH`, `0xFF12`, immediately after `CAP`, else `out_of_order`, with `Lpih` 26, else
|
||
`length_mismatch`. Its body, big-endian: `Lcod` 32 bits, `Ppih` 16, `Plev` 16, `Wf` 16, `Hf`
|
||
16, `Cw` 16, `Hsl` 16, `Nc` 8, `Ng` 8, `Ss` 8, `Bw` 8, `Fq` 4, `Br` 4, `Fslc` 1, `Ppoc` 3,
|
||
`Cpih` 4, `Nlx` 4, `Nly` 4, `Lh` 1, `Rl` 1, `Qpih` 2, `Fs` 2, `Rm` 2. It is `reserved_value`
|
||
unless `Wf`, `Hf` and `Hsl` are at least 1, `Nc` is 1 to 8, `Ng` is 4, `Ss` is 8, `Br` is 4,
|
||
`Cpih` is 0, 1 or 3, and `Qpih` is 0 or 1.
|
||
4. Segments up to the first slice header `SLH`, `0xFF20`, each a marker, a big-endian `u16`
|
||
length of at least 2 (else `length_mismatch`) and that many bytes less two: `CDT` `0xFF13`,
|
||
`WGT` `0xFF14`, `COM` `0xFF15`, `NLT` `0xFF16`, `CWD` `0xFF17`, `CTS` `0xFF18`, `CRG`
|
||
`0xFF19`, in any order. `CDT`'s length is `2 + 2·Nc`, else `length_mismatch`; it holds, per
|
||
component, its precision `B` (8 bits) and its sampling factors `Sx` and `Sy` (4 bits each),
|
||
none of which is 0 (else `reserved_value`). `SOC`, `EOC`, `PIH` or `CAP` among these segments is
|
||
`out_of_order`; any other marker is `reserved_value`.
|
||
5. `CDT` and `WGT` are required before `SLH`, and with `Cpih` 3 also `CTS` and `CRG`:
|
||
`missing_structure`. The payload ends with `EOC`, `0xFF11`: otherwise `missing_structure`.
|
||
6. `Lcod` is 0 (a variable-rate codestream) or the codestream's length in bytes, `SOC` to `EOC`;
|
||
otherwise `length_mismatch`.
|
||
|
||
The probe does not read the slices.
|
||
|
||
§3.3 **Video.** A `wai.video.jxs` payload is five `u32` little-endian values, `n`, `h`, `w`,
|
||
`fps_num` and `fps_den`, then `n` codestreams, each preceded by its length as a `u32`
|
||
little-endian value: the framing of `wai.video.av1` (SPEC §5), with a codestream for a temporal
|
||
unit. Any of the five being 0 is `framing_invalid`; a length past the payload's end is
|
||
`truncated`; each codestream is probed by §3.2, and one whose `Wf` exceeds `w` or whose `Hf`
|
||
exceeds `h` is `framing_invalid`; bytes after the `n`-th codestream are `trailing_bytes`.
|
||
|
||
§3.4 **Parameters.** For one codestream: `profile` and `level` (`Ppih` and `Plev` as four
|
||
lowercase hexadecimal digits after `0x`), `width` and `height` (`Wf`, `Hf`), `components` (per
|
||
component `[B, Sx, Sy]`), `structure`, `colour_transform` (`Cpih`), `decompositions`
|
||
(`[Nlx, Nly]`), `precinct_width` (`Cw`), `slice_height` (`Hsl`), `wavelet_precision` (`Bw`),
|
||
`fractional_bits` (`Fq`), `quantizer` (`Qpih`), `long_header` (`Lh`), `raw_mode` (`Rl`),
|
||
`cbr_bytes` (`Lcod`), `cap_bits`, and `rtp` (§3.5). `structure` is `"4:4:4"`, `"4:2:2"` or
|
||
`"4:2:0"` when there are at least three components, the first has `Sx` = `Sy` = 1 and the second
|
||
and third have equal factors of (1, 1), (2, 1) or (2, 2) respectively; otherwise `null`.
|
||
|
||
For a video: `frames` (`n`), `size` (`[w, h]`), `fps` (`[fps_num, fps_den]`),
|
||
`constant_bytes` (the common `Lcod` when every codestream states the same non-zero `Lcod`,
|
||
otherwise `null`) and `first`, the first codestream's parameters.
|
||
|
||
The profile names (white space omitted, as RFC 9134 §7.1 writes them), by `Ppih`:
|
||
|
||
| `Ppih` | profile | `Ppih` | profile |
|
||
|---|---|---|---|
|
||
| `0x0000` | Unrestricted | `0x4240` | High420.12 |
|
||
| `0x1500` | Light422.10 | `0x4A40` | High444.12 |
|
||
| `0x1A00` | Light444.12 | `0x4E40` | High4444.12 |
|
||
| `0x2500` | Light-Subline422.10 | `0x6EC0` | MLS.12 |
|
||
| `0x3240` | Main420.12 | `0x9300` | LightBayer |
|
||
| `0x3540` | Main422.10 | `0xB340` | MainBayer |
|
||
| `0x3A40` | Main444.12 | `0xC340` | HighBayer |
|
||
| `0x3E40` | Main4444.12 | | |
|
||
|
||
The level, by `Plev`'s high byte: `0x00` Unrestricted, `0x10` 2k-1, `0x20` 4k-1, `0x24` 4k-2,
|
||
`0x28` 4k-3, `0x30` 8k-1, `0x34` 8k-2, `0x38` 8k-3, `0x40` 10k-1. The high bytes `0x04` and
|
||
`0x2C` are named 1k-1 and 5k-1 by one open implementation and refused as reserved by the other;
|
||
the probe names them too, and §3.6 records the disagreement. The sublevel, by `Plev`'s low byte:
|
||
`0x00` Unrestricted, `0x80` Full, `0x10` Sublev12bpp, `0x0C` Sublev9bpp, `0x08` Sublev6bpp,
|
||
`0x06` Sublev4bpp, `0x04` Sublev3bpp, `0x03` Sublev2bpp. A code in none of these lists is
|
||
reported with a `null` name and is not refused: a later edition may define it.
|
||
|
||
§3.5 **RTP and SMPTE ST 2110-22.** RFC 9134 carries a JPEG XS codestream in RTP; SMPTE ST
|
||
2110-22:2022 carries constant-bit-rate compressed video over RTP and names no codec. A sender of
|
||
a `wai.video.jxs` payload over RFC 9134:
|
||
|
||
- states the media type `video/jxsv` with the parameters of `rtp` (RFC 9134 §7.1): `profile`,
|
||
`level` and `sublevel` by the names of §3.4 (omitted where `null`), `depth` (the largest
|
||
component precision), `width` and `height`, and `sampling` where the codestream determines it:
|
||
`RGB` where `structure` is `4:4:4` under a colour transform (`Cpih` 1 or 3), whose decoder
|
||
outputs R, G and B; otherwise `rtp.sampling` is `null` and the sender states the sampling,
|
||
since a codestream does not say whether its components are Y′C′BC′R, constant-luminance
|
||
Y′C′BC′R or ICTCP (RFC 9134 §7.1 lists all three);
|
||
- sends each codestream as one picture segment of codestream mode (`K` = 0, RFC 9134 §4.1) at
|
||
the frame rate `fps`, the RTP timestamp at 90 kHz (RFC 9134 §4.2), or each slice in slice mode
|
||
(`K` = 1);
|
||
- for SMPTE ST 2110-22 (§4 there: a constant number of bytes, and of RTP packets, per frame),
|
||
sends only a payload whose `constant_bytes` is not `null`; the codestream's `Lcod` is the
|
||
frame's byte count.
|
||
|
||
A receiver rebuilds the payload by framing each received codestream as §3.3 does, `fps` from
|
||
the session's `exactframerate`. WAI defines no transport (moq-streaming-format §6); this
|
||
mapping says which of a payload's fields fill which of RFC 9134's.
|
||
|
||
§3.6 **Exactness.** A sink that advertises `wai.image.jxs` or `wai.video.jxs` decodes at the
|
||
strict conformance point of ISO/IEC 21122-4 (Annex B.2: decoded images bitwise identical to the
|
||
reference images), not only at its relaxed point (PSNR bounds), so every conforming sink outputs
|
||
the same samples; the registry class is `standard-defined` on that basis. What was measured
|
||
(`format-probe-conformance/provenance.json`): the open decoder's C path and SIMD path give
|
||
byte-identical output on every JPEG XS vector of the corpus, on arm64; the second, independent
|
||
decoder gives the same bytes on every vector whose profile it implements, five of six; it does
|
||
not implement MLS.12 (it refuses `Ppih` `0x6EC0`), and on a copy of that vector with `Ppih` and
|
||
`Plev` set to 0 its output differs, while the first decoder's output equals the vector's source
|
||
picture byte for byte, as a lossless codestream's must. No x86 decode was measured.
|
||
|
||
## 4. H.265 and MV-HEVC
|
||
|
||
§4.1 **Sources.** ITU-T H.265 (V11, 01/2026): the NAL unit header (§7.3.1.2), the video
|
||
parameter set and its extension (§F.7.3.2.1, §F.7.3.2.1.1, derivations (F-2) to (F-6)), the
|
||
sequence parameter set (§7.3.2.2.1), profile_tier_level (§7.3.3, inference §F.7.4.4) and the HRD
|
||
parameters (§E.2.2, §E.2.3).
|
||
|
||
§4.2 **NAL units.** Each NAL unit (§2.5) is at least 2 bytes (else `truncated`); its header is
|
||
`forbidden_zero_bit` 1, `nal_unit_type` 6, `nuh_layer_id` 6, `nuh_temporal_id_plus1` 3 bits.
|
||
`forbidden_zero_bit` 1 or `nuh_temporal_id_plus1` 0 is `reserved_value`. Types 0 to 31 are VCL.
|
||
The probe reads the first VPS (type 32) and the first SPS (type 33) with `nuh_layer_id` 0. A VCL
|
||
NAL unit before both is `out_of_order` if both occur later in the payload and `missing_structure`
|
||
if either never does; a payload with no VCL NAL unit is `missing_structure`.
|
||
|
||
§4.3 **The VPS.** In order: `vps_video_parameter_set_id` u(4), `vps_base_layer_internal_flag`,
|
||
`vps_base_layer_available_flag`, `vps_max_layers_minus1` u(6), `vps_max_sub_layers_minus1` u(3)
|
||
(above 6 is `reserved_value`), `vps_temporal_id_nesting_flag`, `vps_reserved_0xffff_16bits` (any
|
||
other value is `reserved_value`), profile_tier_level(1, `vps_max_sub_layers_minus1`), the
|
||
sub-layer ordering information, `vps_max_layer_id` u(6), `vps_num_layer_sets_minus1` ue(v)
|
||
(above 1023 is `reserved_value`), the layer-id flags, the timing information with its HRD
|
||
parameters (`vps_num_hrd_parameters` above `vps_num_layer_sets_minus1` + 1 is `reserved_value`;
|
||
`cpb_cnt_minus1` above 31 is `reserved_value`), and `vps_extension_flag`. When the flag is 1 and
|
||
`vps_max_layers_minus1` is above 0, the probe reads the alignment bits (each 1, else
|
||
`reserved_value`) and `vps_extension( )` up to and including its profile_tier_level( )
|
||
structures: `splitting_flag`, the sixteen `scalability_mask_flag`s, the dimension lengths, the
|
||
layer ids (each above the one before, else `reserved_value`), the dimension ids, `view_id_len`
|
||
and the view ids, the direct dependency flags, `num_add_layer_sets` and its
|
||
`highest_layer_idx_plus1` fields, the sub-layer and inter-layer temporal fields,
|
||
`default_ref_layers_active_flag`, `vps_num_profile_tier_level_minus1` (above 63 is
|
||
`reserved_value`) and the structures it counts. A profile_tier_level( ) is read as §7.3.3 lays it
|
||
out, its general profile part as 88 bits whatever its branches (the syntax's own note). A
|
||
structure with no profile takes its profile, tier and compatibility flags from the structure
|
||
before it (§F.7.4.4).
|
||
|
||
§4.4 **The SPS** of the base layer: `sps_video_parameter_set_id` u(4), `sps_max_sub_layers_minus1`
|
||
u(3) (above 6 is `reserved_value`), `sps_temporal_id_nesting_flag`, profile_tier_level(1, ·),
|
||
`sps_seq_parameter_set_id` ue(v) (above 15 is `reserved_value`), `chroma_format_idc` ue(v) (above
|
||
3 is `reserved_value`), `separate_colour_plane_flag` when it is 3, `pic_width_in_luma_samples`
|
||
and `pic_height_in_luma_samples` ue(v) (0 is `reserved_value`), the conformance window, and
|
||
`bit_depth_luma_minus8` and `bit_depth_chroma_minus8` ue(v) (above 8 is `reserved_value`). The
|
||
cropped size is the coded size less the window, whose offsets count SubWidthC and SubHeightC
|
||
samples (2 and 2 at 4:2:0, 2 and 1 at 4:2:2, 1 and 1 otherwise); a window as large as the
|
||
picture is `reserved_value`.
|
||
|
||
§4.5 **MV-HEVC.** A `wai.video.mvhevc` payload is also refused `not_multiview` unless the VPS
|
||
extension's scalability mask has bit 1 (multiview, Table F.1), `NumViews` (F-3) is at least 2, and
|
||
a VCL NAL unit with `nuh_layer_id` above 0 is present.
|
||
|
||
§4.6 **Parameters.** `profile_idc`, `tier`, `level_idc` (the base SPS's), `chroma_format_idc`,
|
||
`bit_depth` (`[luma, chroma]`), `coded` and `cropped` (`[width, height]`), `layers`
|
||
(`Min(62, vps_max_layers_minus1)` + 1), `layers_present` (the `nuh_layer_id`s of the VCL NAL units,
|
||
ascending), and, when the VPS extension was read, `multilayer`: `scalability_mask` (bit `i` for
|
||
`scalability_mask_flag[ i ]`), `layer_ids`, `view_order` and `aux` (`ViewOrderIdx` and `AuxId` per
|
||
layer), `views` (`NumViews` when the multiview bit is set, else 1), `view_ids` (`view_id_val`, or
|
||
zeros when `view_id_len` is 0), `profiles` (`general_profile_idc` of each extension structure,
|
||
after inference) and `multiview_profile` (whether any of them indicates profile 6, Multiview Main
|
||
or Multiview Main 10, by its idc or its compatibility flag).
|
||
|
||
## 5. H.266
|
||
|
||
§5.1 **Sources.** ITU-T H.266 (V4, 01/2026) §7.3.1.2, §7.3.2.3, §7.3.2.4, §7.3.3.1 and §7.3.3.2.
|
||
|
||
§5.2 **NAL units.** The header is `forbidden_zero_bit` 1, `nuh_reserved_zero_bit` 1,
|
||
`nuh_layer_id` 6, `nal_unit_type` 5, `nuh_temporal_id_plus1` 3 bits. Either of the first two set,
|
||
`nuh_temporal_id_plus1` 0 or `nuh_layer_id` above 55 is `reserved_value`. Types 0 to 11 are VCL.
|
||
The probe reads the first SPS (type 15) and the first VPS (type 14), of which it reads
|
||
`vps_max_layers_minus1` (the second field, after a 4-bit id). A VCL NAL unit before the SPS is
|
||
`out_of_order` if an SPS occurs later and `missing_structure` if none does; no VCL NAL unit is
|
||
`missing_structure`.
|
||
|
||
§5.3 **The SPS** to its conformance window: `sps_seq_parameter_set_id` u(4),
|
||
`sps_video_parameter_set_id` u(4), `sps_max_sublayers_minus1` u(3) (above 6 is `reserved_value`),
|
||
`sps_chroma_format_idc` u(2), `sps_log2_ctu_size_minus5` u(2) (above 2 is `reserved_value`),
|
||
`sps_ptl_dpb_hrd_params_present_flag` and, when it is 1, profile_tier_level(1,
|
||
`sps_max_sublayers_minus1`), `sps_gdr_enabled_flag`, `sps_ref_pic_resampling_enabled_flag` and
|
||
the flag it conditions, `sps_pic_width_max_in_luma_samples` and
|
||
`sps_pic_height_max_in_luma_samples` ue(v) (0 is `reserved_value`), and the conformance window.
|
||
profile_tier_level( ) is read as §7.3.3.1 lays it out; general_constraints_info( ) is
|
||
`gci_present_flag`, then, when it is 1, 71 bits of constraints, `gci_num_additional_bits` u(8)
|
||
and that many bits, then zero bits to the byte boundary (a one among them is `reserved_value`).
|
||
The cropped size is computed as in §4.4.
|
||
|
||
§5.4 **Parameters.** `profile_idc`, `tier`, `level_idc`, `frame_only`
|
||
(`ptl_frame_only_constraint_flag`) and `multilayer_enabled` (`ptl_multilayer_enabled_flag`), all
|
||
`null` when the SPS carries no profile_tier_level( ); `sub_profiles` (`general_sub_profile_idc`s);
|
||
`chroma_format_idc`; `ctu_size` (`1 << (sps_log2_ctu_size_minus5 + 5)`); `coded`; `cropped`;
|
||
`layers` (`vps_max_layers_minus1` + 1, or 1 without a VPS); `layers_present`.
|
||
|
||
## 6. LCEVC
|
||
|
||
§6.1 **Sources.** ISO/IEC 23094-2 is not openly readable. The NAL unit header, the block
|
||
structure and the two configurations are those an open decoder (BSD-3-Clause-Clear) and an open
|
||
syntax reading under LGPL-2.1 agree on, each citing the standard's tables; the resolution table
|
||
is the standard's Table 20 as the decoder reproduces it. The two readings disagree on the byte
|
||
that extends a profile or level of 15; the probe does not read it (`outside_probe`).
|
||
|
||
§6.2 **NAL units.** A `wai.video.lcevc` payload is the byte stream of SPEC §5 (§2.5). Each NAL
|
||
unit is at least 3 bytes (else `truncated`). Its first byte is `forbidden_zero_bit` (0),
|
||
`forbidden_one_bit` (1), `nal_unit_type` (5 bits) and the first bit of `reserved_flag` (1); its
|
||
second byte is the other eight bits of `reserved_flag`, all 1. Any other value of those bits is
|
||
`reserved_value`. `nal_unit_type` is 29 (IDR) or 28 (non-IDR), else `reserved_value`; the first NAL
|
||
unit is IDR, else `out_of_order`. The payload, emulation prevention removed, ends with the byte
|
||
`0x80`, else `reserved_value`.
|
||
|
||
§6.3 **Blocks.** The payload before that byte is a sequence of blocks: a header byte, its high
|
||
three bits `payload_size_type` and its low five `payload_type`, then the body. A size type of 0 to
|
||
5 is the body's length; 6 is `reserved_value`; 7 is followed by the length as a multi-byte value:
|
||
seven bits a byte, most significant first, each byte but the last with its top bit set, at most
|
||
ten bytes (else `reserved_value`). A body past the payload's end is `length_mismatch`. Types: 0
|
||
sequence configuration, 1 global configuration, 2 picture configuration, 3 and 4 encoded data,
|
||
5 additional information, 6 filler; the probe reads the first 0 and the first 1, counts the 2s,
|
||
and passes over the rest. A picture configuration before both configurations is `out_of_order`;
|
||
a payload without both is `missing_structure`.
|
||
|
||
§6.4 **The configurations.** The sequence configuration: `profile_idc` 4, `level_idc` 4,
|
||
`sublevel_idc` 2, `conformance_window_flag` 1, five reserved bits that are 0 (else
|
||
`reserved_value`); a profile or level of 15 is `outside_probe`; with the flag, four multi-byte
|
||
window offsets (left, right, top, bottom); bytes left in the body are `length_mismatch`. The
|
||
global configuration: `processed_planes_type_flag` 1, `resolution_type` 6, `transform_type` 1,
|
||
`chroma_sampling_type` 2, `base_depth_type` 2, `enhancement_depth_type` 2,
|
||
`temporal_step_width_modifier_signalled_flag` 1, `predicted_residual_mode_flag` 1,
|
||
`temporal_tile_intra_signalling_enabled_flag` 1, `temporal_enabled_flag` 1, `upsample_type` 3,
|
||
`level1_filtering_signalled_flag` 1, `scaling_mode_level1` 2, `scaling_mode_level2` 2,
|
||
`tile_dimensions_type` 2, `user_data_enabled` 2, `level1_depth_flag` 1, `chroma_step_width_flag`
|
||
1; then, each where its condition holds: a byte of planes type (the planes flag), a byte of step
|
||
width modifier (its flag), four 16-bit kernel coefficients (`upsample_type` 4), a byte of two
|
||
filter coefficients (the filtering flag), for `tile_dimensions_type` above 0 the custom tile
|
||
width and height as 16-bit values when it is 3 and then a byte of tile compression, and, for
|
||
`resolution_type` 63, the custom width and height as 16-bit values. `resolution_type` 0 or 51 to
|
||
62, an `upsample_type` above 4, or a custom width or height of 0 is `reserved_value`.
|
||
|
||
§6.5 **Parameters.** `nal_units` (`[IDR, non-IDR]` counts), `pictures` (picture configurations),
|
||
`profile_idc`, `level_idc`, `sublevel_idc`, `conformance_window` (the four offsets as signalled,
|
||
or `null`), `resolution_type`, `size` (Table 20's for types 1 to 50, the custom size for 63),
|
||
`transform_type`, `chroma_sampling_type`, `base_depth` and `enhancement_depth` (`8 + 2·type`),
|
||
`temporal_enabled`, `upsample_type`, `tile_dimensions_type`.
|
||
|
||
Table 20, types 1 to 50: 360×200, 400×240, 480×320, 640×360, 640×480, 768×480, 800×600,
|
||
852×480, 854×480, 856×480, 960×540, 960×640, 1024×576, 1024×600, 1024×768, 1152×864,
|
||
1280×720, 1280×800, 1280×1024, 1360×768, 1366×768, 1400×1050, 1440×900, 1600×1200, 1680×1050,
|
||
1920×1080, 1920×1200, 2048×1080, 2048×1152, 2048×1536, 2160×1440, 2560×1440, 2560×1600,
|
||
2560×2048, 3200×1800, 3200×2048, 3200×2400, 3440×1440, 3840×1600, 3840×2160, 3840×2400,
|
||
4096×2160, 4096×3072, 5120×2880, 5120×3200, 5120×4096, 6400×4096, 6400×4800, 7680×4320,
|
||
7680×4800.
|
||
|
||
## 7. MPEG-H 3D Audio
|
||
|
||
§7.1 **Sources.** ISO/IEC 23008-3 is not openly readable. The MHAS packet syntax, the packet
|
||
types and the first fields of the configuration are those two independent open decoders agree
|
||
on; the low-complexity profile-level codes 0x0B to 0x0D are confirmed by ATSC A/342-3:2024-04
|
||
§5.2.2.1. Neither open decoder is under a licence this corpus can use, so the corpus's MHAS
|
||
vectors are written by its generator (§13.2).
|
||
|
||
§7.2 **Packets.** A `wai.audio.mpegh` payload is an MHAS stream: packets, each a header of
|
||
`MHASPacketType` = escapedValue(3, 8, 8), `MHASPacketLabel` = escapedValue(2, 8, 32) and
|
||
`MHASPacketLength` = escapedValue(11, 24, 24), then that many bytes. escapedValue(n1, n2, n3)
|
||
reads `v` = u(n1); when `v` is 2^n1 − 1 it reads `a` = u(n2) and adds it; when `a` is
|
||
2^n2 − 1 it reads u(n3) and adds that too. Every header is a whole number of bytes. The first
|
||
packet is a synchronisation packet (type 6) or a configuration packet (type 1), else
|
||
`no_signature`; a packet past the end is `truncated`. A synchronisation packet has label 0 and the
|
||
one byte `0xA5`, else `reserved_value`. A frame packet (type 2) before the first configuration is
|
||
`out_of_order`; a payload with no configuration is `missing_structure`. Other types are passed
|
||
over.
|
||
|
||
§7.3 **The configuration.** The first configuration packet's payload: the profile-level
|
||
indication u(8); `usacSamplingFrequencyIndex` u(5), its rate by the table below, or, for 31, a
|
||
rate u(24) (0 is `reserved_value`); `coreSbrFrameLengthIndex` u(3); one reserved bit;
|
||
`receiverDelayCompensation` u(1); `speakerLayoutType` u(2); then, for type 0,
|
||
`CICPspeakerLayoutIdx` u(6), and for types 1 and 2 the speaker count, escapedValue(5, 8, 16) + 1.
|
||
Rates by index 0 to 30: 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000,
|
||
11025, 8000, 7350, reserved, reserved, 57600, 51200, 40000, 38400, 34150, 28800, 25600, 20000,
|
||
19200, 17075, 14400, 12800, 9600, reserved, reserved, reserved; a reserved index is
|
||
`reserved_value`.
|
||
|
||
§7.4 **Parameters.** `profile_level`; `profile` and `level`: `low-complexity` 1 to 5 for 0x0B to
|
||
0x0F, `baseline` 1 to 5 for 0x10 to 0x14, else `null`; `sampling_rate`; `core_frame_length_index`;
|
||
`speaker_layout_type`; `cicp_layout`; `speakers`; and the counts `packets`, `frames`, `syncs` and
|
||
`configs`.
|
||
|
||
## 8. AVS3 video
|
||
|
||
§8.1 **Sources.** T/AI 109.2 is not openly readable. The sequence header and the pseudo-start-code
|
||
prevention are read as an open decoder (BSD-3-Clause) reads them, with the start codes it and an
|
||
open syntax reading under LGPL-2.1 agree on. ETSI TS 101 154 V2.10.1 §5.16.2 requires the library
|
||
flags to be 0 and confirms the profile codes 0x20, 0x22 and 0x32.
|
||
|
||
§8.2 **Units.** A `wai.video.avs3` payload begins, after any zero bytes (at least two), with the
|
||
prefix `0x000001`, else `no_signature`. A unit is the byte after a prefix (its start code) and the
|
||
bytes up to the next prefix. A unit's bytes are read with the prevention bits removed: in each
|
||
byte `0x02` that follows two zero bytes of the unit, its two low bits. Start codes: `0xB0`
|
||
sequence header, `0xB1` sequence end, `0xB3` intra picture, `0xB6` inter picture. A payload with no
|
||
sequence header is `missing_structure`; one whose first unit is not one is `out_of_order`; one
|
||
with no intra picture is `missing_structure`.
|
||
|
||
§8.3 **The sequence header.** `profile_id` u(8), `level_id` u(8), `progressive_sequence` u(1),
|
||
`field_coded_sequence` u(1), `library_stream_flag` u(1) (1 is `outside_probe`),
|
||
`library_picture_enable_flag` u(1) (1 is `outside_probe`: a flag follows whose place the open
|
||
texts do not establish), `marker_bit`, `horizontal_size` u(14), `marker_bit`, `vertical_size` u(14),
|
||
`chroma_format` u(2), `sample_precision` u(3), `encoding_precision` u(3) for profiles 0x22 and
|
||
0x32 only, `marker_bit`, `aspect_ratio` u(4), `frame_rate_code` u(4), `marker_bit`,
|
||
`bit_rate_lower` u(18), `marker_bit`, `bit_rate_upper` u(12), `low_delay` u(1),
|
||
`temporal_id_enable_flag` u(1), `marker_bit`, `bbv_buffer_size` u(18), `marker_bit`,
|
||
`max_dpb_size_minus1` u(4). A `marker_bit` of 0 is `reserved_value`, and so are a size, chroma
|
||
format or sample precision of 0 and a frame rate code of 0 or above 13.
|
||
|
||
§8.4 **Parameters.** `profile_id`, `level_id`, `progressive`, `field_coded`, `size`,
|
||
`chroma_format`, `sample_precision`, `encoding_precision` (or `null`), `aspect_ratio`,
|
||
`frame_rate_code`, `bit_rate` (`bit_rate_upper` · 2^18 + `bit_rate_lower`), `low_delay`,
|
||
`temporal_id_enabled`, `bbv_buffer_size`, `max_dpb_size`, `pictures` (`[intra, inter]` counts) and
|
||
`sequence_end` (whether a sequence end unit is present).
|
||
|
||
## 9. AVS3 audio
|
||
|
||
§9.1 **Sources.** T/AI 109.3 is not openly readable. The frame header is read as an open
|
||
demultiplexer under LGPL-2.1 reads it; ETSI TS 101 154 V2.10.1 §6.10.2 constrains the values a
|
||
broadcast stream uses. The demultiplexer reads only the lossy codec and refuses ancillary data,
|
||
and the probe does the same (`outside_probe`). It also skips two 8-bit fields it does not name,
|
||
and so does the probe. The header states no frame length, so the probe reads the first frame's
|
||
header only.
|
||
|
||
§9.2 **The header.** A sync word of 12 bits, `0xFFF` (else `no_signature`); `audio_codec_id` u(4)
|
||
(1, lossless, is `outside_probe`; anything but 2 is `reserved_value`); `anc_data` u(1) (1 is
|
||
`outside_probe`); `nn_type` u(3) (above 1 is `reserved_value`); `coding_profile` u(3) (above 2 is
|
||
`reserved_value`); `sampling_frequency_index` u(4), rates 192000, 96000, 48000, 44100, 32000,
|
||
24000, 22050, 16000, 8000 (above 8 is `reserved_value`); 8 bits; then for profile 0
|
||
`channel_number_index` u(7); for profile 1 `soundbed_type` u(2): for 0 the object count less one
|
||
u(7) and the per-object bitrate index u(4), for 1 `channel_number_index` u(7), the bitrate index
|
||
u(4), the object count less one u(7) and the per-object bitrate index u(4), and above 1
|
||
`reserved_value`; for profile 2 the ambisonic order less one u(4) (an order outside 1 to 3 is
|
||
`reserved_value`); then `resolution` u(2) (above 2 is `reserved_value`), the bitrate index u(4)
|
||
unless the profile is 1, and 8 bits.
|
||
|
||
§9.3 **Parameters.** `codec_id`, `nn_type`, `coding_profile`, `sampling_rate`, and as the profile
|
||
gives them `channel_number_index`, `soundbed_type`, `objects`, `bitrate_index`,
|
||
`bitrate_index_per_object`, `ambisonic_order`; and `resolution_bits` (8 · (`resolution` + 1)).
|
||
|
||
## 10. IEEE 1857.11
|
||
|
||
§10.1 `wai.image.ieee1857_11` is a candidate (SPEC §5): IEEE 1857.11-2024 is not openly readable,
|
||
and the open reference software (BSD-2-Clause) writes a picture header with no start code, from a
|
||
working draft, marking the code that would write one as not yet written. So no payload format is
|
||
pinned. This parse reads that header as the software's writer lays it out, at the revision the
|
||
corpus README names. Its reader masks `level_id` differently from its writer; the parse follows
|
||
the writer. With no signature, the parse cannot tell this format from another; it reads a payload
|
||
declared to be one, and never refuses `no_signature`.
|
||
|
||
§10.2 **The header**, big-endian: 3 bytes holding `profile_id` (3 bits), `level_id` (6),
|
||
`model_id` (3), `parameter_set_id` (7) and `quality_id` (5); the picture's height and width as
|
||
32-bit values; 2 bytes holding 2 unused bits (0), `output_bit_depth` (3), `picture_format` (3),
|
||
`log2_slice_size_h_minus6` (4) and `log2_slice_size_w_minus6` (4). Fewer than 13 bytes is
|
||
`truncated`. A `profile_id` above 2, an unused bit set, an `output_bit_depth` other than 1 (8
|
||
bits) or 2 (10 bits), or a height or width of 0 is `reserved_value`.
|
||
|
||
§10.3 **Parameters.** `profile_id`, `level_id`, `model_id`, `parameter_set_id`, `quality_id`,
|
||
`size` (`[width, height]`), `bit_depth`, `picture_format`, `slice_size`
|
||
(`[2^(w+6), 2^(h+6)]`).
|
||
|
||
## 11. The projection descriptor
|
||
|
||
§11.1 The probe of `wai.meta.projection` reads the descriptor as [projection](projection.md) §3
|
||
lays it out and checks it as its §4 does; its parameters are those of projection.md §3. The
|
||
check of a descriptor against the rendition it accompanies, which needs that rendition's probe,
|
||
is projection.md §5's.
|
||
|
||
## 12. Refusals
|
||
|
||
| code | meaning |
|
||
|---|---|
|
||
| `no_signature` | the payload does not begin with the format's signature |
|
||
| `truncated` | the bytes end inside a structure the probe reads |
|
||
| `out_of_order` | a structure is where the format does not allow it |
|
||
| `reserved_value` | a field holds a value the format forbids or reserves |
|
||
| `length_mismatch` | a length a structure declares disagrees with the bytes |
|
||
| `missing_structure` | a structure the format requires is absent |
|
||
| `not_multiview` | a `wai.video.mvhevc` payload with no second view |
|
||
| `framing_invalid` | the framing of a `wai.video.jxs` payload is wrong |
|
||
| `trailing_bytes` | bytes follow the end of the payload's last structure |
|
||
| `descriptor_invalid` | a projection descriptor's fields disagree with each other |
|
||
| `layer_absent` | a projection descriptor names a layer its rendition does not hold |
|
||
| `outside_probe` | the payload uses a feature whose syntax the probe's sources do not establish |
|
||
| `no_probe` | no probe is defined for the capability |
|
||
|
||
## 13. Conformance
|
||
|
||
§13.1 [`format-probe-conformance/`](../format-probe-conformance/) holds `vectors.json`: every
|
||
vector's capability, file, SHA-256, origin and outcome (its parameters, or its refusal), the
|
||
projection descriptors' bindings with theirs (projection.md §5), and the facts of §13.2.
|
||
|
||
§13.2 **External vectors** (`ext/`) were written by permissively licensed encoders at pinned
|
||
revisions from synthetic pictures, and each was decoded again; `tools/make_external.sh` writes
|
||
them and `provenance.json`, which records every command and decode. **Facts** are what each
|
||
encoder was asked for (a size, a profile, a view count): the probe must read them, which ties the
|
||
probe to the encoder and not to itself. **Generated vectors** (`gen/`) are written by
|
||
`wai_format_probe gen` from fixed values and from the external vectors: the formats no
|
||
permissively licensed encoder writes (LCEVC, MHAS, AVS3 audio, the IEEE 1857.11 header, the
|
||
projection descriptor) and the negative controls, each refused with a code of §12, every code
|
||
given.
|
||
|
||
§13.3 **Fetched vectors.** `fetch.sh` fetches five LCEVC streams an open decoder's tests use,
|
||
written by an LCEVC encoder, and checks each SHA-256; the corpus names them and does not hold
|
||
them, because their licence notice names their owner. Each is a container of blocks (an 8-byte
|
||
magic `lcevcbin`, a `u32` version, then per block a `u16` type, a `u32` size and that many bytes,
|
||
the first 16 of which are two indices) whose remaining bytes, concatenated, are the byte stream.
|
||
`vectors.json` states, for each, what its encoder was asked for.
|
||
|
||
§13.4 `wai_format_probe verify` and `wai-rs/tests/format_probe.rs` require every outcome, binding
|
||
and fact, and the generated files byte for byte; with `--fetched` the verifier requires every
|
||
fetched stream. `format_probe_verify.py`, written from this text and projection.md and sharing no
|
||
code with wai-rs, does the same, and requires every mutated copy of the corpus to fail.
|