Skip to content

2. FGS Table Structure

Michele Cosentino edited this page Apr 30, 2026 · 3 revisions

The filmgrn1 format is a standardized textual representation of AV1 Film Grain Synthesis (AFGS1) metadata. Tools like grav1synth and FGSEditor use this format to manipulate grain tables in a human-readable form before compiling them into the binary OBU (Open Bitstream Unit).

Here is a complete breakdown of a typical filmgrn1 block, line by line. We will explain every single value, its purpose, and the maximum allowed limits according to the specification.

Example Block

filmgrn1
E 0 14230000000 1 7391 1
  p 3 9 0 11 0 1 128 192 256 128 192 256
  sY 14  16 1 19 73 38 42 58 33 77 30 96 28 116 27 135 26 155 25 174 25 193 24 213 24 232 24 235 1
  sCb 0
  sCr 0
  cY 4 -1 3 18 5 1 5 0 4 2 -16 -6 1 -2 3 -2 7 67 18 6 5 20 -17 72
  cCb 7 4 8 18 8 5 10 5 -1 7 28 16 5 11 16 9 38 52 35 31 22 32 70 25 4
  cCr 7 3 8 18 7 6 11 6 -1 6 26 16 4 12 16 8 38 50 35 32 23 33 70 27 8

1. Event Definition (E)

The E line defines the temporal window and activation settings for the grain event.

E 0 14230000000 1 7391 1

Value Name Limits Purpose
0 start_time $\ge 0$ The starting timestamp. Typically measured in 100-nanosecond units (AV1 standard timescale), meaning 10,000,000 = 1 second.
14230000000 end_time > start_time The ending timestamp. When this specific grain event stops applying.
1 apply_grain 0 or 1 1 = Enabled, 0 = Disabled (no film grain is applied to the video during this event).
7391 random_seed 0 to 65535 The initial seed for the pseudo-random number generator. Drives the specific starting state of the noise pattern.
1 update_parameters 0 or 1 1: Instructs the decoder to read a completely new set of grain parameters from the bitstream, updating its internal model.

0: Instructs the decoder to reuse the grain parameters it already has in memory from a previous referred frame. This drastically reduces the size of the injected metadata in the video file because the full FGS table isn't written on every single frame.

Note

update_parameters or update_film_grain should be always set to 1, except in very rare cases.


2. Global Parameters (p)

The p line defines the mathematical setup and limits of the Auto-Regressive filter and the scaling formulas.

p 3 9 0 11 0 1 128 192 256 128 192 256

Value Name Limits Purpose
3 ar_coeff_lag 0 to 3 Defines the size of the spatial "grid" used to correlate noise pixels. A value of 3 indicates the maximum lag (generating a 24-coefficient luma matrix). 0 means no spatial correlation (pure noise).
9 ar_coeff_shift 6 to 9 The binary shift used to divide the algebraic sum of the AR coefficients. It controls the stability and visual magnitude of the grain clusters.
0 grain_scale_shift 0 to 3 Determines how much the base Gaussian random numbers are "attenuated" before passing through the AR filter. Higher values mean weaker base noise.
11 scaling_shift 8 to 11 CRITICAL. Defines the binary shift (the final division) to scale the grain intensity to the correct bit-depth before adding it to the video pixels (noise = (grain_sample * scaling_value) >> scaling_shift). Without it, the grain would mathematically exceed valid ranges and produce extreme artifacts.
0 chroma_scaling_from_luma 0 or 1 If set to 1, it ignores Chroma scaling curves (sCb, sCr) and forces the color grain to use the Luma intensity scaling, simplifying processing.
1 overlap_flag 0 or 1 1 allows the overlapping of synthesized noise blocks (which are $32\times32$ for Luma, and scaled down proportionally for Chroma depending on subsampling, e.g. $16\times16$ for 4:2:0) to avoid visible grid-like seams on screen.
128 cb_mult 0 to 255 8-bit multiplier for the Cb chroma plane, used during chroma correlation equations.
192 cb_luma_mult 0 to 255 8-bit Luma multiplier used for adjusting Cb intensity relative to luma.
256 cb_offset 0 to 511 9-bit offset for the Cb chroma plane correlation, shifting the baseline value.
128 cr_mult 0 to 255 Same as cb_mult, but applied to the Cr chroma plane.
192 cr_luma_mult 0 to 255 Same as cb_luma_mult, but applied to the Cr chroma plane.
256 cr_offset 0 to 511 Same as cb_offset, but applied to the Cr chroma plane.

3. Scaling Curves (sY, sCb, sCr)

Defines how the grain intensity changes relative to the brightness of the pixel. Grain is often stronger in mid-tones and weaker in pure blacks or pure whites (Luma Masking).

sY 14 16 1 19 73 38 42 ...

  • sY: Indicates we are defining the points for the Luminance (Luma) curve.
  • 14 (Number of Points): Total number of "points" defined in this curve. Limit: 0 to 14 points.
  • Pairs of numbers (16 1, 19 73, etc.): These are the XY coordinates of the curve. The first number (e.g., 16) is the Base Pixel Value on an 8-bit scale (limit: 0 to 255), representing the brightness of the video pixel. The second number (e.g., 1) is the Scaling Factor (limit: 0 to 255), which is the multiplier that determines "how much grain" to generate at that specific exposure level.

Note

If sCb or sCr show only the value 0 (e.g., sCb 0), it means there are 0 points defined. The equations for the Chroma curves are empty, and Chroma grain will not be produced unless chroma_scaling_from_luma is enabled.

Graph of luma scaling value in the example scaling


4. Auto-Regressive Coefficients (cY, cCb, cCr)

The core mathematical "shape" values for the grain particles. They determine the physical texture (clumping, sharpness, size).

cY 4 -1 3 18 5 1 5 0 4 2 -16 -6 1 -2 3 -2 7 67 18 6 5 20 -17 72

  • cY / cCb / cCr: Identifiers for the Y (Luma), Cb (Blue Chroma), and Cr (Red Chroma) planes.
  • The Array of Numbers (4 -1 3 18 ...): These are the spatial multipliers (AR Coefficients). Every single coefficient must be an 8-bit signed integer, strictly within the range -128 to 127. The amount of numbers in this list depends entirely on the ar_coeff_lag setting: it requires 0 coefficients for Lag 0, 3 coefficients for Lag 1, 12 for Lag 2, and 24 for Lag 3.
  • The 25th Coefficient (Correlated Chroma): If generating independent Chroma noise, the cCb and cCr strings can optionally contain an additional number at the very end of the list (e.g., 25 values instead of 24 when Lag=3). This is the Luma Correlation Coefficient, which is also an 8-bit signed integer (-128 to 127).

Now that you know what every value means syntactically, let's explore the complex mathematics behind the Auto-Regressive Coefficients in the next page.

Clone this wiki locally