# How to Configure FFmpeg Streams for Camera Input in Frigate NVR

> Learn how to configure FFmpeg streams for camera input in Frigate NVR by understanding its three-layer system of global defaults, presets, and per-camera overrides. Get your cameras working with Frigate.

- Repository: [Blake Blackshear/frigate](https://github.com/blakeblackshear/frigate)
- Tags: how-to-guide
- Published: 2026-05-25

---

**Frigate NVR builds FFmpeg command lines through a three-layer system of global defaults, symbolic presets, and per-camera overrides defined in [`frigate/config/camera/ffmpeg.py`](https://github.com/blakeblackshear/frigate/blob/main/frigate/config/camera/ffmpeg.py) and [`frigate/ffmpeg_presets.py`](https://github.com/blakeblackshear/frigate/blob/main/frigate/ffmpeg_presets.py).**

Every camera stream in the `blakeblackshear/frigate` repository relies on FFmpeg for ingestion, decoding, and optional re-encoding. Understanding how Frigate assembles the final command line helps you optimize performance, enable hardware acceleration, and troubleshoot protocol-specific issues without verbose manual arguments.

## The Three Layers of FFmpeg Configuration

Frigate constructs FFmpeg commands by merging three distinct configuration layers. This architecture keeps standard setups concise while allowing surgical overrides for problematic cameras.

### Global Defaults

Every FFmpeg process starts with baseline arguments defined in **[`frigate/config/camera/ffmpeg.py`](https://github.com/blakeblackshear/frigate/blob/main/frigate/config/camera/ffmpeg.py)**【^1†L19-L22】. The defaults suppress verbose output and limit thread usage:

```yaml
global_args: -hide_banner -loglevel warning -threads 2

```

These arguments appear before any input definition in the final command line.

### Presets System

Presets are symbolic names that expand to hardware-specific or protocol-specific argument lists. All preset definitions reside in **[`frigate/ffmpeg_presets.py`](https://github.com/blakeblackshear/frigate/blob/main/frigate/ffmpeg_presets.py)**【^2†L84-L124】, with human-readable documentation in **[`docs/docs/configuration/ffmpeg_presets.md`](https://github.com/blakeblackshear/frigate/blob/main/docs/docs/configuration/ffmpeg_presets.md)**【^3†L12-L50】.

The preset parser functions—`parse_preset_hardware_acceleration_decode`, `parse_preset_input`, and `parse_preset_output_record`—resolve symbolic names into concrete FFmpeg arguments at runtime【^2†L12-L61】.

### Per-Camera Overrides

Individual cameras can replace any layer using the `ffmpeg` configuration block. The schema in **[`frigate/config/camera/ffmpeg.py`](https://github.com/blakeblackshear/frigate/blob/main/frigate/config/camera/ffmpeg.py)**【^1†L64-L73】 supports `hwaccel_args`, `input_args`, `global_args`, and `output_args` at both the camera level and per-input stream level.

## Available FFmpeg Presets

Selecting the correct preset eliminates manual tuning for GPU acceleration and transport protocols.

### Hardware Acceleration Presets

Use these to enable GPU decoding and scaling:

- **preset-vaapi** – Intel/AMD VA-API acceleration
- **preset-nvidia** – NVIDIA CUDA (auto-detects codec)
- **preset-nvidia-h264** / **preset-nvidia-h265** – Explicit NVIDIA codec selection
- **preset-rpi-64-h264** – Raspberry Pi V4L2 M2M decoder
- **preset-jetson-h264** / **preset-jetson-h265** – Jetson NV MPI decoding

The `auto` value for `hwaccel_args` triggers automatic detection based on available hardware【^2†L23-L30】.

### Input Presets

Match these to your camera's protocol and behavior:

- **preset-rtsp-generic** – TCP transport RTSP (default)
- **preset-rtsp-udp** – UDP-only RTSP for cameras that reject TCP
- **preset-http-reolink** – HTTP-FLV streams for Reolink cameras behind restreams
- **preset-http-jpeg-generic** / **preset-http-mjpeg-generic** – Static image or MJPEG HTTP feeds

### Output Presets

Control recording behavior and audio handling:

- **preset-record-generic** – Copy video stream, no audio
- **preset-record-generic-audio-aac** – Copy video, re-encode audio to AAC (default)
- **preset-record-generic-audio-copy** – Copy both video and audio (FFmpeg 6.x; falls back to AAC on FFmpeg 7.x)【^2†L36-L44】

## Practical Configuration Examples

### Minimal Setup with Auto-Detection

For standard RTSP cameras, Frigate can auto-select hardware acceleration:

```yaml
cameras:
  front_door:
    ffmpeg:
      input_args: preset-rtsp-generic
    # Uses default detect and record roles

```

This relies on the default `input_args` value of `preset-rtsp-generic` defined in the FFmpeg configuration schema【^1†L64-L67】.

### Explicit Hardware Acceleration

Force Intel VAAPI and UDP transport for a specific camera:

```yaml
cameras:
  driveway:
    ffmpeg:
      hwaccel_args: preset-vaapi
      input_args: preset-rtsp-udp
    inputs:
      - path: rtsp://192.168.1.45/stream
        roles: [detect, record]
        global_args: ["-reorder_queue_size", "5"]

```

The `hwaccel_args` field accepts preset names that resolve through the parsing functions in **[`frigate/ffmpeg_presets.py`](https://github.com/blakeblackshear/frigate/blob/main/frigate/ffmpeg_presets.py)**【^1†L59-L63】.

### Multi-Protocol Reolink Setup

Mix HTTP-FLV for detection with RTSP for recording via go2rtc:

```yaml
go2rtc:
  streams:
    reolink_front: http://192.168.1.99/flv?port=1935&app=bcs&stream=channel0_main.bcs&user=admin&password=***

cameras:
  reolink_front:
    ffmpeg:
      inputs:
        - path: http://192.168.1.99/flv?port=1935&app=bcs&stream=channel0_ext.bcs&user=admin&password=***
          input_args: preset-http-reolink
          roles: [detect]
        - path: rtsp://127.0.0.1:8554/reolink_front
          input_args: preset-rtsp-generic
          roles: [record]

```

This pattern appears in the official documentation for handling Reolink-specific HTTP-FLV streams【^3†L78-L95】.

### Apple Compatibility and Audio Copy

Force iOS-compatible HEVC tags and stream-copy audio:

```yaml
cameras:
  garden:
    ffmpeg:
      apple_compatibility: true  # Adds hvc1 tag for H.265 recordings【^1†L80-L84】

      
  garage:
    ffmpeg:
      output_args:
        record: preset-record-generic-audio-copy

```

## How Frigate Builds the FFmpeg Command

When loading a camera definition, Frigate executes the following merge strategy:

1. **Start** with global defaults (`-hide_banner`, `-loglevel warning`, `-threads 2`)
2. **Merge** camera-level `global_args` overrides
3. **Resolve** the hardware acceleration preset via `parse_preset_hardware_acceleration_decode` (or scale/encode variants)
4. **For each input**, expand the input preset using `parse_preset_input` and append role-specific output arguments
5. **Launch** the asynchronous FFmpeg process with the assembled command line

The `retry_interval` parameter (default 10 seconds) governs reconnection attempts for failed streams. GPU selection logic for multi-GPU systems is handled by `LibvaGpuSelector` inside **[`frigate/ffmpeg_presets.py`](https://github.com/blakeblackshear/frigate/blob/main/frigate/ffmpeg_presets.py)**【^2†L23-L70】.

## Summary

- Frigate assembles FFmpeg commands from **global defaults**, **symbolic presets**, and **per-camera overrides** defined in [`frigate/config/camera/ffmpeg.py`](https://github.com/blakeblackshear/frigate/blob/main/frigate/config/camera/ffmpeg.py).
- **Hardware presets** like `preset-vaapi` and `preset-nvidia` automatically configure GPU-accelerated decoding.
- **Input presets** handle protocol specifics, including `preset-rtsp-udp` for UDP-only cameras and `preset-http-reolink` for Reolink HTTP-FLV streams.
- **Output presets** control recording quality and audio handling, with options for AAC re-encoding or direct stream copy.
- Override any layer at the camera level or per-input stream level for fine-grained control without verbose argument lists.

## Frequently Asked Questions

### What preset should I use for Intel Quick Sync hardware acceleration?

Use `preset-vaapi` for Intel integrated graphics. Frigate's `LibvaGpuSelector` logic in [`frigate/ffmpeg_presets.py`](https://github.com/blakeblackshear/frigate/blob/main/frigate/ffmpeg_presets.py) automatically selects the correct render device node (typically `/dev/dri/renderD128`) when multiple GPUs are present【^2†L23-L70】.

### How do I configure FFmpeg for a UDP-only RTSP camera?

Set `input_args: preset-rtsp-udp` in the camera's ffmpeg configuration. This preset explicitly sets `-rtsp_transport udp` instead of the default TCP transport, which resolves connection issues with cameras that do not support TCP interleaved RTP【^2†L84-L124】.

### Can I use different presets for detect and record roles on the same camera?

Yes. Define separate entries in the `inputs` list, each with distinct `input_args` presets and specific roles. For example, use `preset-http-reolink` with the `detect` role for a low-latency sub-stream, and `preset-rtsp-generic` with the `record` role for the high-quality main stream, as shown in the Reolink multi-protocol example.

### Where are the FFmpeg presets defined in the Frigate source code?

All preset mappings reside in **[`frigate/ffmpeg_presets.py`](https://github.com/blakeblackshear/frigate/blob/main/frigate/ffmpeg_presets.py)**, which contains the expansion logic for hardware acceleration, input handling, and output recording. The Pydantic models that validate these configurations are located in **[`frigate/config/camera/ffmpeg.py`](https://github.com/blakeblackshear/frigate/blob/main/frigate/config/camera/ffmpeg.py)**【^1†L19-L73】.