AVTransport

Living Document,

This version:
https://cyanreg.github.io/avtransport/
Issue Tracking:
GitHub
Editor:

Abstract

AVTransport is a new mechanism for multimedia transmission and storage. It covers use cases from sub-frame latency streaming of video and audio over raw wireless links, to long-term archival. Its key design goals are robustness and reliability, and it achieves this through extensive error correction, and state-minimal design. Learning from the limitations of other similar protocols and containers, it has built-in future-proofing and allows extensibility.

1. AVTransport protocol

The AVTransport protocol is a standardized mechanism for multimedia transport and storage. This protocol aims to be robust, reliable and low-overhead. Rather than being specialized, the protocol is scalable, from archival to chip to chip interconnect, Ethernet links to satellite links, post-production intermediates to final cinematic deliverables.

The protocol addresses shortcomings of other formats, such as timestamp rounding, lack of DTS, fragile parsing, inflexible metadata, inconvenient index positions and layout, inextensible formats, and rigid overseeing organizations.

1.1. Overview

On a high-level, AVTransport is a packetized wrapper around codec, metadata and user packets and provides context and error resilience, as well as defining a standardized way to transmit such data between clients.

AVTransport is based on individual packets, for which a demuxer interprets and maintains a structure. There is no higher-level structure to the data stored or transmitted.

As a simple example, a possible structure of packets in a general AVTransport session could be:

Packet type Description
§ 2.1 Session start Starts the session with a signature. May be used to identify the stream as an AVTransport session.
§ 2.3 Stream registration Register a new stream.
§ 2.5 Stream configuration Configuration data for the new stream.
§ 2.15 Video information Information about a video stream.
§ 2.12 Metadata Stream or session metadata.
§ 2.11 Index Optional index packets to enable fast seeking.
§ 2.6 Stream Data Stream data packets.
§ 2.6.3 Stream data segmentation Segmented stream data packets.
§ 2.18 User data Optional user data packets.
§ 2.20 End of stream Finalizes a stream or session.

1.2. Packet descriptor

Each packet must be prefixed with a 2-bytes descriptor to identify it. Below is a table of how they’re allocated:

Descriptor values Packet
0x4156 § 2.1 Session start
0x0002 § 2.3 Stream registration
[0x0003:0x0005] § 2.5 Stream configuration
0x0008 § 2.15 Video information
0x0009 § 2.10 Hash packets
[0x00A:0x000C] § 2.12 Metadata
0x0051 § 2.11 Index
[0x0010:0x0012] § 2.13 LUT/ICC profile
[0x0020:0x0023] § 2.14 Font data
[0x0030:0x0031] § 2.8 FEC grouping
0x0040 § 2.16 Video orientation
0x0041 § 2.17 Stereo video
0x0050 § 2.19 Stream duration
0x00FE § 2.9 Stream data parity
0x00FF § 2.6.3 Stream data segmentation
[0x0100:0x01FF] § 2.6 Stream Data
[0x0200:0x02FF] § 2.7 Extended stream data
0x0300 § 2.2 Time synchronization
[0x0600:0x0602] § 2.18 User data
0x0FFF § 2.20 End of stream
0xF001 § 3.3.1 Session control data
0xF002 § 3.3.3 Feedback
0xF003 § 3.3.4 Resend
0xF004 § 3.3.5 Stream control

Note: Range 0x8000 to 0x80FF is reserved for § 3.3 Reverse signalling.

Note: The 16-bit descriptor may be split into two sections, a constant upper 8-bits and variable bottom 8-bits, hence some descriptors are considered a range.

Anything not specified in the table is reserved and must not be used. Demuxers must ignore unknown packets. Future additions will require a version bump of the protocol, but are expected to be backwards compatible.

1.3. Specification conventions

Throughout all of this document, bit sequences are always big-endian, and numbers are always two’s complement.

A special notation is used to describe sequences of bits:

All packets are at least 36 bytes long (288 bits), and always have an 8 byte (64 bits) § 1.4 LDPC code after the first 28 bytes to verify and correct their data.

Identification of the packet is always possible via the first two bytes (the descriptor).

All floating point samples and pixels are always normalized to fit within the interval [-1.0, 1.0].

Padding may be present in some packets (padding). Unless otherwise indicated, the data in padding must be 0x0.

Note: This document is machine-parseable. Each symbol of a packet or enum has an assigned ID of the form descriptor in hex+index, where index is a number starting from 0, incremented for each element in a structure.

1.4. LDPC

To improve reliability, and make the protocol general-purpose, a small amount of parity data is added to each header, in the form of [LDPC].

Their main purpose is to correct bitflips which may occur during transmission or storage of packets.
In situations where bitflips are less likely, they eliminate corrupt packets which may break demuxer state.
Being able to quickly determine whether any 36 or more byte buffer contains a valid packet makes AVTransport streams self-synchronizing.

This makes AVTransport suitable for not only switched networks, but also raw radio frequency links, optical links, or plain serial links. Details for each are available in the § 3.2 Streaming section.

Their theory of operation and specifications are detailed in § 4.3 Annex W: LDPC.

To simplify implementations, two different lengths are used:

Note: Applying LDPC error correction is optional for receiver implementations.
Senders must implement it. This document provides example routines in § 4.3 Annex W: LDPC.

1.5. Global sequence

The global_seq is a 32-bit unsigned integer, incremented by 1 each time after a packet has been sent. Once at 0xffffffff, it MUST overflow back to 0x0. This overflow MUST be handled by the receiver.

Note: global_seq should start at 0x0, but receivers MUST be prepared for any starting offset.

1.6. Stream ID

stream_id is a 16-bit unsigned integer, uniquely identifying each stream contained within an AVTransport stream.

Note: Senders should never reuse stream_id indices, but receivers should be prepared to deal with this scenario.

1.7. Timestamps

AVTransport supports high resolution timestamps, with a maximum resolution of 465.66129 picoseconds. Furthermore, the reliability of the timestamps can be assured through optional § 1.8.1 Jitter compensation.

All time-related fields (pts, dts, duration, and skip_preroll) have a corresponding timebase field with which to interpret them.

The mathematical expression to calculate the time t, in seconds, of a timestamp or duration v and a rational timebase b is the following:

t = v * b.num / b.den

Note: All mathematical operations on timestamps should be done in the integer domain, as floating-point operations may be inaccurate and inconsistent.

The timebase of § 2.6 Stream Data, § 2.19 Stream duration, or any other packets with an explicit stream_id field is given in the § 2.3 Stream registration packets for the appropriate stream.

The time t of a pts field corresponds to the exact time when a packet must be instantaneously released from a decoding buffer, and instantaneously presented.

The time t of a dts field corresponds to the exact time when a packet must be input into a synchronous 1-in-1-out decoder. The dts field is defined as part of the payload when necessary (§ 3.1 Codec encapsulation).

The time t of a duration field corresponds to the exact time difference between two consecutive frames of audio or video. If the field is non-zero, this assertion MUST hold. If this condition is violated, the behavior is unspecified.

1.8. Subtitle timestamps

For subtitle frames, the duration field’s definition is different. It specifies the time during which the contents of the current packet must be presented.

Unlike video or audio, subtitle packets are allowed to have overlapping timestamps. This means that players should be simultaneously presenting all subtitles on screen whose duration indicates that they should be on screen.

For exact information on how this should be done, implementors are invited to view the specifications of each encapsulated subtitle format.

Additionally, for subtitles, duration has two special values:

Implementations are welcome to normalize subtitle timestamps and remove any occurrences of the two special values.

1.8.1. Jitter compensation

Implementations should use the derived ts_clock_freq field from § 2.2 Time synchronization packets to perform jitter compensation of stream timestamps.

The ts_clock_id is a unique 8-bit identifier for the clock. It allows to associate a clock with a given stream. A value of zero indicates the stream has no associated clock.

The ts_clock_id of the § 2.3 Stream registration packets is matched up to the ts_clock_id of § 2.2 Time synchronization packets. If a match is not found, then no processing must be done.

Note: The only valid targets to perform timestamp jitter compensation are streams with the same timebase, which must be equal to the inverse of ts_clock_freq. Jitter compensation is otherwise undefined.

As the ts_clock_freq field defines a strictly monotonic clock signal with a rate of ts_clock_freq, which atomically increments a counter, ts_clock_seq on the rising edge of the waveform, this can be used to compensate the pts, dts and duration values of stream packets.

The following is a suggestion for implementations:

On every received packet:

This is a very simple example which depends on the local receiver oscillator simply being more precise than the transmitter’s oscillator.

Note: The way receivers handle jitter is intentionally left undefined. As a recommendation, implementations should resampple the audio and adjust video frame duration such that synchronization is maintained. Otherwise, implementations can drop or duplicate frames.

1.8.2. Negative times

The time t of a pts may be negative. Packets with a negative timestamps must be decoded, but not presented.

For audio packets, this corresponds to the internal algorithmic delay between the first output sample and the correct sample being available.
For audio, the time between t and 0 may not be a multiple of the audio data’s duration of a packet. Implementations must nevertheless remove any decoded samples with a negative time.

Negative pts values are allowed, and implementations must decode such frames, however must not present any such frames unless pts + duration is greater than 0, in which case they must present the data required for that duration. This enables removal of extra samples added during audio compression, as well as permitting video segments taken out of context from a stream to bundle all dependencies (other frames) required for their presentation.

1.8.3. Epoch definition

The epoch field of § 2.2 Time synchronization packets is an optional field.

If non-zero, it MUST signal the exact time, in nanoseconds, since 00:00:00 UTC on 1 January 1970, according to the transmitter’s wall clock time, of the stream starting. If a start time is not known, it MUST be zero. Once a stream has started, it MUST NOT be changed.

The user is allowed to handle the field in the following ways:

Action Description
Use as metadata The epoch field is used to override § 2.12 Metadata packet’s date field.
Ignore The field is completely ignored.
Stream duration The field is used to measure the total time the stream has been operational.
Stream latency The field is used to measure latency.
Synchronization The field is used to synchronize several unconnected receivers.

By default, implementations must use the field as metadata, if present. Otherwise, they should ignore it.

Users are free to use the field to measure the stream duration by converting the t of the pts field of any stream’s packet to nanoseconds (multiply by 1000000000), rounding it, and subtracting it from the epoch time (t - epoch).

Users are also free to measure the latency in a similar way, by measuring their current wallclock time t, and using Δ = t' - t - epoch. Δ will be the delay in nanoseconds.

Finally, if explicitly requested, implementations are allowed to delay presentation by interpreting a negative latency value of Δ as a delay.

Note: Packets which had a negative timestamp before must still be dropped to permit for correct decoding and presentation.

Note: The stream latency and synchronization actions depend on all devices having accurately synchronized clocks. This protocol does not guarantee, nor specify this, as this is outside its scope. Users can use the Network Time Protocol (NTP), specified in [RFC5905], or any other protocol to synchronize clocks, or simply assume all device are already synchronized.

1.9. URI scheme

The recommended URI scheme is:

avt://[<transport>[:<mode>]@]<address>[:<port>][/[<sender_uuid>][#<params>]]

The syntax complies with [RFC8820] and can be parsed by existing code. Implementations are free to extend the syntax.

Note: Alternatively, for UDP-only, the udp://<address>:<port> URI scheme may be used, at the risk of conflict with other protocols (MPEG-TS or Matroska).

Note: When handling AVTransport files, it is recommended to use the .avt file extension. Alternatively, for image-only files, .ati is recommended, and for subtitles, the recommendation is .avs.

1.9.1. MIME type

AVTransport shall use the following MIME types:

2. Packet structure

This section lists the syntax of each individual packet type and specifies its purpose, and rules about its usage.

Special considerations and suggestions which need to be taken into account in a streaming scenario are described in the § 3.2 Streaming section.

2.1. Session start

Session start packets allow receivers to plausibly identify a stream of bytes as an AVTransport session. The syntax is as follows:

Type Name Data Description
b(16) session_start_descriptor 0x4156 Indicates this is a AVTransport session (`AV`).
b(16) session_version 0x5430 Indicates the session version. This document describes version `21552` (`T0`).
u(32) global_seq Monotonically incrementing per-packet global sequence number.
16*b(8) session_uuid UUID Lasting session UUID.
u(32) session_seq 32-bit current session sequence number.
b(64) ldpc_288_224 LDPC(288, 224) 64-bits of LDPC parity data to correct the previous 224 bits of the packet.
u(16) session_flags enum SessionFlags Session flags.
16*b(8) producer_name fixed-length string 16-byte UTF-8 string, containing the name of the producer.
u(16) producer_major Major version of the producer.
u(16) producer_minor Minor version of the producer.
u(16) producer_micro Micro version of the producer.
b(32) padding Padding, reserved for future use. Must be 0x0.
b(64) ldpc_288_224 LDPC(288, 224) 64-bits of LDPC parity data to correct the previous 224 bits of the packet.

Multiple session packets may be present in a session, but must remain bytewise-identical.

The producer_name field is a fixed-length string, meaning that the field is always 16 bytes. If the name is less than 16 bytes, it must be zero-padded.

session_uuid is a long-term pre-agreed token between the sender and receiver. It is meant to represent a user ID, or a generic access token. If no pre-agreed token is required, it must contain random data.

session_seq is an ephemeral ID that is supposed to change each time a transmission is initiated. It is meant to help with longer duration disconnections.

2.1.1. Stream Session Flags Enumeration (enum SessionFlags)

The session_flags field must be interpreted in the following way:

SESSION_REVERSE_SIGNAL_READY = 0x1

Indicates session is capable and ready to receive § 3.3 Reverse signalling packets.

Implementations can test the first 4 bytes to detect a AVTransport stream.

The LDPC data is, like for all packets, allowed to be ignored by receivers.

2.2. Time synchronization

Time synchronization packets are optional dual-purpose packets which signal:

The structure of the data in a § 2.2 Time synchronization packet is as follows:

Type Name Data Description
b(8) time_sync_descriptor 0x03 Indicates this is a time synchronization packet.
b(8) ts_clock_id Signals the clock ID for this clock. A value of 0 indicates this packet only carries epoch data.
u(16) ts_clock_hz2 Value, in multiples of 1/65536 Hz, to be added to ts_clock_hz to make ts_clock_freq.
u(32) global_seq Monotonically incrementing per-packet global sequence number.
u(64) epoch Indicates absolute time, in nanoseconds since 00:00:00 UTC on 1 January 1970. [UNIX-time]
u(64) ts_clock_seq Monotonically incrementing counter, incremented once for each cycle of the device clock, at a rate of ts_clock_freq per second.
u(32) ts_clock_hz Hertz value of the device clock.
b(64) ldpc_288_224 LDPC(288, 224) 64-bits of LDPC parity data to correct the previous 224 bits of the packet.

