Repository: blakeblackshear/frigate

Issue:
[HW Accel Support]: FPS massively increases with HW accel, resulting in HIGHER CPU
### Describe the problem you are having

Trying HW accel with 0.12 beta 3 on my raspberry pi. It works now! However, there is weirdness...

Before enabling, on the System page my cameras were all showing ~5 FPS and i was using about 3% CPU for each. After enabling HW acceleration via preset-rpi-64-h264 on the "back_door" camera as per below config, that camera now shows ~109 FPS for ffmpeg and "Capture" (whatever that is), and chewing up 29% and 86% of a CPU respectively.

My cameras stream is 30fps far as i can tell, according to VLC anyway. What gives?

Thanks for all your hard work!

### Version

0.12 beta 3

### Frigate config file

```yaml
mqtt:
    host: 192.168.1.2
    port: 1883
    user: frigate
    password: <masked>


detectors:
  coral:
    type: edgetpu
    device: usb


#ffmpeg:
#  hwaccel_args: preset-rpi-64-h264


cameras:

  driveway:
    ffmpeg:
      inputs:
        - path: rtsp://192.168.2.206:80/ch0_0.264
          roles:
            - restream
        - path: rtsp://localhost:8554/driveway
          roles:
            - record
        - path: rtsp://192.168.2.206:80/ch0_1.264
          roles:
            - detect
    zones:
      front_yard:
        coordinates: 533,360,589,263,640,128,640,61,414,38,191,43,0,360
    objects:
      filters:
        person:
          min_area: 2000

  side_gate:
    ffmpeg:
      inputs:
        - path: rtsp://192.168.2.196:80/ch0_0.264
          roles:
            - restream
        - path: rtsp://localhost:8554/side_gate
          roles:
            - record
        - path: rtsp://192.168.2.196:80/ch0_1.264
          roles:
            - detect
    objects:
      filters:
        person:
          max_area: 35000
    zones:
      back_yard:
        coordinates: 83,360,640,360,640,59,496,7,170,100,2,195

  back_door:
    ffmpeg:
      hwaccel_args: preset-rpi-64-h264
      inputs:
        - path: rtsp://192.168.2.129:80/ch0_0.264
          roles:
            - restream
        - path: rtsp://localhost:8554/back_door
          roles:
            - record
        - path: rtsp://192.168.2.129:80/ch0_1.264
          roles:
            - detect
    zones:
      back_yard:
        coordinates: 523,0,616,61,493,284,460,276,415,325,427,360,90,360,0,294,0,0
    objects:
      filters:
        person:
          min_area: 20000
          max_area: 100000
          mask:
            - 407,92,424,37,477,21,521,45,513,112,497,145,467,221,421,211,403,247,355,235,376,163,369,152
        cat:
          max_area: 20000


#motion:
#  improve_contrast: True


detect:
  width: 640
  height: 360
  fps: 5


objects:
  track:
    - person
    - cat


record:
  enabled: True
  events:
    required_zones:
      - front_yard
      - back_yard


snapshots:
  enabled: True
  required_zones:
    - front_yard
    - back_yard


#live:
#  height: 360

  
birdseye:
  width: 640
  height: 360
```


### docker-compose file or Docker CLI command

```yaml
HA addon
```


### Relevant log output

```shell
not sure anything is relevant
```


### FFprobe output from your camera

```shell
"[\n  {\n    \"return_code\": 1,\n    \"stderr\": {},\n    \"stdout\": {}\n  },\n  {\n    \"return_code\": 1,\n    \"stderr\": {},\n    \"stdout\": {}\n  },\n  {\n    \"return_code\": 1,\n    \"stderr\": {},\n    \"stdout\": {}\n  }\n]"
```


### Operating system

HassOS

### Install method

HassOS Addon

### Network connection

Wired

### Camera make and model

unknown / generic

### Any other information that may be helpful

Issue may have existed before 0.12 beta 3 but i didn't have working HWaccel until now.


Discussion:

Resolving patch:
diff --git a/frigate/ffmpeg_presets.py b/frigate/ffmpeg_presets.py
--- a/frigate/ffmpeg_presets.py
+++ b/frigate/ffmpeg_presets.py
@@ -80,44 +80,14 @@
 }
 
 PRESETS_HW_ACCEL_SCALE = {
-    "preset-rpi-32-h264": ["-f", "rawvideo", "-pix_fmt", "yuv420p"],
-    "preset-rpi-64-h264": ["-f", "rawvideo", "-pix_fmt", "yuv420p"],
-    "preset-vaapi": [
-        "-vf",
-        "fps={},scale_vaapi=w={}:h={},hwdownload,format=yuv420p",
-        "-f",
-        "rawvideo",
-    ],
-    "preset-intel-qsv-h264": [
-        "-vf",
-        "vpp_qsv=framerate={},scale_qsv=w={}:h={}:format=nv12,hwdownload,format=nv12,format=yuv420p",
-        "-f",
-        "rawvideo",
-    ],
-    "preset-intel-qsv-h265": [
-        "-vf",
-        "vpp_qsv=framerate={},scale_qsv=w={}:h={}:format=nv12,hwdownload,format=nv12,format=yuv420p",
-        "-f",
-        "rawvideo",
-    ],
-    "preset-nvidia-h264": [
-        "-vf",
-        "fps={},scale_cuda=w={}:h={}:format=nv12,hwdownload,format=nv12,format=yuv420p",
-        "-f",
-        "rawvideo",
-    ],
-    "preset-nvidia-h265": [
-        "-vf",
-        "fps={},scale_cuda=w={}:h={}:format=nv12,hwdownload,format=nv12,format=yuv420p",
-        "-f",
-        "rawvideo",
-    ],
-    "default": [
-        "-r",
-        "{}",
-        "-s",
-        "{}",
-    ],
+    "preset-rpi-32-h264": "-r {} -s {}x{} -f rawvideo -pix_fmt yuv420p",
+    "preset-rpi-64-h264": "-r {} -s {}x{} -f rawvideo -pix_fmt yuv420p",
+    "preset-vaapi": "-vf fps={},scale_vaapi=w={}:h={},hwdownload,format=yuv420p -f rawvideo",
+    "preset-intel-qsv-h264": "-r {} -vf vpp_qsv=w={}:h={}:format=nv12,hwdownload,format=nv12,format=yuv420p -f rawvideo",
+    "preset-intel-qsv-h265": "-r {} -vf vpp_qsv=w={}:h={}:format=nv12,hwdownload,format=nv12,format=yuv420p -f rawvideo",
+    "preset-nvidia-h264": "-vf fps={},scale_cuda=w={}:h={}:format=nv12,hwdownload,format=nv12,format=yuv420p -f rawvideo",
+    "preset-nvidia-h265": "-vf fps={},scale_cuda=w={}:h={}:format=nv12,hwdownload,format=nv12,format=yuv420p -f rawvideo",
+    "default": "-r {} -s {}x{}",
 }
 
 PRESETS_HW_ACCEL_ENCODE = {
@@ -159,15 +129,18 @@ def parse_preset_hardware_acceleration_scale(
 ) -> list[str]:
     """Return the correct scaling preset or default preset if none is set."""
     if not isinstance(arg, str) or " " in arg:
-        scale = PRESETS_HW_ACCEL_SCALE["default"].copy()
-        scale[1] = str(fps)
-        scale[3] = f"{width}x{height}"
+        scale = PRESETS_HW_ACCEL_SCALE["default"].format(fps, width, height).split(" ")
         scale.extend(detect_args)
         return scale
 
-    scale = PRESETS_HW_ACCEL_SCALE.get(arg, PRESETS_HW_ACCEL_SCALE["default"]).copy()
-    scale[1] = scale[1].format(fps, width, height)
-    return scale
+    scale = PRESETS_HW_ACCEL_SCALE.get(arg, "")
+
+    if scale:
+        return scale.format(fps, width, height).split(" ")
+    else:
+        scale = scale.format(fps, width, height).split(" ")
+        scale.extend(detect_args)
+        return scale
 
 
 def parse_preset_hardware_acceleration_encode(arg: Any, input: str, output: str) -> str:


Test patch: