Skip to main content

WAI Extension: Frame Streams

Mirrored from the canonical text at commit c5e7133e ().

Status: Draft. Carries an inter-frame video capability one frame an object: each object is one whole WAI1 envelope holding one frame; a group opens with an intra frame, which resets the decoder state; and each later frame of the group names its predecessor by content hash, so that a sink refuses a lost, reordered or altered frame instead of decoding past it against the wrong reference. Registers four frame capabilities (§1), the manifest member frame (§2), the neural frame payload WNF1 (§4) beside the integer one, WIF1 (integer-payloads §16), and the checks a sink makes (§5). The MoQ catalog member that declares a frame stream on a track, wai_frame_stream, is moq-streaming-format §4.3. §9 maps a neural frame stream to and from a track of the neural video packaging of the MOQT Streaming Format (NMSF, draft-herz-moq-nmsf-01), byte for byte where both sides state a frame. No transport is defined or changed: a frame stream rides any carrier that delivers objects in order. Reference implementation: wai-rs — frame_stream::{FrameStream, IntFrames, ParseOnly, split_wiv1, split_dcvc, join_dcvc, catalog, nmsf}, neural::DcvcFrames. Conformance: int-payload-conformance/frame-stream/. Keywords MUST, MUST NOT, SHOULD, MAY are RFC 2119/8174.

1. Scope

An inter-frame capability’s registered payload holds a whole clip: WIV1 codes every frame of a clip in one residual stream (integer-payloads §3), and the reference neural inter-frame payload holds every frame’s bitstreams behind one header (§6). A live sender has one frame at a time, and a carrier that moves objects (MoQ, SPEC §1) moves each frame as it is made. Each frame capability below carries one frame of its base’s bitstream as its payload:

frame capabilitybasepayloadparameter setregistry class
wai.video.int_motion.framewai.video.int_motionWIF1, keyframe 0 (integer-payloads §16)noneStandardDefined
wai.video.int_hyper.framewai.video.int_hyperWIF1, keyframe 1 (integer-payloads §16)the base’s: entropy.json, g_s.whm, h_s.whmNeuralIntegerExact
wai.video.int_cond.framewai.video.int_condWCF1 (integer-payloads §17)the base’s: model.wcbNeuralIntegerExact
wai.neural.dcvc_rt.framewai.neural.dcvc_rtWNF1 (§4)the base’s, sink-suppliedNeuralFloat
wai.neural.dcvc_fm.framewai.neural.dcvc_fmWNF1 (§4)the base’s, sink-suppliedNeuralFloat

A frame capability is a capability of its own because it is a different framing of its base’s bitstream, and a registered string’s payload format is fixed (SPEC §8); wai.audio.opus.packet is the precedent, a capability of one Opus packet whose decoder state carries from packet to packet. Each is a payload capability, media class video, with its base’s fidelity tier and licence class, and decodes against its base’s parameter set, of its base’s shape: a pin on a frame object names the set its base’s pin would name.

2. Groups and the frame member

A frame stream is a sequence of objects of one frame capability, in the order a sink receives them. It is made of groups: a group is one intra frame, then zero or more inter frames, in order. An intra frame’s decode reads nothing but its own payload (and the parameter set); an inter frame’s reads the state the frames before it in its group left (for WIF1, the previous decoded frame and its intra frame’s table; for WNF1 and WCF1, the reference feature).

Every envelope of a frame capability carries the manifest member frame, an object:

membertypemeaning
indexinteger, 0 to 2^53 − 1the frame’s position in its group: 0 for its intra frame, the frame before it plus 1 for every other
prevstring, or nullon an inter frame, the content hash (jwp-receipts §2.1) of the envelope of the frame before it in its group, as 64 lowercase hexadecimal digits; null on an intra frame
numberOPTIONAL, integer, 0 to 2^53 − 1the frame’s sequence number in its stream, as its publisher counts it: on every frame of a group whose intra frame carries one, each the one before it plus 1; on none of a group whose intra frame carries none
capture_msOPTIONAL, integer, 1 to 2^53 − 1the wallclock at which the frame was captured, in milliseconds since 1970-01-01T00:00:00Z, as its publisher states it; absent where it states none
"frame": { "index": 3, "prev": "<64 lowercase hexadecimal digits>", "number": 1203, "capture_ms": 1793491239699 }

