# Preset Grading vs Auto-Grade vs Raw ffmpeg Filters in video-use

> Understand video-use's preset grading, auto-grade, and raw ffmpeg filters. Learn how each mode constructs filter chains for video extraction to optimize your workflow.

- Repository: [Browser Use/video-use](https://github.com/browser-use/video-use)
- Tags: deep-dive
- Published: 2026-07-05

---

**video-use provides three colour-grading modes—preset grading, auto-grade, and raw ffmpeg filters—that determine how the `-vf` filter chain is constructed during per-segment extraction.**

The `browser-use/video-use` repository ships a compact colour-grading subsystem that exposes **preset grading**, **auto-grade**, and **raw ffmpeg filters** to shape the look of extracted segments. Whether you want a deterministic cinematic look, a data-driven cleanup, or complete manual control, the chosen mode dictates how the ffmpeg filter string is generated and injected into the pipeline.

## Preset Grading: Reusable, Author-Defined Looks

Preset grading relies on the `PRESETS` dictionary defined in [`helpers/grade.py`](https://github.com/browser-use/video-use/blob/main/helpers/grade.py). Each named entry—such as `warm_cinematic` or `neutral_punch`—maps to a static ffmpeg filter string assembled from `eq`, `colorbalance`, `curves`, and other filters. When a user requests a preset, `get_preset()` returns the corresponding expression, and `extract_segment()` in [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py) inserts it directly into the `-vf` chain of the per-segment extraction step.

This mode is ideal when you need a deterministic, artistic look that applies the same fixed corrections across every segment.

### Example: Applying a Preset from the CLI

```bash
python helpers/grade.py input.mp4 -o out.mp4 --preset warm_cinematic

```

## Auto-Grade: Conservative, Statistics-Based Correction

Auto-grade is the default behaviour when no preset or raw filter is supplied. The implementation lives in [`helpers/grade.py`](https://github.com/browser-use/video-use/blob/main/helpers/grade.py), where `auto_grade_for_clip()` drives the process. It first invokes `_sample_frame_stats()` to run ffmpeg with the `signalstats` filter and `metadata=print`, sampling frames to collect Y-luma and saturation values. These metrics are normalised by bit-depth to produce `y_mean`, `y_std`, and `sat_mean`.

A deterministic rule set maps those statistics to subtle contrast, gamma, and saturation adjustments that are deliberately clamped to **±8%** and never introduce a colour shift. If the source clip is already well-balanced, the function falls back to the `subtle` preset (`eq=contrast=1.03:saturation=0.98`).

### Example: Using Default Auto-Grade

```bash
python helpers/grade.py input.mp4 -o out.mp4

```

The resulting filter string—something like `eq=contrast=1.045:gamma=1.017:saturation=1.012`—is injected into the same `-vf` chain used for preset grading.

## Raw ffmpeg Filters: Unrestricted Manual Control

Raw ffmpeg filters give callers full manual control by accepting any valid ffmpeg filter string via the `--filter` CLI flag or the `grade` field of an EDL. No validation is performed beyond treating the input as a literal filter expression.

Inside [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py), `resolve_grade_filter()` detects a raw string by checking for characters like `=` or `,`. When found, it bypasses the `PRESETS` lookup and returns the expression verbatim. `extract_segment()` then appends that literal string to the `-vf` chain immediately after HDR tone-mapping and scaling.

### Example: Supplying a Custom Filter String

```bash
python helpers/grade.py input.mp4 -o out.mp4 \
    --filter "eq=contrast=1.12:saturation=0.95,curves=master='0/0 0.5/0.6 1/1'"

```

## Architectural Flow and Filter Injection

The three grading modes converge in the same rendering pipeline. Understanding the resolution flow clarifies how each mode is selected and where it is applied.

### CLI Argument Resolution

In [`helpers/grade.py`](https://github.com/browser-use/video-use/blob/main/helpers/grade.py), the `--preset` and `--filter` arguments are mutually exclusive. If both are omitted, the code automatically falls back to `auto_grade_for_clip()`.

### EDL Grade Resolution

`resolve_grade_filter()` in [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py) interprets the `grade` field of each EDL entry. It returns exactly one of the following:

- A preset filter via `get_preset(name)`
- The literal raw filter string
- The sentinel `"__AUTO__"`, which is expanded per-segment by calling `auto_grade_for_clip()` with the source video and segment timestamps

Raw strings are detected heuristically and passed straight through without preset lookup.

### EDL Examples for Each Mode

```json
{
  "source": "clip1.mp4",
  "grade": "auto"
}

```

```json
{
  "source": "clip2.mp4",
  "grade": "neutral_punch"
}

```

```json
{
  "source": "clip3.mp4",
  "grade": "eq=gamma=1.08"
}

```

### Per-Segment ffmpeg Assembly

`extract_segment()` builds the final `-vf` argument by concatenating, in order, tone-mapping, scaling, and the resolved grade filter. This ensures every extracted segment receives a consistent colour-correction step regardless of how the filter was derived.

## Summary

- **Preset grading** uses static, author-defined filter strings stored in [`helpers/grade.py`](https://github.com/browser-use/video-use/blob/main/helpers/grade.py) for deterministic looks.
- **Auto-grade** derives conservative corrections from frame-level `signalstats` analysis via `_sample_frame_stats()` and `auto_grade_for_clip()`.
- **Raw ffmpeg filters** allow unrestricted manual control by passing literal strings through `--filter` or EDL `grade` fields.
- All three modes are injected by `extract_segment()` in [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py) into the same per-segment `-vf` chain after tone-mapping and scaling.

## Frequently Asked Questions

### What happens if I supply both `--preset` and `--filter`?

The CLI parser in [`helpers/grade.py`](https://github.com/browser-use/video-use/blob/main/helpers/grade.py) treats these arguments as mutually exclusive. You cannot supply both simultaneously; the tool enforces a single grading path and will reject or override the conflicting input.

### How does auto-grade decide when to apply corrections?

`auto_grade_for_clip()` analyses sampled frames using ffmpeg's `signalstats` filter. It computes `y_mean`, `y_std`, and `sat_mean`, then maps those values to contrast, gamma, and saturation adjustments clamped to ±8%. If the metrics indicate the clip is already well-balanced, the system falls back to the `subtle` preset instead of applying a custom correction.

### Can I use raw ffmpeg filters inside an EDL?

Yes. If an EDL entry's `grade` field contains characters like `=` or `,`, `resolve_grade_filter()` in [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py) treats the value as a raw ffmpeg filter string and appends it verbatim to the `-vf` chain. No preset lookup occurs.

### Where is the grade filter positioned in the final ffmpeg command?

The resolved filter is appended inside `extract_segment()` in [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py) after HDR tone-mapping and scaling steps. This ordering ensures colour corrections apply to the correctly transformed image.