AOMedia Film Grain Synthesis 1 (AFGS1) specification

Last modified: 2024-01-17 14:15 PT

Editor
Andrey Norkin (Netflix)

Version 1.0.0

This version 1.0.0 of the AOMedia Film Grain Synthesis 1 (AFGS1) specification corresponds to the AOMediaCodec/afgs1-spec project.

To comment on this document, use the issue tracker.

Copyright 2024, The Alliance for Open Media

Licensing information is available at http://aomedia.org/license/

The MATERIALS ARE PROVIDED “AS IS.” The Alliance for Open Media, its members, and its contributors expressly disclaim any warranties (express, implied, or otherwise), including implied warranties of merchantability, non-infringement, fitness for a particular purpose, or title, related to the materials. The entire risk as to implementing or otherwise using the materials is assumed by the implementer and user. IN NO EVENT WILL THE ALLIANCE FOR OPEN MEDIA, ITS MEMBERS, OR CONTRIBUTORS BE LIABLE TO ANY OTHER PARTY FOR LOST PROFITS OR ANY FORM OF INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER FROM ANY CAUSES OF ACTION OF ANY KIND WITH RESPECT TO THIS DELIVERABLE OR ITS GOVERNING AGREEMENT, WHETHER BASED ON BREACH OF CONTRACT, TORT (INCLUDING NEGLIGENCE), OR OTHERWISE, AND WHETHER OR NOT THE OTHER MEMBER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Abstract

This document defines the format, the required parsing and decoding processes, and the processing steps for the standalone Alliance for Open Media film grain synthesis technology. Signaling of the film grain parameters can be done using ITU-T T.35 registered user metadata, which is described in this document.

Contents

Scope

This document specifies the syntax, semantics, and decoding process for the AOMedia Film Grain Synthesis process. This process can be used and indicated with any video coding or transport mechanism. This includes the use of ITU-T T.35 based signaling, which is also specified in this document. Alternatively, the payload can be carried by other suitable transport mechanisms.

This specification is based on the film grain modeling process that is specified in the AV1 specification. However, this AOMedia Film Grain Synthesis process specification allows sending more than one film grain parameter set for a decoded picture. A decoder can apply the film grain synthesis process at a different resolution than the decoded picture resolution if the parameters for such resolution are present in the bitstream. A film grain parameter set that corresponds to the decoded picture resolution has to be present, which may be useful for certain AV1 film grain synthesis implementations.

Terms and definitions

For the purposes of this document, the following terms and definitions apply:

Bitstream

The sequence of bits generated by encoding a sequence of pictures.

Bit string

An ordered string with a limited number of bits. The left most bit is the most significant bit (MSB) and the right most bit is the least significant bit (LSB).

Byte

An 8-bit bit string.

Byte alignment

One bit, byte, or syntax element is byte aligned if the position of the bit, byte, or syntax element, respectively in the bitstream is an integer multiple of eight from the position of the first bit in the bitstream.

Chroma

A sample value matrix or a single sample value of one of the two color difference signals.

Note: Symbols of chroma are U and V or Cb and Cr.

Coded picture

The representation of one picture before the decoding process.

Coded video sequence

A coded video sequence is a sequence of access units or temporal units that consists of a random access point, which is followed by zero or more access units or temporal units up to but not including the subsequent random access point.

Component

One of the three sample value matrices (one luma matrix and two chroma matrices) or its single sample value.

Decoded picture

The picture reconstructed out of the bitstream by the video decoder.

Field

A collection of samples from alternate rows of a frame. A frame is composed of two fields, a top field and a bottom field.

Film grain analysis process

A process not specified in this Specification that generates film grain parameters that conforms to the description provided in this document.

Film grain analyzer

One embodiment of the film grain analysis process.

Film grain synthesis module

One embodiment of the film grain synthesis process.

Film grain synthesis process

The process that derives film grain parameters from syntax elements, including any processing steps used for the film grain synthesis process.

Flag

A binary variable - some variables and syntax elements (e.g. video_signal_characteristics_flag) are described using the word flag to highlight that the syntax element can only be equal to 0 or equal to 1.

Frame

A composition of samples that constitute an entire image and includes samples from a top and a bottom field, where the top and bottom fields correspond to samples from even and odd numbered rows respectively. A frame may be composed of one luma sample matrix (Y) and optionally two chroma sample matrices (U and V).

Key picture

An Intra picture which resets the decoding process when it is shown.

Luma

A sample value matrix or a single sample value representing the monochrome signal related to the primary colors.

Note: The symbol representing luma is Y.

Parse

The procedure of getting the syntax element from the bitstream.

Picture

The representation of video signals in the spatial domain, composed of one luma sample matrix (Y) and , optionally, two chroma sample matrices (U and V) in a 4:2:0, 4:2:2, 4:4:4, 4:0:0 color format. The picture could be either a frame or a field.

Profile

A subset of syntax, semantics, and algorithms defined in a part.

Raster scan

Maps a two dimensional rectangular raster into a one dimensional raster, in which the entry of the one dimensional raster starts from the first row of the two dimensional raster, and the scanning then goes through the second row and the third row, and so on. Each raster row is scanned in left to right order.

Random Access Point (RAP)

A picture, at which a decoder may start decoding a coded video sequence.

Reconstruction

Obtaining the addition of the decoded residual and the corresponding prediction values.

Reference

One of a set of tags, each of which is mapped to a reference picture.

Reserved

A special syntax element value which may be used to extend this part in the future.

Sample

The basic elements that compose the picture.

Sample value

The value of a sample. This is an number in the range from the minimum sample value to the maximum sample value.

Sequence

The highest level syntax structure of coding bitstream, including one or several consecutive coded picture.

Syntax element

An element of data represented in the bitstream.

Video decoder

One embodiment of the video decoding process.

Video decoding process

The process that derives decoded pictures from syntax elements, including any processing steps used prior to and after generating the decoded video pictures.

Video encoding process

A process not specified in this Specification that generates a video bitstream.

Symbols and abbreviated terms

LSB

Least Significant Bit

MSB

Most Significant Bit

Conventions

General

The mathematical operators and their precedence rules used to describe this Specification are similar to those used in the C programming language. However, the operation of integer division with truncation is specifically defined.

When a variable is said to be representable by a signed integer with x bits, it means that the variable is greater than or equal to -(1 << (x-1)), and that the variable is less than or equal to (1 << (x-1))-1.

The key words “must”, “must not”, “required”, “shall”, “shall not”, “should”, “should not”, “recommended”, “may”, and “optional” in this document are to be interpreted as described in RFC 2119.

Arithmetic operators

+ Addition
Subtraction (as a binary operator) or negation (as a unary prefix operator)
* Multiplication
/ Integer division with truncation of the result toward zero. For example, 7/4 and -7/-4 are truncated to 1 and -7/4 and 7/-4 are truncated to -1.

Logical operators

a && b Logical AND operation between a and b
a || b Logical OR operation between a and b
! Logical NOT operation.

Relational operators

> Greater than
>= Greater than or equal to
< Less than
<= Less than or equal to
== Equal to
!= Not equal to

Bitwise operators

& AND operation
| OR operation
^ XOR operation
~ Negation operation
a >> b Shift a in 2’s complement binary integer representation format to the right by b bit positions. This operator is only used with b being a non-negative integer. Bits shifted into the MSBs as a result of the right shift have a value equal to the MSB of a prior to the shift operation.
a << b Shift a in 2’s complement binary integer representation format to the left by b bit positions. This operator is only used with b being a non-negative integer. Bits shifted into the LSBs as a result of the left shift have a value equal to 0.

Assignment

= Assignment operator
++ Increment, x++ is equivalent to x = x + 1. When this operator is used for an array index, the variable value is obtained before the auto increment operation
- - Decrement, i.e. x-- is equivalent to x = x - 1. When this operator is used for an array index, the variable value is obtained before the auto decrement operation
+= Addition assignment operator, for example x += 3 corresponds to x = x + 3
-= Subtraction assignment operator, for example x -= 3 corresponds to x = x - 3

Mathematical functions

The following mathematical functions (Abs, Clip3, Clip1, Min, Max, Round2 and Round2Signed) are defined as follows:

The definition of Round2 uses standard mathematical power and division operations, not integer operations. An equivalent definition using integer operations is:

Round2( x, n ) {
  if ( n == 0 )
    return x
  return ( x + ( 1 << (n - 1) ) ) >> n
}

Method of describing bitstream syntax

The description style of the syntax is similar to the C programming language. Syntax elements in the bitstream are represented in bold type. Each syntax element is described by its name (using only lower case letters with underscore characters) and a descriptor for its method of coded representation. The decoding process behaves according to the value of the syntax element and to the values of previously decoded syntax elements. When a value of a syntax element is used in the syntax tables or the text, it appears in regular (i.e. not bold) type. If the value of a syntax element is being computed (e.g. being written with a default value instead of being coded in the bitstream), it also appears in regular type (e.g. tile_size_minus_1).

In some cases the syntax tables may use the values of other variables derived from syntax elements values. Such variables appear in the syntax tables, or text, named by a mixture of lower case and upper case letter and without any underscore characters. Variables starting with an upper case letter are derived for the decoding of the current syntax structure and all depending syntax structures. These variables may be used in the decoding process for later syntax structures. Variables starting with a lower case letter are only used within the process from which they are derived. (Single character variables are allowed.)

Constant values appear in all upper case letters with underscore characters (e.g. MI_SIZE).

Constant lookup tables appear as words (with the first letter of each word in upper case, and remaining letters in lower case) separated with underscore characters (e.g. Block_Width[…]).

Hexadecimal notation, indicated by prefixing the hexadecimal number by 0x, may be used when the number of bits is an integer multiple of 4. For example, 0x1a represents a bit string 0001 1010.

A value equal to 0 represents a FALSE condition in a test statement. The value TRUE is represented by any value not equal to 0.

The following table lists examples of the syntax specification format. When syntax_element appears (with bold face font), it specifies that this syntax element is parsed from the bitstream.

                                                           Type
/* A statement can be a syntax element with associated  
descriptor or can be an expression used to specify its  
existence, type, and value, as in the following  
examples */  
                                                            
syntax_element f(1)
   
/* A group of statements enclosed in brackets is a  
compound statement and is treated functionally as a single  
statement. */  
   
{  
    statement  
    …  
}  
   
/* A “while” structure specifies that the statement is  
to be evaluated repeatedly while the condition remains  
true. */  
   
while ( condition )  
    statement  
   
/* A “do .. while” structure executes the statement once,  
and then tests the condition. It repeatedly evaluates the  
statement while the condition remains true. */  
   
do  
    statement  
while ( condition )  
   
/* An “if .. else” structure tests the condition first. If  
it is true, the primary statement is evaluated. Otherwise,  
the alternative statement is evaluated. If the alternative  
statement is unnecessary to be evaluated, the “else” and  
corresponding alternative statement can be omitted. */  
   
if ( condition )  
    primary statement  
else  
    alternative statement  
   
/* A “for” structure evaluates the initial statement at the  
beginning then tests the condition. If it is true, the primary  
and subsequent statements are evaluated until the condition  
becomes false. */  
   
for ( initial statement; condition; subsequent statement )  
    primary statement  
   
/* The return statement in a syntax structure specifies  
that the parsing of the syntax structure will be terminated  
without processing any additional information after this stage.  
When a value immediately follows a return statement, this value  
shall also be returned as the output of this syntax structure. */  
   
return x  

Functions

Bitstream functions used for syntax description are specified in this section.

Other functions are included in the syntax tables. The convention is that a section is called syntax if it causes syntax elements to be read from the bitstream, either directly or indirectly through subprocesses. The remaining sections are called functions.

The specification of these functions makes use of a bitstream position indicator. This bitstream position indicator locates the position of the bit that is going to be read next.

get_position( ): Return the value of the bitstream position indicator.

Descriptors

f(n)

Unsigned n-bit number appearing directly in the bitstream. The bits are read from high to low order. The parsing process specified in section 9.1 is invoked and the syntax element is set equal to the return value.

Syntax structures

General

This section presents the syntax structures in a tabular form. The meaning of each of the syntax elements is presented in Section 6.

AOMedia ITU-T T.35 metadata syntax

metadata_aom_itu_t_t35( ) { Type
    itu_t_t35_country_code f(8)
    itu_t_t35_terminal_provider_code f(16)
    itu_t_t35_terminal_provider_oriented_code f(8)
    if ( itu_t_t35_terminal_provider_oriented_code == 0x01 ) {  
        av1_film_grain_param_sets( )  
    }  
}  

Film grain parameter sets syntax

av1_film_grain_param_sets( ) { Type
    afgs1_enable_flag f(1)
    if( !afgs1_enable_flag ) {  
       return  
    }  
    /* Add reserved bits so that av1_film_grain_payload is byte aligned */  
    reserved_4bits f(4)
    num_film_grain_sets_minus1 f(3)
    for ( i = 0; i < num_film_grain_sets_minus1 + 1; i++ ) {  
       av1_film_grain_payload( )  
    }  
    selectedParamSet = select_film_grain_param_set( )  
    load_grain_params( selectedParamSet )  
}  

Film grain parameter payload syntax

av1_film_grain_payload( ) { Type
    /* Store the current bit-stream position */  
    startPosition = get_position( )  
   
    /* Receive the payload size. Note that when update_grain is equal to 0,  
    film grain parameter messages will be 21 bits. Receive the  
    size of these messages with 3 bits so that there is no additional  
    overhead for byte alignment in this case. */  
   
    payload_less_than_4byte_flag f(1)
    n = payload_less_than_4byte_flag ? 2 : 8  
    payload_size f(n)
   
    /* Receive the film grain parameters */  
    av1_film_grain_params( )  
   
    /* Determine the number of bits consumed by the payload */  
    currentPosition = get_position( )  
    payloadBits = currentPosition - startPosition  
   
    / * Zero pad (and byte align) to the payload size */  
    padding_bits( payload_size * 8 - payloadBits )  
}  

Film grain parameters syntax

av1_film_grain_params( ) { Type
    film_grain_param_set_idx f(3)
    apply_grain_flag f(1)
    if ( !apply_grain_flag ) {  
        load_grain_params( film_grain_param_set_idx )  
        apply_grain_flag = 0  
        save_grain_params( film_grain_param_set_idx )  
        return  
    }  
    grain_seed f(16)
    update_grain_flag f(1)
    if ( !update_grain_flag ) {  
        tempGrainSeed = grain_seed  
        load_grain_params( film_grain_param_set_idx )  
        apply_grain_flag = 1  
        grain_seed = tempGrainSeed  
        save_grain_params( film_grain_param_set_idx )  
        return  
    }  
    apply_units_resolution_log2 f(4)
    apply_horz_resolution f(12)
    apply_vert_resolution f(12)
    luma_only_flag f(1)
    SubX = SubY = 0  
    if ( !luma_only_flag ) {  
         subsampling_x f(1)
         SubX = subsampling_x  
         subsampling_y f(1)
         SubY = subsampling_y  
    }  
    video_signal_characteristics_flag f(1)
    if (video_signal_characteristics_flag)  
        bit_depth_minus8 f(3)
        BitDepth = bit_depth_minus8 + 8  
        cicp_info_present_flag f(1)
        if ( cicp_info_present_flag ) {  
            color_primaries f(8)
            transfer_characteristics f(8)
            matrix_coefficients f(8)
            video_full_range_flag f(1)
        }  
    }  
    predict_scaling_flag f(1)
    if (predict_scaling_flag) {  
        predict_y_scaling_flag f(1)
    } else {  
        predict_y_scaling_flag = 0  
    }  
    if (predict_y_scaling_flag) {  
        y_scaling_mult f(9)
        y_scaling_add f(9)
        bits_per_y_scaling_res f(3)
        if (bits_per_y_scaling_res) {  
              bitsRes = bits_per_y_scaling_res  
              for ( i = 0; i < numYPointsInRef; i++ )  
                  point_y_scaling_res[ i ] f(bitsRes)
              y_scaling_res_granularity f(3)
        }  
    } else {  
        num_y_points f(4)
        if (num_y_points) {  
            point_y_value_increment_bits_minus1 f(3)
            bitsIncr = point_y_value_increment_bits_minus1 + 1  
            point_y_scaling_bits_minus5 f(2)
            bitsScal = point_y_scaling_bits_minus5 + 5  
            for ( i = 0; i < num_y_points; i++ ) {  
                point_y_value_increment[ i ] f(bitsIncr)
                point_y_scaling[ i ] f(bitsScal)
            }  
        }  
    }  
    if ( luma_only_flag ) {  
        chroma_scaling_from_luma_flag = 0  
    } else {  
        chroma_scaling_from_luma_flag f(1)
    }  
    if ( luma_only_flag || chroma_scaling_from_luma_flag ) {  
        num_cb_points = 0  
        num_cr_points = 0  
    } else {  
        if (predict_scaling_flag) {  
            predict_cb_scaling_flag f(1)
        } else  
            predict_cb_scaling_flag = 0  
        if (predict_cb_scaling_flag) {  
            cb_scaling_mult f(9)
            cb_scaling_add f(9)
            bits_per_cb_scaling_res f(3)
            if (bits_per_cb_scaling_res) {  
                bitsRes = bits_per_cb_scaling_res  
                for ( i = 0; i < numCbPointsInRef; i++ )  
                    point_cb_scaling_res[ i ] f(bitsRes)
                cb_scaling_res_granularity f(3)
            }  
        } else {  
            num_cb_points f(4)
            if (num_cb_points) {  
                point_cb_value_increment_bits_minus1 f(3)
                bitsIncr = point_cb_value_increment_bits_minus1 + 1  
                point_cb_scaling_bits_minus5 f(2)
                bitsScal = point_cb_scaling_bits_minus5 + 5  
                cb_scaling_offset f(8)
                for ( i = 0; i < num_cb_points; i++ ) {  
                    point_cb_value_increment[ i ] f(bitsIncr)
                    point_cb_scaling[ i ] f(bitsScal)
                }  
            }  
        }  
        if (predict_scaling_flag) {  
            predict_cr_scaling_flag f(1)
        } else  
            predict_cr_scaling_flag = 0  
        if (predict_cr_scaling_flag) {  
            cr_scaling_mult f(9)
            cr_scaling_add f(9)
            bits_per_cr_scaling_res f(3)
            if (bits_per_cr_scaling_res) {  
                bitsRes = bits_per_cr_scaling_res  
                for ( i = 0; i < numCrPointsInRef; i++ )  
                    point_cr_scaling_res[ i ] f(bitsRes)
                cr_scaling_res_granularity f(3)
            }  
        } else {  
            num_cr_points f(4)
            if (num_cr_points) {  
                point_cr_value_increment_bits_minus1 f(3)
                bitsIncr = point_cr_value_increment_bits_minus1 + 1  
                point_cr_scaling_bits_minus5 f(2)
                bitsScal = point_cr_scaling_bits_minus5 + 5  
                cr_scaling_offset f(8)
                for ( i = 0; i < num_cr_points; i++ ) {  
                    point_cr_value_increment[ i ] f(bitsIncr)
                    point_cr_scaling[ i ] f(bitsScal)
                }  
            }  
        }  
    }  
    grain_scaling_minus8 f(2)
    ar_coeff_lag f(2)
    numPosLuma = 2 * ar_coeff_lag * ( ar_coeff_lag + 1 )  
    if ( num_y_points || predict_y_scaling_flag ) {  
        numPosChroma = numPosLuma + 1  
        bits_per_ar_coeff_y_minus5 f(2)
        BitsArY = bits_per_ar_coeff_y_minus5 + 5  
        for ( i = 0; i < numPosLuma; i++ )  
            ar_coeffs_y[ i ] f(BitsArY)
    } else {  
        numPosChroma = numPosLuma  
    }  
    if ( chroma_scaling_from_luma_flag || num_cb_points || predict_cb_scaling_flag ) {  
        bits_per_ar_coeff_cb_minus5 f(2)
        BitsArCb = bits_per_ar_coeff_cb_minus5 + 5  
        for ( i = 0; i < numPosChroma; i++ )  
            ar_coeffs_cb[ i ] f(BitsArCb)
    }  
    if ( chroma_scaling_from_luma_flag || num_cr_points || predict_cr_scaling_flag ) {  
        bits_per_ar_coeff_cr_minus5 f(2)
        BitsArCr = bits_per_ar_coeff_cr_minus5 + 5  
        for ( i = 0; i < numPosChroma; i++ )  
            ar_coeffs_cr[ i ] f(BitsArCr)
    }  
    ar_coeff_shift_minus6 f(2)
    grain_scale_shift f(2)
    if ( num_cb_points && !predict_cb_scaling_flag) {  
        cb_mult f(8)
        cb_luma_mult f(8)
        cb_offset f(9)
    }  
    if ( num_cr_points && !predict_cr_scaling_flag ) {  
        cr_mult f(8)
        cr_luma_mult f(8)
        cr_offset f(9)
    }  
    overlap_flag f(1)
    clip_to_restricted_range_flag f(1)
    process_grain_params( )  
    save_grain_params( film_grain_param_set_idx )  
}  

Padding bits syntax

padding_bits( nbBits ) { Type
    while( nbBits > 0 ) {  
       padding_zero_bit f(1)
       nbBits--  
    }  
}  

Syntax structures semantics

General

This section specifies the meaning of the syntax elements present in the syntax structures.

Important variables and function calls are also described.

AOMedia ITU-T T.35 metadata semantics

itu_t_t35_country_code is a syntax element that corresponds to the country code in an ITU-T T.35 user registered metadata syntax. itu_t_t35_country_code shall be equal to 0xB5 for bitstreams conforming to this version of the specification.

itu_t_t35_terminal_provider_code is a syntax element that corresponds to a terminal provider code in an ITU-T T.35 user registered metadata syntax. itu_t_t35_terminal_provider_code shall be equal to 0x5890 for bitstreams conforming to this version of the specification.

itu_t_t35_terminal_provider_oriented_code shall be equal to 0x01 for bitstreams conforming to this version of the specification.

Film grain parameter sets semantics

afgs_enable_flag equal to 1 specifies that the film grain synthesis process is applied to the decoded picture associated with the current av1_film_grain_param_sets function. afgs_enable_flag equal to 0 specifies that the film grain synthesis process is not applied to the decoded picture associated with the current av1_film_grain_param_sets function.

reserved_4bits must be set to 0. The value is ignored by a decoder.

num_film_grain_sets_minus1 plus 1 specifies the number of signaled film grain parameter sets in the current av1_film_grain_param_sets function.

select_film_grain_param_set() is a function call that returns the index of the film grain parameter set signaled in the current av1_film_grain_param_sets function that is most appropriate for the current decoder configuration.

Note: It is recommended that the most appropriate film grain parameter set is the film grain parameter set having the largest spatial resolution that is both supported by the film grain synthesis process of the decoder and is less than or equal to the intended display resolution.

