FFMPEG 4.0 überspringt Frames

Ich habe heute bemerkt, dass, wenn ich ffmpeg 4.0 stable verwende, um einige TS-Dateien in y4m oder ffv1 zu decodieren, es gelegentlich einige Frames überspringt. Meine Eingabedatei hat alle Frames in das Bild eingebrannt und ich extrahiere in regelmäßigen Abständen einige Frames. Manchmal funktioniert es ganz gut ohne übersprungene Frames, aber manchmal überspringt es ein oder zwei Frames. Ich verwende den folgenden Befehl, um meine Eingabe zu dekodieren:

ffmpeg -i input.ts -vsync 0 output.y4m

und ich extrahiere die Frames mit:

ffmpeg -ss xxx -i output.y4m -vframes 1 xxx.png

Ich ersetze xxx durch 0, 100, 200 usw. und manchmal sehe ich, dass 1-2-3 Frames ausgelassen werden, was sehr ärgerlich ist, da ich versuche, den PSNR danach auszuwerten, und dies die gesamte PSNR/SSIM-Auswertung durcheinander bringt.

[BEARBEITEN] Ich habe den Befehl ausgeführt, den @Gyan vorgeschlagen hat:

ffmpeg -v 99 -loglevel 99 -i test.ts \
-c:v rawvideo -vsync 0 \
-enc_time_base 1/1000 output.nut &> test.log

Und hier ist die Protokolldatei test.log

Antworten (1)

Y4M hat keine Zeitstempel, nur Framerate in seinem Header. Wenn Ihre Quelle also Schwankungen in der Framerate aufweist, sehen Sie eine Verschiebung des scheinbaren Zeitstempels in den Y4M.

z.B

n     src     y4m
0       0       0
1    0.04    0.04 
2    0.07    0.08
3    0.12    0.12
4    0.21    0.16
5    0.24    0.20
6    0.27    0.24 
...

Über einen langen Zeitraum können sich diese Störungen summieren. Hier ist Frame #6 in src bei TS von src #5 in Y4M.

Bearbeiten : Die Beispiel-TS-Datei enthält VFR-Zeitstempel.

Verwenden -c:v rawvideo -vsync 0 -vf setpts=N/FRAME_RATE/TB -anund speichern Sie unter .nut.

