AlexxIT / go2rtc

Ultimate camera streaming application with support RTSP, RTMP, HTTP-FLV, WebRTC, MSE, HLS, MP4, MJPEG, HomeKit, FFmpeg, etc.
https://github.com/AlexxIT/Blog
MIT License
4.22k stars 344 forks source link

How to disable P1 P2 profil from nvenc encoding for old nvidia drivers ? #1146

Closed kevincaradant closed 3 months ago

kevincaradant commented 3 months ago

Hi

I'm currently using a old graphics cards with Ubuntu 22.04. I'm under Nvidia Graphics Driver : 390.157 using nv-codecs-headers 8.1.4.15 and cuda 9.1.85 ( the maximum that I can do for Nvidia GT 650M ) I builded using version gcc 6.4 my own ffmpeg version. I'm under FFMPEG 5 which is the minimal required by Go2RTC.

Everything seems works using manually the command line.

However under go2RTC I got the following issues

[h264_nvenc @ 0x63d2bb16d640] [Eval @ 0x7fff7e7ac290] Undefined constant or missing '(' in 'p2' => the main issue
[h264_nvenc @ 0x63d2bb16d640] Unable to parse option value "p2"
[h264_nvenc @ 0x63d2bb16d640] Error setting option preset to value p2.
Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height

I searched what was this P2 preset. It's seems to be a preset available from Nvidia only for cuda 10 and later. However, mine is too old and it's only the parameter p2 which crash everything. If I remove this parameter, it works.

sqdqdqdsq

Is it possible for you @AlexxIT to add an option to disable this optional parameter ?.

For the moment, I don't know how to run it manually into config file go2Rtc.yaml without this parameter.

Example not working:

ffmpeg -hide_banner -hwaccel_output_format cuda -fflags nobuffer -flags low_delay -rtsp_flags prefer_tcp -i rtsp://admin:xxxxxxxx@192.168.1.21/Preview_01_main -vf "hwupload_cuda" -c:v h264_nvenc -g 50 -bf 0 -profile:v high -level:v auto -preset:v p2 -tune:v ll -an -c:a copy test.mp4

Example working:

ffmpeg -hide_banner -hwaccel_output_format cuda -fflags nobuffer -flags low_delay -rtsp_flags prefer_tcp -i rtsp://admin:xxxxxxxxxxx@192.168.1.21/Preview_01_main -vf "hwupload_cuda" -c:v h264_nvenc -g 50 -bf 0 -profile:v high -level:v auto -tune:v ll -an -c:a copy test.mp4

However how to use the corect one into go2rtc file ?

I'm trying this one where I got the same issue running from browser: image

streams:
ffmpeg_rtsp_camera_jardin_main: ffmpeg:rtsp://admin:xxxxx@192.168.1.21/Preview_01_main#video=h264#width=1280#height=720#hardware=cuda

Thank you

AlexxIT commented 3 months ago

You can rewrite exact this preset in your go2rtc config. It will work only for your setup

kevincaradant commented 3 months ago

Thank you for your quick reply ! :) @AlexxIT

To be honest, I'm not very familiar with FFmpeg commands ( I got mine from forums and reading what's you wrote into the file in the initial thread but I don't understand all these parameters ) . It may seem simple to you, but I'm unsure how to write the command correctly to achieve what I described earlier. Specifically, I don't know how to write it without encountering issues in go2RTC. For instance, I removed test.mp4 at the end of the command, but I'm still having trouble.

Could you please provide guidance on how to correctly format the command for my use case?

Thank you

I tried an other things using your ffmpeg.test.go and ffmpeg.go files into your library

streams:
  ffmpeg_rtsp_camera_jardin_main:
    exec: ffmpeg -hide_banner -hwaccel_output_format cuda -fflags nobuffer -flags low_delay -rtsp_flags prefer_tcp -i rtsp://admin:XXXXX@192.168.121/Preview_01_main -vf "hwupload_cuda" -c:v h264_nvenc -g 50 -bf 0 -profile:v high -level:v auto -tune:v ll -an -c:a copy  -user_agent ffmpeg/go2rtc -rtsp_transport tcp -f rtsp {{output}}

But I got

22:32:19.894 INF [rtsp] listen addr=:8554
22:32:19.894 INF [api] listen addr=:1984
22:32:19.896 INF [webrtc] listen addr=:8555
22:32:24.477 WRN github.com/AlexxIT/go2rtc/internal/rtsp/rtsp.go:225 > error="parse \"{rtsp://127.0.0.1:8554/ff345a83c72650141178b8d3a52f646c}\": first path segment in URL cannot contain colon"