The ts_clock_freq field is equal to ts_clock_freq = ts_clock_hz + ts_clock_hz2/65536. Implementations should prefer to use integer math, and instead have the ts_clock_freq in increments of 1/65536 Hz.

Note: If ts_clock_freq is 0, then the sender should be assumed to be relying entirely on its real-time clock.

The field defines a strictly monotonic clock signal with a rate of ts_clock_freq, which atomically increments a counter, ts_clock_seq on the rising edge of the waveform.

To interpret the clock, read the § 1.8.1 Jitter compensation section. Senders should send time synchronization packets as often as necessary to prevent clock drift and jitter.

In case of a zero ts_clock_hz, the sender must be assumed to not provide a clock signal reference, and the timestamps MUST be interpreted as being, in the receiver’s understanding, realtime.

The epoch is a global, optional field that receivers may interpret.
The epoch value must not change between packets.
The epoch is an absolute starting point, for all timestamps in all streams, in nanoseconds since 00:00:00 UTC on 1 January 1970 ([UNIX-time]).

The possible applications of the epoch field are described in the § 1.8.3 Epoch definition section.

2.3. Stream registration

This packet is used to signal stream registration.

The layout of the data is as follows:

Type Name Data Description
b(16) stream_registration_descriptor 0x0002 Indicates this is a Indicates this is a stream registration packet.
b(16) stream_id Indicates the stream ID for the new stream to be registered.
u(32) global_seq Monotonically incrementing per-packet global sequence number.
b(16) related_stream_id Indicates the stream ID for which this stream is related to. Relations are defined by StreamFlags set in stream_flags. Must be 0xFFFF if this stream has no relations.
b(16) derived_stream_id Indicates the stream ID for which this stream is derived from. Derivation is defined by StreamFlags set in stream_flags. Must be 0xFFFF if this stream is not derived from any other stream.
u(64) bandwidth Average bitrate in bits per second. MAY be 0 to indicate VBR or unknown.
b(64) stream_flags enum StreamFlags Flags to indicate the type of stream.
b(64) ldpc_288_224 LDPC(288, 224) 64-bits of LDPC parity data to correct the previous 224 bits of the packet.
b(32) codec_id Indicates the codec ID for the data packets in this stream.
R(64) timebase Signals the timebase of the timestamps present in the § 2.6 Stream Data packets.
b(8) ts_clock_id An 8-bit non-zero clock ID identifier to associate a stream with a given clock.
i(64) skip_preroll Amount of time in `timebase` units to skip immediately after seeking or reinitializing.
u(32) init_packets enum StreamInitPackets Flags to indicate which packets should be received before decoding or presenting any stream data packets.
b(24) padding Padding, reserved for future use. Must be 0x0.
b(64) ldpc_288_224 LDPC(288, 224) 64-bits of LDPC parity data to correct the previous 224 bits of the packet.

This packet may be sent for an already-initialized stream. The bandwidth field and the stream_flags fields may change, however the codec_id, timebase AND related_stream_id fields must remain the same. If the latter are to change an § 2.20 End of stream packet must be sent first.

The skip_preroll field is a duration in timebase units to signal how much to skip after reinitializing or seeking. The duration of negative timestamps at the start of streams must be at least as long as the skip_preroll.

2.3.1. Stream Init Packets Enumeration (enum StreamInitPackets)

The init_packets field indicates which packets are required, and will be transmitted, for the stream to be correctly decoded and presented. It MUST be interpreted as follows:

STREAM_INIT_PKT_METADATA = 0x1

Stream requires a § 2.12 Metadata packet in order to be fully initialized.

STREAM_INIT_PKT_STREAM_DURATION = 0x2

Stream requires a § 2.19 Stream duration packet in order to be fully initialized.

STREAM_INIT_PKT_CONFIG_DATA = 0x4

Stream requires a § 2.5 Stream configuration packet in order to be fully initialized.

STREAM_INIT_PKT_VIDEO_INFO = 0x8

Stream requires a § 2.15 Video information packet in order to be fully initialized.

STREAM_INIT_PKT_LUT_ICC = 0x10

Stream requires a § 2.13 LUT/ICC profile packet in order to be fully initialized.

STREAM_INIT_PKT_FONT_DATA = 0x20

Stream requires a § 2.14 Font data packet in order to be fully initialized.

Implementations MUST wait to parse the packets signalled before exposing the new stream and decoding/presenting packets from it.

2.3.2. Stream Flags Enumeration (enum StreamFlags)

The stream_flag field provides context for the stream. It MUST be interpreted in the following manner:

STREAM_SUBTITLES = 0x1

Stream contains timed text.

STREAM_DEFAULT = 0x2

Stream should be chosen by default amongst other streams of the same type, unless the user has specified otherwise.

STREAM_STILL_PICTURE = 0x4

Stream is a still picture and only a single decodable frame will be sent.

STREAM_COVER_ART = 0x8

Stream is a cover art picture for the stream signalled in related_stream_id.

STREAM_LOW_QUALITY = 0x10

Stream is a lower quality version of the stream signalled in derived_stream_id.

STREAM_DUB = 0x20

Stream is a dubbed version of the stream signalled in related_stream_id.

STREAM_COMMENTARY = 0x40

Stream is a commentary track to the stream signalled in related_stream_id.

STREAM_LYRICS = 0x80

Stream is a lyrics track to the stream signalled in related_stream_id.

STREAM_KARAOKE = 0x100

Stream is a karaoke track to the stream signalled in related_stream_id.

STREAM_HEARING_IMPAIRED = 0x200

Stream is intended for hearing impaired audiences.

Note: If related_stream_id is not equal to stream_id, both should be mixed in.

STREAM_VISUALLY_IMPAIRED = 0x400

Stream is intended for visually impaired audiences.

Note: If related_stream_id is not equal to stream_id, both should be mixed in.

STREAM_NO_DIALOGUE = 0x800

Stream contains music and sound effects without voice.

STREAM_NON_DIEGETIC = 0x1000

Stream contains non-diegetic audio.

Note: If related_stream_id is not equal to stream_id, both should be mixed in.

STREAM_DESCRIPTIONS = 0x2000

Stream contains textual or spoken descriptions to the stream signalled in related_stream_id.

STREAM_TIMING_METADATA = 0x4000

Stream contains timed metadata and is not intended to be directly presented to the user.

STREAM_THUMBNAILS = 0x8000

Stream contains temporally sparse thumbnails to the stream signalled in related_stream_id.

STREAM_BINAURAL = 0x10000

Stream contains binaural audio. If set, pre-processing for headphones should be disabled.

STREAM_MULTILAYER = 0x20000

Stream contains multiple layers in the codec bitstream. For example, alternative views.

Several streams can be chained with the STREAM_LOW_QUALITY bit set to indicate progressively lower quality/bitrate versions of the same stream. The very first stream in the chain MUST NOT have bit STREAM_LOW_QUALITY set.

Sparse thumbnail streams may exactly match chapters from related_stream_id, but could be sparser or more frequent.

If bits STREAM_COVER_ART, STREAM_DUB, STREAM_COMMENTARY, STREAM_LYRICS, STREAM_KARAOKE, STREAM_HEARING_IMPAIRED are all unset, then related_stream_id must match stream_id, otherwise the stream with a related different ID must exist.

2.4. Generic data

To ease parsing, the specification defines a common template for data that requires no special treatment, but only differ by descriptor.

This way, any generic data can share a common code path, have parity data and be a part of an § 2.8 FEC grouping packet.

The following template shall be used for generic data packets:

Type Name Data Description
b(16) generic_data_descriptor as specified Indicates the data packet type. Defined in later sections.
b(16) stream_id Indicates the stream ID for which this packet is applicable.
u(32) global_seq Monotonically incrementing per-packet global sequence number.
u(32) total_payload_length The total size of all data needed to receive the payload correctly. Must be either 0 if unknown, or the total size of the payload across all segments.
i(64) pts Indicates the presentation timestamp for when this data becomes valid at. To interpret the value, read the § 1.7 Timestamps section.
u(32) payload_length The size of the data in this packet.
u(8) generic_data_compression enum DataCompression Type of data compression used.
b(24) padding Padding, reserved for future use. MUST be 0x0.
b(64) ldpc_288_224 LDPC(288, 224) 64-bits of LDPC parity data to correct the previous 224 bits of the packet.
payload_length*b(8) generic_payload payload The packet data itself.

2.4.1. Generic data segmentation

In case the data needs to be segmented, the following template has to be used for segments that follow the above:

Type Name Data Description
b(16) generic_segment_descriptor as specified Indicates the segment type. Defined in later sections along with generic_data_descriptor.
b(16) stream_id Indicates the stream ID for which this packet is applicable.
u(32) global_seq Monotonically incrementing per-packet global sequence number.
b(32) target_seq The sequence number of the starting § 2.4 Generic data packet.
u(32) pkt_total_data Total number of data bytes, including the first data packet’s, and ending segment’s.
u(32) seg_offset The offset since the start of the data where the segment starts.
u(32) seg_length The size of the data segment.
4*b(8) header_7 A seventh of the starting § 2.4 Generic data header. The part taken is determined by global_seq % 7.
b(64) ldpc_288_224 LDPC(288, 224) 64-bits of LDPC parity data to correct the previous 224 bits of the packet.
seg_length*b(8) generic_segment_payload payload The data for the segment.

If the data in a § 2.4 Generic data packet is to be segmented, it will have a different descriptor. The generic_segment_descriptor shall be different for segments that finalize the data.

The header_7 field can be used to reconstruct the header of the very first packet in order to determine the timestamps and data type.

Note: Segments are forbidden from partially overlapping. Each segment’s offset and size must either completely overlap with another segment (such as when retransmitting lost packets), or must fit in between two segments perfectly.

2.4.2. Generic data parity

Finally, in case the data requires parity data (FEC, but only on the current packet), the following § 2.4 Generic data structure is to be used:

Type Name Data Description
b(16) generic_parity_descriptor as specified Indicates this packet carries parity. Defined in later sections along with generic_data_descriptor.
b(16) stream_id Indicates the stream ID for which this packet is applicable.
u(32) global_seq Monotonically incrementing per-packet global sequence number.
b(32) target_seq The sequence number of the starting § 2.4 Generic data packet.
u(32) parity_data_offset The byte offset for the RaptorQ parity data for this parity data packet protects.
u(32) parity_data_length The length of the RaptorQ data in this packet.
u(32) parity_total The total amount of payload bytes across all parity data packets.
4*b(8) header_7 A seventh of the starting § 2.4 Generic data header. The part taken is determined by global_seq % 7.
b(64) ldpc_288_224 LDPC(288, 224) 64-bits of LDPC parity data to correct the previous 224 bits of the packet.
parity_data_length*b(8) parity_data_payload payload The RaptorQ parity data that can be used to check or correct the previous data packet’s payload.

The data in an parity packet MUST be systematic RaptorQ, as per [RFC6330].
Common FEC Object Transmission Information (OTI) format and Scheme-Specific FEC Object Transmission Information as described in the document are never used.

The FEC symbol size MUST be 128 bytes.

The header_7 field can be used to reconstruct the header of the very first packet in order to determine the timestamps and data type.

2.5. Stream configuration

Codecs generally require a one-off special piece of data needed to initialize them.

To provide this data to receivers, the templates defined in the MUST be used, with the following descriptors:

Descriptor value Name Structure Description
0x0003 stream_config_descriptor § 2.4 Generic data Codec initialization data.
0x0004 stream_config_segment_descriptor § 2.4.1 Generic data segmentation Non-final segment for segmented codec configuration.
0x0005 stream_config_parity_descriptor § 2.4.2 Generic data parity Parity data for codec configuration data.

For more information on the layout of the specific data, consult the § 3.1 Codec encapsulation addendum.

However, in general, the data follows the same layout as what [FFmpeg]’s libavcodec produces and requires.

An implementation may error out in case it cannot handle the data in the payload. If so, when reading a file, it must stop, otherwise in a live scenario, it must send an unsupported § 3.3.1 Session control data packet, if such a connection is open.

2.6. Stream Data

The data packets indicate the start of a stream packet, which may be fragmented into more § 2.6.3 Stream data segmentation. It is laid out as follows:

Type Name Data Description
b(16) stream_data_descriptor_structure
b(8) stream_data_descriptor 0x01
b(3) frame_type enum FrameType
b(1) pkt_segmented Packet is incomplete and extra segments are required.
b(1) pkt_in_fec_group Packet is part of an FEC group and must be retained.
b(1) field_id As defined in enum Interlacing.
b(2) pkt_compression enum DataCompression
b(16) stream_id Indicates the stream ID for which this packet is applicable.
u(32) global_seq Monotonically incrementing per-packet global sequence number.
i(64) pts Indicates the presentation timestamp for when this frame should be presented at. To interpret the value, read the § 1.7 Timestamps section.
i(64) duration The duration of this packet in stream timebase unis.
u(32) data_length The size of the data in this packet.
b(64) ldpc_288_224 LDPC(288, 224) 64-bits of LDPC parity data to correct the previous 224 bits of the packet.
data_length*b(8) packet_data payload The packet data itself.

For information on the layout of the specific codec-specific packet data, consult the § 3.1 Codec encapsulation addenda.

2.6.1. Frame Type Enumeration (enum FrameType)

FRAME_TYPE_KEY = 0x0

Packet data contains a keyframe, able to be decoded standalone.

FRAME_TYPE_S = 0x1

Packet data contains a scalable/switch frame, able to be decoded standalone, with acceptable degradation.

FRAME_TYPE_P = 0x2

Packet data contains an inter frame, requiring additional reference frames in order to be validly decoded.

2.6.2. Data Compression Enumeration (enum DataCompression)

DATA_COMPRESSION_NONE = 0x0

Packet data is uncompressed

DATA_COMPRESSION_ZSTD = 0x1

Packet data is compressed with Zstandard, defined in IETF [RFC8878].

Note: Zstandard is a general purpose format, suitable for images, audio, and binary data such as TTF, OTF, ICC, or CUBE packets. Therefore, it should be the preferred format for such payloads.

DATA_COMPRESSION_BROTLI = 0x2

