Warum funktioniert ffmpeg nicht deterministisch?

Ich nehme eine Datei und mache das Video langsamer, indem ich zweimal ein und denselben Befehl verwende:

ffmpeg -nostdin -i test.avi -filter:v "setpts=2.0*PTS" -vtag xvid -an slow1.avi
ffmpeg -nostdin -i test.avi -filter:v "setpts=2.0*PTS" -vtag xvid -an slow2.avi

Aber slow1.aviund slow2.avisind anders.

Überprüfen Sie zuerst durch Vergleichen md5sumund Dateigröße:

1ceef0b7c6b498399e7ee4ff3ce99427  slow1.avi
cc844d77193e2ad37dc1e06d6cac5166  slow2.avi
-rw-r--r-- 1 user user 66606564 Jul 14 09:28 slow1.avi
-rw-r--r-- 1 user user 66867612 Jul 14 09:28 slow2.avi

Überprüfen Sie dann, indem Sie die Terminalausgabe vergleichen:

@@ -16,7 +16,7 @@
   Duration: 00:21:52.21, start: 0.000000, bitrate: 344 kb/s
     Stream #0:0: Video: mpeg4 (Simple Profile) (XVID / 0x44495658), yuv420p, 614x480 [SAR 1:1 DAR 307:240], 203 kb/s, 25 fps, 25 tbr, 25 tbn, 25 tbc
     Stream #0:1: Audio: mp3 (U[0][0][0] / 0x0055), 44100 Hz, stereo, s16p, 128 kb/s
-Output #0, avi, to 'slow1.avi':
+Output #0, avi, to 'slow2.avi':
   Metadata:
     ISFT            : Lavf57.25.100
     Stream #0:0: Video: mpeg4 (xvid / 0x64697678), yuv420p, 614x480 [SAR 1:1 DAR 307:240], q=2-31, 200 kb/s, 25 fps, 25 tbn, 25 tbc
@@ -26,5 +26,5 @@
       unknown side data type 10 (24 bytes)
 Stream mapping:
   Stream #0:0 -> #0:0 (mpeg4 (native) -> mpeg4 (native))
-frame=32804 fps=459 q=2.0 Lsize=   65045kB time=00:43:44.36 bitrate= 203.0kbits/s speed=36.8x    
-video:63486kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 2.456314%
+frame=32804 fps=438 q=2.0 Lsize=   65300kB time=00:43:44.36 bitrate= 203.8kbits/s speed=  35x
+video:63741kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 2.446085%

ffmpeg gibt diesen Nichtdeterminismus mit jeder Datei, zum Beispiel versuchen Sie es mit:

/usr/local/bin/youtube-dl --recode-video avi -o 'test.%(ext)s' tPEE9ZwTmy0

Warum ist die gleiche Verarbeitung einer Datei durch ffmpeg nicht deterministisch? Beeinflusst dies, wie diese Datei tatsächlich vom Movie Player wiedergegeben wird?

BEARBEITEN

Wenn wir -flags bitexactvorher hinzufügen -filter:v, unterscheiden sich die Ergebnisse sowieso.

Dies ist die vollständige Ausgabe auf Maschine A:

user@debian:~/Downloads$ md5sum test.avi 
621ebcd080da91817bb47a93e877cd6e  test.avi
user@debian:~/Downloads$ ./ffmpeg-git-20160714-64bit-static/ffmpeg -nostdin -i test.avi -flags bitexact -filter:v "setpts=2.0*PTS" -vtag xvid -an slow1.avi
ffmpeg version N-80999-gf41e37b-static http://johnvansickle.com/ffmpeg/  Copyright (c) 2000-2016 the FFmpeg developers
  built with gcc 5.4.0 (Debian 5.4.0-6) 20160609
  configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --enable-libmp3lame --enable-libx264 --enable-libx265 --enable-libwebp --enable-libspeex --enable-libvorbis --enable-libvpx --enable-libfreetype --enable-fontconfig --enable-libxvid --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libtheora --enable-libvo-amrwbenc --enable-gray --enable-libopenjpeg --enable-libopus --enable-libass --enable-gnutls --enable-libvidstab --enable-libsoxr --enable-frei0r --enable-libfribidi --disable-indev=sndio --disable-outdev=sndio --enable-librtmp --enable-libmfx --enable-libzimg --cc=gcc
  libavutil      55. 28.100 / 55. 28.100
  libavcodec     57. 50.100 / 57. 50.100
  libavformat    57. 41.100 / 57. 41.100
  libavdevice    57.  0.102 / 57.  0.102
  libavfilter     6. 47.100 /  6. 47.100
  libswscale      4.  1.100 /  4.  1.100
  libswresample   2.  1.100 /  2.  1.100
  libpostproc    54.  0.100 / 54.  0.100