frame is an OPTIONAL manifest member under SPEC §8’s rule for a MINOR revision: an envelope that does not carry it keeps its bytes and its meaning. It is carried exactly when the capability is a frame capability. A reader of an earlier revision does not advertise a frame capability, so it finds such an envelope’s capability unsupported and the envelope inert (SPEC §4).

3. The integer frame forms

wai.video.int_motion.frame and wai.video.int_hyper.frame carry WIF1 (integer-payloads §16). A group’s intra frame carries the group’s residual table, its q and offset, and frame 0: with keyframe 0 its residual symbols, predicted from grey; with keyframe 1 the base’s nested WIH1, the learned keyframe. Each inter frame carries its motion vectors, its mv_precision and block, and its residual symbols, in a stream of its own. The decode of each frame is WIV1’s frame step (integer-payloads §3), through the same stage operators (integer-operators §13.5; the keyframe through whm1/1, §13.2), so:

wai.video.int_cond.frame carries WCF1 (integer-payloads §17): one frame of conditional inter-frame coding, whose latent is coded given the feature the frame before it in its group left, and which leaves its own feature to the frame after it. Its intra frame reads the zero feature. Each frame is decoded by integer-payloads §17.4 through its pinned set, so the same two properties hold: its frames reproduce on every conforming sink given their chain, and a group split from a WIC1 clip (integer-payloads §17.2, a copy of the clip’s frames) decodes to the clip’s frames, byte for byte.

4. WNF1 — one frame of the reference neural inter-frame payload

wai.neural.dcvc_rt.frame and wai.neural.dcvc_fm.frame carry WNF1: one frame’s two bitstreams, behind the clip header every frame of its group repeats.

offsizefieldrule
04magic WNF1
41version1
51kind0 intra, 1 inter
62reserved0
84h≥ 1
124w≥ 1
164fps_milliframes per second × 1000
202cy≥ 1: the latent’s channels
222cz≥ 1: the hyper-latent’s channels
241sy_log2≤ 15: the latent’s side is sy = 2^sy_log2
251sz_log2≤ 15: the hyper-latent’s side is sz = 2^sz_log2
262qthe quality index the entropy tables are read at
282cf≥ 1: the reference feature’s channels
302reserved0
324lzthe hyper-latent bitstream’s length
364lythe latent bitstream’s length
40lzthe hyper-latent bitstream
…lythe latent bitstream

Nothing follows the latent bitstream. Every multi-byte field is little-endian.

Checks, in this order, each with its code from integer-payloads §8: the magic (bad_magic); the version byte, present (stream_length) and 1 (version); the fixed header of 40 bytes (stream_length); the reserved fields (reserved_nonzero); kind, then h, w, cy, cz and cf at least 1, then sy_log2 and sz_log2 at most 15 (field_range); the frame h·w·3, the latent cy·sy·sy, the hyper-latent cz·sz·sz and the reference feature cf·sy·sy, each at most 2^26 elements (too_large); the two bitstreams (stream_length); nothing after them (trailing).

Decode. The bitstreams are the capability’s own, as its reference decoder reads them (neural/video_dcvc.rs): the latents are entropy-decoded from the two bitstreams against the base’s parameter set at q, and the base’s temporal network maps the latents and the reference feature to the frame and the next reference feature. An intra frame starts the reference feature at zero; an inter frame reads the one the frame before it left, and carries its intra frame’s header, every field from h to cf (geometry_mismatch). A decode the capability’s decoder cannot complete is refused payload_malformed, and a pin that does not resolve with SPEC §3.1’s code. The decode runs floating point: its frames reproduce on one build and not across hardware (NeuralFloat, SPEC §7), so these strings never back intent = replicate. The chain of §2 still holds every frame to its predecessor: two sinks may present different pixels, never different frames.

5. What a sink checks

A sink holds, for each frame stream it decodes, its reference: the last frame it decoded, its content hash, its index and its pin, and the decoder state the frame left. It checks each object it receives, in this order, and refuses it at the first rule that fails:

  1. The envelope reads (SPEC §2): envelope_malformed.
  2. Its capability is the stream’s: frame_capability_mismatch.
  3. It carries frame, an object: frame_link_missing.
  4. frame’s index is an integer from 0 to 2^53 − 1, its prev is null or 64 lowercase hexadecimal digits, its number, where present, is an integer from 0 to 2^53 − 1, and its capture_ms, where present, is an integer from 1 to 2^53 − 1: frame_link_malformed.
  5. The payload parses alone: integer-payloads §16 for WIF1, §17.1 for WCF1, §4 for WNF1, each with its code.
  6. frame agrees with the payload’s kind: an intra frame has index 0 and prev null, an inter frame an index of 1 or more and a prev: frame_link_mismatch.

An intra frame then drops the reference, is decoded (SPEC §3.1’s pin checks, then the decode’s codes), and becomes the reference. An inter frame is checked against the reference first:

  1. The sink holds a reference: frame_no_reference.
  2. Its prev is the reference’s content hash: frame_gap when its index is past the one after the reference’s (frames are missing), frame_prev_mismatch otherwise.
  3. Its index is the reference’s plus 1: frame_index_mismatch. Its number is the reference’s plus 1 where the reference carries one, and absent where the reference carries none: frame_number_mismatch.
  4. Its conditioning.prior is the reference’s, compared as JSON values (both absent counts as the same): frame_prior_changed.
  5. It is decoded against the reference: for WIF1, its h × w is its group’s (geometry_mismatch), then the decode’s codes; for WCF1, its header, h to cf, is its group’s (geometry_mismatch), then the decode’s codes (integer-payloads §17.4); for WNF1, its header is its group’s (geometry_mismatch), then the decode’s.

It then becomes the reference. After any refusal the sink holds no reference: every inter frame it receives is refused (frame_no_reference) until an intra frame opens a group. So a sink never decodes an inter frame against a reference that is not its predecessor’s decode: a lost frame, a frame delivered twice or out of order, and an altered prev are each refused at the first frame they would corrupt, and the stream resumes at the next group. A sink that joins a stream joins at an intra frame.

codewhen
envelope_malformedthe object is not a WAI1 envelope that reads
frame_capability_mismatchthe object’s capability is not the stream’s
frame_link_missingno frame member, or one that is not an object
frame_link_malformedan index or prev outside its type or range
frame_link_mismatchan intra frame with a prev or an index other than 0, or an inter frame with no prev or index 0
frame_no_referencean inter frame while the sink holds no reference
frame_gapan inter frame whose predecessor is not the reference, with frames missing between
frame_prev_mismatchan inter frame whose prev is not the reference’s content hash
frame_index_mismatchan inter frame that names the reference but whose index is not the next
frame_number_mismatchan inter frame whose number is not the one after the reference’s, or that carries one where the reference carries none, or none where it carries one
frame_prior_changedan inter frame whose pin is not its group’s

A payload’s refusals are integer-payloads §8’s codes; a pin’s are SPEC §3.1’s.

6. Splitting a clip

WIV1. A WIV1 clip is one group of WIF1 frames, frame for frame. Frame 0 is the intra frame: the clip’s table, q and offset, and, with keyframe 0, frame 0’s residual symbols; with keyframe 1, the clip’s nested WIH1. Each frame f ≥ 1 is an inter frame: frame f’s motion vectors, the clip’s mv_precision and block, and frame f’s residual symbols. Each frame’s symbols are the ones the clip’s residual stream decodes to for that frame, coded into a stream of their own by the rANS coder integer-payloads §2 decodes (its state starting at 2^31, so each stream ends canonically). The group decodes, frame by frame, to the clip’s frames, byte for byte (§3). The split refuses a clip whose residual stream does not decode: stream_exhausted, stream_noncanonical, and the parse’s codes. A stream of several groups is the split of several clips, one after another.

The reference neural payload. The reference decoder of wai.neural.dcvc_rt and wai.neural.dcvc_fm reads a whole clip as: h, w, n_frames, fps_milli (u32), cy, cz (u16), sy_log2, sz_log2 (u8), q, cf (u16), 26 bytes; then n_frames pairs of u32 lengths (lz, ly); then each frame’s hyper-latent and latent bitstreams, in order. Its split is one group of WNF1 frames, each with the clip’s header and its own two bitstreams, copied; frame 0 intra, every other inter. The split reads the clip strictly: its header as WNF1’s checks read it, at least one frame (field_range), every bitstream inside it (stream_length) and nothing after the last (trailing). The join is its inverse: one group of WNF1 frames, the first intra and the others inter (field_range), each with the first’s header (geometry_mismatch), back to the clip. The split and the join give each other’s input back, byte for byte, and the decode of the frames is the decode of the clip: the reference decoder’s whole-clip decode runs the same step a frame (neural/video_dcvc.rs, Temporal::step).

7. Carriage

A frame stream rides any carrier that delivers its objects in order; this extension defines no transport. Each object keeps every rule of the carrier for a WAI1 object, and its receipt is an object receipt like any other (jwp-receipts).

A frame object is complete when its frame is coded, so a live sender publishes each frame as it is made, and a sink presents it when it is decoded.

8. Reference implementation and conformance

9. NMSF tracks

draft-herz-moq-nmsf-01 (NMSF) packages the frames of a neural inter-frame codec for the MOQT Streaming Format as packaging nvc: one frame an object, a group of pictures a MOQT group that opens with a neural keyframe (NMSF §3.5), the model’s weights installed on both sides and named, not sent (NMSF §8). A frame stream of wai.neural.dcvc_rt.frame or wai.neural.dcvc_fm.frame carries the same bitstreams, so a publisher maps one to the other: an NMSF frame becomes one WNF1 frame object (a rewrap, §9.4), and a frame object becomes one NMSF object, or two (an unwrap, §9.5). Neither changes a bitstream; an unwrap of a rewrap gives the NMSF objects back byte for byte; and a relay forwards both tracks as it forwards any track. A section number of NMSF here is one of that revision’s; where a later revision renumbers or changes what this section cites, this section is what changes.

9.1 What maps

An NMSF object is a 26-byte header and a payload (NMSF §3.2). This section reads the header from the field definitions, which give each field’s size and sum to the 26 bytes the section states; the figure before them draws pts_ms one byte short. Every field is big-endian:

offsizefield
01frame_type: 0x00 Intra, 0x01 Inter, 0x02 to 0xFF reserved (NMSF §3.3)
11qp: 0 to 63; 64 to 255 reserved
24frame_number
68pts_ms
144width
184height
224payload_len
26payload_lenthe payload

The payload is components (NMSF §3.6), each channels, height, width and data_len (u32, big-endian) and then data_len bytes of an entropy-coded tensor. In single-track mode an object’s payload is the hyperprior’s component and then the latent’s; in two-track mode the hyperprior track’s object holds the hyperprior’s component and the latent track’s object the latent’s, the two objects of a frame with the same header (NMSF §3.4). A frame object holds the same frame as:

NMSFframe objectwhere it has no form
codec dcvc-rt, dcvc-fm (NMSF §5)the capability wai.neural.dcvc_rt.frame, wai.neural.dcvc_fm.frame; conditioning.kind dcvc_rt, dcvc_fmany other codec: nmsf_codec_unmapped. dcvc-dc is SPEC §5’s candidate wai.neural.dcvc_dc, which pins no bitstream and has no frame form; ssf, fvc, rlvc and elfvc WAI does not register
a MOQT group: an Intra frame, then Inter framesa group of the stream (§2); the object of Object ID k is the frame of index k (moq-streaming-format §4.3)
frame_type Intra, InterWNF1 kind 0 (index 0, prev null), 1 (index 1 or more, prev the frame before)a reserved type: nmsf_reserved
qpWNF1 qa reserved qp: nmsf_reserved; a q past 63 (§9.5): nmsf_value_unmappable
frame_numberframe.number (§2)a frame with no number, or one past 2^32 − 1 (§9.5): nmsf_value_unmappable
pts_ms; 0 where it states noneframe.capture_ms (§2); absent where it states nonea pts_ms past 2^53 − 1: nmsf_value_unmappable
width, heightWNF1 w, h
the hyperprior’s componentWNF1 cz, sz_log2 (the side is 2^sz_log2) and the hyper-latent bitstreama tensor that is not square, whose side is not a power of two at most 2^15, or of channels outside 1 to 65 535 (§4): nmsf_shape_unmappable
the latent’s componentWNF1 cy, sy_log2 and the latent bitstreamas the hyperprior’s
the catalog’s framerateWNF1 fps_millia framerate that is not a whole number of thousandths (§9.2), or a frame of another fps_milli (§9.5): nmsf_value_unmappable
—WNF1 cf, the reference feature’s channels, from the model binding (§9.3)
codec and nvc.modelVersion, the model by nameconditioning.prior and wai_priors, its parameter set by SHA-256 (SPEC §3.1), through the model binding

9.2 The catalog member wai_nmsf

A WAI track whose frames map to an NMSF track keeps that track’s catalog entries in the member wai_nmsf: an array of one entry (single-track mode) or two (two-track mode, a hyperprior and a latent track, NMSF §3.1), each a JSON object as NMSF §3.7 and §3.8 state it, in the order given. The frame objects do not carry colorspace, gopSize, priority, nvcRole, depends or the nvc object, and wai_nmsf keeps them, so the entries an unwrap publishes are the entries the rewrap read, member for member. A rewrap publishes the entry:

{ "name": "video/wai", "packaging": "wai", "isLive": true, "role": "video",
  "width": 64, "height": 64, "framerate": 30,
  "wai_capabilities": ["wai.neural.dcvc_rt.frame"],
  "wai_frame_stream": { "capability": "wai.neural.dcvc_rt.frame" },
  "wai_priors": [ { "capability": "wai.neural.dcvc_rt.frame",
                    "sha256": "<64 lowercase hexadecimal digits>",
                    "form": "wai.prior.set", "tier": "none" } ],
  "wai_nmsf": [ { "name": "video", "packaging": "nvc", "isLive": true, "codec": "dcvc-rt",
                  "width": 64, "height": 64, "framerate": 30, "colorspace": "ycbcr-bt709",
                  "gopSize": 4, "nvc": { "modelVersion": "cvpr2025" } } ] }

Its name is the publisher’s; isLive, width, height and framerate are the first NMSF entry’s; it declares the frame stream (moq-streaming-format §4.3); wai_priors (§4.2) lists the binding’s pin, with its form and tier where the pin states them, and is absent where the binding has no pin; wai_nmsf holds the NMSF entries.

Reading NMSF entries. A publisher reads them, in this order, and refuses the track at the first rule that fails:

  1. Each entry is an object with name (a non-empty string), packaging "nvc", isLive (a boolean), codec and colorspace (strings), width, height and gopSize (integers of at least 1) and framerate (a number above 0); priority, where present, a number; nvcRole and depends, where present, strings; and nvc, where present, an object whose modelVersion, where present, is a string. There is one entry, with no nvcRole, or two: one of nvcRole "hyperprior" and one of "latent", whose depends is the hyperprior entry’s name, the two names different. Otherwise nmsf_catalog_malformed.
  2. Two entries agree on codec, isLive, width, height, framerate (as numbers), colorspace, gopSize and nvc.modelVersion (both absent counts as the same): nmsf_track_mismatch.
  3. The codec has a frame capability (§9.1): nmsf_codec_unmapped.
  4. fps_milli is the integer m nearest framerate × 1000, from 1 to 2^32 − 1, where m ÷ 1000 is framerate in binary64 arithmetic: 29.97 is 29 970, and 30 000 ÷ 1 001 has none (nmsf_value_unmappable).

