# Limitations of the Current Color Grading Implementation in video-use

> Discover the limitations of current color grading in video-use. Explore constraints in adjustment axes, missing LUT support, clip-level processing, and CPU-bound encoding. Learn about its shortcomings.

- Repository: [Browser Use/video-use](https://github.com/browser-use/video-use)
- Tags: performance
- Published: 2026-06-30

---

**The current color grading implementation in video-use restricts adjustments to three basic axes with hard-coded ±8% bounds, lacks LUT support, processes only per-clip rather than per-frame, and relies solely on CPU-based ffmpeg encoding without GPU acceleration.**

The **video-use** repository provides a lightweight color grading utility located in [`helpers/grade.py`](https://github.com/browser-use/video-use/blob/main/helpers/grade.py) designed for quick "clean-up" of standard footage. While functional for basic corrections, the implementation makes deliberate trade-offs that constrain creative flexibility and technical capability. Understanding these **limitations of the current color grading implementation** helps developers determine when to extend the tool or switch to professional grading suites.

## Restricted Adjustment Axes and Creative Controls

The grader exposes only **three adjustment parameters**: contrast, gamma (brightness), and saturation. This restriction prevents sophisticated color work such as teal-orange grading, film emulation, or selective color replacement.

In [`helpers/grade.py`](https://github.com/browser-use/video-use/blob/main/helpers/grade.py), the preset definitions contain only `eq=` filters and a simple `curves=` option in the optional *warm_cinematic* preset (lines 38-63). The `auto_grade_for_clip()` function builds its filter string exclusively from `contrast`, `gamma`, and `saturation` values (lines 52-59). No mechanism exists for loading external **LUTs** (Look-Up Tables) or applying advanced curves adjustments.

## Hard-Coded Bounds Prevent Strong Corrections

Every automatic adjustment is clamped within narrow ±8% limits, preventing strong creative looks or correction of extreme exposure issues.

The code explicitly constrains values using:
- `max(0.94, min(1.08, …))` for contrast
- `max(0.94, min(1.10, …))` for gamma  
- `max(0.94, min(1.06, …))` for saturation

These clamps appear in lines 146-149 of [`helpers/grade.py`](https://github.com/browser-use/video-use/blob/main/helpers/grade.py). Even when manually specifying stronger adjustments via command line, the `auto_grade_for_clip()` function silently caps the values to these narrow ranges.

## Per-Clip Processing Limitations

The implementation applies **uniform corrections across entire clips**, making it impossible to compensate for dynamic scenes with changing exposure or lighting conditions.

The `auto_grade_for_clip()` function returns a single filter string that gets applied to the complete input video (lines 84-91). There is no keyframe system or per-frame analysis capability to handle time-varying corrections.

## Sampling Strategy Constraints

The automatic analysis relies on a sparse sampling method that may mischaracterize short or rapidly changing clips.

In `_sample_frame_stats()` (lines 98-100), the code calculates:

```python
fps = max(0.5, min(n_samples / max(duration, 0.1), 10.0))

```

With `n_samples` hard-coded to **10 frames maximum** and sampling rate capped at **10 fps**, brief clips or scenes with quick transitions may receive inaccurate statistical analysis leading to suboptimal grades.

## Color Space and Bit Depth Restrictions

The pipeline lacks modern color management capabilities, forcing all output to **8-bit YUV420P** regardless of source material.

The ffmpeg command construction in `apply_grade()` hard-codes `-pix_fmt yuv420p` (lines 85-88), discarding chroma information from YUV-422 or BT.2020 sources. While the code parses bit depth via `YBITDEPTH` and normalizes using `max_val = (2 ** bit_depth) - 1` (lines 158-162), the subsequent mathematics assumes 0-1 ranges that may under-represent high-dynamic-range material.

Additionally, if ffmpeg's `signalstats` filter cannot decode the source (common with HDR or unusual pixel formats), the system falls back to neutral defaults of `y_mean=0.5` and `sat_mean=0.25` (lines 154-157), effectively bypassing analysis.

## Performance and Architectural Constraints

**No GPU acceleration** is available; all processing uses libx264 on the CPU with fixed settings.

The `apply_grade()` function always invokes `-c:v libx264 -preset fast -crf 18` (lines 82-87), making no provision for hardware encoding (NVENC, Quick Sync, etc.) or GPU-accelerated filters. This limitation results in slow processing times for long or high-resolution clips.

The architecture also enforces a **single-pass filter chain** with no support for multi-pass color correction. The filter string consists of a single `eq=` chain without secondary `curves=` or `colorbalance` passes in auto mode (lines 51-58).

## Practical Examples of Current Constraints

Attempting to apply the auto-grade reveals the narrow bounds in action:

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

```

To inspect the generated filter and verify the clamping:

```bash
python helpers/grade.py --analyze input.mp4

# Example output:

# filter: eq=contrast=1.074:gamma=1.098:saturation=0.982

```

The preset selection is limited to three static options:

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

```

Available presets (`subtle`, `neutral_punch`, `warm_cinematic`) are hard-coded in the `PRESETS` dictionary (lines 38-63). Adding creative looks requires editing [`helpers/grade.py`](https://github.com/browser-use/video-use/blob/main/helpers/grade.py) directly; there is no runtime discovery of external LUT files.

Attempting to force stronger adjustments demonstrates the silent capping:

```bash
python helpers/grade.py input.mp4 -o out.mp4 --filter "eq=contrast=1.5:gamma=1.3:saturation=1.2"

# Values are clamped to ~1.08 maximum inside auto_grade_for_clip()

```

## Summary

The **video-use** color grading system prioritizes simplicity over flexibility, resulting in significant technical constraints:

- **Three-axis limitation**: Only contrast, gamma, and saturation; no LUTs or color shifts
- **±8% hard caps**: Preventing strong creative grades or extreme corrections
- **Uniform per-clip application**: No dynamic or per-frame adjustment capability
- **Sparse sampling**: Maximum 10 frames analyzed regardless of clip length
- **8-bit YUV420P output**: Forces color space conversion and loses high-bit-depth information
- **CPU-only processing**: libx264 encoding without GPU acceleration options
- **Static presets**: No external LUT loading or runtime extensibility

These characteristics make the tool suitable for quick normalization of standard 8-bit SDR footage but inadequate for professional color work, HDR pipelines, or artistic grading.

## Frequently Asked Questions

### Can I apply custom LUTs with the current video-use grader?

No. The `PRESETS` dictionary in [`helpers/grade.py`](https://github.com/browser-use/video-use/blob/main/helpers/grade.py) (lines 38-63) is hard-coded and contains no LUT loading mechanism. The auto-grade generates only `eq=` filter strings for contrast, gamma, and saturation. To use custom LUTs, you must manually extend the code to support ffmpeg's `lut3d` filter or preprocess footage externally.

### Why is my color adjustment being capped at 8%?

The `auto_grade_for_clip()` function enforces hard limits using `min()` and `max()` clamps (lines 146-149): contrast is limited to 0.94-1.08, gamma to 0.94-1.10, and saturation to 0.94-1.06. These bounds prevent strong corrections and are applied silently even when manually specifying filter values.

### Does video-use support HDR color grading?

No. While the code parses `YBITDEPTH` to normalize values (lines 158-162), the pipeline forces output to `yuv420p` (lines 85-88) and falls back to neutral defaults if ffmpeg's `signalstats` cannot decode HDR formats (lines 154-157). The mathematics assume SDR 0-1 ranges, making proper HDR grading impossible without significant modifications.

### How can I process high-resolution videos faster with video-use?

Currently, you cannot leverage GPU acceleration. The `apply_grade()` function hard-codes `-c:v libx264` with CPU encoding (lines 82-87). To improve performance, you would need to modify [`helpers/grade.py`](https://github.com/browser-use/video-use/blob/main/helpers/grade.py) to support hardware encoders like NVENC (NVIDIA), VideoToolbox (Apple), or Quick Sync (Intel) by changing the codec parameters in the ffmpeg command construction.