Packet data is compressed with Zstandard, defined in IETF [RFC7932].

Note: Brotli is more optimized for text rather than generic data, and should be the preferred format for subtitles. Presently, it is also more supported on the web.

Any undefined values are hereby reserved and must not be present in a compliant AVTransport stream with this version.

2.6.3. Stream data segmentation

Packets can be split up into separate chunks that may be received out of order and assembled. This allows transmission over switched networks with a limited MTU, or prevents very large packets from one stream interfering with another stream. The packet structure used for segments is the § 2.4.1 Generic data segmentation from § 2.4 Generic data, with the following descriptors:

Descriptor value Name Structure Description
0x00FF stream_data_segment_descriptor § 2.4.1 Generic data segmentation Non-final segment for segmented codec configuration.

The size of the final assembled packet is the sum of all seg_length fields, plus the data_length field from the § 2.6 Stream Data.

Data segments and packets may arrive out of order and be duplicated. Implementations must reorder them, deduplicate them and assemble them into complete packets.

Implementations may try to decode incomplete data packets with missing segments due to latency concerns.

Senders may send duplicate segments to compensate for packet loss, but should use § 2.8 FEC grouping or § 2.9 Stream data parity instead.

Implementations should discard any packets and segments that arrive after their presentation time. Implementations should drop any packets and segments that arrive with unrealistically far away presentation times.

2.7. Extended stream data

Depending upon the codec, using an extended stream data header may be required. It is laid out in the following way:

Type Name Data Description
b(16) extended_stream_data_descriptor_structure
b(8) extended_stream_data_descriptor 0x02
b(3) frame_type enum FrameType
b(1) discard Flag, indicating to decode the frame, but not present it.
b(1) pkt_in_fec_group Packet is part of an FEC group and must be retained.
b(1) field_id As defined in enum Interlacing.
b(2) pkt_compression enum DataCompression
b(16) stream_id Indicates the stream ID for which this packet is applicable.
u(32) global_seq Monotonically incrementing per-packet global sequence number.
i(64) pts Indicates the presentation timestamp for when this frame should be presented at. To interpret the value, read the § 1.7 Timestamps section.
i(64) dts Indicates the timestamp for when to input this frame should be input into the decoder. To interpret the value, read the § 1.7 Timestamps section.
u(32) data_length The size of the data in this packet.
b(64) ldpc_288_224 LDPC(288, 224) 64-bits of LDPC parity data to correct the previous 224 bits of the packet.
i(64) duration The duration of this packet in stream timebase unis.
u(32) total_data_length The total size of all data needed to receive the payload correctly. Must be either 0 if unknown, or the total size of the payload across all segments.
u(16) side_data_desc_1 If not equal to 0xFFFF, it means this packet depends on another packet with the given descriptor for correct decoding or presentation.
u(32) side_data_seq_1 If side_data_desc_1 is non-0xFFFF, a valid sequence ID for the side data packet.
u(16) side_data_desc_2 If not equal to 0xFFFF, it means this packet depends on another packet with the given descriptor for correct decoding or presentation.
u(32) side_data_seq_2 If side_data_desc_2 is non-0xFFFF, a valid sequence ID for the side data packet.
b(32) padding Padding, reserved for future use. MUST be 0x0.
b(64) ldpc_288_224 LDPC(288, 224) 64-bits of LDPC parity data to correct the previous 224 bits of the packet.
data_length*b(8) packet_data payload The packet data itself.

Extended stream data packets should only be used if there’s a need to use them. Regular stream data packets have a much lower overhead.

2.8. FEC grouping

Whilst it’s possible to send uncontextualized FEC data backing individual packets, for most applications, this is only feasible for very high bitrate single streams, as modern FEC algorithms are highly optimized for packet erasure recovery.

FEC grouping allows for multiple buffered packets and segments from multiple streams to be FEC corrected in order to ensure no stream is starved of data.

FEC grouped streams must be registered first via a special packet:

Type Name Data Description
b(16) fec_grouping_descriptor 0x0030 Indicates this is an FEC grouping packet.
b(16) group_id Indicates the ID for this FEC grouping.
Note: Must not overlap with stream_id.
u(32) global_seq Monotonically incrementing per-packet global sequence number.
u(8) fec_grouping_streams Number of streams in the FEC group. Must be less than or equal to 16.
b(64) fec_common_oti RaptorQ Forward Error Correction Scheme for Object Delivery § section-3.3.2 [RFC6330], RaptorQ Common FEC Object Transmission Information.
b(32) fec_scheme_oti RaptorQ Forward Error Correction Scheme for Object Delivery § section-3.3.3 [RFC6330], RaptorQ Scheme-Specific FEC Object Transmission Information.
u(32) fec_start_global_seq The global sequence number of the very first packet in the FEC group.
b(24) padding Padding, reserved for future use. MUST be 0x0.
b(64) ldpc_288_224 LDPC(288, 224) 64-bits of LDPC parity data to correct the previous 224 bits of the packet.
16*u(32) fec_nb_packets Total number of packets for each stream in the FEC group.
16*u(32) fec_seq_number The sequence number of the first packet for the stream to be included in the group.
b(992) padding Padding, reserved for future use. MUST be 0x0.
b(768) ldpc_2784_2016 LDPC(2784, 2016) 768-bits of LDPC parity data to correct the previous 2016 bits of the packet.

It is hightly recommended that the common OTI parameters never change once transmitted. This lets implementations attempt to apply FEC if they miss a § 2.8 FEC grouping packet.

The fec_scheme_oti field must be interpreted as the following, given in RaptorQ Forward Error Correction Scheme for Object Delivery § section-3.3.3:

All streams in an FEC group must have timestamps that cover the same period of time.

A stream may only be part of a single FEC group at any one time. Sending a new grouping that includes an already grouped stream will destroy the previous grouping.

To end a grouping prematurely, one can send an end of stream packet with the group’s ID.

FEC groups use a different packet for the FEC data.

Type Name Data Description
b(16) fec_group_data_descriptor 0x0031 Indicates this is an FEC group data packet.
b(16) group_id Indicates the FEC grouping for which this packet has data for.
u(32) global_seq Monotonically incrementing per-packet global sequence number.
u(32) fec_data_offset The byte offset for the FEC data for this FEC packet protects.
u(32) fec_data_length The length of the FEC data in this packet.
u(32) fec_total_data_length The total amount of bytes in the FEC grouping data.
b(64) fec_source_1 § 2.8.1 FEC Group Source Provides a single source packet which contains data to be forward error corrected.
b(64) ldpc_288_224 LDPC(288, 224) 64-bits of LDPC parity data to correct the previous 224 bits of the packet.
3*b(64) fec_source_234 § 2.8.1 FEC Group Source Provides another three source packet which contains data to be forward error corrected.
b(32) padding Padding, reserved for future use. MUST be 0x0.
b(64) ldpc_288_224 LDPC(288, 224) 64-bits of LDPC parity data to correct the previous 224 bits of the packet.
fec_data_length*b(8) fec_data payload The FEC data that can be used to check or correct the previous data packet’s payload.

The fec_source data is defined as follows:

2.8.1. FEC Group Source

Type Name Value Description
u(32) fec_source_seq Indicates a single packet’s global_seq which is to be backed by this FEC group.
u(16) fec_source_blk Indicates the FEC source block to which the signaled packet belongs to.
u(16) fec_symbol_id Indicates the symbol ID of the packet for the source block.

Each § 2.8.1 FEC Group Source structure MUST reference a valid packet, in transmission order. If there are no more valid packets to reference, the sender must start repeating from the very first FEC source.

To perform FEC, first, concatenate each packet (header and payload) referenced into each source block, in order of the source symbol ID. Then, perform the procedure to apply FEC as described by RaptorQ Forward Error Correction Scheme for Object Delivery § section-4.4.1.

2.9. Stream data parity

Stream data packets and segments may individually be backed by data packets. The structure used for segments follows the § 2.4.2 Generic data parity template from the § 2.4 Generic data section, with the following descriptor:

Descriptor value Name Structure Description
0x00FE stream_data_parity_descriptor § 2.4.2 Generic data parity Parity data segment for individual stream data packets.

Implementations may discard the FEC data, or may delay the previous packet’s decoding to correct it with the FEC data, or may attempt to decode the uncorrected packet data, and if failed, retry with the corrected data packet.

The data in an FEC packet must be RaptorQ, as per [RFC6330]. The symbol size must be 128 bytes.

The same lifetime and duplication rules apply for parity packets as they do for regular data segments.

2.10. Hash packets

For some niche cases, AVTransport provides the ability to signal a hash for the packet. This is purely optional for both senders and receivers to signal and interpret.

Note: Most filesystems, interfaces and protocols provide a CRC. While this hash is much more resistant to bitflips and secure, it is recommended to use this in cases like long-term archival, or raw RF links (to avoid retransmissions for corrupt packets).

The hash cover exactly one payload-carrying packet’s payload.

Type Name Data Description
b(16) hash_data_descriptor 0x0009 Indicates this is a hash packet.
b(16) stream_id Indicates the stream ID of the target packet. May be 0xFFFF, in which case, it applies to all streams.
u(32) global_seq Monotonically incrementing per-packet global sequence number.
u(32) hash_target Indicates the sequence number of the packet for which this hash applies for.
16*b(8) hash_data XXH128 of the target packet’s payload.
b(64) ldpc_288_224 LDPC(288, 224) 64-bits of LDPC parity data to correct the previous 224 bits of the packet.

The hashing algorithm used is [XXHASH], with a length of 128-bits (referred to as XXH128 by the authors).

If present in an AVTransport stream, this packet should be sent before the hash_target packet is transmitted.

Demuxers are not required to process this packet or verify that the target packet’s data is received correctly, but they should.

2.11. Index

The index packet contains available byte offsets of nearby keyframes, reconfiguration packets or metadata changes, and the distance to the next index packet.

Type Name Data Description
b(16) stream_index_descriptor 0x0051 Indicates this is an index packet.
b(16) stream_id Indicates the stream ID for the index. May be 0xFFFF, in which case, it applies to all streams.
u(32) global_seq Monotonically incrementing per-packet global sequence number.
u(32) prev_idx Negative offset of the previous index packet, if any, in bytes, relative to the current position. If exactly 0, indicates no such index is available, or is out of scope.
u(32) next_idx Positive offset of the next index packet, if any, in bytes, relative to the current position. May be inexact, specifying the minimum distance to one. Users may search for it.
u(32) nb_indices The total number of indices present in this packet.
b(64) padding Padding, reserved for future use. MUST be 0x0.
b(64) ldpc_288_224 LDPC(288, 224) 64-bits of LDPC parity data to correct the previous 224 bits of the packet.
nb_indices*b(144) index_entry_list struct IndexEntry Descriptor of the packet that each index points to.

If index packets are present, an index packet must be sent for any stream reconfiguration packets, or metadata changes. No future index packets must be signalled or sent, until all the packets needed to correctly reinitialize streams have been sent. The exception to this is if a newer reinitialization has begun.

If valid, prev_idx, next_idx and pkt_offset offsets must point to the start of a packet. In other words, the byte pointed to by the offsets must contain the first, most significant byte of the descriptor of the pointed packet.

If stream_id is 0xFFFF, the timebase used for pts must be assumed to be 1 nanosecond, numerator of 1, denominator of 1000000000.

When streaming, prev_idx and next_idx must be 0.

2.11.1. Index entry (struct IndexEntry)

The structure of the data for each index entry is as follows:

Type Name Data Description
b(16) index_entry_descriptor Descriptor of the packet that each index points to.
i(64) pts Timestamp of the packet that the index entry points to.
u(32) target_seq Sequence number of the packet pointed to by this index entry.
i(32) pkt_offset The offset of the index entry relative to the current position in bytes. May be 0 if unavailable or not applicable.

Note: If a packet starts before the value of pts but has a duration that matches or exceeds the PTS, then it must be included. This is to permit correct subtitle presentation, or long duration still pictures like slideshows.

2.12. Metadata

The metadata packets can be sent for the overall session, or for a specific `stream_id` substream. The data is contained in structures templated in the § 2.4 Generic data structures, with the following descriptors:

Descriptor value Name Structure Description
0x000A metadata_descriptor § 2.4 Generic data First metadata segment.
0x000B metadata_segment_descriptor § 2.4.1 Generic data segmentation Final segment of segmented metadata.
0x000C metadata_parity_descriptor § 2.4.2 Generic data parity Parity data for metadata.

The actual metadata must be stored using CBOR, as standardized in [RFC8949], as a key and value pair.

Implementations are free to use any key or value names. But, to maintain interoperability, implementations are required to either follow the tags given by § 4.1 Annex A: Metadata tags, or use custom tags if the format of the values differ.

Each key may be present multiple times. Implementations must discard the old value associated with the key and update the metadata.

If stream_id is equal to 0xFFFF, the metadata applies for the session as a whole.

If stream_id is not 0xFFFF, the metadata is a separate set of values that just describe a single stream. Tags from other streams, or the general file metadata must not overwrite each other.

Metadata can be updated by sending new metadata packets with new values. The entire metadata must be replaced with the contents of a new metadata packet, incremental updates are not possible.

Metadata may be padded by appending zeroed bytes to the end. This must be accounted by the payload value. Implementations may do this to write metadata after starting and outputting a packet.

2.13. LUT/ICC profile

Embedding of color lookup tables (LUTs) and ICC profiles for accurate color reproduction is supported.
The following structure MUST be followed:

Type Name Data Description
b(16) lut_icc_descriptor 0x0010 Indicates this packet contains a complete LUT or ICC profile or the start of one.
b(16) stream_id The stream ID for which to apply the LUT/ICC profile.
u(32) global_seq Monotonically incrementing per-packet global sequence number.
i(64) pts Timestamp (in stream timebase units) at which this orientation packet has to be applied at.
u(8) lut_type enum LutType The data type contained in the lut_data.
b(8) lut_major_ver Major version of the file. Currently only applies to ICC profiles.
b(8) lut_minor_ver Minor version of the file. Currently only applies to ICC profiles.
u(8) lut_compression enum DataCompression LUT/ICC data compression.
b(32) lut_data_length The length of the LUT/ICC profile.
b(32) lut_pl_length The length of the LUT/ICC profile in this packet.
b(64) ldpc_288_224 LDPC(288, 224) 64-bits of LDPC parity data to correct the previous 224 bits of the packet.
252*b(8) lut_name fixed-length string 252-byte UTF-8 string, containing the original file name of the LUT/ICC profile.
b(768) ldpc_2784_2016 LDPC(2784, 2016) 768-bit LDPC parity data to correct the previous 2016 bits of the packet.
lut_pl_length*b(8) lut_data payload The LUT/ICC profile data

