FFmpeg. CUDA-Decodierung. Vergangene Dauer zu groß. Variable FPS

Bitte sehen Sie sich meine Eingabe-UDP-Stream-Informationen an:

ffprobe udp://IP:PORT

Input #0, mpegts, from 'udp://IP:PORT':
  Duration: N/A, start: 42243.737022, bitrate: N/A
  Program 17
  . . .
    Stream #0:0[0x781]: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p(tv, bt470bg, top first), 720x576 [SAR 12:11 DAR 15:11], 24.67 fps, 25 tbr, 90k tbn, 50 tbc
    Stream #0:1[0x782](Tam): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, mono, s16p, 64 kb/s
    Stream #0:2[0x783](Kan): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, mono, s16p, 64 kb/s

Und führen Sie diesen Befehl erneut aus:

ffprobe udp://IP:PORT

Input #0, mpegts, from 'IP:PORT':
  Duration: N/A, start: 42589.601022, bitrate: N/A
  . . . 
  Program 17
    Stream #0:0[0x781]: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p(tv, bt470bg, top first), 720x576 [SAR 12:11 DAR 15:11], 24.58 fps, 25 tbr, 90k tbn, 50 tbc
    Stream #0:1[0x782](Tam): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, mono, s16p, 64 kb/s
    Stream #0:2[0x783](Kan): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, mono, s16p, 64 kb/s

Bitte achten Sie auf den FPS-Wert. In der ersten Ausführung 24.67 und in der zweiten 24.58

Ich möchte diesen Stream mit dem folgenden Befehl transcodieren:

ffmpeg -y -hwaccel cuvid -c:v h264_cuvid -deint 2 -i "udp://IP:PORT" -map 0:#0x0781 -map 0:#0x0782 -vcodec h264_nvenc -acodec libfdk_aac -f flv rtmp:// IP/Test/Name

Bitte sehen Sie sich das Protokoll an:

Past duration 0.981102 too large
frame=83 fps=0.0 q=18.0 size=502kB time=00:00:04.05 bitrate=1015.4kbits/s dup=0 drop=80 speed=7.42x  
frame=96 fps=90 q=18.0 size=643kB time=00:00:04.69 bitrate=1122.1kbits/s dup=0 drop=93 speed=4.38x  
frame=111 fps=70 q=18.0 size=802kB time=00:00:05.14 bitrate=1278.1kbits/s dup=0 drop=108 speed=3.26x 
frame=121 fps=57 q=19.0 size=921kB time=00:00:05.61 bitrate=1344.7kbits/s dup=0 drop=118 speed=2.64x 
frame=137 fps=49 q=19.0 size=1096kB time=00:00:06.25 bitrate=1436.4kbits/s dup=0 drop=134 speed=2.26x

Ich kann auch den Framerate-Parameter "-r" hinzufügen. Wie folgt:

ffmpeg -y -hwaccel cuvid -c:v h264_cuvid -deint 2 -r 25 -i "udp://IP:PORT" -map 0:#0x0781 -map 0:#0x0782 -vcodec h264_nvenc -r 25 -acodec libfdk_aac - fflv rtmp://IP/test/name

In diesem Fall wird diese Warnung nicht angezeigt. Aber der Transcoding-FFmpeg-Prozess schlug nach 10-15 Sekunden fehl, ohne Fehler im Protokoll.

Alles funktioniert gut, wenn ich es über Software-Decodierung mache:

ffmpeg -y -i "udp://IP:PORT" -map 0:#0x0781 -map 0:#0x0782 -vcodec h264_nvenc -acodec libfdk_aac -f flv rtmp://IP/test/name

Auch funktioniert alles einwandfrei, wenn ich es in die lokale Datei transcodiere und die Framerate festlege:

ffmpeg -y -hwaccel cuvid -c:v h264_cuvid -deint 2 -r 25 -i "udp://IP:PORT" -map 0:#0x0781 -map 0:#0x0782 -vcodec h264_nvenc -r 25 -acodec libfdk_aac - f flv result.flv

Dieses Problem betrifft nur einige Eingabestreams.
Wie kann ich diesen UDP-Stream mit CUDA-Decodierung in einen FLV-Stream transcodieren?

Antworten (1)

Der Schlüssel -drop_second_field 1 hat dieses Problem behoben.
Und der Ergebnisbefehl sieht wie folgt aus:

ffmpeg -y -hwaccel cuvid -c:v h264_cuvid -deint 2 -drop_second_field 1 -i "udp://IP:PORT"
-vcodec h264_nvenc -acodec libfdk_aac -f flv rtmp://IP/test/name


Was ich zu diesem Problem denke: Im Moment können wir in der cuda-Decodierung nur 2 Deinterlace-Varianten verwenden:

  • -deint 1 es ist bob deinterlacing,
  • -deint 2 ist adaptives Deinterlacing.

Beide Varianten erhöhen die Bitrate, da nach dem Deinterlacing jedes Feld (die Hälfte des Frames), das als Frame angezeigt wird (Framerate wird verdoppelt), die Bitrate wächst und wenn fps variabel ist, haben wir Zeitstempelprobleme. Und wenn wir Drop Second Field aktivieren, sieht alles mit Bitrate und Zeitstempeln gut aus.