web-dev-qa-db-fra.com

codage sans perte h264

Est-il possible de faire un encodage sans perte en h264? Par sans perte, je veux dire que si je l'alimente d'une série d'images et que je les encode, puis si j'extrais toutes les images de la vidéo encodée, j'obtiendrai exactement les mêmes images que dans l'entrée, pixel par pixel, image par image . Est-ce vraiment possible? Prenez cet exemple:

Je génère un tas d'images, puis j'encode la séquence d'images en un AVI non compressé (avec quelque chose comme virtualdub), j'applique ensuite sans perte h264 (les fichiers d'aide prétendent que le réglage --qp 0 permet une compression sans perte, mais je ne suis pas sûr si cela signifie qu'il n'y a pas de perte à aucun moment du processus ou que la quantification est sans perte). Je peux ensuite extraire les images de la vidéo h264 résultante avec quelque chose comme mplayer.

J'ai d'abord essayé avec Handbrake, mais il s'avère qu'il ne prend pas en charge l'encodage sans perte. J'ai essayé x264 mais ça plante. Cela peut être dû au fait que mon fichier AVI source se trouve dans l'espace colorimétrique RVB au lieu de YV12. Je ne sais pas comment alimenter une série de bitmaps YV12 et dans quel format en x264 de toute façon, donc je ne peux même pas essayer.

En résumé, ce que je veux savoir, s'il y a moyen de passer de

Série de bitmaps sans perte (dans n'importe quel espace colorimétrique) -> certaines transformations -> codage h264 -> décodage h264 -> certaines transformations -> la série originale de bitmaps sans pertes

S'il existe un moyen d'y parvenir?

EDIT: Il y a un point TRÈS valide à propos du H264 sans perte qui n'a pas trop de sens. Je suis bien conscient qu'il n'y a aucun moyen de voir (avec mes yeux) la différence entre un clip non compressé et un autre compressé à un taux élevé en H264, mais je ne pense pas que ce ne soit pas sans utilisations. Par exemple, il peut être utile pour stocker des vidéos à éditer sans prendre énormément d'espace, sans perdre en qualité et sans passer trop de temps d'encodage à chaque enregistrement du fichier.

MISE À JOUR 2: x264 ne plante plus. Je peux utiliser comme sources avisynth ou yar12 lagarith sans perte (pour éviter l'avertissement de compression de l'espace colorimétrique). Cependant, même avec --qp 0 et une source rgb ou yv12, j'obtiens toujours quelques différences, minimes mais présentes. C'est troublant, car toutes les informations que j'ai trouvées sur le codage prédictif sans perte (--qp 0) prétendent que le codage entier devrait être sans perte, mais je ne suis pas en mesure de le vérifier.

40
cloudraven

Je vais ajouter une réponse tardive à celle-ci après avoir passé toute la journée à essayer de comprendre comment obtenir des pixels YUV 4: 4: 4 en x264. Bien que x264 accepte les pixels bruts 4: 2: 0 dans un fichier, il est vraiment très difficile de faire passer les pixels 4: 4: 4. Avec les versions récentes de ffmpeg, ce qui suit fonctionne pour un encodage et une extraction sans perte pour vérifier l'encodage.

Commencez par écrire vos pixels bruts 4: 4: 4 dans un fichier au format planaire. Les plans sont un ensemble d'octets Y, puis les octets U et V où U et V utilisent 128 comme valeur zéro. Maintenant, appelez ffmpeg et passez la taille des images YUV brutes en utilisant deux fois le format de pixel "yuv444p", comme ceci:

ffmpeg -y -s 480x480 -pix_fmt yuv444p -i Tree480.yuv \
-c:v libx264 -pix_fmt yuv444p -profile:v high444 -crf 0 \
-preset:v slow \
Tree480_lossless.m4v

Une fois l'encodage en h264 et l'encapsulation sous forme de fichier Quicktime, on peut extraire exactement les mêmes octets comme ceci:

ffmpeg -y -i Tree480_lossless.m4v -vcodec rawvideo -pix_fmt yuv444p \
Tree480_m4v_decoded.yuv

Enfin, vérifiez les deux fichiers binaires avec diff:

$ diff -s Tree480.yuv Tree480_m4v_decoded.yuv
Files Tree480.yuv and Tree480_m4v_decoded.yuv are identical

Gardez juste à l'esprit que vous devez écrire les octets YUV dans un fichier vous-même, ne laissez pas ffmpeg effectuer une conversion des valeurs YUV!

23
MoDJ

Si x264 fait un encodage sans perte mais n'aime pas votre format d'entrée, alors votre meilleur pari est d'utiliser ffmpeg pour traiter le fichier d'entrée. Essayez de commencer avec quelque chose comme

ffmpeg -i input.avi -f yuv4mpegpipe -pix_fmt yuv420p -y /dev/stdout \
  | x264 $OPTIONS -o output.264 /dev/stdin

et ajouter des options à partir de là. YUV4MPEG est un format non compressé sans perte adapté à la tuyauterie entre différents outils vidéo; ffmpeg sait comment l'écrire et x264 sait le lire.

5
hobbs

FFmpeg a un mode "sans perte" pour x264, voir FFmpeg et x264 Encoding Guide

§ Sans perte H.264

c'est essentiellement -qp 0

3
rogerdpack

Pour générer H.264 sans perte avec l'interface graphique HandBrake, définissez Codec vidéo: H.264, Qualité constante, RF: 0, Profil H.264: auto. Bien que ce fichier ne soit pas pris en charge nativement par Apple, il peut être ré-encodé comme presque sans perte pour la lecture.

Fenêtre d'activité de l'interface graphique de HandBrake:

Profil H.264: auto; Encodage à constante RF 0.0000 ...profil haut 4: 4: 4 Prédictif, niveau 3.0, 4: 2: 0 8- bit

Profil H.264: élevé; Encodage à constante RF 0.0000 ...sans perte nécessite un profil élevé 444, désactivation ...profil élevé, niveau 3.0

2
user3054109

Je ne connais pas vos exigences en matière de compression et de décompression, mais un archiveur à usage général (comme 7-Zip avec LZMA2) devrait être capable de compresser à peu près aussi petit ou, dans certains cas, même beaucoup plus petit qu'un codec vidéo sans perte. Et c'est beaucoup plus simple et plus sûr qu'une chaîne de traitement vidéo entière. L'inconvénient est la vitesse beaucoup plus lente, et que vous devez extraire avant de la voir. Mais pour les images, je pense que vous devriez l'essayer.

Il existe également des formats d'image sans perte, comme .png.

Pour encoder le RGB sans perte avec x264, vous devez utiliser la version en ligne de commande de x264 (vous ne pouvez pas faire confiance aux interfaces graphiques dans ce cas Edge, elles vont probablement foirer) r2020 ou plus récent, avec quelque chose comme ça:

x264 --qp 0 --preset fast --input-csp rgb --output-csp rgb --colormatrix GBR --output "the_lossless_output.mkv" "someinput.avs"

Toutes les pertes/différences entre l'entrée et la sortie doivent provenir d'une conversion de l'espace colorimétrique (avant l'encodage ou lors de la lecture), de mauvais paramètres ou de certains en-têtes/métadonnées qui ont été perdus. x264 ne prend pas en charge RGBA, mais RGB est correct. La compression YUV 4: 4: 4 est plus efficace, mais vous perdrez certaines données dans la conversion de l'espace colorimétrique car votre entrée est RVB. Le YV12/i420 est beaucoup plus petit et de loin l'espace colorimétrique le plus courant en vidéo, mais vous avez une résolution chromatique inférieure.

Plus d'informations sur les paramètres x264: http://mewiki.project357.com/wiki/X264_Settings

Évitez également le lagarith. Il utilise la virgule flottante x87 ... et il existe de meilleures alternatives. http://codecs.multimedia.cx/?p=3 http://mod16.org/hurfdurf/?p=142

EDIT: Je ne sais pas pourquoi j'ai été voté. Veuillez laisser un commentaire lorsque vous faites cela.

2
ReneSac

Si vous ne pouvez pas obtenir de compression sans perte en utilisant un encodeur et un décodeur h.264, vous pouvez peut-être envisager deux alternatives:

(1) Plutôt que de transmettre toutes les données au format h.264, certaines personnes expérimentent la transmission de certaines données avec un "canal latéral" résiduel :

  • (fichier h.264) -> décodage h264 -> une certaine transformation -> une approximation avec perte de la série originale de bitmaps
  • (fichier résiduel compressé) -> décodeur -> une série de bitmaps résiduels sans perte
  • Pour chaque pixel de chaque bitmap, approximate_pixel + residuel_pixel = un pixel bit à bit égal au pixel d'origine.

(2) Utilisez le format de compression vidéo Dirac en mode "sans perte".

1
David Cary

Je suis d'accord que parfois la perte de données est acceptable, mais ce n'est pas simplement une question d'apparence immédiatement après la compression.

Même une perte visuellement imperceptible de données couleur peut dégrader le métrage de telle sorte que la correction des couleurs, la saisie d'écran vert, le suivi et d'autres tâches de publication deviennent plus difficiles, voire impossibles, ce qui ajoute des dépenses à une production.

Cela dépend vraiment quand et comment vous compressez dans le pipeline, mais en fin de compte, il est logique d'archiver la qualité d'origine, car le stockage est généralement beaucoup moins cher que le redémarrage.

1
LDaly