Often, LUT/ICC profiles may be too large to fit, hence they can be segmented in the same way as data packets, as well as have parity data. Segmentation happens only when lut_data_length is less than lut_pl_length. The syntax for segmentation and parity packets is via the following § 2.4 Generic data templates:

Descriptor value Name Structure Description
0x0011 lut_icc_segment_descriptor § 2.4.1 Generic data segmentation Non-final segment for segmented LUT/ICC profile.
0x0012 lut_icc_parity_descriptor § 2.4.1 Generic data segmentation Final segment of a segmented LUT/ICC profile.

2.13.1. LUT/ICC Profile Type Enumeration (enum LutType)

The lut_type field must be interpreted in the following way:

CLUT_TYPE_ICC_PROFILE = 0x1

Indicates that the data contains a regular ICC profile, with version lut_major_ver.lut_minor_ver.

CLUT_TYPE_ADOBE_CUBE = 0x2

Indicates that the data contains an Adobe [CUBE] file.

Note: Lookup tables and ICC profiles must take precedence over the primaries and transfer characteristics values in § 2.15 Video information. The matrix coefficients are still required for RGB conversion.

Note: Both an ICC profile and a color lookup table may be applied for a single stream.

2.14. Font data

Subtitles may often require custom fonts. AVTransport supports embedding of fonts for use by subtitles.

Currently, this only applies for ASS streams (§ 3.1.18 ASS encapsulation). Once parsed, these fonts must be made available for the ASS stream.

The following structure MUST be followed:

Type Name Data Description
b(16) font_data_descriptor 0x0020 Indicates the payload contains a font.
b(16) stream_id The stream ID for which to make the font available.
Note: May be set to 0xffff to make the font available for all streams.
u(32) global_seq Monotonically incrementing per-packet global sequence number.
u(8) font_type enum FontType The data type contained in the font_data.
u(8) font_compression enum DataCompression Font data compression.
u(32) font_data_length The length in bytes of the font file data.
u(32) font_pl_length The length in bytes of the current packet’s font data.
b(80) padding Padding, reserved for future use. MUST be 0x0.
b(64) ldpc_288_224 LDPC(288, 224) 64-bits of LDPC parity data to correct the previous 224 bits of the packet.
252*b(8) font_name fixed-length string 252-byte UTF-8 string, containing the original file name of the font.
b(768) ldpc_2784_2016 LDPC(2784, 2016) 768-bit LDPC parity data to correct the previous 2016 bits of the packet.
font_pl_length*b(8) font_data payload The font data.

Font data can too be segmented in the same way as data packets, as well as have parity data. Segmentation happens only when font_data_length is less than font_pl_length. The syntax for segmentation and parity packets is via the following § 2.4 Generic data templates:

Descriptor value Structure Name Description
0x0021 font_data_segment_descriptor § 2.4.1 Generic data segmentation Non-final segment for segmented font file.
0x0022 font_data_parity_descriptor § 2.4.2 Generic data parity Parity data for a font file.

2.14.1. Font Type Enumeration (enum FontType)

The font_type field must be interpreted in the following way:

FONT_TYPE_OTF = 0x0

Indicates that the font data contained is an [OpenType] font.

FONT_TYPE_TTF = 0x1

Indicates that tata contains a [TrueType] font.

FONT_TYPE_WOFF2 = 0x2

Indicates that tata contains a [WOFF2] (Web Open Font Format 2) font.

Note: FONT_TYPE_WOFF2 fonts should not be compressed, as they’re already compressed.

2.15. Video information

Video info packets contain everything needed to correctly interpret a video stream after decoding.

Type Name Data Description
b(16) video_info_descriptor 0x0008 Indicates this packet contains video information.
b(16) stream_id The stream ID for which to apply the video information to.
u(32) global_seq Monotonically incrementing per-packet global sequence number.
i(64) pts Timestamp (in stream timebase units) at which this orientation packet has to be applied at.
u(32) width Indicates the video width in pixels, before any cropping.
u(32) height Indicates the video height in pixels, before any cropping
u(8) chroma_subsampling enum ChromaSubsampling Indicates the chroma subsampling being used.
u(8) colorspace enum Colorspace Indicates the kind of colorspace the video is in.
u(8) bit_depth Number of bits per output video sample.
u(8) interlaced enum Interlacing Indicates the video interleaving.
b(64) ldpc_288_224 LDPC(288, 224) 64-bits of LDPC parity data to correct the previous 224 bits of the packet.
R(64) signal_aspect Indicates the sample aspect ratio of the image.
R(64) gamma Indicates the gamma power curve for the video sample values.
R(64) framerate Indicates the framerate of the video. If it’s variable, may be used to indicate the average bitrate. If the video is interlaced, indicates the field rate.
u(8) output_range enum ColorRange Indicates the range for the output video samples.
u(8) chroma_pos enum ChromaPosition Chroma sample alignment for subsampled chroma.
u(8) primaries enum Primaries Video color primaries. Must be interpreted according to ITU Standard [H.273], ColourPrimaries field.
u(8) transfer enum Transfer Video transfer characteristics. Must be interpreted according to ITU Standard [H.273], TransferCharacteristics field.
u(8) matrix enum Matrix Video matrix coefficients. Must be interpreted according to ITU Standard [H.273], MatrixCoefficients field.
u(8) has_mastering_primaries If 1, indicates that the following mastering_primaries and mastering_white_point contain valid data. Other values are reserved.
u(8) has_luminance If 1, indicates that the following min_luminance and max_luminance contain valid data. Other values are reseved.
16*R(64) custom_matrix If the color matrix value is equal to 0xFF, use this custom matrix instead. Top left to bottom right, in "raster-order". Otherwise, must be set to 0.
6*R(64) mastering_primaries [CIE1931] X/Y chromacity coordinates of the color primaries, x value, then y value, for each r, g, b, in order.
2*R(64) mastering_white_point [CIE1931] X/Y chromacity coordinates of the white point, x value, then y value.
R(64) min_luminance Minimal luminance of the mastering display, in cd/m2.
R(64) max_luminance Maximum luminance of the mastering display, in cd/m2.
u(32) cropped_width Indicates the presentable video width in samples.
u(32) cropped_height Indicates the presentable video height in samples.
u(16) crop_x_offset X offset for the location of the final presentation box.
u(16) crop_y_offset Y offset for the location of the final presentation box.
b(8) padding Padding, reserved for future use. Must be 0x0.
b(768) ldpc_2784_2016 LDPC(2784, 2016) 768-bit LDPC parity data to correct the previous 2016 bits of the packet.

2.15.1. Colorspace Enumeration (enum Colorspace)

The colorspace field must be interpreted in the following way:

CSP_MONO = 0x0

Video contains no chroma data.

CSP_RGB = 0x1

Video data contains a form of RGB.

CSP_YUV = 0x2

Video contains a form of YUV (YCbCr).

CSP_YCOCGR = 0x3

Video contains a reversible form of YCoCg, as defined by [H.273], equations 47-50.

CSP_YCGCOR = 0x4

Video contains a reversible form of YCgCo (same as above, with swapped chroma planes).

CSP_XYZ = 0x5

Video contains [CIE1931] XYZ color data.

CSP_XYB = 0x6

Video contains XYB color data, as defined by [ISO18181].

Note: matrix must be equal to 0xFF and the custom_matrix must be a valid matrix to transform XYB into RGB.

CSP_ICTCP = 0x5

Video contains [BT2100] ICtCp color data.

CSP_BAYER_BGGR = 0x6

Video contains raw CMOS voltages, from 4x4 cells with a pattern Blue, Green, Green, Red, in raster-order.

CSP_BAYER_RGGB = 0x7

Same as above, with a Red, Green, Green, Blue order.

CSP_BAYER_GBRG = 0x8

Same as above, with a Green, Blue, Red, Green order.

CSP_BAYER_GRBG = 0x9

Same as above, with a Green, Red, Blue, Green order.

2.15.2. Color Range Enumeration (enum ColorRange)

COLOR_RANGE_FULL = 0x0

Video sample values contains the full range of the bit_depth.

COLOR_RANGE_LIMITED = 0x1

Video sample values contains the limited range of the bit_depth.

Note: This describes the cannonical limited range representation: (219 * E + 16) * 2(bit_depth-8), where E, the input range, is 0.0 to 1.0 for luma planes and -0.5 to 0.5 for chroma planes. This means, for 8-bits, the luma range is 16-235 and the chroma range is 16-240.

2.15.3. Chroma Subsampling Enumeration (enum ChromaSubsampling)

CHROMA_444 = 0x0

Chromatic data is not subsampled, or subsampling does not apply.

CHROMA_420 = 0x1

Chromatic data is subsampled at half the horizontal and vertical resolution of the luminance data.

CHROMA_422 = 0x2

Chromatic data is subsampled at half the horizontal resolution of the luminance data.

CHROMA_440 = 0x3

Chromatic data is subsampled at half the vertical resolution of the luminance data.

CHROMA_411 = 0x4

Chromatic data is subsampled at a quarter of the horizontal resolution of the luminance data.

CHROMA_311 = 0x5

Luma data is subsampled at 3/4 of the output horizontal resolution, chromatic data is subsampled at 1/4 of the output horizontal resolution.

2.15.4. Interlacing Enumeration (enum Interlacing)

The value of interlaced determines whether the video is interlaced, as well as how to interpret the value of field_id in stream data packet headers.

ILACE_PROG = 0x0

Video contains progressive data, or interlacing does not apply.

Note: In this mode, the field_id bit is free to use by users. Implementations must ignore it, and preserve it.

ILACE_TFF = 0x1

Video is interlaced. One § 2.6 Stream Data packet per field. If the data packet’s field_id bit is unset, indicates the field contained is the top field, otherwise it’s the bottom field.

ILACE_BFF = 0x2

Same as above, with reversed polarity, such that packets with field_id bit set contain the top field, otherwise it’s the bottom.

ILACE_TW = 0x3

Video is interlaced. The § 2.6 Stream Data packet contains both fields, weaved together, with the top field being on every even line.

ILACE_BW = 0x4

Same as above, but with reversed polarity, such that the bottom field is encountered first.

The ILACE_TFF and ILACE_TW, as well as the ILACE_BFF and ILACE_BW values may be interchanged if it’s possible to output one or the other, depending on the setting used, if the codec supports this.

2.15.5. Chroma Position Enumeration (enum ChromaPosition)

CHROMA_POS_UNSPEC = 0x0

Chroma position not specified or does not apply.

CHROMA_POS_LEFT = 0x1

Chroma position is between 2 luma samples on different lines.

Note: This is the default chroma position for MPEG-2, H.263 with CHROMA_422, and H.264 with CHROMA_420.

CHROMA_POS_CENTER = 0x2

Chroma position is in the middle between all neighbouring luma samples on 2 lines.

Note: This is the default chroma position for JPEG with CHROMA_420, and H.263 with CHROMA_420.

CHROMA_POS_TOPLEFT = 0x3

Chroma position coincides with top left’s luma sample position.

Note: This is the default chroma position for MPEG-2 with CHROMA_422.

CHROMA_POS_TOP = 0x4

Chroma position is between 2 luma samples on the same top line.

CHROMA_POS_BOTTOMLEFT = 0x5

Chroma position coincides with bottom left’s luma sample position.

CHROMA_POS_BOTTOM = 0x6

Chroma position is between 2 luma samples on the same bottom line.

To illustrate:

Luma line number Luma row 1 Between rows Luma row 3
1 Luma pixel 0x3 0x4 Luma pixel
Between lines 0x1 0x2
2 Luma pixel 0x5 0x6 Luma pixel

2.15.6. Primaries Enumeration (enum Primaries)

These values are copied verbatim from [H.273].

PRIM_RESERVED_0 = 0x0

For future use by ITU-T | ISO/IEC

PRIM_BT709 = 0x1

Rec. ITU-R BT.709-6

IEC 61966-2-1 sRGB or sYCC

PRIM_UNSPEC = 0x2

Image characteristics are unknown or are determined by the application.

PRIM_RESERVED_3 = 0x0

For future use by ITU-T | ISO/IEC

PRIM_BT470 = 0x4

United States Federal Communications Commission (2003) Title 47 Code of Federal Regulations 73.682 (a) (20)

PRIM_BT601_625 = 0x5

Rec. ITU-R BT.1700-0 625 PAL and 625 SECAM

PRIM_BT601_525 = 0x6

Rec. ITU-R BT.1700-0 NTSC

PRIM_ST240 = 0x7

SMPTE ST 240 (1999) (functionally the same as the value 6)

PRIM_FILM = 0x8

Generic film (colour filters using Illuminant C)

PRIM_BT2020 = 0x9

Rec. ITU-R BT.2100-2

PRIM_ST428 = 0xA

SMPTE ST 428-1 (2019) (CIE 1931 XYZ as in ISO 11664-1)

PRIM_ST431 = 0xB

SMPTE RP 431-2 (2011)

PRIM_ST432 = 0xC

SMPTE EG 432-2 (2010)

Note: This list may not be up to date in this version of the AVTransport specifications. Users should consult the latest [H.273] spec for up-to-date values and how to interpret them.

2.15.7. Transfer Function Enumeration (enum Transfer)

These values are copied verbatim from [H.273]. The same note applies.

TRANSFER_RESERVED_0 = 0x0

For future use by ITU-T | ISO/IEC

TRANSFER_BT709 = 0x1

Rec. ITU-R BT.709-6

TRANSFER_UNSPEC = 0x2

Image characteristics are unknown or are determined by the application.

TRANSFER_FCC = 0x4

United States Federal Communications Commission (2003) Title 47 Code of Federal Regulations 73.682 (a) (20)

TRANSFER_BT470 = 0x5

Rec. ITU-R BT.470-6 System B, G (historical)

TRANSFER_BT601 = 0x6

Rec. ITU-R BT.601-7 525 or 625

TRANSFER_ST240 = 0x7

SMPTE ST 240 (1999)

TRANSFER_LINEAR = 0x8

Linear transfer characteristics

TRANSFER_LOG = 0x9

Logarithmic transfer characteristic (100:1 range)

TRANSFER_LOG_SQ = 0xA