Input #0, avi, from 'test.avi':
  Metadata:
    encoder         : Lavf57.25.100
  Duration: 00:00:01.04, start: 0.000000, bitrate: 777 kb/s
    Stream #0:0: Video: mpeg4 (Simple Profile) (XVID / 0x44495658), yuv420p, 854x470 [SAR 1:1 DAR 427:235], 29.97 fps, 29.97 tbr, 29.97 tbn, 29.97 tbc
    Stream #0:1: Audio: mp3 (U[0][0][0] / 0x0055), 44100 Hz, stereo, s16p, 128 kb/s
[avi @ 0x51c4680] Setting the AVFormatContext to bitexact mode, because the AVCodecContext is in that mode. This behavior will change in the future. To keep the current behavior, set AVFormatContext.flags |= AVFMT_FLAG_BITEXACT.
[avi @ 0x51c4680] Using AVStream.codec to pass codec parameters to muxers is deprecated, use AVStream.codecpar instead.
Output #0, avi, to 'slow1.avi':
    Stream #0:0: Video: mpeg4 (xvid / 0x64697678), yuv420p, 854x470 [SAR 1:1 DAR 427:235], q=2-31, 200 kb/s, 29.97 fps, 29.97 tbn, 29.97 tbc
    Metadata:
      encoder         : Lavc mpeg4
    Side data:
      cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: -1
Stream mapping:
  Stream #0:0 -> #0:0 (mpeg4 (native) -> mpeg4 (native))
frame=   27 fps=0.0 q=13.4 Lsize=      99kB time=00:00:01.83 bitrate= 444.1kbits/s speed=15.7x    
video:93kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 7.451477%
user@debian:~/Downloads$ md5sum slow1.avi 
653f2bf66a01b67911b5bd61a4e197e0  slow1.avi

Dies ist die vollständige Ausgabe auf Maschine B:

user@debian:~/Downloads$ md5sum test.avi 
621ebcd080da91817bb47a93e877cd6e  test.avi
user@debian:~/Downloads$ ./ffmpeg-git-20160714-64bit-static/ffmpeg -nostdin -i test.avi -flags bitexact -filter:v "setpts=2.0*PTS" -vtag xvid -an slow2.avi
ffmpeg version N-80999-gf41e37b-static http://johnvansickle.com/ffmpeg/  Copyright (c) 2000-2016 the FFmpeg developers
  built with gcc 5.4.0 (Debian 5.4.0-6) 20160609
  configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --enable-libmp3lame --enable-libx264 --enable-libx265 --enable-libwebp --enable-libspeex --enable-libvorbis --enable-libvpx --enable-libfreetype --enable-fontconfig --enable-libxvid --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libtheora --enable-libvo-amrwbenc --enable-gray --enable-libopenjpeg --enable-libopus --enable-libass --enable-gnutls --enable-libvidstab --enable-libsoxr --enable-frei0r --enable-libfribidi --disable-indev=sndio --disable-outdev=sndio --enable-librtmp --enable-libmfx --enable-libzimg --cc=gcc
  libavutil      55. 28.100 / 55. 28.100
  libavcodec     57. 50.100 / 57. 50.100
  libavformat    57. 41.100 / 57. 41.100
  libavdevice    57.  0.102 / 57.  0.102
  libavfilter     6. 47.100 /  6. 47.100
  libswscale      4.  1.100 /  4.  1.100
  libswresample   2.  1.100 /  2.  1.100
  libpostproc    54.  0.100 / 54.  0.100