Reading a WAI entry. An unwrap reads the entry’s frame stream (moq-streaming-format §4.3, catalog_frame_stream_malformed; a track that declares none has no NMSF form, nmsf_no_form); its wai_nmsf (absent or null: nmsf_no_form; not an array: nmsf_catalog_malformed), whose entries read as above and whose codec’s frame capability is the declared one (nmsf_catalog_malformed); and the pin wai_priors lists for that capability: each of its entries an object, and one for the capability with a sha256 of 64 lowercase hexadecimal digits and a form that is absent, null or a string (nmsf_catalog_malformed). It lists none, and the frames carry no pin; or one, and they carry it; or several, and the track has no NMSF form, which names one model (nmsf_no_form). A publisher that unwraps a frame stream it wrote itself states its NMSF entries in wai_nmsf: the colorspace and GOP size its frames do not carry are its to state.

9.3 The model binding

NMSF names a model by codec and nvc.modelVersion and leaves the distribution of its weights to the deployment (NMSF §8). A frame object names its parameter set by SHA-256 in its pin, which a sink checks before it decodes (SPEC §3.1). A model binding is the publisher’s statement of the set a name stands for, and of what WNF1 needs of the model that an NMSF object does not carry:

{ "codec": "dcvc-rt", "modelVersion": "cvpr2025", "cf": 64,
  "prior": { "id": "dcvc-rt/cvpr2025", "sha256": "<64 lowercase hexadecimal digits>",
             "determinism": "float", "form": "wai.prior.set", "tier": "none" } }
memberpresencemeaning
codecREQUIRED, stringthe NMSF codec identifier
modelVersionstring, null or absentthe nvc.modelVersion it binds; null or absent binds a track that names none
cfREQUIRED, integer, 1 to 65 535the channels of the model’s reference feature, WNF1’s cf (§4)
priora pin (SPEC §3.1), null or absentthe parameter set every frame object carries as its pin; null or absent, the frames carry none

A binding that does not read so is nmsf_binding_malformed. A rewrap maps a track through the first binding whose codec and modelVersion are the track’s: none is nmsf_model_unbound. The neural frame forms are NeuralFloat, so a binding’s pin claims no tier above none (SPEC §3.1). A binding is the publisher’s configuration and is not carried: in the catalog a rewrap publishes, its name is in wai_nmsf and its pin in wai_priors, so an unwrap reads both from there.

9.4 Rewrap: NMSF to frame objects

A publisher maps an NMSF track’s frames in the order it receives them: each frame one object, or in two-track mode the hyperprior track’s object and the latent track’s object of the frame (NMSF §4.2), with the MOQT Object ID where the carrier gives one. It holds the group it is mapping: its last frame’s index, frame_number, WNF1 header and frame object’s content hash. It checks each frame in this order, and refuses it at the first rule that fails:

  1. The frame is one object in single-track mode and two in two-track mode: nmsf_track_mismatch.
  2. Each object, in order, is at least 26 bytes and its payload_len is the length of the bytes after its header (nmsf_object_malformed), and its frame_type and qp are not reserved (nmsf_reserved).
  3. The two objects of a frame have the same header, payload_len aside: nmsf_track_mismatch.
  4. Components fill each payload: two in single-track mode, one in each object in two-track mode: nmsf_object_malformed.
  5. An Intra frame drops the group, and is at Object ID 0 where it has one. An Inter frame follows a group, its frame_number the group’s last plus 1 and its Object ID, where it has one, the group’s last index plus 1. Otherwise nmsf_group_order.
  6. Its pts_ms is at most 2^53 − 1: nmsf_value_unmappable.
  7. Each component has a WNF1 form (§9.1), and the WNF1 header the frame gives passes §4’s checks: nmsf_shape_unmappable.
  8. An Inter frame’s WNF1 header is its group’s, so its qp, width, height and tensor shapes are its Intra frame’s: nmsf_group_header_changed.

It then writes the frame object: a WAI1 envelope of the codec’s frame capability, media video, intent perceptual, conditioning.kind the codec’s (§9.1) and conditioning.prior the binding’s pin, with no fallback (§2). Its payload is the WNF1 frame of kind frame_type, h height, w width, fps_milli the track’s (§9.2), cy, cz, sy_log2 and sz_log2 the components’, q qp, cf the binding’s, and the components’ data as its two bitstreams. Its frame is index, prev, number frame_number and capture_ms pts_ms, absent where pts_ms is 0. The frame object becomes the group’s last.

After any refusal the publisher holds no group: it refuses every Inter frame (nmsf_group_order) until an Intra frame opens one. A lost or damaged NMSF object therefore yields no frame object for any frame its loss would have changed. A single-track frame and the two objects of the same frame in two-track mode give the same frame object, which a sink admits as any frame (§5).

9.5 Unwrap: frame objects to NMSF

A publisher whose WAI entry reads (§9.2) maps each frame object in order, and refuses it at the first rule that fails:

  1. It is admitted as a sink admits a frame (§5), its payload parsed and held to its group’s header as ParseOnly holds it: §5’s codes and §4’s.
  2. An intra frame’s pin is the one the entry lists: the same sha256 and form, or no pin where the entry lists none: nmsf_model_unbound. §5 holds each inter frame’s pin to its group’s.
  3. Its frame.number is present and at most 2^32 − 1: nmsf_value_unmappable.
  4. Its WNF1 q is at most 63 and its fps_milli is the track’s: nmsf_value_unmappable.

It then writes the NMSF object, or the two: the header frame_type kind, qp q, frame_number number, pts_ms capture_ms (0 where absent), width w, height h; the hyperprior’s component (cz channels, a side of 2^sz_log2 both ways, the hyper-latent bitstream) and the latent’s (cy, 2^sy_log2, the latent bitstream). In single-track mode one object holds both components; in two-track mode the hyperprior track’s object holds the first and the latent track’s object the second, the same header on both. The frame’s cf is not carried. After any refusal the publisher holds no reference (§5), and refuses every inter frame until an intra frame opens a group.

9.6 What each side carries, and the codes

A frame object carries what an NMSF object does not:

An NMSF track carries what a frame stream does not:

codewhen
nmsf_catalog_malformedan NMSF entry, or wai_nmsf or wai_priors in a WAI entry, does not read (§9.2)
nmsf_track_mismatchtwo NMSF entries disagree (§9.2), or the two objects of a frame are not two, or differ in their headers (§9.4)
nmsf_codec_unmappedan NMSF codec with no frame capability
nmsf_model_unboundno model binding for the track’s codec and model version (§9.3), or an intra frame whose pin is not the one the WAI entry lists (§9.5)
nmsf_binding_malformeda model binding that does not read (§9.3)
nmsf_object_malformedan object shorter than its header, whose payload_len is not its payload’s length, or whose payload is not its components (§9.4)
nmsf_reserveda reserved frame_type or qp
nmsf_group_orderan Intra frame past Object ID 0, an Inter frame with no group, or not the next frame_number or Object ID
nmsf_value_unmappablea pts_ms, framerate, number, q or fps_milli the other side cannot state
nmsf_shape_unmappablea tensor or frame WNF1 cannot state (§9.1)
nmsf_group_header_changedan Inter frame whose qp, size or tensor shapes are not its group’s
nmsf_no_forma WAI track with no frame stream, no wai_nmsf, or several pins

9.7 Reference implementation and conformance