-
Notifications
You must be signed in to change notification settings - Fork 41
New Varint Encoding #1016
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
New Varint Encoding #1016
Changes from 4 commits
8b5f6bc
2a2f16d
ae23d21
eac1557
cb4af37
4527fc9
654a77c
a22a952
7a1bd7a
7150fd2
b950764
211018d
086de2c
ca87191
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -243,11 +243,6 @@ x (L): | |
|
|
||
| : Indicates that x is L bits long | ||
|
|
||
| x (i): | ||
|
|
||
| : Indicates that x holds an integer value using the variable-length | ||
| encoding as described in ({{?RFC9000, Section 16}}) | ||
|
|
||
| x (..): | ||
|
|
||
| : Indicates that x can be any length including zero bits long. Values | ||
|
|
@@ -262,6 +257,13 @@ x (L) ...: | |
| : Indicates that x is repeated zero or more times and that each instance | ||
| has a length of L | ||
|
|
||
| This document redfines the following RFC9000 syntax: | ||
afrind marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| x (i): | ||
|
||
|
|
||
| : Indicates that x holds an integer value using the variable-length | ||
| encoding as described in {{variable-length-integers}}. | ||
|
|
||
| This document extends the RFC9000 syntax and with the additional field types: | ||
|
|
||
| x (b): | ||
|
|
@@ -276,10 +278,45 @@ x (tuple): | |
| as described in ({{?RFC9000, Section 16}}), followed by that many variable | ||
| length tuple fields, each of which are encoded as (b) above. | ||
|
|
||
|
|
||
| ### Variable-Length Integers | ||
afrind marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| MoQT requires a variable-length integer encoding with the following properties: | ||
|
|
||
| 1. The encoded length can be determined from the first encoded byte. | ||
| 2. The range of 1 byte values is as large as possible. | ||
| 3. All 64 bit numbers can be encoded. | ||
|
|
||
| The variable-length integer encoding reserves the most one to four significant | ||
| bits of the first byte to encode the length of the integer encoding in | ||
| bytes. The integer value is encoded on the remaining bits, in network byte | ||
| order. | ||
afrind marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| Integers are encoded in 1, 2, 4, 8, or 9 bytes and can encode 7-, 14-, 29-, 60-, | ||
| or 64-bit values, respectively. The following table summarizes the encoding | ||
| properties. | ||
|
|
||
| |--------------|----------------|-------------|---------------| | ||
| | Leading Bits | Length (bytes) | Usable Bits | Range | | ||
| |--------------|----------------|-------------|---------------| | ||
| | 0 | 1 | 7 | 0-127 | | ||
| |--------------|----------------|-------------|---------------| | ||
| | 10 | 2 | 14 | 0-16,383 | | ||
ianswett marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| |--------------|----------------|-------------|---------------| | ||
| | 110 | 4 | 29 | 0-536,870,911 | | ||
| |--------------|----------------|-------------|---------------| | ||
| | 1110 | 8 | 60 | 0-2^60-1 | | ||
| |--------------|----------------|-------------|---------------| | ||
| | 1111XXXX | 9 | 64 | 0-2^64-1 | | ||
|
||
| |--------------|----------------|-------------|---------------| | ||
| {: format title="Summary of Integer Encodings"} | ||
|
|
||
| To reduce unnecessary use of bandwidth, variable length integers SHOULD | ||
afrind marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| be encoded using the least number of bytes possible to represent the | ||
| required value. | ||
|
|
||
| A sample encoding and decoding algorithm is in {{sample-varint}}. | ||
|
|
||
| ### Location Structure | ||
|
|
||
| Location identifies a particular Object in a Group within a Track. | ||
|
|
@@ -2060,18 +2097,18 @@ SUBSCRIBE_DONE Message { | |
| * Status Code: An integer status code indicating why the subscription ended. | ||
|
|
||
| * Stream Count: An integer indicating the number of data streams the publisher | ||
| opened for this subscription. This helps the subscriber know if it has received | ||
| all of the data published in this subscription by comparing the number of | ||
| streams received. The subscriber can immediately remove all subscription state | ||
| once the same number of streams have been processed. If the track had | ||
| Forwarding Preference = Datagram, the publisher MUST set Stream Count to 0. If | ||
| the publisher is unable to set Stream Count to the exact number of streams | ||
| opened for the subscription, it MUST set Stream Count to 2^62 - 1. Subscribers | ||
| SHOULD use a timeout or other mechanism to remove subscription state in case | ||
| the publisher set an incorrect value, reset a stream before the SUBGROUP_HEADER, | ||
| or set the maximum value. If a subscriber receives more streams for a | ||
| subscription than specified in Stream Count, it MAY close the session with a | ||
| Protocol Violation. | ||
| opened for this subscription. This helps the subscriber know if it has | ||
| received all of the data published in this subscription by comparing the | ||
| number of streams received. The subscriber can immediately remove all | ||
| subscription state once the same number of streams have been processed. If | ||
| the track had Forwarding Preference = Datagram, the publisher MUST set Stream | ||
| Count to 0. If the publisher is unable to set Stream Count to the exact | ||
| number of streams opened for the subscription, it MUST set Stream Count to a | ||
| value greater than or equal to 2^60. Subscribers SHOULD use a timeout or other | ||
afrind marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| mechanism to remove subscription state in case the publisher set an incorrect | ||
| value, reset a stream before the SUBGROUP_HEADER, or set the maximum value. If | ||
| a subscriber receives more streams for a subscription than specified in Stream | ||
| Count, it MAY close the session with a Protocol Violation. | ||
|
|
||
| * Error Reason: Provides the reason for subscription error. See {{reason-phrase}}. | ||
|
|
||
|
|
@@ -3443,6 +3480,58 @@ document: | |
|
|
||
| --- back | ||
|
|
||
| # Sample Variable-Length Integer Encoding and Decoding {#sample-varint} | ||
|
|
||
|
||
| The WriteVarint function takes two parameters, a 64 bit integer and an | ||
| output buffer with an append operation. | ||
|
|
||
| ~~~pseudocode | ||
|
||
| Function WriteVarint(value, output): | ||
| if value <= 127: | ||
| output.append(value, 1) | ||
| else if value <= 16383: | ||
| output.append(networkByteOrder(uint16_t(value | 0x8000)), 2) | ||
| else if value <= 536870911: | ||
| output.append(networkByteOrder( | ||
| uint32_t(value | 0xC0000000)), 4) | ||
| else if value <= 1152921504606846975: | ||
| output.append(networkByteOrder( | ||
| uint64_t(value | 0xE000000000000000)), 8) | ||
| else: | ||
| output.append(0xF0, 1) | ||
| output.append(networkByteOrder(value), 8) | ||
| ~~~ | ||
|
|
||
|
|
||
| The function ReadVarint takes a single argument -- a sequence of bytes, which | ||
afrind marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| can be read in network byte order. | ||
|
|
||
| ~~~pseudocode | ||
| ReadVarint(data): | ||
| lengths = [ 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 8, 9 ] | ||
| masks = [ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, | ||
| 0x3f, 0x3f, 0x3f, 0x3f, 0x1f, 0x1f, 0x0f, 0x00 ] | ||
| // The length of variable-length integers is encoded in the | ||
| // first one to four bits of the first byte. | ||
| v = data.next_byte() | ||
| prefix = v >> 4 | ||
| length = lengths[prefix] | ||
| mask = masks[prefix] | ||
|
|
||
| // Once the length is known, remove these bits and read any | ||
| // remaining bytes. | ||
| v = v & mask | ||
| repeat length-1 times: | ||
| v = (v << 8) + data.next_byte() | ||
| return v | ||
| ~~~ | ||
| For example, the nine-byte sequence 0xf0ffffffffffffffff decodes to the decimal | ||
| value 18,446,744,073,709,551,615; the eight-byte sequence 0xe2197c5eff14e88c | ||
| decodes to the decimal value 151,288,809,941,952,652; the four-byte sequence | ||
| 0xdd7f3e7d decodes to 494,878,333; the two-byte sequence 0xbbbd decodes to | ||
| 15,293; and the single byte 0x25 decodes to 37 (as does the two-byte sequence | ||
| 0x8025). | ||
|
|
||
afrind marked this conversation as resolved.
Show resolved
Hide resolved
afrind marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| # Change Log | ||
|
|
||
| RFC Editor's Note: Please remove this section prior to publication of a final version of this document. | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.