Input #0, avi, from 'test.avi':
  Metadata:
    encoder         : Lavf57.25.100
  Duration: 00:00:01.04, start: 0.000000, bitrate: 777 kb/s
    Stream #0:0: Video: mpeg4 (Simple Profile) (XVID / 0x44495658), yuv420p, 854x470 [SAR 1:1 DAR 427:235], 29.97 fps, 29.97 tbr, 29.97 tbn, 29.97 tbc
    Stream #0:1: Audio: mp3 (U[0][0][0] / 0x0055), 44100 Hz, stereo, s16p, 128 kb/s
[avi @ 0x468f680] Setting the AVFormatContext to bitexact mode, because the AVCodecContext is in that mode. This behavior will change in the future. To keep the current behavior, set AVFormatContext.flags |= AVFMT_FLAG_BITEXACT.
[avi @ 0x468f680] Using AVStream.codec to pass codec parameters to muxers is deprecated, use AVStream.codecpar instead.
Output #0, avi, to 'slow2.avi':
    Stream #0:0: Video: mpeg4 (xvid / 0x64697678), yuv420p, 854x470 [SAR 1:1 DAR 427:235], q=2-31, 200 kb/s, 29.97 fps, 29.97 tbn, 29.97 tbc
    Metadata:
      encoder         : Lavc mpeg4
    Side data:
      cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: -1
Stream mapping:
  Stream #0:0 -> #0:0 (mpeg4 (native) -> mpeg4 (native))
frame=   27 fps=0.0 q=14.8 Lsize=     102kB time=00:00:01.83 bitrate= 456.8kbits/s speed=17.9x    
video:95kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 7.225229%
user@debian:~/Downloads$ md5sum slow2.avi 
9e6eed35b37a05c62141adefd249751f  slow2.avi
Upgrade kann ich nur sagen. Ich habe 4 Mal einen Test mit Ihrem Befehl durchgeführt und eine identische Ausgabe erhalten. Probieren Sie die Binärdateien unter johnvansickle.com/ffmpeg aus
@Mulvya Mit der Version N-80953-gd4c8e93-static sind die Ergebnisse auf einem Computer gleich, aber wenn dieselbe Datei mit gleicher ffmpeg-Version auf verschiedenen Computern (beide 64bit) verarbeitet wird, unterscheidet sich das Ergebnis trotzdem, wie beschrieben. Wie auch immer, was kann die Ursache für den in der Frage gezeigten Unterschied der Terminalausgabe sein?
Hinzufügen -flags bitexactund prüfen.
Zeigt die vollständige Konsolenausgabe an.
Versuchen Sie es mit der gleichen Version von ffmpeg.
Führen Sie die Befehle mit -v traceaus und führen Sie das Diff aus.
@Mulvya, dies ist das Diff pastebin.com/fk2wNWQ7 , dies ist das vollständige Protokoll von A pastebin.com/LVJJ1kKv , dies ist das vollständige Protokoll von B pastebin.com/0hVByQtE
Ich sehe keinen signifikanten Unterschied in der Anzeige. Dies kann mit dem nativen mpeg4-Encoder zu tun haben. Versuchen Sie es mit -c:v libxvidoder-c:v libx264
@Mulvya hat -c:v libxviddas Problem gelöst - die Hashsummen sind jetzt gleich.
Weil ffmpeges so komplex ist, hat es Empfindungsvermögen und freien Willen erreicht.

Antworten (1)

Basierend auf allen Informationen sieht es so aus, als ob der Unterschied beim internen MPEG-4 Teil 2-Encoder von FFmpeg auftritt, dessen Verwendung durch die Zeichenfolge mpeg4 (native)nach dem 2. Pfeil in identifiziert werden kann Stream #0:0 -> #0:0 (mpeg4 (native) -> mpeg4 (native)). Wenn Sie libxvideinen MPEG-4 Part 2-Encoder eines Drittanbieters verwenden, tritt der Fehler nicht auf.


Meine Vermutung ist, dass das Verhalten des internen MPEG4-Encoders mit den möglichen Unterschieden in den zusätzlichen Befehlssätzen zusammenhängt, die zwischen den beiden Maschinen vorhanden sind, dh MMX, SSE n . Jemand mit technischem Wissen kann sich gerne melden.