-
Notifications
You must be signed in to change notification settings - Fork 0
1. Introduction to FGS
AOMedia Film Grain Synthesis (AFGS1) is a standardized specification that defines a mathematical model for representing and synthesizing film grain. Unlike traditional noise reduction or grain management, AFGS1 provides a normative way to describe grain through metadata.
Instead of burning physical noise directly into the pixels of a video frame (which massively inflates the file size and consumes huge amounts of bitrate), AFGS1 instructs the video player to mathematically generate synthetic noise on top of the clean video during playback.
Note
While AFGS1 was developed in conjunction with the AV1 specification, it is technically codec-agnostic. In theory, it can be utilized with other video standards such as HEVC or AVC. However, current decoding support and toolchains are primarily mature only for AV1.
Although you can use FGSEditor to design grain tables and export them to standard FGS text files, using them in HEVC workflows comes with major caveats, particularly due to encoder and player limitations. In the AFGS1 specification, the chroma_scaling_from_luma parameter allows the chroma grain intensity to dynamically scale based on luma levels. However, the x265 encoder (including popular custom builds like Patman's mod) does not support this feature and will completely ignore and discard all Chroma grain if it is enabled. FGSEditor will display a safety warning if you attempt to save a table with this setting active.
From a player's behavior perspective, static and dynamic grain behave identically. Static grain is applied on an event basis by repeating the exact same seed, keeping the synthesized noise pattern identical across the event. Dynamic grain, on the other hand, cycles through a table of different seeds using an anti-repetition logic to prevent the viewer from noticing repeating pattern artifacts.
While their structure is equivalent from a decoder perspective, toolchain support varies. Specifically, external utility tools like grav1synth do not support applying static grain to AV1 streams (for now). In contrast, static grain is fully supported and implemented in x265 via the FGSE parser.
In the context of FGS, the term "Grain" is a linguistic legacy tied to aesthetic intent, but it is technically inaccurate. AFGS1 effectively generates synthetic digital noise.
Analog film grain is a physical, optical artifact inherent to the photochemical development process, formed by actual silver halide crystals. The FGS process, on the other hand, is a purely mathematical construct: it generates synthetic digital noise via a pseudo-random number generator (PRNG), which is then processed through a spatial filter to simulate the appearance of real film.
The "G" in the acronym remains purely as an industry-standard convention to indicate the final goal: calibrating the equations so that the resulting noise simulates the visual behavior of film. However, at the decoding level, we are fundamentally injecting pure digital noise.
That being said, we establish the following practical distinction for these terms within our ecosystem:
- Noise: Refers to FGS tables where the spatial filters (AR coefficients) are turned off. This results in the application of pure, unshaped digital noise.
- Grain: Refers to FGS tables where the spatial filters are active. The noise is shaped into structured, spatially correlated patterns that clump together, mimicking real physical grain.
Using Film Grain Synthesis instead of traditionally encoded grain offers a massive paradigm shift in video encoding, but it comes with its own set of trade-offs.
- Extreme Bitrate Savings: Traditional grain is high-frequency, random detail. Video encoders (like AV1, HEVC, x264) struggle immensely to compress random noise, often wasting massive amounts of bitrate trying to retain it, or blurring it out completely. FGS removes the grain before encoding, compresses a perfectly clean image, and sends a tiny text file (metadata) describing the grain. The bitrate savings can be enormous (often 20% to 50% for grainy sources).
- Perfect Grain Retention: Because the grain is generated algorithmically at playback, it never suffers from compression artifacts. You will never see "blocky" or "mushy" grain typical of starved bitrate scenarios. The grain remains perfectly sharp regardless of the underlying video's compression level.
- Customizability: With tools like FGSEditor, you can completely replace the original grain of a film with a different texture, size, or intensity without re-encoding the video stream. You can add grain to digitally shot sterile footage, or remove it entirely by stripping the metadata.
- Visual Disconnect on Bad Encodes: If the underlying clean video is compressed too heavily and exhibits severe banding or blocking, FGS will blindly generate perfect grain on top of a flawed image. This can sometimes look unnatural, like looking at a pristine layer of noise floating on top of a heavily compressed JPEG. FGS is not a magical fix for a bad encode.
- Aesthetic Purity: Purists often argue that synthetic grain, no matter how well-tuned, lacks the absolute organic randomness of true photochemical film. While AFGS1 is highly advanced, it is ultimately a mathematical approximation.
- Restricted Noise Distribution: The core pseudo-random number generator (PRNG) defined by the specification is strictly tied to generating a base of Gaussian noise. This fundamentally limits applications where different statistical noise distributions (such as Poisson or Uniform noise) might be more physically accurate for specific sensor types. However, as we will see, it is partially possible to emulate other visual textures by cleverly manipulating the Auto-Regressive (AR) coefficients.
By understanding what FGS is, we can now look at how this data is actually written and stored inside the video file.