load_grain_params( idx ) is a function call that specifies that all syntax elements determined in the av1_film_grain_params function and all variables beginning with upper case determined in the av1_film_grain_params function (and its sub-functions) shall be set equal to the values located in the memory location denoted by idx.

Conformance

Conformance to this specification requires that all requirements specified in this section be fulfilled.

For a given decoded picture, there shall not be more than one film grain parameter set for a given combination of luma horizontal and luma vertical resolution.

For a given decoded picture, if film grain parameter sets are associated with this picture, one film grain parameter set shall be provided satisfying the following conditions: (i) apply_horz_resolution equal to the luma horizontal resolution of the decoded picture » apply_units_resolution_log2, (ii) apply_vert_resolution equal to the luma vertical resolution of the decoded picture » apply_units_resolution_log2, (iii) subsampling_x equal to the chroma horizontal subsampling of the decoded picture, (iv) subsampling_y equal to the chroma vertical subsampling of the decoded picture, (v) bitdepth equal to the bitdepth of the decoded picture when the bitdepth syntax element is present, (vi) color_primaries equal to the color primaries of the decoded picture when the color_primaries syntax element is present, (vii) transfer_characteristics equal to the transfer characteristics of the decoded picture when the transfer_characteristics syntax element is present, (viii) matrix_coefficients equal to the matrix coefficients of the decoded picture when the matrix_coefficients syntax element is present, and (ix) video_full_range_flag equal to the video full range flag of the decoded picture when the video_full_range_flag syntax element is present.

For a given decoded picture, there shall not be more than one film grain parameter set for a given combination of luma horizontal resolution, luma vertical resolution, and, when present, color primaries, transfer characteristics, matrix coefficients, and video full range values.

When there are more than one film grain parameter set with the same combination of luma horizontal and luma vertical resolution for a given decoded picture, the value of cicp_info_present_flag shall be equal to 1 for these film grain parameter sets.

For a given decoded picture, all film grain parameter sets associated with the picture shall have the same value for afgs1_enable_flag.

Note: The conformance statements above mean that if film grain parameter sets are associated with a decoded picture, there must be one film grain parameter set that corresponds to the decoded picture resolution and other decoded frame characteristics, there shall not be more than one film grain parameter set that correspond to the same resolution and decoded frame characteristics, and film grain parameter sets related to the same decoded picture shall each use a unique of film_grain_param_set_idx.

Note: The conformance statements above mean that if multiple distinct decoded pictures could be generated from the same bitstream (for example, when scalable layers are present with operating points which produce different resolutions) and film grain parameter sets are present, then a film grain parameter set must be available matching the parameters of each possible decoded picture.

Film grain parameter payload semantics

payload_less_than_4byte_flag equal to 1 specifies that the number of bytes used by the data in the current av1_film_grain_payload is less than four bytes. payload_less_than_4byte_flag equal to 0 specifies that the number of bytes used by the data in the current av1_film_grain_payload may be equal to four or more bytes.

payload_size specifies the number of bytes used by the data in the current av1_film_grain_payload.

Note: The number of bytes used by the data in the current av1_film_grain_payload includes the payload_less_than_4byte_flag and payload_size syntax elements, all syntax elements in the av1_film_grain_params function (and any sub-functions), as well as optional zero padding bytes. The zero padding bytes can be useful for applications that choose to create an av1_film_grain_payload prior to determining the payload contents.

Film grain parameters semantics

This metadata provides the post-processing module with a model for parameterized film grain synthesis. The film grain process is applied to pictures output by a video decoder or a video post-processing module. The film grain synthesis should be applied at the resolution specified for the selected film grain parameter set.

Note: An encoder may use this film grain metadata to characterize film grain that was present in the original source video material and was removed by pre-processing filtering techniques. The specified film grain parameters and the post-processing algorithm are equivalent to the AV1 film grain synthesis at the picture level.

The film grain parameters signaled in this metadata message are applied to the output video picture that is associated with the coded video picture that is associated with the current metadata message in the encoded video bitstream.

Note: When coding the film grain parameters in this metadata message, the encoder should consider the scalability layering structure of the bitstream. In particular, the metadata associated with lower scalability layers should not refer to the film grain parameters associated with higher scalability layers.

film_grain_param_set_idx specifies the index of a film grain parameter set. Up to 8 separate film grain parameter sets can be simultaneously stored by the film grain processing module.

Note: An encoder may use film_grain_param_set_idx to differentiate between up to 8 separate film grain models.

apply_grain_flag equal to 1 specifies that the film grain synthesis process is enabled when the film grain parameters specified in the current av1_film_grain_params function are selected. apply_grain_flag equal to 0 specifies that the film grain synthesis process is disabled when the film grain parameters specified in the current av1_film_grain_params function are selected.

process_grain_params( ) is a function call that specifies that all variables beginning with upper case specified in the current section are determined by performing any process specified in the semantics of each parsed syntax elements.

save_grain_params( idx ) is a function call that specifies that all syntax elements determined in the av1_film_grain_params function and all variables beginning with upper case determined in the av1_film_grain_params function (and its sub-functions) shall be stored in the memory location denoted by idx.

grain_seed specifies the starting value for the pseudo-random numbers used during film grain synthesis.

update_grain_flag equal to 1 specifies the presence of a new set of film grain parameters. update_grain_flag equal to 0 specifies that a set of film grain parameters corresponding to the film_grain_param_set_idx value should be used.

It is a requirement of the specification conformance that for every distinct value of film_grain_param_set_idx used in a coded video sequence, the first picture in the decoding order with that value of film_grain_param_set_idx that has apply_grain_flag flag equal to 1 have update_grain_flag equal to 1.

Note: This requirement means that film grain parameters associated with a particular film_grain_param_set_idx value can only be inferred from previously signaled parameters in the picture decoding order with the same value of film_grain_param_set_idx in the current coded video sequence.

It is a requirement of the specification conformance that if (i) update_grain_flag is equal to zero, (ii) apply_horz_resolution equal to the luma horizontal resolution of the decoded picture » apply_units_resolution_log2, and (iii) apply_vert_resolution equal to the luma vertical resolution of the decoded picture » apply_units_resolution_log2 then the film_grain_param_set_idx shall reference the film grain parameter set that when the save_grain_params( film_grain_param_set_idx ) function was called, the following conditions were true (i) update_grain_flag was equal to 1, (ii) apply_horz_resolution was equal to the luma horizontal resolution of the decoded picture » apply_units_resolution_log2, and (iii) apply_vert_resolution was equal to the luma vertical resolution of the decoded picture » apply_units_resolution_log2.

Note: This requirement means that film grain parameters associated with the decoded picture resolution can only be inferred from previously signaled parameters that corresponded to the decoded picture resolution. This requirement is intended to make sure that bitstreams that exercise variable decoded picture resolution do not copy the film grain parameters for the decoded picture resolutions from pictures that were not at a decoded picture resolution. This requirement helps decoders that only use (and store) film grain parameter sets that correspond to the decoded picture resolution.

tempGrainSeed is a temporary variable that is used to preserve the value of grain_seed when load_grain_params is called.

apply_units_resolution_log2 specifies the units used for indicating apply_horz_resolution and apply_vert_resolution.

apply_vert_resolution specifies the luma vertical resolution corresponding to the film grain synthesis parameters in units of 1 « apply_units_resolution_log2 luma samples.

apply_horz_resolution specifies the luma horizontal resolution corresponding to the film grain synthesis parameters in units of 1 « apply_units_resolution_log2 luma samples.

luma_only_flag equal to 1 specifies that the film grain synthesis parameters in the current set do not include U and V color planes. luma_only_flag equal to 0 specifies that the film grain synthesis parameters in the current set include U and V color planes.

subsampling_x equal to 0 specifies that the horizontal resolution of the chroma component of the film grain synthesis parameters in the current set is the same as the horizontal resolution of the luma component. subsampling_x equal to 1 specifies that the horizontal resolution of the chroma component of the film grain synthesis parameters in the current set is equal to the horizontal resolution of the luma component subsampled by a factor of two.

subsampling_y equal to 0 specifies that the vertical resolution of the chroma component of the film grain synthesis parameters in the current set is the same as the vertical resolution of the luma component. subsampling_y equal to 1 specifies that the vertical resolution of the chroma component of the film grain synthesis parameters in the current set is equal to the vertical resolution of the luma component subsampled by a factor of two.

Note: The table below shows example mappings between common image formats and values for the subsampling_x, subsampling_y, and luma_only_flag syntax elements.

subsampling_x subsampling_y luma_only_flag Description
0 0 0 YUV 4:4:4
1 0 0 YUV 4:2:2
1 1 0 YUV 4:2:0
- - 1 Monochrome 4:0:0

video_signal_characteristics_flag equal to 1 specifies that bit_depth_minus8, color_primaries, transfer_characteristics, and matrix_coefficients may be present. video_signal_characteristics_flag equal to 0 specifies that bit_depth_minus8, color_primaries, transfer_characteristics, and matrix_coefficients are not present.

bit_depth_minus8 indicates the bitdepth of the decoded video picture associated with the current film grain parameters. When bit_depth_minus8 is not present, the variable BitDepth is derived from the decoded video picture that is associated with the current film grain parameters.

It is a requirement of conformance to this specification that the value of bit_depth_minus8 is less or equal to 4.

Note: The reference decoding process is described with the assumption that the bit depth of the decoded picture does not exceed 12 bits.

cicp_info_present_flag equal to 1 specifies that color_primaries, transfer_characteristics, and matrix coefficients are present. cicp_info_present_flag equal to 0 specifies that color_primaries, transfer_characteristics, and matrix coefficients are not present.

color_primaries is an integer that indicates the color primaries of the decoded video picture associated with the current film grain parameters. The integer value is defined by the corresponding color primaries section of ISO/IEC 23091-4 and/or ITU-T H.273. The syntax element is intended to be informative and is not used in the film grain process defined in this specification. When present, color_primaries should match any color primary information of the decoded video picture that is associated with the current film grain parameters. The behavior of the film grain synthesis process in response to this syntax element not matching the decoded picture associated with the current film grain parameters is outside the scope of this specification.

transfer_characteristics is an integer that indicates the transfer characteristics of the decoded picture associated with the current film grain parameters. The integer value is defined by the corresponding transfer characteristics section of ISO/IEC 23091-4 and/or ITU-T H.273. The syntax element is intended to be informative and is not used in the film grain process defined in this specification. When present, transfer_characteristics should match any transform characteristics information of the decoded video picture that is associated with the current film grain parameters. The behavior of the film grain synthesis process in response to this syntax element not matching the decoded picture associated with the current film grain parameters is outside the scope of this specification.

matrix_coefficients is an integer that indicates the matrix coefficients of the decoded picture associated with the current film grain parameters. The integer value is defined by the corresponding matrix coefficients section of ISO/IEC 23091-4 and/or ITU-T H.273. The syntax element is intended to be informative and is not used in the film grain process defined in this specification. When present, matrix_coefficients should match any matrix coefficient information of the decoded video picture that is associated with the current film grain parameters. The behavior of the film grain synthesis process in response to this syntax element not matching the decoded picture associated with the current film grain parameters is outside the scope of this specification.

video_full_range_flag is a flag that indicates the scaling and offset values applied in association with the matrix coefficients of the decoded picture associated with the current film grain parameters. The value is defined by the corresponding matrix coefficients section of ISO/IEC 23091-4 and/or ITU-T H.273. The syntax element is intended to be informative and is not used in the film grain process defined in this specification. When present, video_full_range_flag should match any video full range information of the decoded video picture that is associated with the current film grain parameters.
The behavior of the film grain synthesis process in response to the syntax element not matching the decoded picture associated with the current film grain parameters is outside the scope of this specification.

