web-dev-qa-db-fra.com

Comment créer un fichier AVI non compressé à partir d'une série de 1 000 images PNG à l'aide de FFMPEG

Comment créer un fichier AVI non compressé à partir d'une série de 1 000 images PNG à l'aide de FFMPEG?

J'ai utilisé cette commande pour convertir un fichier input.avi en une série de cadres PNG:

ffmpeg -y -i input.avi  -an -vcodec png  -s 1024x768 pic%d.png`

Maintenant, j'ai besoin de savoir comment faire une vidéo AVI non compressée à partir de toutes ces images PNG. J'ai essayé ceci:

ffmpeg -i pic%d.png -y -f avi -b 1150 -s 1024x768 -r 29.97 -g 12 -qmin 3 -qmax 13 -ab 224 -ar 44100 -ac 2 test.avi

Mais la vidéo résultante perd beaucoup de qualité par rapport à l’AVI original.

30
user995074

Alors j'ai fini par faire ma propre réponse trop longtemps.
Résumé TL: DR: pour stocker une séquence d’images sans perte, utilisez libx264 ou libx264rgb avec -preset ultrafast -qp 0. Il est presque aussi rapide que ffvhuff, avec un débit binaire beaucoup plus bas et décodé plus rapidement. huffyuv est beaucoup plus largement supporté en dehors de ffmpeg, mais ne prend pas en charge autant de formats de pixels que ffvhuff. C'est donc une autre raison d'utiliser h.264, en supposant que vos autres outils puissent gérer le profil h.264 High 4:4:4 Predictive que x264 utilise en mode sans perte. x264 peut être utilisé uniquement si un accès aléatoire rapide à des images arbitraires est nécessaire.

Méfiez-vous des bogues ffmpeg affectant libx264rgb lors de la lecture d'un répertoire d'images. (et qui sait quels autres cas.) Vérifiez si votre configuration est sans perte avant de l'utiliser. (facile avec ffmpeg -i in -pix_fmt rgb24 -f framemd5 sur le source et compressé sans perte)

edit: utvideo encode et décode assez rapidement, et est un codec beaucoup plus simple que le h.264. C'est fondamentalement une huffyuv moderne, avec un support pour des espaces de couleurs plus utiles. Si vous rencontrez un problème avec h.264, essayez immédiatement utvideo pour les fichiers temporaires.

edit2: le codec RGB semble bien fonctionner, du moins sur la bande-annonce de Sintel.

Voir aussi ma réponse similaire à une question similaire: https://superuser.com/a/860335/20798

La réponse de Warren Young contient de nombreuses informations sur divers formats et codecs bruts. Je pense que la réponse serait plus utile si elle était plus courte, alors je vais vous donner une nouvelle réponse. Si vous travaillez avec un logiciel qui ne prend pas en charge x264 ou ffvhuff sans perte, certaines de ces informations sont probablement toujours utiles.

La définition la plus utile de "sans perte" dans ce contexte est que vous pouvez récupérer l'entrée bit à bit. Zéro souci de la dégradation de la qualité de l'encodage vidéo, peu importe ce que vous faites.

http://en.wikipedia.org/wiki/Chroma_subsampling

Idéalement, évitez les conversions de plusieurs espaces colorimétriques. Les erreurs d'arrondi peuvent potentiellement s'accumuler. Si vous opérez sur votre vidéo avec des filtres qui fonctionnent dans l'espace colorimétrique RVB, il est logique de le conserver, tant que les débits binaires plus élevés ne posent pas problème. En fin de compte, vous allez probablement produire une vidéo yuv 4:2:0, mais le maintien de la résolution de chrominance supplémentaire est potentiellement utile, en fonction des filtres que vous allez appliquer.

Dans les deux cas, x264 sans perte et ffvhuff prennent en charge les formats RVB et yuv 4:4:4, 4:2:2 et 4:2:0. Je suggérerais x264, car il est rapide à décoder. Si vous essayez de lire des vidéos RVB HD en temps réel, essayez opengl au lieu de xv, car celui-ci sur mon système n'accepte que les entrées yuv. mplayer prenait un peu plus de temps CPU pour effectuer une conversion espace-couleur.

Source pour les tests d’encodeur suivants: https://media.xiph.org/ . https://media.xiph.org/sintel/sintel_trailer-1080-png.tar.gz Ils ont oublié de gzip les fichiers y4m pour la bande-annonce sintel , l’archive png est donc beaucoup plus petite.

ffmpeg -i 1080/sintel_trailer_2k_%4d.png -i sintel_trailer-audio.flac \
-c:a copy -c:v libx264rgb -preset ultrafast -qp 0 \
frompng.sintel.264rgb.mkv

par exemple.

peter@tesla:/mnt/GP1TB/p/encoder-sample/sintel$ time ffmpeg -i 1080/sintel_trailer_2k_%4d.png -i sintel_trailer-audio.flac -c:a copy -c:v libx264rgb -preset ultrafast -qp 0 frompng.sintel.264rgb.mkv
ffmpeg version N-67983-g2b358b4 Copyright (c) 2000-2015 the FFmpeg developers
  built on Jan 10 2015 05:32:37 with gcc 4.8 (Ubuntu 4.8.2-19ubuntu1)
  configuration: --enable-gpl --enable-version3 --enable-nonfree --disable-doc --disable-ffserver --enable-libx264 --enable-libx265 --enable-libmp3lame --enable-libopus --enable-libwebp --enable-libvpx --disable-outdev=oss --disable-indev=oss --disable-encoder=vorbis --enable-libvorbis --enable-libfdk-aac --disable-encoder=aac --disable-decoder=jpeg2000
  libavutil      54. 16.100 / 54. 16.100
  libavcodec     56. 20.100 / 56. 20.100
  libavformat    56. 18.100 / 56. 18.100
  libavdevice    56.  3.100 / 56.  3.100
  libavfilter     5.  7.100 /  5.  7.100
  libswscale      3.  1.101 /  3.  1.101
  libswresample   1.  1.100 /  1.  1.100
  libpostproc    53.  3.100 / 53.  3.100
Input #0, image2, from '1080/sintel_trailer_2k_%4d.png':
  Duration: 00:00:50.12, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: png, rgb24, 1920x1080 [SAR 72:72 DAR 16:9], 25 fps, 25 tbr, 25 tbn, 25 tbc
Input #1, flac, from 'sintel_trailer-audio.flac':
  Duration: 00:00:52.00, start: 0.000000, bitrate: 721 kb/s
    Stream #1:0: Audio: flac, 48000 Hz, stereo, s16
File 'frompng.sintel.264rgb.mkv' already exists. Overwrite ? [y/N] y
No pixel format specified, rgb24 for H.264 encoding chosen.
Use -pix_fmt yuv420p for compatibility with outdated media players.
[libx264rgb @ 0x2770760] using SAR=1/1
[libx264rgb @ 0x2770760] using cpu capabilities: MMX2 SSE2Fast SSSE3 Cache64 SlowShuffle
[libx264rgb @ 0x2770760] profile High 4:4:4 Predictive, level 4.0, 4:4:4 8-bit
[libx264rgb @ 0x2770760] 264 - core 144 r2525+2 6a4fca8 - H.264/MPEG-4 AVC codec - Copyleft 2003-2014 - http://www.videolan.org/x264.html - options: cabac=0 ref=1 deblock=0:0:0 analyse=0:0 me=dia subme=0 psy=0 mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip=0 chroma_qp_offset=0 threads=3 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=0 keyint=250 keyint_min=25 scenecut=0 intra_refresh=0 rc=cqp mbtree=0 qp=0
Output #0, matroska, to 'frompng.sintel.264rgb.mkv':
  Metadata:
    encoder         : Lavf56.18.100
    Stream #0:0: Video: h264 (libx264rgb) (H264 / 0x34363248), rgb24, 1920x1080 [SAR 72:72 DAR 16:9], q=-1--1, 25 fps, 1k tbn, 25 tbc
    Metadata:
      encoder         : Lavc56.20.100 libx264rgb
    Stream #0:1: Audio: flac ([172][241][0][0] / 0xF1AC), 48000 Hz, stereo (16 bit)
Stream mapping:
  Stream #0:0 -> #0:0 (png (native) -> h264 (libx264rgb))
  Stream #1:0 -> #0:1 (copy)
Press [q] to stop, [?] for help
frame= 1253 fps= 18 q=-1.0 Lsize=  834790kB time=00:00:51.96 bitrate=131592.5kbits/s
video:830198kB audio:4575kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.002025%
[libx264rgb @ 0x2770760] frame I:6     Avg QP: 0.00  size:612470
[libx264rgb @ 0x2770760] frame P:1247  Avg QP: 0.00  size:678787
[libx264rgb @ 0x2770760] mb I  I16..4: 100.0%  0.0%  0.0%
[libx264rgb @ 0x2770760] mb P  I16..4: 50.3%  0.0%  0.0%  P16..4: 12.0%  0.0%  0.0%  0.0%  0.0%    skip:37.6%
[libx264rgb @ 0x2770760] coded y,u,v intra: 71.1% 68.2% 70.0% inter: 22.8% 22.8% 23.2%
[libx264rgb @ 0x2770760] i16 v,h,dc,p: 50% 48%  1%  1%
[libx264rgb @ 0x2770760] kb/s:135693.94

Notez que j'ai oublié de spécifier -r 24 fps, de sorte qu'il ne restera pas synchronisé avec l'audio. (et le débit binaire (mais pas la taille du fichier), les chiffres seront également désactivés. ffmpeg prend la valeur 25fps par défaut). Le processeur de cette machine est un core2duo 2,4 GHz (E6600) de première génération (conroe).

résultats:

4.5M    sintel_trailer-audio.flac  # this is muxed in to every mkv
948M    1080  # the directory of PNGs
940M    /var/tmp/dl/sintel_trailer-1080-png.tar.gz
7434M   sintel.y4m  # yuv444, uncompressed.  mplayer gets the colors wrong?
2342M   qtrle.mkv   # encode went at 16fps, so qtrle is slower and worse filesize
2105M   sintel.huff.mkv  # ffvhuff with default options, rgb pix fmt
1228M    sintel.utvideo.mkv  # muxed without audio, I should update the others this way
946M    png-copy.mkv  # -codec copy makes a MPNG stream.  Use -codec png for non-png sources, but it won't make PNGs as small.  Decodes very fast
824M    lossy.prores_ks.mov # yuv444p10le extremely slow to encode (2.3fps), and worse bitrate.
816M    frompng.sintel.264rgb.mkv
735M    sintel.x264rgb.medium.nocabac.mkv  # encode went at 3.3 fps instead of 18.  Better gain than for live-action, though
626M    sintel_trailer.rgb.lossless.veryslow.mkv # 1.1fps.  With CABAC, 16 ref frames, etc. etc.
512M    lossy.prores.mov # yuv422p10le, 12fps
341M    sintel.yuv420.x264.lossless.mkv
21M     lossy.rgb.crf26.preset=medium.mkv
13M     lossy.yuv420.crf26.preset=medium.mkv  # remember this is WITH 4.5MB audio

Notez que mediainfo ne connaît pas la norme RVB h.264, mais indique toujours que les fichiers sont YUV.

Vérifiez que c'était vraiment sans perte:

ffmpeg -i 1080/sintel_trailer_2k_%4d.png -f framemd5 png.framemd5
ffmpeg -i fromhuff.sintel.264rgb.mkv -an -sn -pix_fmt rgb24  -f framemd5 x264rgb.framemd5
diff -s *.framemd5
Files png.framemd5 and x264rgb.framemd5 are identical

Ainsi, vous pouvez récupérer l’entrée PNG originale de cette façon, c’est-à-dire que vous pouvez créer des PNG contenant des données d’image identiques.

Notez le -pix_fmt rgb24 pour le test x264. Le décodeur h.264 de ffmpeg génère une sortie gbrp (planaire, non compressée), de sorte que les bits sont identiques, mais dans un ordre différent. Le "conteneur" framemd5 n'impose aucune sorte de restriction de format, mais vous obtiendrez le même md5 si les bits sont disposés de la même manière. Je viens de regarder ce que ffmpeg a déclaré utiliser comme fichier fmt lorsque je l’ai alimenté avec des fichiers PNG, puis l’utiliser comme argument pour -pix_fmt pour décoder. Incidemment, c’est la raison pour laquelle vlc ne lit pas les fichiers RVB h.264 (jusqu’à la prochaine version ou les versions nocturnes actuelles): Il ne prend pas en charge le format de pixel gbrp.

Pour yuv, utilisez libx264, pas libx264rgb. Vous n'avez pas besoin d'installer une version RVB de x264, la bibliothèque actuelle prend en charge les deux. C'est juste ffmpeg qui l'a implémenté sous la forme de deux encodeurs de noms différents. Je pense que s'ils ne l'avaient pas fait, le comportement par défaut serait de laisser l'entrée rgb en tant que rgb et de fonctionner très lentement tout en produisant une sortie à débit binaire beaucoup plus élevé pour la même qualité. (vous devez encore parfois utiliser -pix_fmt yuv420p si vous voulez 420 au lieu de 444 h.264 en sortie.

Sauf si vous créez des fichiers pour un stockage à long terme, utilisez toujours -preset ultrafast pour x264 sans perte. Davantage de cadres de référence et de recherche de mouvement ne font guère de différence pour le matériel sans perte, qu'il s'agisse d'un contenu non animé animé de n'importe quel bruit. CABAC prend une quantité énorme de CPU aux débits binaires sans perte, même pour les décoder. Utilisez uniquement à des fins d'archivage, pas de fichiers de travail. (ultra-rapide désactive CABAC). CABAC permet des économies de débit de 10 à 15%.

Si vous souhaitez que chaque image soit une image clé, définissez -keyint 1. Ensuite, un logiciel de montage vidéo qui ne veut que couper sur les images clés ou sans vous limiter.

Pour répondre à la question initiale: Voici ce que vous devriez faire pour jeter des fichiers temporaires tout en essayant des opérations par étapes (par exemple, un désentrelacement lent, en enregistrant une sortie sans perte avant d'essayer autre chose):

ffmpeg -i dv-video-source.ts -vf yadif=2:1,mcdeint=3:1:10 -c:a copy -c:v libx264 -preset ultrafast -qp 0 deinterlaced.mkv

Si vous avez vraiment besoin de votre sortie dans des fichiers image que vous pouvez modifier avec des outils d'image fixe, décodez-le en png. Vous ne perdrez rien de plus que peut-être le moins significatif des 8 bits de chacune des valeurs Y, Cb et Cr de chaque pixel.

x264 s'en sort VRAIMENT bien parce qu'il y a beaucoup de cadres noirs avec un peu de texte, un fondu enchaîné et un fondu enchaîné, et une similitude parfaite entre les grandes zones de nombreux cadres, dont il réussit à tirer parti même avec -preset ultrafast . En live-action, je vois toujours x264 à la moitié de la taille du fichier de ffvhuff (yuv420).

Pour ceux qui sont curieux: Le code RGB sans perte de temps élevé de processeur a (noyau x264 144 r2525):

[libx264rgb @ 0x35b97a0] frame I:27    Avg QP: 0.00  size:604367
[libx264rgb @ 0x35b97a0] frame P:1226  Avg QP: 0.00  size:517512
[libx264rgb @ 0x35b97a0] mb I  I16..4..PCM: 46.3% 38.1% 15.7%  0.0%
[libx264rgb @ 0x35b97a0] mb P  I16..4..PCM: 24.3%  5.4%  4.5%  0.0%  P16..4: 10.5%  3.3%  5.7%  0.0%  0.0%    skip:46.3%
[libx264rgb @ 0x35b97a0] 8x8 transform intra:17.3% inter:46.1%
[libx264rgb @ 0x35b97a0] coded y,u,v intra: 81.6% 77.5% 80.0% inter: 28.0% 27.7% 28.1%
[libx264rgb @ 0x35b97a0] i16 v,h,dc,p: 35% 64%  1%  0%
[libx264rgb @ 0x35b97a0] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 31% 49% 13%  2%  1%  1%  1%  1%  1%
[libx264rgb @ 0x35b97a0] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 31% 37%  5%  5%  6%  5%  5%  4%  3%
[libx264rgb @ 0x35b97a0] Weighted P-Frames: Y:41.1% UV:40.7%
[libx264rgb @ 0x35b97a0] ref P L0: 74.5%  4.2%  9.1%  4.1%  2.1%  1.7%  1.2%  0.8%  0.6%  0.5%  0.3%  0.2%  0.2%  0.2%  0.2%  0.1%
[libx264rgb @ 0x35b97a0] kb/s:99721.66

Notez la fraction très élevée d'images p pondérées, ainsi que la fraction très élevée de macroblocs de saut. Chaque transition de scène est un fondu, pas une coupure, et x264 en profite si vous lui donnez le temps processeur pour comprendre comment.

notes supplémentaires (codecs avec perte pour l'édition):

Pour le défilement avant/arrière des clips, les codecs intra-internes sont généralement privilégiés (utvideo, ffvhuff, mjpeg, jpeg2000, pro-res, AVC-Intra). J'imagine qu'un AVC normal avec de courts GOP (1/2 à 1 seconde) gommerait assez bien aussi, tant que le logiciel sait ce qu'il fait (décoder le plus près de l'image I lorsque je scrute rapidement, décoder dans le GOP pour arriver à une inter-image si vous avez suffisamment zoomé sur une timeline pour que cela soit nécessaire).

J'ai posté des choses négatives à ce sujet et https://video.stackexchange.com/ à propos de pro-res, comme "à quoi ça sert compression plus lente et pire qu’un codec sans perte ", mais il a quelques fonctionnalités intéressantes. Apple indique qu'il peut décoder à demi-résolution en utilisant aussi peu que 1/3 du temps de calcul d'un décodage complet.

l'implémentation prores de ffmpeg n'est probablement pas aussi optimisée en termes de vitesse que celle d'Apple non plus, c'est pourquoi mes tests avec ffmpeg l'ont rendu plus lent. Cela ne vaut probablement pas la peine de l'utiliser si vous avez un flux de travail de logiciel gratuit avec des outils basés sur ffmpeg, mais cela pourrait valoir la peine d'essayer si vous utilisez un logiciel commercial.

Je ne fais pas beaucoup de montage vidéo, principalement du codage, donc je ne sais pas trop quels tests conviendraient à des codecs comme les prores. Je suppose que mjpeg serait peut-être une bonne alternative rapide, si short-GOP x264 ne fonctionne pas bien. Il existe des implémentations accélérées par le format jpeg dans les distributions Linux, et il s’agit d’un codec assez simple. Vous pouvez augmenter ou diminuer la qualité selon les besoins pour faire le compromis qualité/taille de fichier + vitesse d'encodage/décodage. C'est ancien, mais si vous voulez un codec intra-seulement qui est vraiment rapide, il pourrait battre x264.

Pour x264, j'essaierais quelque chose comme x264 --crf 10 --keyint=1 --preset superfast --tune fastdecode (intra-uniquement, sans aucun des autres éléments définis par --avcintra-class.) Remarque: superfast (sans CABAC), ou faster, pas ultrafast est probablement préférable pour une opération avec pertes. Je pense que l’ultrafast perd beaucoup de qualité sans être beaucoup plus rapide. Plus vous utilisez une qualité inférieure (plus élevée), plus vous gagnerez un peu de temps CPU pour trouver un meilleur encodage. Une grande partie de cela n'est probablement pas pertinente avec la taille du groupe d'images = 1, cependant.

Avec une taille de groupe d'images> 1, si vous générez autant de bits au codage qu'une meilleure inter-prédiction n'en économisera pas lors du codage des résidus (car les modifications de bruit/grain/subtile entre les images sont conservées de manière très précise), le superfast suffit probablement. Sinon, avec --keyint=30 ou quelque chose comme cela, probablement --preset veryfast --crf 12 serait intéressant.

En théorie, la qualité pour un réglage CRF donné devrait être constante d'un préréglage à l'autre. Si vous recherchez des fichiers plus petits (décodages plus rapides), échanger de la qualité contre du temps de codage est logique.

9
Peter Cordes

Je pense que ffmpeg prend en charge la conversion en vidéo non compressée.
J'ai utilisé ffmpeg -i input.mp4 -vcodec rawvideo out.avi et le fichier .avi obtenu était à peu près la bonne taille de fichier. Le lecteur multimédia Windows ne semblait pas pouvoir le lire correctement, mais VirtualDub pouvait le lire et je ne voyais aucune perte de qualité d'image.

2
jmnben