sqdsqdqsdqs

If I replace -rtsp_transport tcp -f rtsp {{output}} into command line by toto.mkv I got this: image

It works in this case

I think I'm close but it's still not working into go2RTC :(

skrashevich commented 3 months ago

Add the following to the root level of your configuration:

ffmpeg:
  "h264/cuda": "-c:v h264_nvenc -g 50 -bf 0 -profile:v high -level:v auto -tune:v ll"

And revert any changes described in your previous message. :)

AlexxIT commented 3 months ago

@skrashevich nvenc

skrashevich commented 3 months ago

@skrashevich nvenc

thx. I have no idea where 'nvint' came from

kevincaradant commented 3 months ago

@AlexxIT @skrashevich

Thank you for your help, In the mean time, I finished to apply setting of better stream for my usecase with my cameras.

Locally using my ffmpeg and my own stream broadcasted with mediamtx library. I have 3 streams in High quality which are running without any issues

My command line is :

ffmpeg -hide_banner -hwaccel_output_format cuda -fflags nobuffer -flags low_delay -rtsp_flags prefer_tcp -i rtsp://admin:xxxxxx@192.168.1.222/Preview_01_main -vf "hwupload_cuda,scale_npp=w=1920:h=1080" -c:v h264_nvenc -g 50 -bf 0 -profile:v high -level:v auto -b:v 3M -r 20 -tune:v ll -an -c:a copy -user_agent ffmpeg/go2rtc -rtsp_transport tcp -f rtsp rtsp://127.0.0.1:8554/camera_arriere

So I applied as you mentioned @skrashevich ( sorry I think @AlexxIT try to said the same thing but I didn't understand the first time ;) )

Go2RTC.yaml

 webrtc:
  listen: ":8555" # external TCP/UDP port

ffmpeg:
  "h264/cuda": "-vf 'hwupload_cuda,scale_npp=w=1920:h=1080' -c:v h264_nvenc -g 50 -bf 0 -profile:v high -level:v auto -b:v 3M -r 20 -tune:v ll -an -c:a copy"

streams:
  ffmpeg_rtsp_camera_jardin_main: ffmpeg:rtsp://admin:xxxxxxx@192.168.1.11/Preview_01_main
  ffmpeg_rtsp_camera_devant_main: ffmpeg:rtsp://admin:xxxxxxxxxx@192.168.1.222/Preview_01_main
  ffmpeg_rtsp_camera_arriere_main: ffmpeg:rtsp://admin:xxxxxxxxx@192.168.1.122/Preview_01_main

Is it correct for you ?

I got an issue. From Chrome or Opera I have only black stream when I load them as you can see on the picture:

Capture d’écran de 2024-05-30 16-12-56

(NB: It's also black into Home Assistant)

Then I'm wondering about cuda with Docker. It seems to be broken when I try to mount an old GPU ( Nvidia GT 650 M) Due to docker issue on start, I commented all the lines about GPU mount:

  go2rtc:
    container_name: go2rtc
    image: alexxit/go2rtc
    network_mode: host       # important for WebRTC, HomeKit, UDP cameras
    privileged: true         # only for FFmpeg hardware transcoding
    restart: unless-stopped  # autorestart on fail or config change from WebUI
    volumes:
      - "/home/xxxx/Documents/go2rtc:/config"   # folder for go2rtc.yaml file (edit from WebUI)
    environment:
      - TZ=Europe/Paris
    # devices:
    #   - /dev/dri/renderD128:/dev/dri/renderD128
    #   - /dev/nvidia-caps:/dev/nvidia-caps
    #   - /dev/nvidia0:/dev/nvidia0
    #   - /dev/nvidiactl:/dev/nvidiactl
    #   - /dev/nvidia-modeset:/dev/nvidia-modeset
    #   - /dev/nvidia-uvm:/dev/nvidia-uvm
    #   - /dev/nvidia-uvm-tools:/dev/nvidia-uvm-tools
    # deploy:  
    #   resources:
    #     reservations:
    #       devices:
    #         - driver: nvidia
    #           device_ids: ['0'] # this is only needed when using multiple GPUs
    #           count: 1 # number of GPUs
    #           capabilities: [gpu]

Locally I can see the cuda / nvenc encode / decode is used running myself the FFMPEG command and load it into VLC.

But from Go2RTC ( binary and docker ) is it my FFMPEG own library builded my self which is used or yours from the docker container or binary ?

After to run go2RTC, I tried to open it from VLC using: rtsp://192.168.1.122:8554/ffmpeg_rtsp_camera_arriere_main

It's sluttering a little bit in VLC ( I can see some freeze every seconds, quickly ) but I don't know how to check what is used as codec on go2rtc using docker or even the binary. It's more fluent when I execute my self directly the ffmpeg command line into console but if it works enought with go2RTC, it's good for me

Sorry if I ask a lot of questions, I like to understand what I'm doing and there are some question mark about it :)

skrashevich commented 3 months ago
  1. Read README again. And again.
  2. add '#video=h264/cuda' to each stream
  3. Uncomment "deploy" section in compose file
kevincaradant commented 3 months ago

My apologies, after to try soooooo many things I removed #video=h264 that I always used before. I think I got black stream because it was maybe H265 which was provided by default. Anyway it doesn't matter.

However #video=h264 give me many issues ( got image every 5s or 10s only :(. It was pretty unstable.

I read that you mentioned to read the readme again and again but I really read it so many times, I saw many things but sometimes I'm a little bit lost on every solution that I read or change every time that I want to try something ... and can change depending the version like ffmpeg settings. Sorry if I miss something logical for you.

So

When you said 1) Read the readme: => should I saw something about h264_nvenc with your mention about readme ? About Docker it doesn't work.

2) I never saw before about '#video=h264/cuda', I though it was #video=h264 and #hardware=cuda to put on the config Yours settings suggested ('#video=h264/cuda) works as expected with the binary running on Linux Os .

