Est-il possible pour FFmpeg / ffv1.3 / mkv de créer une vidéo sans perte n'est pas plus grande que la somme de ses parties (et si oui, comment) et si non, quelle est une bonne alternative pour se rapprocher de la taille ? La vidéo doit être sans perte.
J'essaie d'utiliser FFmpeg pour créer un mkv avec ffv1.3 sur un ensemble d'images jpeg similaires (images d'une webcam). Je suis capable de créer la vidéo, mais elle est au moins deux fois plus grande que la collection d'images jpeg. Je m'attendais à un niveau de compression équivalent ou supérieur.
Je comprends que le format JPEG est optimisé pour la compression. Cependant, un grand ensemble d'images très similaires devrait pouvoir être davantage compressé, ou dans ce cas, similaire aux images originales additionnées.
Les commandes que j'utilise pour créer le fichier sont les suivantes :
ffmpeg -pattern_type glob -i '*.jpg' -vcodec ffv1 -level 3 -an -pass 1 -passlogfile passlog -f matroska /dev/null
ffmpeg -pattern_type glob -i '*.jpg' -vcodec ffv1 -level 3 -an -pass 2 -passlogfile passlog -f matroska ~/foo.mkv
Les fichiers d'entrée font 24M au total mais le mkv résultant fait 96M (par du -h).
Les résultats de la deuxième passe :
ffmpeg version N-79053-g7eedad9 Copyright (c) 2000-2016 the FFmpeg developers
built with gcc 4.6 (Debian 4.6.3-14+rpi1)
configuration: --enable-cross-compile --cross-prefix= --arch=armel --target-os=linux --prefix=/my/path/were/i/keep/built/arm/stuff
libavutil 55. 19.100 / 55. 19.100
libavcodec 57. 28.103 / 57. 28.103
libavformat 57. 28.101 / 57. 28.101
libavdevice 57. 0.101 / 57. 0.101
libavfilter 6. 39.102 / 6. 39.102
libswscale 4. 0.100 / 4. 0.100
libswresample 2. 0.101 / 2. 0.101
Input #0, image2, from '*.jpg':
Duration: 00:00:21.32, start: 0.000000, bitrate: N/A
Stream #0:0: Video: mjpeg, yuvj422p(pc, bt470bg/unknown/unknown), 640x480, 25 fps, 25 tbr, 25 tbn, 25 tbc
File '/home/pi/foo.mkv' already exists. Overwrite ? [y/N] y
[swscaler @ 0x3671f30] deprecated pixel format used, make sure you did set range correctly
Output #0, matroska, to '/home/pi/foo.mkv':
Metadata:
encoder : Lavf57.28.101
Stream #0:0: Video: ffv1 (FFV1 / 0x31564646), yuv422p, 640x480, q=2-31, pass 2, 200 kb/s, 25 fps, 1k tbn, 25 tbc
Metadata:
encoder : Lavc57.28.103 ffv1
Stream mapping:
Stream #0:0 -> #0:0 (mjpeg (native) -> ffv1 (native))
Press [q] to stop, [?] for help
frame= 533 fps=4.2 q=-0.0 Lsize= 97815kB time=00:00:21.32 bitrate=37584.4kbits/s speed=0.168x
video:97808kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.006607%
Chaque jpeg fait environ 43143 octets (par ls -al) mais en exécutant la commande suivante, l'outil indique que chaque image fait 614400 octets (à la fois dans la vidéo et dans les images jpeg indépendantes). Je suppose qu'il s'agit de la taille de l'image décompressée (640x480x2).
ffmpeg -pattern_type glob -i '*.jpg' -f framemd5 -
les résultats ci-dessous sont pour les images, les mêmes tailles sont rapportées pour le mkv.
ffmpeg version N-79053-g7eedad9 Copyright (c) 2000-2016 the FFmpeg developers
built with gcc 4.6 (Debian 4.6.3-14+rpi1)
configuration: --enable-cross-compile --cross-prefix= --arch=armel --target-os=linux --prefix=/my/path/were/i/keep/built/arm/stuff
libavutil 55. 19.100 / 55. 19.100
libavcodec 57. 28.103 / 57. 28.103
libavformat 57. 28.101 / 57. 28.101
libavdevice 57. 0.101 / 57. 0.101
libavfilter 6. 39.102 / 6. 39.102
libswscale 4. 0.100 / 4. 0.100
libswresample 2. 0.101 / 2. 0.101
Input #0, image2, from '*.jpg':
Duration: 00:00:21.32, start: 0.000000, bitrate: N/A
Stream #0:0: Video: mjpeg, yuvj422p(pc, bt470bg/unknown/unknown), 640x480, 25 fps, 25 tbr, 25 tbn, 25 tbc
#format: frame checksums
#version: 1
#hash: MD5
#software: Lavf57.28.101
#tb 0: 1/25
#stream#, dts, pts, duration, size, hash
Output #0, framemd5, to 'pipe:':
Metadata:
encoder : Lavf57.28.101
Stream #0:0: Video: rawvideo (Y42B / 0x42323459), yuvj422p, 640x480, q=2-31, 200 kb/s, 25 fps, 25 tbn, 25 tbc
Metadata:
encoder : Lavc57.28.103 rawvideo
Stream mapping:
Stream #0:0 -> #0:0 (mjpeg (native) -> rawvideo (native))
Press [q] to stop, [?] for help
0, 0, 0, 1, 614400, 2148ff8b95296f4bacc1099d13235063
0, 1, 1, 1, 614400, da330e2acd2f7d7a1e79fe79fccc90cf
0, 2, 2, 1, 614400, f55563c13a9f232ce32419fa26e37214
0, 3, 3, 1, 614400, c53d994fff0a9b26529fa8763deae520
EDITAR: La meilleure compression (et la bonne vitesse) provenait d'un conteneur des images jpeg elles-mêmes :
ffmpeg -pattern_type glob -i '*.jpg' -vcodec copy -an -f matroska ~/foo.mkv
Le fichier résultant était juste au-dessus de 24M (contre les 96M de ffv1). De même, les images jpeg décompressées faisaient 312M, dans les deux cas, elles ont été assez bien compressées. Si j'avais commencé avec autre chose qu'un jpeg, ffv1 aurait été idéal mais dans mon cas, les jpeg avec perte étaient aussi les images initiales sans perte.