Warum gibt ffmpeg ein 600-fps-Video von einem 120-fps-Videoeingang aus?

Ich habe ein sehr kurzes 120fps-Video .

ffprobe input.mp4zeigt 118.99fps:

ffprobe version 3.0 Copyright (c) 2007-2016 the FFmpeg developers
  built with Apple LLVM version 7.3.0 (clang-703.0.29)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/3.0 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-opencl --enable-libx264 --enable-libmp3lame --enable-libxvid --enable-ffplay --enable-vda
  libavutil      55. 17.103 / 55. 17.103
  libavcodec     57. 24.102 / 57. 24.102
  libavformat    57. 25.100 / 57. 25.100
  libavdevice    57.  0.101 / 57.  0.101
  libavfilter     6. 31.100 /  6. 31.100
  libavresample   3.  0.  0 /  3.  0.  0
  libswscale      4.  0.100 /  4.  0.100
  libswresample   2.  0.101 /  2.  0.101
  libpostproc    54.  0.100 / 54.  0.100
[h264 @ 0x7f8262009600] Increasing reorder buffer to 1
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 1
    compatible_brands: mp41mp42isom
    creation_time   : 2016-04-27 10:43:14
  Duration: 00:00:02.76, start: 0.000000, bitrate: 10318 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 720x1280, 10272 kb/s, 118.99 fps, 600 tbr, 600 tbn, 1200 tbc (default)
    Metadata:
      creation_time   : 2016-04-27 10:43:14
      handler_name    : Core Media Video

Ich führe einen quadratischen Zuschneide- und Größenänderungsvorgang aus:

ffmpeg -i input.mp4 -vf "crop='if(gte(iw,ih),ih,iw):if(gte(ih,iw),iw,ih)', scale=640x640" -an -c:v libx264 -profile:v high -level 4.1 -preset veryslow -crf 20 output.mp4

Das gibt:

....
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 1
    compatible_brands: mp41mp42isom
    creation_time   : 2016-04-27 10:43:14
  Duration: 00:00:02.76, start: 0.000000, bitrate: 10318 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 720x1280, 10272 kb/s, 118.99 fps, 600 tbr, 600 tbn, 1200 tbc (default)
....
Output #0, mp4, to 'output.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 1
    compatible_brands: mp41mp42isom
    encoder         : Lavf57.25.100
    Stream #0:0(und): Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p, 640x640, q=-1--1, 600 fps, 19200 tbn, 600 tbc (default)
....

Und tatsächlich, ffprobe output.mp4bestätigt, dass output.mp4dies bei 600 fps liegt, ebenso wie VLC.

Wie kann ich sicherstellen, dass ffmpeg mein Video mit derselben Framerate wie die Eingabe codiert (sei es 30, 60, 120 oder 240 fps)?

Antworten (1)

Update : Die PTS-Einträge der Ein- und Ausgabe für den folgenden Befehl sind in Version N-79630-g9ac154d identisch. Sieht so aus, als wäre die Datei fälschlicherweise als VFR gekennzeichnet. Aber dieser einstufige Befehl unten funktioniert für das Beispielvideo.

Verwenden

ffmpeg -i input.mp4 -vf "crop='if(gte(iw,ih),ih,iw):if(gte(ih,iw),iw,ih)', scale=640x640" \
   -an -c:v libx264 -profile:v high -level 4.1 -preset veryslow -crf 20 -vsync 0 output.mp4

Die im Container ( tbr) gespeicherte Framerate beträgt 600, wobei die gemeldeten fps von 118.99durch Zählen der Anzahl der Videopakete und Teilen durch die Gesamtdauer ermittelt werden. Wenn es sich nicht um einen Stream mit variabler Bildrate handelt, fügen Sie ihn -r 118.99als Ausgabeoption hinzu.


Für ältere Versionen alternativ Ausgabe an MKV, dh

ffmpeg -i input.mp4 -vf "crop='if(gte(iw,ih),ih,iw):if(gte(ih,iw),iw,ih)', scale=640x640" \
   -vsync 0 -an -c:v libx264 -profile:v high -level 4.1 -preset veryslow -crf 20 output.mkv

Wenn Sie dann das MKV in MP4 muxen,

ffmpeg -i output.mkv -c copy output.mp4

Das resultierende MP4 zeigt (nahezu) die Quell-Framerate.

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'no-rc.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf57.34.103
  Duration: 00:00:02.75, start: 0.000000, bitrate: 2462 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 640x640, 2444 kb/s, 119.88 fps, 600 tbr, 16k tbn (default)
Danke - das Problem bei der Verwendung -r 118.99ist, dass die Eingabe unterschiedliche Frameraten haben kann. Gibt es eine Möglichkeit, es dynamisch zu machen, damit es -r <value>mit der Eingabe übereinstimmt fps?
Nicht direkt, aber ja, wenn Sie die MKV-Methode wie bearbeitet durchlaufen.
Coole Problemumgehung - es funktioniert. Ich werde die Frage ein paar Tage offen lassen, um zu sehen, ob jemand mit einem Ein-Schritt-Prozess aufwartet - wenn nicht, dann werde ich akzeptieren!
Wenn es einen Fehler gibt, melden Sie ihn bitte bei trac.ffmpeg.org ...