3) Unfortunatly I don't have codec inside Docker container.

With :

  go2rtc:
    container_name: go2rtc
    image: alexxit/go2rtc
    network_mode: host       # important for WebRTC, HomeKit, UDP cameras
    privileged: true         # only for FFmpeg hardware transcoding
    restart: unless-stopped  # autorestart on fail or config change from WebUI
    volumes:
      - "/home/xxxxx/Documents/go2rtc:/config"   # folder for go2rtc.yaml file (edit from WebUI)
    environment:
      - TZ=Europe/Paris
    devices:
      - /dev/dri/renderD128:/dev/dri/renderD128
      - /dev/nvidia-caps:/dev/nvidia-caps
      - /dev/nvidia0:/dev/nvidia0
      - /dev/nvidiactl:/dev/nvidiactl
      - /dev/nvidia-modeset:/dev/nvidia-modeset
      - /dev/nvidia-uvm:/dev/nvidia-uvm
      - /dev/nvidia-uvm-tools:/dev/nvidia-uvm-tools
    deploy:    # <------------- Add this section
      resources:
        reservations:
          devices:
            - driver: nvidia
              device_ids: ['0'] # this is only needed when using multiple GPUs
              count: 1 # number of GPUs
              capabilities: [gpu]

The container runs but I got an issue about codec h264_nvenc not found ?

Capture d’écran de 2024-05-30 17-46-30

I already read links you give in the readme, I read Jellyfin config and frigate config. That why I try the previous setup but maybe I miss again something else

Thank you

skrashevich commented 3 months ago

wrong image: use 'alexxit/go2rtc:latest-hardware' for nvidia hardware acceleration

kevincaradant commented 3 months ago

@skrashevich Thank you for pointing that out. I think I would have encountered the issue later on, but in fact, my initial problem still remains.

I apologize, I had just started and stopped the container. I should have done a down/up cycle when changing the docker-compose configuration. So my previous issue / message was not use uncommented configuration of Nvidia ... The commented configuration was still there.

Indeed, I am getting the following error Capture d’écran de 2024-05-30 18-26-04

Even using the good image :

 go2rtc:
    container_name: go2rtc
    image: alexxit/go2rtc:latest-hardware

and I don't know how to handle it... I'm not even sure it's possible.

I got this error since the begining as soon as I use the docker GPU Nvidia in the docker-compose.yaml file

@skrashevich 1 last question 1) Is the FFmpeg build on my server being used by go2RTC, or does go2RTC (in its binaries and Docker versions) come with an embedded version of FFmpeg? Alternatively, is there an option to use the embedded version if available?

Thank you.

Note: I read a suggestion to use a different NVIDIA driver, but in my case, I'm already using the latest available version. Perhaps you have encountered this error before in your experience with Docker?