predict_scaling_flag equal to 0 specifies that scaling functions in the current film grain parameter set are not predicted from scaling functions that belong to other film grain parameter sets. predict_scaling_flag equal to 1 specifies that scaling functions in the current film grain parameter set may be predicted from scaling functions that belong to other film grain parameter sets in the current av1_film_grain_payload( ) function.

It is a requirement of conformance to this specification that the film grain parameter set at the decoded picture resolution for each decoded picture has the predict_scaling_flag flag equal to zero.

filmGrainParamSetIdxForPrediction is a variable equal to the value of film_grain_param_set_idx that is determined in the first call to av1_film_grain_params( ) within the current aom_itu_t_t35_payload( ).

It is a requirement of conformance to this specification that the value of the film grain parameter set with index filmGrainParamSetIdxForPrediction have been initialized with values of the scaling functions that are in the current coded video sequence before use. It is also a requirement of conformance to this specification that the value of filmGrainParamSetIdxForPrediction is different from the value of film_grain_param_set_idx for the current film grain parameter set before use.

Note: This requirement restricts prediction between the film grain parameter sets to be within one aom_itu_t_t35_payload( ). It also restricts the reference for the prediction process to be the film grain parameter set determined in the first av1_film_grain_params( ) call.

predict_y_scaling_flag equal to 0 specifies that the luma scaling functions in the current film grain parameter set are not predicted from a different film grain parameter set. predict_y_scaling_flag equal to 1 specifies that the luma scaling functions in the current film grain parameter set are predicted from a different film grain parameter set having an index film_grain_param_set_idx equal to filmGrainParamSetIdxForPrediction.

y_scaling_mult specifies the multiplier used for predicting the luma film grain scaling function.

y_scaling_add specifies the additive offset parameter used for predicting the luma film grain scaling function.

numYPointsInRef is a variable equal to the number of points for the piecewise linear scaling function of the luma component in the film grain parameter set referenced by filmGrainParamSetIdxForPrediction.

bits_per_y_scaling_res specifies the number of bits used for encoding point_y_scaling_res[ i ].

point_y_scaling_res[ i ] specifies the prediction difference of the parameters. The parameter is signaled using bits_per_y_scaling_res bits and is in the [ -(1 « (bits_per_y_scaling_res - 1)) , (1 « (bits_per_y_scaling_res - 1)) - 1 ] range.

y_scaling_res_granularity specifies the granularity with which the difference values for the predicted scaling function are encoded.

num_y_points specifies the number of points for the piece-wise linear scaling function of the luma component.

It is a requirement of conformance to this specification that num_y_points is less than or equal to 14.

point_y_value_increment_bits_minus1 plus 1 specifies the number of bits used for encoding point_y_values_increment[ i ].

point_y_scaling_bits_minus5 plus 5 specifies the number of bits used for encoding point_y_scaling[ i ].

point_y_value_increment[ i ] is the increment of PointYValue[ i ] relative to the PointYValue[ i - 1 ].

point_y_scaling[ i ] represents the scaling (output) value for the i-th point of the piecewise linear scaling function for the luma component.

When predict_y_scaling_flag is equal to 1, the luma scaling function values are derived as follows:

The values of PointYValueRef[ i ] and PointYScalingRef[ i ] for all instances of index i are equal to PointYValue[ i ] and PointYScaling[ i ], respectively, in the film grain parameter set with film_grain_param_set_idx equal to filmGrainParamSetIdxForPrediction.

for ( i = 0; i < numYPointsInRef; i++ ) {
    PointYValue[ i ] = PointYValueRef[ i ]
    PointYScaling[ i ] =
        Clip3(0, 255, ( (PointYScalingRef[ i ] * (y_scaling_mult - 256) + 8) >> 4) + y_scaling_add - 256
        + (point_y_scaling_res[ i ] - ( 1 << (bits_per_y_scaling_res - 1)  ) )* y_scaling_res_granularity )
}

Note: y_scaling_mult represents a value of a multiplier from -16 to +15.9375 with a value granularity of 1/16. y_scaling_add represents an integer value of intercept in the range [ -256, 255].

When predict_y_scaling_flag is equal to 0, the luma scaling function values PointYValue[ i ] and PointYScaling[ i ] are obtained as follows:

for ( i = 0; i < num_y_points; i++ ){
    if ( i )
        PointYValue[ i ] = PointYValue[ i - 1 ] + point_y_value_increment[ i ]
    else
        PointYValue[ 0 ] = point_y_value_increment[ 0 ]
    PointYScaling[ i ] = point_y_scaling[ i ]
}

PointYValue[ i ] represents the x (luma value) coordinate for the i-th point of the piecewise linear scaling function for the luma component. The values are signaled in the scale of 0 to 255. In the case of 10-bit video, these values correspond to luma values divided by 4. In the case of 12-bit video, these values correspond to luma values divided by 16.

chroma_scaling_from_luma_flag equal to 1 specifies that the chroma scaling is inferred from the luma scaling. chroma_scaling_from_luma_flag equal to 0 specifies that the chroma scaling is signaled independently.

predict_cb_scaling_flag equal to 0 specifies that the Cb component scaling functions in the current film grain parameter set are not predicted from a different film grain parameter set. predict_cb_scaling_flag equal to 1 specifies that the Cb component scaling functions in the current film grain parameter set are predicted from a film grain parameter set indicated by filmGrainParamSetIdxForPrediction.

If predict_cb_scaling_flag is equal to 1, the variables CbMult, CbLumaMult, and CbOffset are set equal to the syntax elements cb_mult, cb_luma_mult, and cb_offset, respectively, specified in av1_film_grain_params( ) function, in which
film_grain_param_set_idx value is equal to filmGrainParamSetIdxForPrediction value of the current av1_film_grain_params( ) function.

If predict_cb_scaling_flag is equal to 0, the variables CbMult, CbLumaMult, and CbOffset are set equal to the syntax elements cb_mult, cb_luma_mult, and cb_offset, respectively, of the current av1_film_grain_params( ) function.

cb_scaling_mult specifies the multiplier used for predicting the Cb component film grain scaling function.

cb_scaling_add specifies the additive offset parameter used for predicting the Cb component film grain scaling function.

numCbPointsInRef is a variable equal to the value of num_cb_points of the film grain parameter set referred to by filmGrainParamSetIdxForPrediction

bits_per_cb_scaling_res specifies the number of bits used for encoding the parameters point_cb_scaling_res[ i ] for all possible values of i.

point_cb_scaling_res[ i ] specifies the prediction difference of the Cb parameter for the point with index i. The parameter is signaled using bits_per_cb_scaling_res bits and is in the [ -(1 « (bits_per_cb_scaling_res - 1)), (1 « (bits_per_cb_scaling_res - 1)) - 1 ] range.

cb_scaling_res_granularity specifies the granularity with which the difference values for the predicted scaling function for the Cb component are encoded.

num_cb_points specifies the number of points for the piece-wise linear scaling function of the Cb component.

It is a requirement of conformance to this specification that num_cb_points is less than or equal to 10.

Note: When chroma_scaling_from_luma_flag is equal to 1, it is still allowed for num_y_points to take values up to 14. This means that the chroma scaling also needs to support up to 14 points.

point_cb_value_increment_bits_minus1 plus 1 specifies the number of bits used to signal point_cb_values[ i ].

point_cb_scaling_bits_minus5 plus 5 specifies the number of bits used to signal point_cb_scaling[ i ]

cb_scaling_offset specifies the offset applied to obtain point_cb_scaling[ i ] values.

point_cb_value_increment[ i ] specifies the increment of point_cb_value[ i ] relative to the point_cb_value[ i - 1 ].

point_cb_scaling[ i ] represents the scaling (output) value for the i-th point of the piecewise linear scaling function for the Cb component.

When predict_cb_scaling_flag parameters is equal to 1, the Cb scaling function values are obtained as follows:

The values of PointCbValueRef[ i ] and PointCbScalingRef[ i ] for all instances of index i are equal to PointCbValue[ i ] and PointCbScaling[ i ], respectively, in the film grain parameter set with film_grain_param_set_idx equal to filmGrainParamSetIdxForPrediction.

for ( i = 0; i < numCbPointsInRef; i++ ) {
    PointCbValue[ i ] = PointCbValueRef[ i ]
    PointCbScaling[ i ] =
        Clip3(0, 255, ( (PointCbScalingRef[ i ] * (cb_scaling_mult - 256) + 8) >> 4) + cb_scaling_add - 256
        + (point_cb_scaling_res[ i ] - ( 1 << (bits_per_cb_scaling_res-1)  ) ) * cb_scaling_res_granularity)
}

Note: cb_scaling_mult represents a value of a multiplier from -16 to +15.9375 with a value granularity of 1/16. cb_scaling_add represents an integer value of intercept in the range [-256, 255].

When predict_cb_scaling_flag parameters is equal to 0, the Cb scaling function values PointCbValue[ i ] and PointCbScaling[ i ] are derived as follows:

for ( i = 0; i < num_cb_points; i++ ){
    if ( i )
        PointCbValue[ i ] = PointCbValue[ i - 1 ] + point_cb_value_increment[ i ]
    else
        PointCbValue[ 0 ] = point_cb_value_increment[ 0 ]
    PointCbScaling[ i ] = point_cb_scaling[ i ] + cb_scaling_offset
}

PointCbValue[ i ] represents the x coordinate for the i-th point of the piece-wise linear scaling function for the Cb component. The values are signaled on the scale of 0..255.

predict_cr_scaling_flag equal to 0 specifies that the Cr component scaling functions in the current film grain parameter set are not predicted from a different film grain parameter set. predict_cr_scaling_flag equal to 1 specifies that the Cr component scaling functions in the current film grain parameter set are predicted from a film grain parameter set indicated by film_grain_param_set_idx equal to filmGrainParamSetIdxForPrediction.

If predict_cr_scaling_flag is equal to 1, the variables CrMult, CrLumaMult, and CrOffset are set equal to the syntax elements cr_mult, cr_luma_mult, and cr_offset, respectively, specified in av1_film_grain_params( ) function, in which
film_grain_param_set_idx value is equal to filmGrainParamSetIdxForPrediction value of the current av1_film_grain_params( ) function.

If predict_cr_scaling_flag is equal to 0, the variables CrMult, CrLumaMult, and CrOffset are set equal to the syntax elements cr_mult, cr_luma_mult, and cr_offset, respectively, of the current av1_film_grain_params( ) function.

cr_scaling_mult specifies the multiplier used for predicting the Cr component film grain scaling function.

cr_scaling_add specifies the addition parameter used for predicting the Cr component film grain scaling function.

numCrPointsInRef is a variable equal to the value of num_cr_points of the film grain parameter set referred to by filmGrainParamSetIdxForPrediction.

bits_per_cr_scaling_res specifies the number of bits used for encoding point_cr_scaling[ i ].

point_cr_scaling_res[ i ] specifies the prediction difference of the parameters. The parameter is signaled using bits_per_cr_scaling_res bits and is in the [ -(1 « (bits_per_cr_scaling_res - 1)), (1 « (bits_per_cr_scaling_res - 1)) - 1 ] range.

cr_scaling_res_granularity specifies the granularity with which the difference values for the predicted scaling function are encoded.

It is a requirement of conformance to this specification that when filmGrainParamSetIdxForPrediction is present, it shall be equal to the value of film_grain_param_set_idx that is determined in the first call to av1_film_grain_params( ) within the current aom_itu_t_t35_payload( ).

Note: This requirement restricts prediction between the film grain parameter sets to be within one aom_itu_t_t35_payload( ). It also restricts the reference for the prediction process to be the film grain parameter set determined in the first av1_film_grain_params( ) call.

num_cr_points specifies the number of points for the piece-wise linear scaling function of the Cr component.

It is a requirement of conformance to this specification that num_cr_points is less than or equal to 10.

If SubX is equal to 1 and SubY is equal to 1 and num_cb_points is equal to 0, it is a requirement of conformance to this specification that num_cr_points is equal to 0.

If SubX is equal to 1 and SubY is equal to 1 and num_cb_points is not equal to 0, it is a requirement of conformance to this specification that num_cr_points is not equal to 0.

Note: These requirements ensure that for 4:2:0 chroma subsampling, film grain noise will be applied to both chroma components, or to neither. There is no restriction for 4:2:2 or 4:4:4 chroma subsampling.

point_cr_value_increment_bits_minus1 plus 1 specifies the number of bits used to signal point_cr_value_increment[ i ].

point_cr_scaling_bits_minus5 plus 5 specifies the number of bits used to signal point_cr_scaling[ i ].

cr_scaling_offset specifies the offset applied to obtain point_cr_scaling[ i ] values.

point_cr_value_increment[ i ] specifies the increment of point_cr_value[ i ] relative to the point_cr_value[ i - 1 ].

point_cr_scaling[ i ] represents the scaling (output) value for the i-th point of the piecewise linear scaling function for the Cr component.

When predict_cr_scaling_flag parameters is equal to 1, the Cr scaling function values are derived as follows:

The values of PointCrValueRef[ i ] and PointCrScalingRef[ i ] for all instances of index i are equal to PointCrValue[ i ] and PointCrScaling[ i ], respectively, in the film grain parameter set with film_grain_param_set_idx equal to filmGrainParamSetIdxForPrediction.

for ( i = 0; i < numCrPointsInRef; i++ ) {
    PointCrValue[ i ] = PointCrValueRef[ i ]
    PointCrScaling[ i ] =
        Clip3(0, 255, ( (PointCrScalingRef[ i ] * (cr_scaling_mult - 256) + 8) >> 4) + cr_scaling_add - 256
        + (point_cr_scaling_res[ i ] - ( 1 << (bits_per_cr_scaling_res-1)  )) * cr_scaling_res_granularity)
}

Note: cr_scaling_mult represents a value of a multiplier from -16 to +15.9375 with a value granularity of 1/16. cr_scaling_add represents an integer value of intercept in the range between [ - 256, 255].

When predict_cr_scaling_flag parameters is equal to 0, the Cr scaling function values PointCrValue[ i ] and PointCrScaling[ i ] are obtained as follows:

for ( i = 0; i < num_cr_points; i++ ) {
    if ( i )
        PointCrValue[ i ] = PointCrValue[ i - 1 ] + point_cr_value_increment[ i ]
    else
        PointCrValue[ 0 ] = point_cr_value_increment[ 0 ]
    PointCrScaling[ i ] = point_cr_scaling[ i ] + cr_scaling_offset
}

PointCrValue[ i ] represents the x coordinate for the i-th point of the piece-wise linear scaling function for the Cr component. The values are signaled in the range of 0 to 255.

grain_scaling_minus8 plus 8 specifies the shift applied to the values of the chroma component. The grain_scaling_minus8 can take values of 0 to 3 and determines the range and quantization step of the standard deviation of film grain.

ar_coeff_lag specifies the number of auto-regressive coefficients for luma and chroma.

bits_per_ar_coeff_y_minus5 plus 5 specifies the number of bits used to signal ar_coeffs_y[ i ].

ar_coeffs_y[ i ] specifies the auto-regressive coefficients used for the luma component.

The values of auto-regressive coefficients plus 128 for the luma component ArCoeffsYPlus128[ i ] are derived as follows

for ( i = 0; i < numPosLuma; i++ )
    ArCoeffsYPlus128[ i ] = ar_coeffs_y[ i ] - (1<<(BitsArY - 1)).

bits_per_ar_coeff_cb_minus5 plus 5 specifies the number of bits used to signal ar_coeffs_cb[ i ].

ar_coeffs_cb[ i ] specifies the auto-regressive coefficients used for the Cb plane.

The values of the auto-regressive coefficients plus 128 for the Cb component ArCoeffsCbPlus128[ i ] are derived as follows:

for ( i = 0; i < numPosChroma; i++ )
    ArCoeffsCbPlus128[ i ] = ar_coeffs_cb[ i ] - (1<<(BitsArCb - 1)).

bits_per_ar_coeff_cr_minus5 plus 5 specifies the number of bits used to signal ar_coeffs_cr[ i ].

ar_coeffs_cr[ i ] specifies the auto-regressive coefficients used for the Cr plane.

The values of the auto-regressive coefficients plus 128 for the Cr component ArCoeffsCrPlus128[ i ] are derived as follows:

for ( i = 0; i < numPosChroma; i++ )
        ArCoeffsCrPlus128[ i ] = ar_coeffs_cr[ i ] - (1<<(BitsArCr - 1)).

ar_coeff_shift_minus6 specifies the range of the auto-regressive coefficients. Values of 0, 1, 2, and 3 correspond to the ranges for auto-regressive coefficients of [-2, 2), [-1, 1), [-0.5, 0.5) and [-0.25, 0.25), respectively.

grain_scale_shift specifies how much the Gaussian random numbers should be scaled down during the grain synthesis process.

cb_mult specifies the multiplier for the Cb component used in the derivation of the input index to the Cb component scaling function.

cb_luma_mult specifies the multiplier for the average luma component used in the derivation of the input index to the Cb component scaling function.

cb_offset specifies the offset used in the derivation of the input index to the Cb component scaling function.

cr_mult specifies the multiplier for the Cr component used in the derivation of the input index to the Cr component scaling function.

cr_luma_mult specifies the multiplier for the average luma component used in the derivation of the input index to the Cr component scaling function.

cr_offset specifies the offset used in the derivation of the input index to the Cr component scaling function.

overlap_flag equal to 1 specifies that the overlap between film grain blocks shall be applied. overlap_flag equal to 0 specifies that the overlap between film grain blocks shall not be applied.

clip_to_restricted_range_flag equal to 1 specifies that clipping to the restricted range is applied to the sample values after adding the film grain. clip_to_restricted_range_flag equal to 0 specifies that clipping to the full range shall be applied to the sample values after adding the film grain.

Padding bits semantics

padding_zero_bit shall be equal to 0.

Conformance requirements

When AFGS1 metadata are not present in the bitstream, the AFGS1 film grain synthesis module shall produce output pictures that are identical in all respects and have the same output order as the input pictures to the AFGS1 film grain synthesis module.

When AFGS1 metadata is present in the bitstream, a film grain synthesis module conforming to this specification shall implement a film grain synthesis process that modifies its input arrays OutY, OutU, OutV. The reference film grain synthesis process is described in section 8.2.

When AFGS1 metadata is present in the bitstream, a conformant AFGS1 film grain synthesis module shall satisfy at least one of the following two options:

  1. A conformant AFGS1 film grain synthesis module shall produce output pictures that are identical in all respects and have the same output order as those produced by the AFGS1 film grain synthesis process specified herein including applying the exact film grain synthesis process as specified in section 8.2.

  2. A conformant AFGS1 film grain synthesis module shall produce output pictures that are in the same order and do not have perceptually significant differences with the pictures produced by the reference film grain synthesis process specified in section 8.2 when applied to the input pictures of the film grain synthesis process with the film grain parameters signaled for these pictures. The definition of “perceptually significant differences” is beyond the scope of this specification and may be specified, for example, by a service provider as part of their accreditation program. The film grain synthesis process applied by a conformant AFGS1 film grain synthesis module should be feature complete with regards to the reference film grain synthesis process of section 8.2 including scaling strength of the film grain as a function of intensity according to the signaled parameters, same maximum AR lag, and similar modeling of correlation between luma and chroma and smoothing of transitions between blocks of grain when applicable.

Note: To ensure conformance, film grain module manufacturers are advised to implement the film grain synthesis process as specified in section 8.2. One reason to choose the second conformance option is implementation of optional processing steps before input or after the output of the film grain synthesis process, in which case there could be minor differences in the output with the reference film grain synthesis process of section 8.2. Examples of these optional processing steps are algorithms improving output picture quality, such as de-banding filtering and coding artefacts removal.

Note: Some applications, such as transcoding from or to another video coding standard, may use intermediate output pictures for transcoding. In such cases, the film grain synthesis information may be adapted and inserted in the transcoded bitstream.

Decoding process

General

The input to this process is a sequence of the reconstructed pictures and a sequence of associated AFGS1 film grain metadata messages. AFGS1 film grain metadata messages may be contained in an elementary bitstream or in a transport bitstream.

The output from this process is a sequence of updated pictures.

AFGS1 film grain metadata messages are processed in the order they are included in the elementary bitstream, which is typically a picture decoding order.

For each AFGS1 film grain metadata message, in turn the syntax elements are extracted as specified in section 5.

The syntax tables include function calls indicating when the corresponding decode processes are triggered.

A film grain parameter set associated with the av1_film_grain_params( ) function is selected and is associated with the output picture.

If afgs1_enable_flag is equal to 1 and apply_grain_flag is present and equal to 1, then the film grain synthesis process specified in section 8.2 is invoked with inputs of w, h, SubX, and SubY.

Note: The apply_grain_flag is from the selected film grain parameter set av1_film_grain_params( ).

This process modifies arrays OutY, OutU, and OutV that contain the output picture samples of the video decoder or

intermediate values of pictures from the previous post-processing modules.

Finally, the picture to be processed is defined to be the arrays OutY, OutU, and OutV where the bit depth for each sample is BitDepth.

This picture is the overall output and further processing (such as color conversion) is outside the scope of this specification.

For example, a real implementation might use these arrays to display the picture to the user, or a test system might save the arrays so the output can be verified.

Note: If NumPlanes is equal to 1, then the U and V planes should be ignored.

Film grain synthesis process

General

The inputs to this process are:

  • variables w and h specifying the width and height of the picture,

  • variables SubX and SubY specifying the subsampling parameters of the picture,

  • arrays OutY, OutU, and OutV,

  • variable BitDepth specifying the bit depth of the picture samples.

The process modifies the arrays OutY, OutU, and OutV to add film grain noise as follows:

  1. The variable RandomRegister (used for generating pseudo-random numbers) is set equal to grain_seed.

  2. The variable GrainCenter is set equal to 128 << (BitDepth - 8).

  3. The variable GrainMin is set equal to = -GrainCenter.

  4. The variable GrainMax is set equal to (256 << (BitDepth - 8)) - 1 - GrainCenter.

  5. The generate grain process specified in section 8.2.3 is invoked.

  6. The scaling lookup initialization process specified in section 8.2.4 is invoked.

  7. The add noise process specified in section 8.2.5 is invoked with w, h, SubX, and SubY as inputs.

Random number process

The input to this process is a variable bits specifying the number of random bits to return.

The output of this process is a pseudo-random number based on the state in RandomRegister.

The process is specified as follows:

get_random_number( bits ) {
  r = RandomRegister
  bit = ((r >> 0) ^ (r >> 1) ^ (r >> 3) ^ (r >> 12)) & 1
  r = (r >> 1) | (bit << 15)
  result = (r >> (16 - bits)) & ((1 << bits) - 1)
  RandomRegister = r
  return result
}

The output of this process is the variable result.

Generate grain process

This process generates noise via an auto-regressive filter.

First, an array LumaGrain, which is 82 samples wide and 73 samples high, of white noise is generated for luma as follows:

shift = 12 - BitDepth + grain_scale_shift
for ( y = 0; y < 73; y++ ) {
  for ( x = 0; x < 82; x++ ) {
    if ( num_y_points > 0 ) {
      g = Gaussian_Sequence[ get_random_number( 11 ) ]
    } else {
      g = 0
    }
    LumaGrain[ y ][ x ] = Round2( g, shift )
  }
}

where the function call get_random_number() invokes the random number process specified in section 8.2.2.

Then an auto-regressive filter is applied to the white noise as follows:

shift = ar_coeff_shift_minus6 + 6
for ( y = 3; y < 73; y++ ) {
  for ( x = 3; x < 82 - 3; x++ ) {
    s = 0
    pos = 0
    for ( deltaRow = -ar_coeff_lag; deltaRow <= 0; deltaRow++ ) {
      for ( deltaCol = -ar_coeff_lag; deltaCol <= ar_coeff_lag; deltaCol++ ) {
        if ( deltaRow == 0 && deltaCol == 0 )
          break
        c = ArCoeffsYPlus128[ pos ] - 128
        s += LumaGrain[ y + deltaRow ][ x + deltaCol ] * c
        pos++
      }
    }
    LumaGrain[ y ][ x ] = Clip3( GrainMin, GrainMax, LumaGrain[ y ][ x ] + Round2( s, shift ) )
  }
}

If luma_only_flag is equal to 0, the chroma grain is generated in a similar way, except the filtering includes a coefficient that introduces a correlation with the luma grain.

The variable chromaW (representing the width of the chroma noise array) is set equal to (SubX ? 44 : 82).

The variable chromaH (representing the height of the chroma noise array) is set equal to (SubY ? 38 : 73).

White noise arrays CbGrain and CrGrain, which are chromaW samples wide and chromaH samples high, are generated as follows:

shift = 12 - BitDepth + grain_scale_shift
RandomRegister = grain_seed ^ 0xb524
for ( y = 0; y < chromaH; y++ ) {
  for ( x = 0; x < chromaW; x++ ) {
    if ( num_cb_points > 0 || chroma_scaling_from_luma_flag) {
      g = Gaussian_Sequence[ get_random_number( 11 ) ]
    } else {
      g = 0
    }
    CbGrain[ y ][ x ] = Round2( g, shift )
  }
}
RandomRegister = grain_seed ^ 0x49d8
for ( y = 0; y < chromaH; y++ ) {
  for ( x = 0; x < chromaW; x++ ) {
    if ( num_cr_points > 0 || chroma_scaling_from_luma_flag) {
      g = Gaussian_Sequence[ get_random_number( 11 ) ]
    } else {
      g = 0
    }
    CrGrain[ y ][ x ] = Round2( g, shift )
  }
}

Then the auto-regressive filter is applied as follows:

shift = ar_coeff_shift_minus6 + 6
for ( y = 3; y < chromaH; y++ ) {
  for ( x = 3; x < chromaW - 3; x++ ) {
    s0 = 0
    s1 = 0
    pos = 0
    for ( deltaRow = -ar_coeff_lag; deltaRow <= 0; deltaRow++ ) {
      for ( deltaCol = -ar_coeff_lag; deltaCol <= ar_coeff_lag; deltaCol++ ) {
        c0 = ArCoeffsCbPlus128[ pos ] - 128
        c1 = ArCoeffsCrPlus128[ pos ] - 128
        if ( deltaRow == 0 && deltaCol == 0 ) {
          if ( num_y_points > 0 ) {
            luma = 0
            lumaX = ( (x - 3) << SubX ) + 3
            lumaY = ( (y - 3) << SubY ) + 3
            for ( i = 0; i <= SubY; i++ )
              for ( j = 0; j <= SubX; j++ )
                luma += LumaGrain[ lumaY + i ][ lumaX + j ]
            luma = Round2( luma, SubX + SubY )
            s0 += luma * c0
            s1 += luma * c1
          }
          break
        }
        s0 += CbGrain[ y + deltaRow ][ x + deltaCol ] * c0
        s1 += CrGrain[ y + deltaRow ][ x + deltaCol ] * c1
        pos++
      }
    }
    CbGrain[ y ][ x ] = Clip3( GrainMin, GrainMax, CbGrain[ y ][ x ] + Round2( s0, shift ) )
    CrGrain[ y ][ x ] = Clip3( GrainMin, GrainMax, CrGrain[ y ][ x ] + Round2( s1, shift ) )
  }
}

Note: When num_y_points is equal to 0, this process may use uninitialized values within ArCoeffsYPlus128 to compute LumaGrain. However, LumaGrain will never be read in this case so it does not matter what values are constructed. Similarly, when num_cr_points/num_cb_points are equal to 0 and chroma_scaling_from_luma_flag is equal to 0, the CbGrain/CrGrain arrays will never be read.

Scaling lookup initialization process

This process computes a lookup table for each available color component.

Each lookup table ScalingLut[ plane ] contains 256 entries constructed by a piecewise linear interpolation of the given points as follows:

for ( plane = 0; plane < NumPlanes; plane++ ) {
    if ( plane == 0 || chroma_scaling_from_luma_flag )
        numPoints = num_y_points
    else if ( plane == 1 )
        numPoints = num_cb_points
    else
        numPoints = num_cr_points
    if ( numPoints == 0 ) {
        for ( x = 0; x < 256; x++ ) {
            ScalingLut[ plane ][ x ] = 0
        }
    } else {
        for ( x = 0; x < get_x( plane, 0 ); x++ ) {
            ScalingLut[ plane ][ x ] = get_y( plane, 0 )
        }
        for ( i = 0; i < numPoints - 1; i++ ) {
            deltaY = get_y( plane, i + 1 ) - get_y( plane, i )
            deltaX = get_x( plane, i + 1 ) - get_x( plane, i )
            delta = deltaY * ( ( 65536 + (deltaX >> 1) ) / deltaX )
            for ( x = 0; x < deltaX; x++ ) {
                v = get_y( plane, i ) + ( ( x * delta + 32768 ) >> 16 )
                ScalingLut[ plane ][ get_x( plane, i )  + x ] = v
            }
        }
        for ( x = get_x( plane, numPoints - 1 ); x < 256; x++ ) {
            ScalingLut[ plane ][ x ] = get_y( plane, numPoints - 1 )
        }
    }
}

where the functions get_x() and get_y() return the coordinates for a specific point and are specified as:

get_x( plane, i ) {
    if ( plane == 0 || chroma_scaling_from_luma_flag )
        return PointYValue[ i ]
    else if ( plane == 1 )
        return PointCbValue[ i ]
    else
        return PointCrValue[ i ]
}

get_y( plane, i ) {
    if ( plane == 0 || chroma_scaling_from_luma_flag )
        return PointYScaling[ i ]
    else if ( plane == 1 )
        return PointCbScaling[ i ]
    else
        return PointCrScaling[ i ]
}

Add noise synthesis process

The inputs to this process are:

  • variables w and h specifying the width and height of the picture,

  • variables SubX and SubY specifying the subsampling parameters of the picture.

This process combines the film grain with the image data.

First an array of noise data noiseStripe is generated for each 32 luma sample high stripe of the image.

noiseStripe[ lumaNum ][ 0 ] is 34 samples high and w samples wide (a few additional samples across are actually written to the array, but these are never read) and contains noise for the luma component.

noiseStripe[ lumaNum ][ 1 ] and noiseStripe[ lumaNum ][ 2 ] are (34 >> SubY) samples high and Round2(w, SubX) samples wide and contain noise for the chroma components.

noiseStripe represents the result of constructing square grain blocks and blending horizontally adjacent blocks together (although blending is only applied if overlap_flag is equal to 1) and is constructed as follows:

lumaNum = 0
for ( y = 0; y < (h + 1)/2 ; y += 16 ) {
  RandomRegister = grain_seed
  RandomRegister ^= ((lumaNum * 37 + 178) & 255) << 8
  RandomRegister ^= ((lumaNum * 173 + 105) & 255)
  for ( x = 0; x < (w + 1)/2 ; x += 16 ) {
    rand = get_random_number( 8 )
    offsetX = rand >> 4
    offsetY = rand & 15
    for ( plane = 0 ; plane < NumPlanes; plane++ ) {
      planeSubX = ( plane > 0) ? SubX : 0
      planeSubY = ( plane > 0) ? SubY : 0
      planeOffsetX = planeSubX ? 6 + offsetX : 9 + offsetX * 2
      planeOffsetY = planeSubY ? 6 + offsetY : 9 + offsetY * 2
      for ( i = 0; i < 34 >> planeSubY ; i++ ) {
        for ( j = 0; j < 34 >> planeSubX ; j++ ) {
          if ( plane == 0 )
            g = LumaGrain[ planeOffsetY + i ][ planeOffsetX + j ]
          else if ( plane == 1 )
            g = CbGrain[ planeOffsetY + i ][ planeOffsetX + j ]
          else
            g = CrGrain[ planeOffsetY + i ][ planeOffsetX + j ]
          if ( planeSubX == 0 ) {
            if ( j < 2 && overlap_flag && x > 0 ) {
              old = noiseStripe[ lumaNum ][ plane ][ i ][ x * 2 + j ]
              if ( j == 0 ) {
                g = old * 27 + g * 17
              } else {
                g = old * 17 + g * 27
              }
              g = Clip3( GrainMin, GrainMax, Round2(g, 5) )
            }
            noiseStripe[ lumaNum ][ plane ][ i ][ x * 2 + j ] = g
          } else {
            if ( j == 0 && overlap_flag && x > 0 ) {
              old = noiseStripe[ lumaNum ][ plane ][ i ][ x + j ]
              g = old * 23 + g * 22
              g = Clip3( GrainMin, GrainMax, Round2(g, 5) )
            }
            noiseStripe[ lumaNum ][ plane ][ i ][ x + j ] = g
          }
        }
      }
    }
  }
  lumaNum++
}

Then the noise stripes are blended together to form a noise image noiseImage as follows:

for ( plane = 0; plane < NumPlanes; plane++ ) {
  planeSubX = ( plane > 0) ? SubX : 0
  planeSubY = ( plane > 0) ? SubY : 0
  for ( y = 0; y < ( (h + planeSubY) >> planeSubY ) ; y++ ) {
    lumaNum = y >> ( 5 - planeSubY )
    i = y - (lumaNum << ( 5 - planeSubY ) )
    for ( x = 0; x < ( (w + planeSubX) >> planeSubX) ; x++ ) {
      g = noiseStripe[ lumaNum ][ plane ][ i ][ x ]
      if ( planeSubY == 0 ) {
        if ( i < 2 && lumaNum > 0 && overlap_flag ) {
          old = noiseStripe[ lumaNum - 1 ][ plane ][ i + 32 ][ x ]
          if ( i == 0 ) {
            g = old * 27 + g * 17
          } else {
            g = old * 17 + g * 27
          }
          g = Clip3( GrainMin, GrainMax, Round2(g, 5) )
        }
      } else {
        if ( i < 1 && lumaNum > 0 && overlap_flag ) {
          old = noiseStripe[ lumaNum - 1 ][ plane ][ i + 16 ][ x ]
          g = old * 23 + g * 22
          g = Clip3( GrainMin, GrainMax, Round2(g, 5) )
        }
      }
      noiseImage[ plane ][ y ][ x ] = g
    }
  }
}