Ich habe Ihre Lösung getestet und ausgeführt ffmpeg -i input.ts -c:v rawvideo -vsync 0 -enc_time_base 1/1000 output.nut, aber leider verliere ich alle ~ 1000 Frames einen Frame, und dies ist ein ziemlich konstanter Verlust. Ich habe versucht, hinzuzufügen -an, zu entfernen, -enc-time-baseaber es wird immer ein Bild alle ~ 1000 Bilder gelöscht. Tatsächlich funktioniert ffmpeg 3.2.4 in dieser Hinsicht besser und lässt bei derselben Eingabe keine Frames fallen.
Teilen Sie das vollständige Protokoll Ihres Befehls.
Ich habe die Datei test.log über einen Link von wetransfer hochgeladen. Es ist ziemlich sperrig: 19 MB und meine ursprüngliche Videosequenz hat ~ 37000 Frames. Der Link und der Befehl waren in meinem ursprünglichen Beitrag im Abschnitt BEARBEITEN zu sehen.
Kannst du die Quelldatei teilen?
Sie können es hier herunterladen @Gyan
Kannst du es woanders hochladen? Wetransfer ist sehr langsam. Laufwerk oder Dropbox usw
Kann nicht reproduzieren. Ich lief ffmpeg -i input.ts -vsync 0 output.y4mund dann ffmpeg -ss xxx -i output.y4m -vframes 1 xxx.pngund ffmpeg -ss xxx -i input.ts -vframes 1 xxx-ts.pngzu vergleichen. Ich bekomme den gleichen Rahmen für 5-6 Werte, die ich versucht habe. Können Sie ein paar ssWerte identifizieren, die das Problem zeigen?
Wenn Sie verwenden: ffmpeg -i test.ts -c:v rawvideo -vsync 0 -enc_time_base 1/1000 output.nutIch erhalte ungefähr einen Frame-Drop alle 1000 Frames. Sie können versuchen, die Frames alle 3000 Frames (60 Sek.) zu extrahieren. Ich glaube, die Gesamtdauer beträgt 5 Minuten, also können Sie -ss 0 - verwenden, um den ersten Frame in der Sequenz zu erhalten, und dann -ss 60, -ss 120, -ss 180, -ss 240, -ss 300. Mit ffmpeg -i input.ts -vsync 0 output.y4mI bekomme mehr zufällige Tropfen, manchmal ist es nur ein Frame für die gesamte Dauer, manchmal mehr. Bitte beachten Sie, dass die Datei tatsächlich eine Schleife durchläuft und ein Frame übersprungen wird: 14998.
Sie können dies leicht bestätigen, indem Sie die eingebrannte Framenummer der extrahierten Frames vergleichen, und Sie sollten genau 3000 Frames Unterschied zwischen den exportierten Frames haben, falls Sie -ss 0, -ss 60 usw. verwenden.
Siehe bearbeitetes cmd.
Danke @Gyan, ich werde den aktualisierten Befehl später überprüfen, aber die variable Bildrate erklärt nicht, warum der ffmpeg -i input.ts -vsync 0 output.y4mBefehl manchmal ein oder zwei Bilder übersprungen hat oder manchmal einwandfrei funktionierte. Wie haben Sie die Datei auch auf VFR und CFR überprüft? Gibt es einen Befehl in ffprobe, um danach zu suchen?
Kürzlich wurde ein Filter hinzugefügt: vfrdet . Für das Beispiel zeigt es VFR:0.400005 (15185/22777) min: 1801 max: 3604). 40 % der Frames haben eine vom Standard abweichende Dauer. Alle sollten 1800 Einheiten in dieser Datei haben.
Du hast absolut recht, @Gyan, ich habe deinen Befehl ausprobiert und er funktioniert sehr gut, ich habe auch den detvfrFilter ausprobiert und er hat mir die Abweichung angezeigt. Ich frage mich, warum die TS-Datei VFR hat, da ich sie mit ffmpeg aufgenommen habe und ich mir ziemlich sicher bin, dass die Eingabe CFR hat. Muss ich -rein diesem Fall den Aufnahmebefehl verwenden, um die eingegebene Bildrate (Dauer) beizubehalten? Können Sie auch einen Aufnahmebefehl vorschlagen, der das Auffüllen mit Nullen (Stuffing) nicht aus dem TS schneidet?
TS ist ein VFR-Container, also müssen Sie in der Ausgabe hinzufügen -vsync cfrund auch -r, ob dieser Wert sich von den nominellen Eingabe-fps unterscheidet.
und was ist mit der Beibehaltung der Nullauffüllung am Ausgang? Standardmäßig löscht ffmpeg alle Null-PIDs, die PCR-Fehler im aufgezeichneten Stream verursachen. Ist es möglich, sie beizubehalten?
Meinst du beim Erstellen des TS oder beim Übertragen auf NUT?
Wann mache ich die TS-Aufnahme? Gibt es eine Möglichkeit, ffmpeg anzuweisen, die Nullauffüllung nicht zu kürzen?
Hast du -muxrate hinzugefügt?
Angenommen, ich mache eine TS-Aufzeichnung aus dem Internet, muss ich zuerst nach der MUX-Rate suchen und sie dann im Aufzeichnungsbefehl konfigurieren? Und wenn ja, wie kann ich die Mux-Rate mit ffmpeg prüfen? Und was ist, wenn der Eingabestrom nicht CBR, sondern VBR mit variabler Bitrate ist, aber immer noch etwas Null-Pad-Füllung?