Logarithmic transfer characteristic (100 * Sqrt( 10 ) : 1 range)

TRANSFER_IEC61966_2_4 = 0xB

IEC 61966-2-4

TRANSFER_BT1361 = 0xC

Rec. ITU-R BT.1361-0 extended colour gamut system (historical)

TRANSFER_IEC61966_2_1 = 0xD

IEC 61966-2-1 sRGB (with MatrixCoefficients equal to 0) or IEC 61966-2-1 sYCC (with MatrixCoefficients equal to 5)

TRANSFER_BT2020_10 = 0xE

Rec. ITU-R BT.2020-2 (10-bit system) (functionally the same as the values 1, 6 and 15)

TRANSFER_BT2020_12 = 0xF

Rec. ITU-R BT.2020-2 (12-bit system) (functionally the same as the values 1, 6 and 15)

TRANSFER_BT2048 = 0x10

Rec. ITU-R BT.2100-2 perceptual quantization (PQ) system

TRANSFER_ST428 = 0x11

SMPTE ST 428-1 (2019)

TRANSFER_HLG = 0x12

Rec. ITU-R BT.2100-2 hybrid log- gamma (HLG) system

2.15.8. Matrix Enumeration (enum Matrix)

These values are copied verbatim from [H.273]. The same note applies.

MATRIX_IDENT = 0x0

The identity matrix. Typically used for GBR (often referred to as RGB); however, may also be used for YZX (often referred to as XYZ);

MATRIX_BT709 = 0x1

Rec. ITU-R BT.709-6

MATRIX_UNSPEC = 0x2

Image characteristics are unknown or are determined by the application

MATRIX_RESERVED_3 = 0x3

For future use by ITU-T | ISO/IEC

MATRIX_FCC = 0x4

United States Federal Communications Commission (2003) Title 47 Code of Federal Regulations 73.682 (a) (20)

MATRIX_BT470 = 0x5

Rec. ITU-R BT.470-6 System B, G (historical) (functionally the same as the value 6)

MATRIX_BT601 = 0x6

Rec. ITU-R BT.601-7 525

MATRIX_ST240 = 0x7

SMPTE ST 240 (1999)

MATRIX_YCGCO = 0x8

See [H.273], equations 38 to 40

MATRIX_BT2020_NCL = 0x9

Rec. ITU-R BT.2100-2 Y′CbCr

MATRIX_BT2020_CL = 0xA

Rec. ITU-R BT.2020-2 (constant luminance)

MATRIX_ST2085 = 0xB

SMPTE ST 2085 (2015)

MATRIX_ST2100 = 0xE

Rec. ITU-R BT.2100-2 ICTCP

MATRIX_IPT_C2 = 0xF

SMPTE ST 2128 (202x), equations 85 to 87

MATRIX_YCGCO_RE = 0x10

[H.273], equations 58 to 65

MATRIX_YCGCO_RO = 0x11

[H.273], equations 58 to 65

2.16. Video orientation

A standardized way to transmit orientation information is as follows:

Type Name Data Description
b(16) video_orientation_descriptor 0x0040 Indicates this is a video orientation packet.
b(16) stream_id The stream ID for which to associate the video information with.
u(32) global_seq Monotonically incrementing per-packet global sequence number.
i(64) pts Timestamp (in stream timebase units) at which this orientation packet has to be applied at.
u(8) reflection enum VideoReflection A fixed transposition that must occur before any arbitrary rotation.
R(64) rotation A fixed-point rational number to indicate rotation in radians once multiplied by π.
b(24) padding Padding, reserved for future use. MUST be 0x0.
b(64) ldpc_288_224 LDPC(288, 224) 64-bits of LDPC parity data to correct the previous 224 bits of the packet.

The effects of video orientation packets MUST persist from the pts value given, until a new orientation packet is sent, or the stream is reinitialized.

2.16.1. Video Reflection Enumeration (enum VideoReflection)

VIDEO_REFLECT_NONE = 0x0

Video is not flipped.

VIDEO_REFLECT_MIRROR = 0x1

Video must be mirrored for correct presentation (flipped horizontally).

VIDEO_REFLECT_FLIP = 0x2>

Video must be flipped upside-down for correct presentation.

reflection must be applied first, before rotation.

The actual rotation in radians is given by π * (rotation.num/rotation.den).

Rotation should be applied after all other transformations have been performed on the image, including cropping via the cropped_width/cropped_height fields in § 2.15 Video information packets.

2.17. Stereo video

A stereoscopic video file consists in multiple views embedded in a single frame, usually describing two views of a scene.

Interlacing and stereoscopic video are explicitly unsupported. Implementations must ignore any stereoscopic information if the value of interlaced is anything except ILACE_PROG.

A standardized way to transmit stereoscopic video information is as follows:

Type Name Data Description
b(16) stereo_video_descriptor 0x0041 Indicates this is a stereo video information packet.
b(16) stream_id The stream ID for which to associate the stereo information with.
u(32) global_seq Monotonically incrementing per-packet global sequence number.
i(64) pts Timestamp (in stream timebase units) at which this stereo packet has to be applied at.
u(8) type enum StereoVideoType Indicates how views are packed within the video.
u(8) flags enum StereoVideoFlags Additional flags.
u(8) primary_eye enum StereoVideoPrimaryEye Determines which eye is the primary eye when rendering in 2D.
u(32) baseline The distance between the centres of the lenses of the camera system, in micrometers.
b(40) padding Padding, reserved for future use. MUST be 0x0.
b(64) ldpc_288_224 LDPC(288, 224) 64-bits of LDPC parity data to correct the previous 224 bits of the packet.
R(64) horizontal_disparity_adjustment Relative shift of the left and right images, which changes the zero parallax plane. Range is -1.0 to 1.0.
R(64) horizontal_field_of_view Horizontal field of view, in degrees.
b(96) padding Padding, reserved for future use. MUST be 0x0.
b(64) ldpc_288_224 LDPC(288, 224) 64-bits of LDPC parity data to correct the previous 224 bits of the packet.

The effects of stereo video packets must persist from the pts value given, until a new stereo video packet is sent, or the stream is reinitialized.

2.17.1. Stereo Video Type Enumeration (enum StereoVideoType)

By convention, the first view is the left eye’s view, and the second view is the right eye’s view. The two are swapped if STEREO_VIDEO_FLAG_INVERTED is set.

STEREO_VIDEO_TYPE_2D = 0x0

Video is not stereoscopic. Only a single view exists. The metadata has to be ignored.

STEREO_VIDEO_TYPE_SIDE_BY_SIDE = 0x1

Views are next to each other, horizontally.

STEREO_VIDEO_TYPE_TOP_AND_BOTTOM = 0x2

Views are on top of each other.

STEREO_VIDEO_TYPE_INDIVIDUAL = 0x3

Views are separate, one in each frame. Indicated by the field_id, if set to 1, then view is the primary_eye.

STEREO_VIDEO_TYPE_CHECKERBOARD = 0x4

Pixels from each view are interleaved in a checkerboard structure.

STEREO_VIDEO_TYPE_SIDE_BY_SIDE_QUINCUNX = 0x5

Views are next to each other, horizontally. But are spatially sampled using a Quincunx pattern.

STEREO_VIDEO_TYPE_LINES = 0x6

Views are interleaved on a line-basis, as if interlaced.

STEREO_VIDEO_TYPE_COLUMNS = 0x7

Views are interleaved on a column basis.

2.17.2. Stereo Video Flags Enumeration (enum StereoVideoFlags)

STEREO_VIDEO_FLAG_INVERTED = 0x0

Views must be swapped during presentation (left->right, right->left).

2.17.3. Stereo Video Primary Eye Enumeration (enum StereoVideoPrimaryEye)

STEREO_VIDEO_PRIMARY_EYE_NONE = 0x0

Neither eye is primary.

STEREO_VIDEO_PRIMARY_EYE_LEFT = 0x1

The left eye is the primary.

STEREO_VIDEO_PRIMARY_EYE_RIGHT = 0x2

The right eye is the primary.

2.18. User data

The user-specific data packet is laid out as follows:

Type Name Data Description
b(16) user_data_descriptor 0x0600 Indicates this is an opaque user-specific data.
b(16) user_field A free to use field for user data.
u(32) global_seq Monotonically incrementing per-packet global sequence number.
u(32) userdata_length The total length of the user data.
u(32) userdata_pl_length The length of the user data in this packet.
b(64) opaque Opaque data, available to users to set.
u(8) userdata_compression enum DataCompression User data compression.
b(24) padding Padding, reserved for future use. MUST be 0x0.
b(64) ldpc_288_224 LDPC(288, 224) 64-bits of LDPC parity data to correct the previous 224 bits of the packet.
userdata_pl_length*b(8) userdata payload The user data itself.

User data may be segmented:

Descriptor value Name Structure Description
0x0601 user_data_segment_descriptor § 2.4.1 Generic data segmentation Non-final segment for segmented user data.
0x0602 user_data_parity_descriptor § 2.4.2 Generic data parity Parity data for user data.

2.19. Stream duration

If the session length is well-known, implementations can reserve space up-front at the start of files to notify implementations of stream lengths.

Type Name Data Description
b(16) stream_duration_descriptor 0x0050 Indicates this is a stream duration packet.
b(16) stream_id Indicates the stream ID for the index. May be 0xFFFF, in which case, it applies to all streams.
u(32) global_seq Monotonically incrementing per-packet global sequence number.
i(64) total_duration The total duration of the stream(s).
b(96) padding Padding, reserved for future use. Must be 0x0.
b(64) ldpc_288_224 LDPC(288, 224) 64-bits of LDPC parity data to correct the previous 224 bits of the packet.

If stream_id is 0xFFFF, the timebase used for total_duration must be assumed to be 1 nanosecond, numerator of 1, denominator of 1000000000.

If the value of total_duration is 0, the entire packet must be ignored. In such cases, implementations are free to attempt to measure stream duration via other methods.
This makes it possible to write stream duration packets at the start of streams, and amend them later.

The duration must be the total amount of time the stream will be presented.
Any negative duration MUST be excluded.

The duration must be treated as metadata rather than a hard limit.

2.20. End of stream

The EOS packet is laid out as follows:

Type Name Data Description
b(16) stream_end_descriptor 0x0FFF Indicates this is a stream duration packet.
b(16) stream_id Indicates the stream ID for the index. May be 0xFFFF, in which case, it applies to all streams.
u(32) global_seq Monotonically incrementing per-packet global sequence number.
b(160) padding Padding, reserved for future use. Must be 0x0.
b(64) ldpc_288_224 LDPC(288, 224) 64-bits of LDPC parity data to correct the previous 224 bits of the packet.

The stream_id field may be used to indicate that a specific stream will no longer receive any packets, and implementations are free to unload decoding and free up any used resources.

The stream_id may be reused afterwards, but this is not recommended.

If not encountered in a stream, and the connection was cut, then the receiver is allowed to gracefully wait for a reconnection.

If encountered in a file, the implementation may regard any data present afterwards as padding and ignore it. AVTransport files should not be concatenated.

3. Addendum

This section expands on certain aspects of the specification.

3.1. Codec encapsulation

The following section lists the supported codecs, along with their encapsulation definitions. Below, a mapping between codec_id and encapsulation is listed:

codec_id codec_id (ASCII) Encapsulation Name
0x4F707573 Opus CODEC_ID_OPUS § 3.1.1 Opus encapsulation
0x41414300 AAC\0 CODEC_ID_AAC § 3.1.2 AAC encapsulation
0x41432d33 AC-3 CODEC_ID_AC3 § 3.1.3 AC-3 encapsulation
0x41545231 ATR1 CODEC_ID_ATRAC1 § 3.1.4 ATRAC-1 encapsulation
0x41545239 ATR9 CODEC_ID_ATRAC9 § 3.1.5 ATRAC-9 encapsulation
0x4154414b ATAK CODEC_ID_TAK § 3.1.6 TAK encapsulation
0x664c6143 fLaC CODEC_ID_FLAC § 3.1.6 TAK encapsulation
0x56503332 VP23 CODEC_ID_THEORA § 3.1.8 Theora encapsulation
0x56503039 VP09 CODEC_ID_VP9 § 3.1.9 VP9 encapsulation
0x41563031 AV01 CODEC_ID_AV1 § 3.1.10 AV1 encapsulation
0x48323634 H264 CODEC_ID_H264 § 3.1.11 H264 encapsulation
0x48323635 H265 CODEC_ID_H265 § 3.1.12 H265 encapsulation
0x42424344 BBCD CODEC_ID_DIRAC § 3.1.15 Dirac/VC-2 encapsulation
0x46467631 FFv1 CODEC_ID_FFV1 § 3.1.16 FFv1 encapsulation
0x6170636e apcn CODEC_ID_PRORES_SD § 3.1.17 ProRes encapsulation
0x61706368 apch CODEC_ID_PRORES_HQ § 3.1.17 ProRes encapsulation
0x61706373 apcs CODEC_ID_PRORES_LT § 3.1.17 ProRes encapsulation
0x6170636f apco CODEC_ID_PRORES_PROXY § 3.1.17 ProRes encapsulation
0x61703468 ap4h CODEC_ID_PRORES_4444 § 3.1.17 ProRes encapsulation
0x61703478 ap4x CODEC_ID_PRORES_4444_XQ § 3.1.17 ProRes encapsulation
0x61707268 aprh CODEC_ID_PRORES_RAW_HQ § 3.1.17 ProRes encapsulation
0x6170726e aprn CODEC_ID_PRORES_RAW_SD § 3.1.17 ProRes encapsulation
0x54494646 TIFF CODEC_ID_TIFF § 3.1.21 DNG/TIFF encapsulation
0x4a504547 JPEG CODEC_ID_JPEG § 3.1.22 JPEG encapsulation
0x4a50324b JP2K CODEC_ID_JPEG2000 § 3.1.23 JPEG-2000 encapsulation
0x48544a32 HTJ2 CODEC_ID_JPEG2000_HT § 3.1.23 JPEG-2000 encapsulation
0x504e4700 PNG\0 CODEC_ID_PNG § 3.1.24 PNG encapsulation
0x53564732 SVG2 CODEC_ID_SVG § 3.1.25 SVG encapsulation
0x52414141 RAAA CODEC_ID_RAW_AUDIO § 3.1.26 Raw audio encapsulation
0x52415656 RAVV CODEC_ID_RAW_VIDEO § 3.1.27 Raw video encapsulation
0x41535334 ASS4 CODEC_ID_ASS § 3.1.18 ASS encapsulation
0x53554252 SUBR CODEC_ID_SRT § 3.1.19 SubRip encapsulation
0x57565454 WVTT CODEC_ID_WEBVTT § 3.1.20 WebVTT encapsulation
0x56433031 VC01 CODEC_ID_VC1 § 3.1.13 VC1 encapsulation
0x61507631 aPv1 CODEC_ID_APV § 3.1.14 APV encapsulation