Note: Although this process is specified in terms of full size noiseStripe and noiseImage arrays, the reference code shows how it is possible to implement the grain synthesis with just 2 line buffers for luma, and 1 line buffer for each chroma component.

Finally, the noise is blended with the original image data as follows:

if ( clip_to_restricted_range_flag ) {
  minValue = 16 << (BitDepth - 8)
  maxLuma = 235 << (BitDepth - 8)
  if ( matrix_coefficients == MC_IDENTITY )
    maxChroma = maxLuma
  else
    maxChroma = 240 << (BitDepth - 8)
} else {
  minValue = 0
  maxLuma = (256 << (BitDepth - 8)) - 1
  maxChroma = maxLuma
}
ScalingShift = grain_scaling_minus8 + 8
for ( y = 0; y < ( (h + SubY) >> SubY) ; y++ ) {
  for ( x = 0; x < ( (w + SubX) >> SubX) ; x++ ) {
    lumaX = x << SubX
    lumaY = y << SubY
    lumaNextX = Min( lumaX + 1, w - 1 )
    if ( SubX )
      averageLuma = Round2( OutY[ lumaY ][ lumaX ] + OutY[ lumaY ][ lumaNextX ], 1 )
    else
      averageLuma = OutY[ lumaY ][ lumaX ]
    if ( num_cb_points > 0 || chroma_scaling_from_luma_flag ) {
      orig = OutU[ y ][ x ]
      if ( chroma_scaling_from_luma_flag ) {
        merged = averageLuma
      } else {
        combined = averageLuma * ( CbLumaMult - 128 ) + orig * ( CbMult - 128 )
        merged = Clip1( ( combined >> 6 ) + ( (CbOffset - 256 ) << (BitDepth - 8) ) )
      }
      noise = noiseImage[ 1 ][ y ][ x ]
      noise = Round2( scale_lut( 1, merged ) * noise, ScalingShift )
      OutU[ y ][ x ] = Clip3( minValue, maxChroma, orig + noise )
    }

    if ( num_cr_points > 0 || chroma_scaling_from_luma_flag) {
      orig = OutV[ y ][ x ]
      if ( chroma_scaling_from_luma_flag ) {
        merged = averageLuma
      } else {
        combined = averageLuma * ( CrLumaMult - 128 ) + orig * ( CrMult - 128 )
        merged = Clip1( ( combined >> 6 ) + ( (CrOffset - 256 ) << (BitDepth - 8) ) )
      }
      noise = noiseImage[ 2 ][ y ][ x ]
      noise = Round2( scale_lut( 2, merged ) * noise, ScalingShift )
      OutV[ y ][ x ] = Clip3( minValue, maxChroma, orig + noise )
    }
  }
}
for ( y = 0; y < h ; y++ ) {
  for ( x = 0; x < w ; x++ ) {
    orig = OutY[ y ][ x ]
    noise = noiseImage[ 0 ][ y ][ x ]
    noise = Round2( scale_lut( 0, orig ) * noise, ScalingShift )
    if ( num_y_points > 0 ) {
      OutY[ y ][ x ] = Clip3( minValue, maxLuma, orig + noise )
    }
  }
}

where scale_lut is a function that performs a piecewise linear interpolation into the appropriate scaling table. The scale_lut function is specified as follows:

scale_lut( plane, index ) {
  shift = BitDepth - 8
  x = index >> shift
  rem = index - ( x << shift )
  if ( BitDepth == 8 || x == 255) {
    return ScalingLut[ plane ][ x ]
  } else {
    start = ScalingLut[ plane ][ x ]
    end = ScalingLut[ plane ][ x + 1 ]
    return start + Round2( (end - start) * rem, shift )
  }
}

Parsing process

Parsing process for f(n)

This process is invoked when the descriptor of a syntax element in the syntax tables is equal to f(n).

The next n bits are read from the bit stream.

This process is specified as follows:

x = 0
for ( i = 0; i < n; i++ ) {
    x = 2 * x + read_bit( )
}

read_bit( ) reads the next bit from the bitstream and advances the bitstream position indicator by 1. If the bitstream is provided as a series of bytes, then the first bit is given by the most significant bit of the first byte.

The value for the syntax element is given by x.

Additional tables

This section contains tables that do not naturally fit in the main sections of the Specification.

The array Gaussian_Sequence contains random samples from a Gaussian distribution with zero mean and standard deviation of about 512 clipped to the range of [-2048, 2047] and rounded to the nearest multiple of 4.

Gaussian_Sequence[ 2048 ] = {
    56,    568,   -180,  172,   124,   -84,   172,   -64,   -900,  24,   820,
  224,   1248,  996,   272,   -8,    -916,  -388,  -732,  -104,  -188, 800,
  112,   -652,  -320,  -376,  140,   -252,  492,   -168,  44,    -788, 588,
  -584,  500,   -228,  12,    680,   272,   -476,  972,   -100,  652,  368,
  432,   -196,  -720,  -192,  1000,  -332,  652,   -136,  -552,  -604, -4,
  192,   -220,  -136,  1000,  -52,   372,   -96,   -624,  124,   -24,  396,
  540,   -12,   -104,  640,   464,   244,   -208,  -84,   368,   -528, -740,
  248,   -968,  -848,  608,   376,   -60,   -292,  -40,   -156,  252,  -292,
  248,   224,   -280,  400,   -244,  244,   -60,   76,    -80,   212,  532,
  340,   128,   -36,   824,   -352,  -60,   -264,  -96,   -612,  416,  -704,
  220,   -204,  640,   -160,  1220,  -408,  900,   336,   20,    -336, -96,
  -792,  304,   48,    -28,   -1232, -1172, -448,  104,   -292,  -520, 244,
  60,    -948,  0,     -708,  268,   108,   356,   -548,  488,   -344, -136,
  488,   -196,  -224,  656,   -236,  -1128, 60,    4,     140,   276,  -676,
  -376,  168,   -108,  464,   8,     564,   64,    240,   308,   -300, -400,
  -456,  -136,  56,    120,   -408,  -116,  436,   504,   -232,  328,  844,
  -164,  -84,   784,   -168,  232,   -224,  348,   -376,  128,   568,  96,
  -1244, -288,  276,   848,   832,   -360,  656,   464,   -384,  -332, -356,
  728,   -388,  160,   -192,  468,   296,   224,   140,   -776,  -100, 280,
  4,     196,   44,    -36,   -648,  932,   16,    1428,  28,    528,  808,
  772,   20,    268,   88,    -332,  -284,  124,   -384,  -448,  208,  -228,
  -1044, -328,  660,   380,   -148,  -300,  588,   240,   540,   28,   136,
  -88,   -436,  256,   296,   -1000, 1400,  0,     -48,   1056,  -136, 264,
  -528,  -1108, 632,   -484,  -592,  -344,  796,   124,   -668,  -768, 388,
  1296,  -232,  -188,  -200,  -288,  -4,    308,   100,   -168,  256,  -500,
  204,   -508,  648,   -136,  372,   -272,  -120,  -1004, -552,  -548, -384,
  548,   -296,  428,   -108,  -8,    -912,  -324,  -224,  -88,   -112, -220,
  -100,  996,   -796,  548,   360,   -216,  180,   428,   -200,  -212, 148,
  96,    148,   284,   216,   -412,  -320,  120,   -300,  -384,  -604, -572,
  -332,  -8,    -180,  -176,  696,   116,   -88,   628,   76,    44,   -516,
  240,   -208,  -40,   100,   -592,  344,   -308,  -452,  -228,  20,   916,
  -1752, -136,  -340,  -804,  140,   40,    512,   340,   248,   184,  -492,
  896,   -156,  932,   -628,  328,   -688,  -448,  -616,  -752,  -100, 560,
  -1020, 180,   -800,  -64,   76,    576,   1068,  396,   660,   552,  -108,
  -28,   320,   -628,  312,   -92,   -92,   -472,  268,   16,    560,  516,
  -672,  -52,   492,   -100,  260,   384,   284,   292,   304,   -148, 88,
  -152,  1012,  1064,  -228,  164,   -376,  -684,  592,   -392,  156,  196,
  -524,  -64,   -884,  160,   -176,  636,   648,   404,   -396,  -436, 864,
  424,   -728,  988,   -604,  904,   -592,  296,   -224,  536,   -176, -920,
  436,   -48,   1176,  -884,  416,   -776,  -824,  -884,  524,   -548, -564,
  -68,   -164,  -96,   692,   364,   -692,  -1012, -68,   260,   -480, 876,
  -1116, 452,   -332,  -352,  892,   -1088, 1220,  -676,  12,    -292, 244,
  496,   372,   -32,   280,   200,   112,   -440,  -96,   24,    -644, -184,
  56,    -432,  224,   -980,  272,   -260,  144,   -436,  420,   356,  364,
  -528,  76,    172,   -744,  -368,  404,   -752,  -416,  684,   -688, 72,
  540,   416,   92,    444,   480,   -72,   -1416, 164,   -1172, -68,  24,
  424,   264,   1040,  128,   -912,  -524,  -356,  64,    876,   -12,  4,
  -88,   532,   272,   -524,  320,   276,   -508,  940,   24,    -400, -120,
  756,   60,    236,   -412,  100,   376,   -484,  400,   -100,  -740, -108,
  -260,  328,   -268,  224,   -200,  -416,  184,   -604,  -564,  -20,  296,
  60,    892,   -888,  60,    164,   68,    -760,  216,   -296,  904,  -336,
  -28,   404,   -356,  -568,  -208,  -1480, -512,  296,   328,   -360, -164,
  -1560, -776,  1156,  -428,  164,   -504,  -112,  120,   -216,  -148, -264,
  308,   32,    64,    -72,   72,    116,   176,   -64,   -272,  460,  -536,
  -784,  -280,  348,   108,   -752,  -132,  524,   -540,  -776,  116,  -296,
  -1196, -288,  -560,  1040,  -472,  116,   -848,  -1116, 116,   636,  696,
  284,   -176,  1016,  204,   -864,  -648,  -248,  356,   972,   -584, -204,
  264,   880,   528,   -24,   -184,  116,   448,   -144,  828,   524,  212,
  -212,  52,    12,    200,   268,   -488,  -404,  -880,  824,   -672, -40,
  908,   -248,  500,   716,   -576,  492,   -576,  16,    720,   -108, 384,
  124,   344,   280,   576,   -500,  252,   104,   -308,  196,   -188, -8,
  1268,  296,   1032,  -1196, 436,   316,   372,   -432,  -200,  -660, 704,
  -224,  596,   -132,  268,   32,    -452,  884,   104,   -1008, 424,  -1348,
  -280,  4,     -1168, 368,   476,   696,   300,   -8,    24,    180,  -592,
  -196,  388,   304,   500,   724,   -160,  244,   -84,   272,   -256, -420,
  320,   208,   -144,  -156,  156,   364,   452,   28,    540,   316,  220,
  -644,  -248,  464,   72,    360,   32,    -388,  496,   -680,  -48,  208,
  -116,  -408,  60,    -604,  -392,  548,   -840,  784,   -460,  656,  -544,
  -388,  -264,  908,   -800,  -628,  -612,  -568,  572,   -220,  164,  288,
  -16,   -308,  308,   -112,  -636,  -760,  280,   -668,  432,   364,  240,
  -196,  604,   340,   384,   196,   592,   -44,   -500,  432,   -580, -132,
  636,   -76,   392,   4,     -412,  540,   508,   328,   -356,  -36,  16,
  -220,  -64,   -248,  -60,   24,    -192,  368,   1040,  92,    -24,  -1044,
  -32,   40,    104,   148,   192,   -136,  -520,  56,    -816,  -224, 732,
  392,   356,   212,   -80,   -424,  -1008, -324,  588,   -1496, 576,  460,
  -816,  -848,  56,    -580,  -92,   -1372, -112,  -496,  200,   364,  52,
  -140,  48,    -48,   -60,   84,    72,    40,    132,   -356,  -268, -104,
  -284,  -404,  732,   -520,  164,   -304,  -540,  120,   328,   -76,  -460,
  756,   388,   588,   236,   -436,  -72,   -176,  -404,  -316,  -148, 716,
  -604,  404,   -72,   -88,   -888,  -68,   944,   88,    -220,  -344, 960,
  472,   460,   -232,  704,   120,   832,   -228,  692,   -508,  132,  -476,
  844,   -748,  -364,  -44,   1116,  -1104, -1056, 76,    428,   552,  -692,
  60,    356,   96,    -384,  -188,  -612,  -576,  736,   508,   892,  352,
  -1132, 504,   -24,   -352,  324,   332,   -600,  -312,  292,   508,  -144,
  -8,    484,   48,    284,   -260,  -240,  256,   -100,  -292,  -204, -44,
  472,   -204,  908,   -188,  -1000, -256,  92,    1164,  -392,  564,  356,
  652,   -28,   -884,  256,   484,   -192,  760,   -176,  376,   -524, -452,
  -436,  860,   -736,  212,   124,   504,   -476,  468,   76,    -472, 552,
  -692,  -944,  -620,  740,   -240,  400,   132,   20,    192,   -196, 264,
  -668,  -1012, -60,   296,   -316,  -828,  76,    -156,  284,   -768, -448,
  -832,  148,   248,   652,   616,   1236,  288,   -328,  -400,  -124, 588,
  220,   520,   -696,  1032,  768,   -740,  -92,   -272,  296,   448,  -464,
  412,   -200,  392,   440,   -200,  264,   -152,  -260,  320,   1032, 216,
  320,   -8,    -64,   156,   -1016, 1084,  1172,  536,   484,   -432, 132,
  372,   -52,   -256,  84,    116,   -352,  48,    116,   304,   -384, 412,
  924,   -300,  528,   628,   180,   648,   44,    -980,  -220,  1320, 48,
  332,   748,   524,   -268,  -720,  540,   -276,  564,   -344,  -208, -196,
  436,   896,   88,    -392,  132,   80,    -964,  -288,  568,   56,   -48,
  -456,  888,   8,     552,   -156,  -292,  948,   288,   128,   -716, -292,
  1192,  -152,  876,   352,   -600,  -260,  -812,  -468,  -28,   -120, -32,
  -44,   1284,  496,   192,   464,   312,   -76,   -516,  -380,  -456, -1012,
  -48,   308,   -156,  36,    492,   -156,  -808,  188,   1652,  68,   -120,
  -116,  316,   160,   -140,  352,   808,   -416,  592,   316,   -480, 56,
  528,   -204,  -568,  372,   -232,  752,   -344,  744,   -4,    324,  -416,
  -600,  768,   268,   -248,  -88,   -132,  -420,  -432,  80,    -288, 404,
  -316,  -1216, -588,  520,   -108,  92,    -320,  368,   -480,  -216, -92,
  1688,  -300,  180,   1020,  -176,  820,   -68,   -228,  -260,  436,  -904,
  20,    40,    -508,  440,   -736,  312,   332,   204,   760,   -372, 728,
  96,    -20,   -632,  -520,  -560,  336,   1076,  -64,   -532,  776,  584,
  192,   396,   -728,  -520,  276,   -188,  80,    -52,   -612,  -252, -48,
  648,   212,   -688,  228,   -52,   -260,  428,   -412,  -272,  -404, 180,
  816,   -796,  48,    152,   484,   -88,   -216,  988,   696,   188,  -528,
  648,   -116,  -180,  316,   476,   12,    -564,  96,    476,   -252, -364,
  -376,  -392,  556,   -256,  -576,  260,   -352,  120,   -16,   -136, -260,
  -492,  72,    556,   660,   580,   616,   772,   436,   424,   -32,  -324,
  -1268, 416,   -324,  -80,   920,   160,   228,   724,   32,    -516, 64,
  384,   68,    -128,  136,   240,   248,   -204,  -68,   252,   -932, -120,
  -480,  -628,  -84,   192,   852,   -404,  -288,  -132,  204,   100,  168,
  -68,   -196,  -868,  460,   1080,  380,   -80,   244,   0,     484,  -888,
  64,    184,   352,   600,   460,   164,   604,   -196,  320,   -64,  588,
  -184,  228,   12,    372,   48,    -848,  -344,  224,   208,   -200, 484,
  128,   -20,   272,   -468,  -840,  384,   256,   -720,  -520,  -464, -580,
  112,   -120,  644,   -356,  -208,  -608,  -528,  704,   560,   -424, 392,
  828,   40,    84,    200,   -152,  0,     -144,  584,   280,   -120, 80,
  -556,  -972,  -196,  -472,  724,   80,    168,   -32,   88,    160,  -688,
  0,     160,   356,   372,   -776,  740,   -128,  676,   -248,  -480, 4,
  -364,  96,    544,   232,   -1032, 956,   236,   356,   20,    -40,  300,
  24,    -676,  -596,  132,   1120,  -104,  532,   -1096, 568,   648,  444,
  508,   380,   188,   -376,  -604,  1488,  424,   24,    756,   -220, -192,
  716,   120,   920,   688,   168,   44,    -460,  568,   284,   1144, 1160,
  600,   424,   888,   656,   -356,  -320,  220,   316,   -176,  -724, -188,
  -816,  -628,  -348,  -228,  -380,  1012,  -452,  -660,  736,   928,  404,
  -696,  -72,   -268,  -892,  128,   184,   -344,  -780,  360,   336,  400,
  344,   428,   548,   -112,  136,   -228,  -216,  -820,  -516,  340,  92,
  -136,  116,   -300,  376,   -244,  100,   -316,  -520,  -284,  -12,  824,
  164,   -548,  -180,  -128,  116,   -924,  -828,  268,   -368,  -580, 620,
  192,   160,   0,     -1676, 1068,  424,   -56,   -360,  468,   -156, 720,
  288,   -528,  556,   -364,  548,   -148,  504,   316,   152,   -648, -620,
  -684,  -24,   -376,  -384,  -108,  -920,  -1032, 768,   180,   -264, -508,
  -1268, -260,  -60,   300,   -240,  988,   724,   -376,  -576,  -212, -736,
  556,   192,   1092,  -620,  -880,  376,   -56,   -4,    -216,  -32,  836,
  268,   396,   1332,  864,   -600,  100,   56,    -412,  -92,   356,  180,
  884,   -468,  -436,  292,   -388,  -804,  -704,  -840,  368,   -348, 140,
  -724,  1536,  940,   372,   112,   -372,  436,   -480,  1136,  296,  -32,
  -228,  132,   -48,   -220,  868,   -1016, -60,   -1044, -464,  328,  916,
  244,   12,    -736,  -296,  360,   468,   -376,  -108,  -92,   788,  368,
  -56,   544,   400,   -672,  -420,  728,   16,    320,   44,    -284, -380,
  -796,  488,   132,   204,   -596,  -372,  88,    -152,  -908,  -636, -572,
  -624,  -116,  -692,  -200,  -56,   276,   -88,   484,   -324,  948,  864,
  1000,  -456,  -184,  -276,  292,   -296,  156,   676,   320,   160,  908,
  -84,   -1236, -288,  -116,  260,   -372,  -644,  732,   -756,  -96,  84,
  344,   -520,  348,   -688,  240,   -84,   216,   -1044, -136,  -676, -396,
  -1500, 960,   -40,   176,   168,   1516,  420,   -504,  -344,  -364, -360,
  1216,  -940,  -380,  -212,  252,   -660,  -708,  484,   -444,  -152, 928,
  -120,  1112,  476,   -260,  560,   -148,  -344,  108,   -196,  228,  -288,
  504,   560,   -328,  -88,   288,   -1008, 460,   -228,  468,   -836, -196,
  76,    388,   232,   412,   -1168, -716,  -644,  756,   -172,  -356, -504,
  116,   432,   528,   48,    476,   -168,  -608,  448,   160,   -532, -272,
  28,    -676,  -12,   828,   980,   456,   520,   104,   -104,  256,  -344,
  -4,    -28,   -368,  -52,   -524,  -572,  -556,  -200,  768,   1124, -208,
  -512,  176,   232,   248,   -148,  -888,  604,   -600,  -304,  804,  -156,
  -212,  488,   -192,  -804,  -256,  368,   -360,  -916,  -328,  228,  -240,
  -448,  -472,  856,   -556,  -364,  572,   -12,   -156,  -368,  -340, 432,
  252,   -752,  -152,  288,   268,   -580,  -848,  -592,  108,   -76,  244,
  312,   -716,  592,   -80,   436,   360,   4,     -248,  160,   516,  584,
  732,   44,    -468,  -280,  -292,  -156,  -588,  28,    308,   912,  24,
  124,   156,   180,   -252,  944,   -924,  -772,  -520,  -428,  -624, 300,
  -212,  -1144, 32,    -724,  800,   -1128, -212,  -1288, -848,  180,  -416,
  440,   192,   -576,  -792,  -76,   -1080, 80,    -532,  -352,  -132, 380,
  -820,  148,   1112,  128,   164,   456,   700,   -924,  144,   -668, -384,
  648,   -832,  508,   552,   -52,   -100,  -656,  208,   -568,  748,  -88,
  680,   232,   300,   192,   -408,  -1012, -152,  -252,  -268,  272,  -876,
  -664,  -648,  -332,  -136,  16,    12,    1152,  -28,   332,   -536, 320,
  -672,  -460,  -316,  532,   -260,  228,   -40,   1052,  -816,  180,  88,
  -496,  -556,  -672,  -368,  428,   92,    356,   404,   -408,  252,  196,
  -176,  -556,  792,   268,   32,    372,   40,    96,    -332,  328,  120,
  372,   -900,  -40,   472,   -264,  -592,  952,   128,   656,   112,  664,
  -232,  420,   4,     -344,  -464,  556,   244,   -416,  -32,   252,  0,
  -412,  188,   -696,  508,   -476,  324,   -1096, 656,   -312,  560,  264,
  -136,  304,   160,   -64,   -580,  248,   336,   -720,  560,   -348, -288,
  -276,  -196,  -500,  852,   -544,  -236,  -1128, -992,  -776,  116,  56,
  52,    860,   884,   212,   -12,   168,   1020,  512,   -552,  924,  -148,
  716,   188,   164,   -340,  -520,  -184,  880,   -152,  -680,  -208, -1156,
  -300,  -528,  -472,  364,   100,   -744,  -1056, -32,   540,   280,  144,
  -676,  -32,   -232,  -280,  -224,  96,    568,   -76,   172,   148,  148,
  104,   32,    -296,  -32,   788,   -80,   32,    -16,   280,   288,  944,
  428,   -484
}

Bibliography

  1. AV1 Bitstream & Decoding Process Specification, Version 1.0.0 with Errata 1, 2019-01-08
  2. Rec. ITU-T T.35:2000, Procedure for the allocation of ITU-T defined codes for non standard facilities.