Note 2: If you're not sure, that's okay. I will continue searching on my own, and in the worst case, I'll still have the fully functional binary version. Thank you for your time and help. ;)

skrashevich commented 3 months ago

go2rtc uses ffmpeg, which is available in its environment. Thus, when launched in a container, the FFmpeg from the container is used, and when launched without a container, the system FFmpeg (from $PATH) is used.

kevincaradant commented 3 months ago

Thank you ;).

Indeed, I realized my mistake. I just ran my container and noticed that we are on version 6 with the latest image. Thank you for confirming about the binary file hosted on the server that uses my compiled version of FFmpeg.

I discovered the issue related to NVIDIA capabilities. After updating the nvidia-container-toolkit, I am now able to start the container and verify my GPU by executing the nvidia-smi command within the container.

This is my config

  go2rtc:
    container_name: go2rtc
    image: alexxit/go2rtc:1.8.5-hardware
    network_mode: host       # important for WebRTC, HomeKit, UDP cameras
    privileged: true         # only for FFmpeg hardware transcoding
    restart: unless-stopped  # autorestart on fail or config change from WebUI
    volumes:
      - "/home/xxxxx/Documents/xxxxxx/go2rtc:/config"   # folder for go2rtc.yaml file (edit from WebUI)
    environment:
      - TZ=Europe/Paris
    devices:
      - /dev/dri/renderD128:/dev/dri/renderD128
      - /dev/nvidia-caps:/dev/nvidia-caps
      - /dev/nvidia0:/dev/nvidia0
      - /dev/nvidiactl:/dev/nvidiactl
      - /dev/nvidia-modeset:/dev/nvidia-modeset
      - /dev/nvidia-uvm:/dev/nvidia-uvm
      - /dev/nvidia-uvm-tools:/dev/nvidia-uvm-tools
    deploy:    # <------------- Add this section
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1 # number of GPUs
              capabilities: [gpu]

And this:

webrtc:
  listen: ":8555" # external TCP/UDP port

ffmpeg:
  "h264/cuda": "-vf 'hwupload_cuda' -c:v h264_nvenc -g 50 -bf 0 -profile:v high"

streams:
  ffmpeg_rtsp_camera_jardin_main: ffmpeg:rtsp://admin:xxxxx@192.168.1.13/Preview_01_main#video=h264/cuda
  ffmpeg_rtsp_camera_devant_main: ffmpeg:rtsp://admin:xxxxx@192.168.1.212/Preview_01_main#video=h264/cuda
  ffmpeg_rtsp_camera_arriere_main: ffmpeg:rtsp://admin:xxxxxx@192.168.1.150/Preview_01_main#video=h264/cuda

If I use latest-hardware image. That does not work because of the API nvenc V12 expected vs V8 found

image

I think the issue is related to the build of FFmpeg, which uses NV header codecs from version 8. So, I need to use the latest compatible version. In my case, I can build FFmpeg up to version 6.0.1 (versions 6.1 and later fail to build) with NV header codecs V8.1.

I noticed that you don't have a release with version 6.0.1, only from 5.4 to 6.1. Therefore, I decided to try version 1.8.5 of go2rtc, which is the latest available version using FFmpeg V5.4, hoping that it supports NV header codecs up to V8.1.

It's a bit complicated, but I hope what I said makes sense to you. I'm trying to stay consistent with all

I tried version Go2RTC 1.8.5, but now I'm encountering MSE stream failures.

I checked in debug mode and found the following issue:

go2rtc              | [h264_nvenc @ 0x56506a256c40] Driver does not support the required nvenc API version. Required: 11.1 Found: 8.1
go2rtc              | [h264_nvenc @ 0x56506a256c40] The minimum required Nvidia driver for nvenc is 470.57.02 or newer

I'm sad because header are later than V8.1

should I understand that I can't get it working with Docker because of FFmpeg? Is there any way to have FFmpeg 6 with NV codec header 8.1 to be compatible with NVIDIA driver version 390, or is it not possible.

That would imply that I should continue solely with the binary, I suppose.

skrashevich commented 3 months ago

You can download needed statically-compiled version of ffmpeg (I suggest btbn-ffmpeg build), mount it's folder to container and set path to this ffmpeg binary in config:

ffmpeg:
  bin: /opt/ffmpeg/bin/ffmpeg

(provided path is just example)

kevincaradant commented 3 months ago

OK, thank you for the very clear additional information. I will take a look at it then :) By the way, I am closing the issue that has been resolved regarding the initial P1 and P2 error.