3.1.1. Opus encapsulation

For Opus encapsulation, the codec_id in § 2.3 Stream registration must be 0x4F707573 (`Opus`).

The payload of the § 2.5 Stream configuration packets MUST be laid out in the following way:

Type Name Value Description
b(64) opus_id 0x4F70757348656164 (OpusHead) Opus magic string.
b(8) opus_init_ver Version of the config data. Must be 0x1.
u(8) opus_channels Number of audio channels.
u(16) opus_prepad Number of samples to discard from the start of decoding (encoder delay).
u(32) opus_rate Samplerate of the data. Must be 48000.
i(16) opus_gain Volume adjustment of the stream. May be 0 to preserve the volume.
u(32) opus_ch_family Opus channel mapping family. Consult [RFC7845] and [RFC8486].
u(8) opus_stream_count Optional, only available if opus_ch_family is not 0.
u(8) opus_coupled_count Optional, only available if opus_ch_family is not 0.
opus_channels*u(8) opus_channel_mapping Optional, only available if opus_ch_family is not 0.

The meaning of each field is defined by [RFC7845].

Implementations must not use the opus_prepad field, but must set the first stream packet’s pts value to a negative value as defined in § 1.8.2 Negative times to remove the required number of prepended samples.

The packet_data MUST contain regular Opus packets with their front uncompressed header intact.

In case of multiple channels, the packets MUST contain the concatenated contents in coding order of all channels' packets.

In case the Opus bitstream contains native Opus FEC data, the FEC data must be appended to the packet as-is, and no § 2.9 Stream data parity packets must be present for this stream.

3.1.2. AAC encapsulation

For AAC encapsulation, the codec_id in § 2.3 Stream registration MUST be 0x41414300 (AAC0).

The § 2.5 Stream configuration packet payload must be the codec’s AudioSpecificConfig, as defined in MPEG-4.

The packet_data MUST contain regular AAC ADTS packtes. Note that LATM is explicitly unsupported.

Implementations must set the first stream packet’s pts value to a negative value as defined in § 2.6 Stream Data to remove the required number of prepended samples.

3.1.3. AC-3 encapsulation

For AAC encapsulation, the codec_id in § 2.3 Stream registration must be 0x41432d33 (AC-3).

AC-3 streams require no § 2.5 Stream configuration packets.

THe `packet_data` must contain regular AC-3 or E-AC-3 frames, starting from the `syncinfo` header defined in the specifications.

3.1.4. ATRAC-1 encapsulation

For ATRAC1, the codec_id in the § 2.3 Stream registration must be 0x41545231 (ATR1).

ATRAC-1 streams require no § 2.5 Stream configuration packets.

The `packet_data` must contain regular ATRAC-1 frames, as contained in RIFF.

3.1.5. ATRAC-9 encapsulation

For ATRAC9, the codec_id in the § 2.3 Stream registration must be 0x41545239 (ATR9).

The payload in § 2.5 Stream configuration packets must be laid out in the following way:

Type Name Value Description
b(32) atrac9_version 0x01000000 The version of ATRAC-9 contained. Must be 0x01000000.
u(8) atrac9_magic 0xFE ATRAC-9 magic byte
u(4) atrac9_samplerate_idx Samplerate index for the stream.
u(3) atrac9_block_config Block configuration for the stream.
b(1) atrac9_verification_bit 0 Constant bit.
u(11) atrac9_avg_frame_size Average frame size in bits, minus one
u(2) atrac9_superframe_idx Superframe index. Must be even.
u(32) atrac9_block_align ATRAC-9 block alignment value for each frame. Must be larger than the largest frame in the stream.

Note: atrac9_block_align is a value carried over from RIFF encapsulation, and is normally given to decoders via a separate mechanism. The configuration data length should omit it (so that it’s 12 bytes long).

The packet_data must contain raw ATRAC-9 frames, with no RIFF headers or encapsulation.

3.1.6. TAK encapsulation

For TAK (Tom’s lossless Audio Kompressor) encapsulation, the codec_id in § 2.3 Stream registration must be 0x4154414b (ATAK).

TAK streams require no § 2.5 Stream configuration packets.

The packet_data must contain raw TAK frames, starting with the frame header.

3.1.7. FLAC encapsulation

For FLAC encapsulation, the codec_id in § 2.3 Stream registration must be 0x664c6143 (fLaC).

FLAC streams require § 2.5 Stream configuration packets, to contain the stream info header, which is defined as follows:

Type Name Value Description
u(16) flac_min_blocksize Minimum block size in samples.
u(16) flac_max_blocksize Maximum number of samples in a block. Must be larger than flac_min_blocksize.
u(24) flac_min_framesize Minimum framesize in bytes.
u(24) flac_max_framesize Maximum framesize in bytes. Must be larger than flac_min_framesize.
u(20) flac_samplerate Samplerate of the signal.
u(3) flac_channels Number of channels.
u(5) flac_bitdepth Bit depth of the signal.
u(24) flac_nb_samples_1 Top 24 bits of the total number of samples in the stream, if known.
u(12) flac_nb_samples_2 Bottom 12 bits of the number of samples in the stream, if known.
b(16) flac_streaminfo_md5 MD5 ([RFC1321]) checksum of the previous 34 bytes.

The `packet_data` must contain raw FLAC frames, with their frame header untouched.

3.1.8. Theora encapsulation

For Xiph Theora encapsulation, the codec_id in § 2.3 Stream registration must be 0x56503332 (VP32).

Stream configuration data is required for Theora. § 2.5 Stream configuration packets must contain an "Identification Header" (defined in Section 6.2), "Comment Header" (defined in Section 6.3), and a "Setup Header" (defined in Section 6.4), concatenated together, as defined in Section 3.2.1, "Decoder Setup".

The packet_data must contain raw Theora packets.

3.1.9. VP9 encapsulation

For VP9 encapsulation, the codec_id in § 2.3 Stream registration must be 0x56503039 (VP09).

The § 2.5 Stream configuration packet payload must be the codec’s so-called uncompressed header. For information on its syntax, consult the specifications, section 6.2 Uncompressed header syntax.

The packet_data must contain raw superframe packets, as defined in Annex B of the VP9 specifications.

3.1.10. AV1 encapsulation

For [AV1] encapsulation, the codec_id in § 2.3 Stream registration must be 0x41563031 (AV01).

The § 2.5 Stream configuration packet payload must be the codec’s so-called uncompressed header. For information on its syntax, consult the specifications, section 5.9.2. Uncompressed header syntax.

The packet_data MUST contain raw, separated OBUs.

3.1.11. H264 encapsulation

For H264 encapsulation, the codec_id in § 2.3 Stream registration must be 0x48323634 (H264).

§ 2.7 Extended stream data must be used, as H264 requires a dts.

The packet_data must contain Annex-B formatted NAL units, with startcode emulation bits included.

A § 2.5 Stream configuration packet may be sent, to speed up stream initialization. If they are present, they must contain an AVCDecoderConfigurationRecord structure, as defined in [ISO14496-15].

In-band parameters are always required to be present, even if an AVCDecoderConfigurationRecord structure is present in a § 2.5 Stream configuration packet.

Note: On some decoder implementations, giving an AVCDecoderConfigurationRecord structure upon initialization will result in the decoder mistaking the packets in the payload as AVCC rather than Annex-B. Implementations should consider whether the decoder being used will accept configuration data without assuming Annex-B, and only input such data if it is safe to do so.

3.1.12. H265 encapsulation

For H265 encapsulation, the codec_id in § 2.3 Stream registration must be 0x48323635 (H265).

§ 2.7 Extended stream data must be used, as H265 requires a dts.

The packet_data must contain Annex-B formatted NAL units, with startcode emulation bits included.

Annex-B formatted packets must be used, with startcode emulation bits included.

A § 2.5 Stream configuration packet may be sent, to speed up stream initialization. If they are present, they must contain an HEVCDecoderConfigurationRecord structure, as defined in [ISO23008].

3.1.13. VC1 encapsulation

For VC-1 encapsulation, the codec_id in § 2.3 Stream registration must be 0x56433031 (VC01).

This codec ID covers the following profiles of VC-1: (WMVA, WVC1).

Users may use the sequence layer data to determine the correct profile of the stream.

§ 2.7 Extended stream data must be used, as VC-1 requires a dts.

A § 2.5 Stream configuration packet may be sent, to speed up stream initialization. If they are present, they must contain a Setup Data/Sequence Layer structure.

3.1.14. APV encapsulation

For APV encapsulation, the codec_id in § 2.3 Stream registration MUST be 0x61507631 (aPv1).

APV is intra-frame only, so § 2.7 Extended stream data are not required.

APV streams require no § 2.5 Stream configuration packets. All decoder initialization data is contained within each access unit’s frame header.

The packet_data MUST contain a single APV access_unit() (as defined in Section 5.3.1 of [RFC9924]) per § 2.6 Stream Data packet, starting with the 4-byte signature (0x61507631, aPv1) and followed by its constituent PBUs. The leading au_size field from the raw bitstream format (Appendix A of [RFC9924]) MUST NOT be present, as the packet size is already conveyed by the AVTransport packet header.

3.1.15. Dirac/VC-2 encapsulation

For Dirac or VC-2 encapsulation, the codec_id in § 2.3 Stream registration MUST be 0x42424344 (BBCD).

§ 2.7 Extended stream data must be used, as Dirac packets require a dts.

Dirac streams require no § 2.5 Stream configuration packets.

The packet_data must contain raw sequences, with one sequence being a picture.

3.1.16. FFv1 encapsulation

For FFv1 encapsulation, the codec_id in § 2.3 Stream registration MUST be 0x46467631 (FFv1).

Stream configuration data is required for FFv1. § 2.5 Stream configuration packets must contain a "Parameters" structure, as defined in FFV1 Video Coding Format Versions 0, 1, and 3 § name-parameters.

The packet_data must contain raw FFv1 packets.

3.1.17. ProRes encapsulation

Apple ProRes is a collection of different profiles, each having its own codec ID:

codec ID codec ID (text) Profile
0x6170636e apcn Apple ProRes 422 Standard Definition
0x61706368 apch Apple ProRes 422 High Quality
0x61706373 apcs Apple ProRes 422 LT
0x6170636f apco Apple ProRes 422 Proxy
0x61703468 ap4h Apple ProRes 4444
0x61703478 ap4x Apple ProRes 4444 XQ
0x61707268 aprh Apple ProRes RAW High Quality
0x6170726e aprn Apple ProRes RAW Standard Definition

All Apple ProRes streams require no § 2.5 Stream configuration packets.

The packet_data must contain raw ProRes packets.

3.1.18. ASS encapsulation

For ASS encapsulation, the codec_id in § 2.3 Stream registration MUST be 0x41535334 (ASS4).

ASS is a popular subtitle format with great presentation capabilities. Although it was not designed to be streamed or packetized, doing so is possible with the following specifications. These match to how Matroska handles [MATROSKA-ASS] encapsulation.

ASS contains 3 important sections:

First, all data MUST be converted to UTF-8.

The § 2.5 Stream configuration packet payload MUST contain the [Script Info] and [V4 Styles] sections as a string, unmodified.

Events listed in ASS files MUST be modified in the following way:

The ReadOrder field is a monotonically incrementing field to identify the correct order in which to reconstruct the original ASS file.

Multiple packets with the same pts are permitted.

3.1.19. SubRip encapsulation

For SubRip encapsulation, the codec_id in § 2.3 Stream registration MUST be 0x53554252 (SUBR).

SubRip are a simple method of subtitle packaging that are de-facto standardized by the following syntax:

1
00:02:17,440 --> 00:02:20,375
Senator, we're making
our final approach into Coruscant.

2
00:02:20,476 --> 00:02:22,501
Very good, Lieutenant.

Each line starts with the sequence number (1), a start timestamp (2), an ending timestamp (3), the line(s) themselves, separated by newlines (4), and finally a blank like to indicate the end of the current line (5).

To encapsulate SubRip subtitles into AVTransport, simply use the subtitle body (3) as the packet_data. The start time is the packet’s pts field, while the duration field is the difference between the ending timestamp (3) and the starting timestamp (2).

SubRip streams require no § 2.5 Stream configuration packets.

Note: Extensions to SubRip files exist, with adding HTML-like tags to serve as markup. Dealing with them, however, is the users’s responsibility. It is recommended to convert such subtitles to § 3.1.18 ASS encapsulation.

Note: All kinds of encodings and line endings are used in SubRip files. They must be converted to UTF-8, with \n line endings.

3.1.20. WebVTT encapsulation

For SubRip encapsulation, the codec_id in § 2.3 Stream registration MUST be 0x57565454 (WVTT).

[WEBVTT] is a patent-free subtitle codec developed by the World Wide Web Consortium (W3C). It is essentially a standardized extension of SRT subtitles.

Unlike SRT, WebVTT supports styling. This is done via WebVTT styling blocks, inserted just before the first subtitle line.

The syling data, starting from and including the WEBVTT identifier, and ending at just before the first subtitle cue, must be put into § 2.5 Stream configuration packets. Any NOTE comments present before the first cue must be included alongside, in the way they appear, into the § 2.5 Stream configuration data.

The packet_data must contain the following structure:

Type Name Value Description
u(32) cue_components_len Length of the cue components.
cue_components_len*b(8) cue_comenents A string with all cue components
(data_length - cue_components_len - 1)*u(8) cue_data The actual line of text to present.

After the timestamp for each cue (line), WebVTT allows a number of cue components to style the line, terminated by a newline. As they are not part of the line, they are separated, and provided upfront as cue_comenents. The line ending may be retained for the cue_data, allowing for direct copy of the cue data.

The timestamps for each cue are translated into a pts and duration, as with SubRip.

3.1.21. DNG/TIFF encapsulation

For DNG/TIFF encapsulation, the codec_id in § 2.3 Stream registration must be 0x54494646 (TIFF).

DNG/TIFF streams require no § 2.5 Stream configuration packets

The packet_data must contain a raw TIFF file, with one packet being a single picture.

3.1.22. JPEG encapsulation

For JPEG and Motion JPEG, the codec_id in the § 2.3 Stream registration must be 0x4a504547 (JPEG).

JPEG and Motion JPEG streams require no § 2.5 Stream configuration packets.

The packet_data must contain a raw JPEG file, with one packet being a single picture.

3.1.23. JPEG-2000 encapsulation

For JPEG-2000 streams, as defined by [ISO15444], the codec_id in the § 2.3 Stream registration must be 0x4a50324b (JP2K).

JPEG-2000 streams require no § 2.5 Stream configuration packets.

The packet_data must contain a raw JPEG-2000 frame.

The packet_data must not contain JP2 data (better known as the JPEG-2000 standalone container), but rather the raw, individual JPEG-2000 frames (known as J2K, or HTJ2K).

High-throughput JPEG-2000, as defined by [ISO15444-15], is supported and recommended. The same considerations as regular JPEG-2000 apply, but the codec_id in the § 2.3 Stream registration must be 0x48544a32 (HTJ2) instead.

3.1.24. PNG encapsulation

For PNG, the codec_id in the § 2.3 Stream registration must be 0x504e4730 (PNG0).

PNG streams require no § 2.5 Stream configuration packets.

The packet_data must contain a raw PNG file. No support for Animated PNG is defined, but simply not flagging the still picture flag (`stream_flags & 0x04`) and sending a single picture per frame is sufficient to animate PNG, as this is allowed for any codec.

3.1.25. SVG encapsulation

For [SVG2] (Scalable Vector Graphics), the codec_id in the § 2.3 Stream registration must be 0x53564732 (SVG2).

SVG streams require no § 2.5 Stream configuration packets.

The packet_data must contain a raw SVG file. Compressed SVGZ are explicitly not supported. Instead, the pkt_compression field must be used if compression is to be used. This is due to DEFLATE ([RFC1951]) being potentially a bottleneck in decompression.

No support for animated SVG (SVG 2 § 2.2.3 Animated mode) is available, or any SVG variant with Javascript embedded. Each SVG packet must be a raw and standalone. Embedded images are, however, permitted.

The width and height dimensions of § 2.15 Video information shall be a suggested dimension, generally set upon creation time.

Note: SVG streams may be either video streams or used as subtitles. The STREAM_SUBTITLES flags must be set if the SVG stream is to be used as subtitles.

3.1.26. Raw audio encapsulation

For raw audio encapsulation, the codec_id in § 2.3 Stream registration MUST be 0x52414141 (RAAA).

§ 2.5 Stream configuration packets are required, and must be laid out in the following way:

Type Name Value Description
u(32) ra_channels The number of channels contained.
b(8) ra_bits The number of bits for each sample.
u(8) ra_float If non-zero, data is floating-point.

The packet_data must contain the concatenated stream of interleaved samples for all channels.

The samples must be normalized between [-1.0, 1.0] if they’re float, and full-range signed if they’re integers.

The size of each sample must be ra_bits, and must be aligned to the nearest power of two, with the padding in the least significant bits. That means that 24-bit samples are coded as 32-bits, with the data contained in the topmost 24 bits.

3.1.27. Raw video encapsulation

For raw video encapsulation, the codec_id in § 2.3 Stream registration MUST be 0x52415656 (RAVV).

Note: § 2.15 Video information packets must be present. The information in this structure is only sufficient to parse data, not enough to present it.

§ 2.5 Stream configuration packets are required, and must be laid out in the following way:

Type Name Value Description
u(8) rv_components The number of components the video stream contains.
u(8) rv_planes The number of planes the video components are placed in.
u(8) rv_bpp The number of bits for each individual component pixel.
u(32) rv_flags enum RawVideoFlags Flags for the video stream.
rv_planes*u(32) rv_plane_stride For each plane, the total number of bytes per horizontal line, including any padding.
rv_components*u(8) rc_plane Specifies the plane index that each component belongs in.
rv_components*u(8) rc_stride Specifies the distance between 2 horizontally consequtive pixels for each component, in bits for bitpacked video, otherwise bytes.
rv_components*u(8) rc_offset Specifies the number of elements before each component, in bits for bitpacked video, otherwise bytes.
rv_components*i(8) rc_shift Specifies the number of bits to shift right (if negative) or shift left (is positive) to get the final value.
rv_components*u(8) rc_bits Specifies the total number of bits the component’s value will contain.

The purpose of the rc_offset field is to allow differentiation between different orderings of pixels in an RGB video, e.g. RGB’s rc_offsets will be [0, 1, 2], whilst BGR’s will be [2, 1, 0]. The components MUST be given in the order they appear in the stream.

The packet_data field must contain rv_planes, with each plane having rv_plane_stride bytes per line.

The number of horizontal lines is height, whicl will be modified by the value of chroma_subsampling for each individual plane as specified.

The actual data within the lines must be filled in according to rc_offset and rc_stride.

3.1.28. Raw Video Flags Enumeration (enum RawVideoFlags)

The rv_flags field must be interpreted in the following way:

RAW_VIDEO_FLOAT = 0x1

Video contains [IEEE-754] normalized floating point values. Size is determined by the rv_bpp value.

RAW_VIDEO_ALPHA = 0x2

Video contains a stright, non-premultiplied alpha. Alpha is always the last component.

RAW_VIDEO_ALPHA_PREMULTIPLIED = 0x4

Video contains a premultiplied alpha channel. Alpha is always the last component.

RAW_VIDEO_PLANAR = 0x8

At least one pixel component is not sharing a plane, e.g. video is planar.

RAW_VIDEO_BITPACKED = 0x10

Video’s components are tightly packed, e.g. video is bitpacked.

RAW_VIDEO_BIG_ENDIAN = 0x20

Video’s values are big-endian. If unset, values are little-endian. Does not apply for bitpacked video.

Note: rv_flags must not signal both RAW_VIDEO_ALPHA and RAW_VIDEO_ALPHA_PREMULTIPLIED. Such a combination of flags is undefined.

This structure is flexible enough to permit zero-copy or one-copy streaming of video from most sources.

3.1.29. Custom codec encapsulation

A special section is dedicated for custom codec storage. While potentially useful for experimentation and for specialized usecases, users of such are invited to submit an addendum to this document to formalize such containerization. This field MUST NOT be used if the codec being contained already has a formal definition in this spec.

For custom encapsulation, the codec_id in § 2.3 Stream registration must be 0x433f**** (C?**), where the bottom 2 bytes can be any value between 0x30 to 0x39 (0 to 9 in ASCII) and 0x61 to 0x7a (a to z in ASCII).

The § 2.5 Stream configuration payload can be any length and contain any sequence of data.

The packet_data field can be any length and contain any sequence of data.

3.2. Streaming

This section describes and suggests behavior for realtime AVTransport streams.

The protocol supports four different streaming arrangements:

In the first case (Unidirectional), the sender initializes the session by sending a § 2.1 Session start to the receiver, and proceeds with sending more packets.

In the second case (Bidirectional), the sender initializes the session by sending a § 2.1 Session start packet with a SESSION_REVERSE_SIGNAL_READY flag, and on the same connection, the receiver sends another § 2.1 Session start packet to initialize reverse connectivity.

In the third case (Multidirectional prompted) case, the sender listens for any § 2.1 Session start sent by clients on a given port. If received, the server begins to send information back to the client address on the same connection it received the session start packet.

In the fourth case (Multicast), the server binds to a multicast UDP address and begins to send data.

Users are strongly recommended to follow the recommendations given in § 4.2.2 Streaming recommendations.

3.2.1. UDP

To adapt AVTransport for streaming over UDP is trivial - simply send the data packets as-is specified, with no changes required. The sender implementation should resent packets at the frequencies listed in § 2.1 Session start to permit for implementations that didn’t catch on the start of the stream begin decoding.

UDP mode is unidirectional, but the implementations are free to use the § 3.3 Reverse signalling data if they negotiate it themselves.
Reverse signalling should not be used if the connection is public.

Implementations must segment the data such that the network MTU is never exceeded and no packet fragmentation occurs.
The minimum network MTU required for the protocol is 384 bytes, as to allow § 2.15 Video information or any future large packets to be sent without fragmentation.

Jumbograms may be used where supported to reduce overhead and increase efficiency.

Note: Data packets may be padded by appending zeroed bytes after the packet_data field up to the maximum MTU size. This permits constant bitrate operation, as well as preventing metadata leakage in the form of a packet size.

Note: When operating at higher MTUs, implementations should consider adding FEC or parity, as the 16-bit UDP datagram CRC may be inadequate to detect errors.

If § 3.3 Reverse signalling is used, the receiver must send packets over to the sender using the same port number that the receiver is listening on.

3.2.2. QUIC

AVTransport tries to use as much of the modern conveniences of QUIC: A UDP-Based Multiplexed and Secure Transport § QUIC# as possible. As such, it uses both reliable and unreliable streams, as well as bidirectionality features of the transport mechanism.

All data packets with descriptors 0x01**, 0x02**, 0xFF, 0xFE, 0xFD and 0xFC must be sent over in an unreliable QUIC datagram stream, as per [RFC9221]. Each stream must map to a different QUIC stream, though their AVTransport and QUIC stream IDs do not have to match.

All other packets must be sent over a reliable steam. FEC data for those packets should not be signalled.

Implementations must segment the data such that the network MTU is never exceeded and no packet fragmentation occurs.

The minimum network MTU required for the protocol is 384 bytes, as to allow § 2.15 Video information or any future large packets to be sent without fragmentation.

The ALPN must contain the extension 0x61, 0x76, 0x74, 0x30 (avt0).

Jumbograms may be used where supported to reduce overhead and increase efficiency.

§ 3.3 Reverse signalling is natively supported on QUIC.

3.2.3. Packetized networks

AVTransport is a series of individual packets with no overarching data structure. This allows for it to be contained over any protocol or transmitted over any packetized network.

The built-in resilience in each data structure makes the protocol suitable even over connections with a high bit error rate.

Poor connection reliability can be largely overcome by using § 2.8 FEC grouping.

This specification does not specify how linking or transmission is performed - only that the AVTransport packets remain compliant with their definition here, and the stream as a whole remains compliant.

3.2.4. Serial

AVTransport explicitly carries the size of the contained data. This makes it suitable for not only packetized networks, but also serial links.

Users must track the start of each AVTransport packet themselves, using the packet headers and, optionally, LDPC data to synchronize with the source.

The specification contains no recommendation on how the data is transported. Users should, if necessary, use FEC and other reliability features.

3.3. Reverse signalling

AVTransport supports bidirectional connections. Implementing this part of the specification is fully optional.

All packets send back from a receiver to the transmitter must have bit 0x8000 set in their descriptors. This means that the receiver can send back the same type of packets that the transmitter can, with a number of extra packets for control.

Receivers must receive a § 2.1 Session start packet from a transmitter, with bit SESSION_REVERSE_SIGNAL_READY set in the session_flags bitmask before they are allowed to send packets back.

3.3.1. Session control data

The receiver can use this type to return errors and more to the sender in a one-to-one transmission. The following syntax is used:

Type Name Data Description
b(16) session_control_descriptor 0x8001 Indicates this is a control data packet.
b(8) cease If not equal to 0x0, indicates a fatal error, and senders MUST NOT sent any more data.
u(8) resend_init If nonzero, asks the sender to resend all § 2.2 Time synchronization, all § 2.3 Stream registration and all required packets for them.
u(32) error enum ErrorCode Indicates an error code, if not equal to 0x0.
b(128) uplink_ip Reports the upstream address to stream to.
u(16) uplink_port Reports the upstream port to stream on to the uplink_ip.
b(8) seek If 1, Asks the sender to seek to the position given by seek_pts and/or seek_seq.
i(64) seek_pts The pts value to seek to.
u(32) seek_seq The sequence number of the packet to seek to.

If the sender gets such a packet, and either its uplink_ip or its uplink_port do not match, the sender must cease this connection, reopen a new connection with the given uplink_ip, and resend all packets needed to begin decoding to the new destination.

The seek request asks the sender to begin sending old data that is still available. The sender may not comply if that data suddenly becomes unavailable. If the value of seek is equal to 0, then the receiver must comply and always start sending the newest data.

If the resend_init flag is set to a non-zero value, senders should flush all encoders such that the receiver can begin decoding as soon as possible.

If operating over QUIC, then any old data must be served over a reliable stream, as latency isn’t critical. If the receiver asks again for the newsest available data, that data’s payload is once again sent over an *unreliable* stream.

The following error values are allowed:

3.3.2. Error Code Enumeration (enum ErrorCode)

ERROR_CODE_GENERIC = 0x1

Signals a generic error.

ERROR_CODE_UNSUPPORTED = 0x2

Unsupported data. May be sent after the sender sends a § 2.3 Stream registration to indicate that the receiver does not support this codec. The sender may send another packet of this type with the same stream_id to attempt reinitialization with different parameters.

3.3.3. Feedback

The following packet MAY be sent from the receiver to the sender.

Type Name Data Description
b(16) stream_feedback_descriptor 0x8002 Indicates this is a statistics packet.
b(16) stream_id Indicates the stream ID for which this packet is relevant to. May be 0xFFFF to indicate all streams.
u(64) epoch_offset Time since epoch. May be 0. Can be used to estimate the latency.
u(64) bandwidth Hint that indicates the available receiver bandwith, in bits per second. May be 0, in which case infinite must be assumed. Senders should respect it. The figure should include all headers and associated overhead.
u(64) fec_corrections A counter that indicates the total amount of repaired packets (packets with errors that FEC was able to correct).
u(64) corrupt_packets Indicates the total number of corrupt packets. This also counts corrupt packets FEC was not able to correct.
u(64) dropped_packets Indicates the total number of dropped packets.

Receivers should send out a new statistics packet every time a count was updated. Additionally, receivers should send new feedback packets often enough to prevent UDP NAT from timing out.

3.3.4. Resend

The following packet MAY be sent to ask the client to resend a recent packet that was likely dropped.

Type Name Data Description
b(16) packet_resend_descriptor 0x8003 Indicates this is a stream data resend packet.
b(16) padding Padding, reserved for future use. Must be 0x0.
u(32) global_seq The sequence number of the packet that is missing.

3.3.5. Stream control

The receiver can use this type to subscribe or unsubscribe from streams.

Type Name Data Description
b(16) stream_control_descriptor 0x8004 Indicates this is a stream control data packet.
b(16) stream_id The stream ID for which this packet applies to. MUST NOT be 0xFFFF.
u(32) global_seq If `1`, asks the sender to not send any packets relating to stream_id streams.

This can be used to save bandwidth. If previously disabled and then enabled, all packets necessary to initialize the stream MUST be resent.

3.4. Informative muxer behaviour

This annex covers recommended practices for muxers, particularly with regards to avoiding stream starvation.

3.5. Informative demuxer behaviour

This annex covers recommended practices for demuxers, mainly with packet lifetime, buffering, and reordering.

4. Annex

Additional data or recommendations for the AVTransport specification is listed here.

4.1. Annex A: Metadata tags

The following string keys should be used, instead of any others:

titletext string

Full name of the stream.

languagetext string

Language name subtag, as per [bcp47].

language_tagtext string

More concise language information, including regional variants, as defined by Tags for Identifying Languages § section-2.1.

datetext string

Date of release. MUST be formatted according to [RFC3339].

trackunsigned integer

Track number, if the stream is part of an album.

tracksunsigned integer

Total number of tracks, if stream is part of an album.

artisttext string

Full name of the performing artist on this track.

album_artisttext string

Full name of the album’s artist.

albumtext string

Full name of the album.

commenttext string

Arbitrary release details.

discunsigned integer

Disc number, in case of multi-disc releases.

discsunsigned integer

Total number of discs, in case of multi-disc releases.

media_typetext string

Original media type of the release.

isrctext string

International Standard Recording Code of the given track.

mcntext string

Media Catalog Number for the album, if available.

REPLAYGAIN_TRACK_GAINfloating point number

ReplayGain 2.0 track gain, in dB.

REPLAYGAIN_TRACK_RANGEfloating point number

ReplayGain 2.0 track range, in dB.

REPLAYGAIN_TRACK_PEAKfloating point number

ReplayGain 2.0 track peak, in dB.

REPLAYGAIN_REFERENCE_LOUDNESSfloating point number

ReplayGain 2.0 reference loudness, in LUFS.

encoderlist of properties

A list of settings used for encoding.

The language field must be formatted as a subtag, according to the [bcp47].

The language_tag field must be formatted as described in Tags for Identifying Languages § section-2.1. It provides more detailed information than the language field, including regional variation and script.

The date field must be formatted according to [RFC3339].

If the value type differs, or is formatted in a different way outside of these specifications, then the metadata field is considered invalid.

This section covers recommended practices for AVTransport streams in common circumstances.

4.2.1. Archival recommendations

For archival, it is recommended to limit the packet size to the maximum packet size that the storage medium natively operates at. This ensures that the native error correction capabilities work to enhance the capabilities of AVTransport.

It is recommended to use FEC groups encapsulating every stream, with a fec_nb_packets of sufficient length to eliminate any remaining packet errors that slip by.

4.2.2. Streaming recommendations

In general, implementations should emit the following packet types at the given frequencies.

Packet type Suggested frequency Description
§ 2.1 Session start Target startup delay To identify a stream as AVTransport without ambiguity.
§ 2.2 Time synchronization Target startup delay Optional time synchronization field to establish an epoch and do timestamp jitter compensation.
§ 2.3 Stream registration Target startup delay Register streams to permit packet processing.
§ 2.5 Stream configuration Target startup delay To initialize decoding of stream packets.
§ 2.15 Video information Target startup delay To correctly present any video packets.
§ 2.13 LUT/ICC profile Target startup delay Optional LUT/ICC profile for correct video presentation.
§ 2.16 Video orientation Target startup delay Video orientation packets, when needed.
§ 2.12 Metadata Target startup delay Session metadata.
§ 2.6 Stream Data Always Stream data packets.
§ 2.8 FEC grouping Appropriate for the packet loss Optional FEC data.
§ 2.18 User data As often as necessary Optional user data packets.
§ 2.20 End of stream Once Finalizes a stream or session.

In particular, § 2.2 Time synchronization packets should be sent as often as necessary if timestamp jitter avoidance is a requirement.

4.3. Annex W: LDPC

This normative annex shall cover the usage and operation of [LDPC] within AVTransport.

The LDPC variant to be used is irregular (each row of each matrix has a non-constant amount of bits set to 1), systematic (parity data is separate from message data), with no subblocks. The full block, along with the check data, shall be sent to an LDPC decoder.

To ease implementations, only two different lengths are used:

For reference, the following code may be used to compute the LDPC parity data:

void ldpc_encode(uint8_t *pkt, const uint64_t *W,
                 int message_bits, int parity_bits)
{
    int j, k, w;
    int words = parity_bits / 64;
    uint64_t parity, data, bits[8];

    /* Parity data goes last */
    uint8_t *dst = pkt + (message_bits / 8);

    /* Compute one 64-row slice of the parity vector at a time */
    for (w = 0; w < words; w++) {
        parity = 0x0; /* Start with zero parity */

        /* Process 8 message bits at a time */
        for (j = 0; j < (message_bits / 8); j++) {
            data = pkt[j];

            /* Duplicate each bit 64 times (reversed, bytestream order) */
            for (k = 0; k < 8; k++)
                bits[k] = ((data >> (7 - k)) & 1) * UINT64_MAX;

            /* XOR in the generator column of every message bit set to 1 */
            for (k = 0; k < 8; k++)
                parity ^= bits[k] & W[(j*8 + k)*words + w];
        }

        /* Write this slice of parity data, in bytestream order */
        for (k = 56; k >= 0; k -= 8)
            *dst++ = (parity >> k) & 0xFF;
    }
}

This code is provided as a reference, and although more efficient algorithms exist, embedded devices and microcontrollers are able to perform millions of LDPC(288, 224) encodings per second with it.

Implementations should consider using more advanced encoding algorithms, such as the Richardson-Urbanke method to reduce the overhead further.

4.3.1. LDPC matrices

Each code is defined by a parity-check matrix H of size (n - k) ⨉ n —​thus 64 ⨉ 288 and 768 ⨉ 2784.

Note: In mathematical notation, matrix sizes are specified as height ⨉ width, not width ⨉ height. This specification uses mathematical nomenclature for this definition.

The matrices are irregular, systematic, and optimized for AWGN channels (though they perform nearly as well in other circumstances). The first k columns of H hold the message bits and the last n - k columns the parity bits; the parity columns do not form an identity matrix.

Because of that, encoding does not use H directly — it uses the systematic generator matrix W, the (n - k) ⨉ k matrix Hp-1·Hd, where Hd and Hp are the message- and parity-bit column blocks of H. The parity bits of a message u are then p = W·u over GF(2). This is what the reference routine above consumes; H itself is used for decoding.

As each matrix value is purely boolean, columns are stored as 64-bit unsigned integers in big endian format: the most significant bit holds the topmost row. A column taller than 64 rows is stored as (n - k) / 64 consecutive integers, the topmost 64 rows first, and columns are stored one after another.

The H-matrices are provided alongside this specification as standard MacKay alist files, ldpc_288_224.alist and ldpc_2784_2016.alist, directly usable for analysis and simulation. The reference implementation embeds both H and the derived generator matrices W as uint64_t arrays.

Conformance

Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.

All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

Examples in this specification are introduced with the words “for example” or are set apart from the normative text with class="example", like this:

This is an example of an informative example.

Informative notes begin with the word “Note” and are set apart from the normative text with class="note", like this:

Note, this is an informative note.

Index

Terms defined by this specification

Terms defined by reference

References

Normative References

[AV1-ISOBMFF]
AV1 Codec ISO Media File Format Binding. Draft Deliverable. URL: https://aomediacodec.github.io/av1-isobmff/
[BCP47]
A. Phillips, Ed.; M. Davis, Ed.. Tags for Identifying Languages. September 2009. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc5646
[CSS-COLOR-4]
Tab Atkins Jr.; Chris Lilley; Lea Verou. CSS Color Module Level 4. URL: https://drafts.csswg.org/css-color-4/
[MEDIAQUERIES-5]
Tab Atkins Jr.; et al. Media Queries Level 5. URL: https://drafts.csswg.org/mediaqueries-5/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[RFC6330]
M. Luby; et al. RaptorQ Forward Error Correction Scheme for Object Delivery. August 2011. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc6330
[RFC9000]
J. Iyengar, Ed.; M. Thomson, Ed.. QUIC: A UDP-Based Multiplexed and Secure Transport. May 2021. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc9000
[RFC9043]
M. Niedermayer; D. Rice; J. Martinez. FFV1 Video Coding Format Versions 0, 1, and 3. August 2021. Informational. URL: https://www.rfc-editor.org/rfc/rfc9043
[SVG2]
Amelia Bellamy-Royds; et al. Scalable Vector Graphics (SVG) 2. URL: https://w3c.github.io/svgwg/svg2-draft/
[XXHASH]
Yann Collet. xxHash fast digest algorithm. URL: https://github.com/Cyan4973/xxHash/blob/dev/doc/xxhash_spec.md

Non-Normative References

[AV1]
Peter de Rivaz; Jack Haughton. AV1 Bitstream & Decoding Process Specification. 8 January 2019. Standard. URL: https://aomediacodec.github.io/av1-spec/av1-spec.pdf
[BT2100]
BT.2100: Image parameter values for high dynamic range television for use in production and international programme exchange. July 2018. URL: https://www.itu.int/rec/R-REC-BT.2100
[CIE1931]
Commission internationale de l'Eclairage proceedings. 1931.
[CUBE]
Cube LUT Specification Version 1.0. URL: https://kono.phpage.fr/images/a/a1/Adobe-cube-lut-specification-1.0.pdf
[FFmpeg]
FFmpeg. URL: https://ffmpeg.org
[H.273]
Coding-independent code points for video signal type identification. September 2023. URL: https://www.itu.int/rec/T-REC-H.273/en
[IEEE-754]
IEEE Standard for Floating-Point Arithmetic. 22 July 2019. URL: https://ieeexplore.ieee.org/document/8766229
[ISO14496-15]
Information technology — Coding of audio-visual objectsPart 15: Carriage of network abstraction layer (NAL) unit structured video in the ISO base media file format. October 2022. URL: https://www.iso.org/standard/83336.html
[ISO15444]
JPEG 2000 image coding system. October 2019. URL: https://www.iso.org/standard/78321.html
[ISO15444-15]
JPEG 2000 image coding system Part 15: High-Throughput JPEG 2000. October 2019. URL: https://www.iso.org/standard/76621.html
[ISO18181]
JPEG XL image coding system — Part 1: Core coding system. March 2022. URL: https://www.iso.org/standard/77977.html
[ISO23008]
Information technology — High efficiency coding and media delivery in heterogeneous environments. January 2023. URL: https://www.iso.org/standard/76386.html
[LDPC]
David J.C. MacKay; Radford M. Neal. Near Shannon Limit Performance of Low Density Parity Check Codes. July 1996. URL: https://www.csie.ntu.edu.tw/~mku/research/LDPC/asset/papers/General/LDPC_MacKay.pdf
[LDPC-encoding]
T. J. Richardson; R. L. Urbanke. Efficient encoding of low-density parity-check codes. February 2001. URL: https://ieeexplore.ieee.org/document/910579
[MATROSKA-ASS]
Matroska specifications, SSA/ASS Subtitles. URL: https://matroska.org/technical/subtitles.html#ssaass-subtitles
[OpenType]
OpenType specification. URL: http://www.microsoft.com/typography/otspec/default.htm
[RFC1321]
R. Rivest. The MD5 Message-Digest Algorithm. April 1992. Informational. URL: https://www.rfc-editor.org/rfc/rfc1321
[RFC1951]
P. Deutsch. DEFLATE Compressed Data Format Specification version 1.3. May 1996. Informational. URL: https://www.rfc-editor.org/rfc/rfc1951
[RFC2675]
D. Borman; S. Deering; R. Hinden. IPv6 Jumbograms. August 1999. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc2675
[RFC3339]
G. Klyne; C. Newman. Date and Time on the Internet: Timestamps. July 2002. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc3339
[RFC3629]
F. Yergeau. UTF-8, a transformation format of ISO 10646. November 2003. Internet Standard. URL: https://www.rfc-editor.org/rfc/rfc3629
[RFC5905]
D. Mills; et al. Network Time Protocol Version 4: Protocol and Algorithms Specification. June 2010. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc5905
[RFC6716]
JM. Valin; K. Vos; T. Terriberry. Definition of the Opus Audio Codec. September 2012. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc6716
[RFC768]
J. Postel. User Datagram Protocol. August 1980. Internet Standard. URL: https://www.rfc-editor.org/rfc/rfc768
[RFC7845]
T. Terriberry; R. Lee; R. Giles. Ogg Encapsulation for the Opus Audio Codec. April 2016. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc7845
[RFC7932]
J. Alakuijala; Z. Szabadka. Brotli Compressed Data Format. July 2016. Informational. URL: https://www.rfc-editor.org/rfc/rfc7932
[RFC8486]
J. Skoglund; M. Graczyk. Ambisonics in an Ogg Opus Container. October 2018. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc8486
[RFC8820]
M. Nottingham. URI Design and Ownership. June 2020. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc8820
[RFC8878]
Y. Collet; M. Kucherawy, Ed.. Zstandard Compression and the 'application/zstd' Media Type. February 2021. Informational. URL: https://www.rfc-editor.org/rfc/rfc8878
[RFC8949]
C. Bormann; P. Hoffman. Concise Binary Object Representation (CBOR). December 2020. Internet Standard. URL: https://www.rfc-editor.org/rfc/rfc8949
[RFC9221]
T. Pauly; E. Kinnear; D. Schinazi. An Unreliable Datagram Extension to QUIC. March 2022. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc9221
[RFC9562]
K. Davis; B. Peabody; P. Leach. Universally Unique IDentifiers (UUIDs). May 2024. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc9562
[RFC9924]
Y. Lim; et al. Advanced Professional Video. February 2026. Informational. URL: https://www.rfc-editor.org/rfc/rfc9924
[TrueType]
TrueType™ Reference Manual. URL: https://developer.apple.com/fonts/TrueType-Reference-Manual/
[UNIX-time]
Unix time. URL: https://en.wikipedia.org/wiki/Unix_time
[WEBVTT]
Gary Katsevman. WebVTT: The Web Video Text Tracks Format. URL: https://w3c.github.io/webvtt/
[WOFF2]
Vladimir Levantovsky. WOFF File Format 2.0. URL: https://w3c.github.io/woff/woff2/