Je crois que libx264 est maintenant capable de faire des encodages 10: 4: 2: 2, mais je n'arrive pas à le faire fonctionner. J'utilise ffmpeg (info ci-dessous), et j'ai également essayé directement l'encodeur x264. J'ai essayé
ffmpeg.exe -i input.mov -c:v libx264 -profile:v high422 -crf 20 -pix_fmt yuv422p output.mp4
et cela produit une belle sortie 4: 2: 2, mais seulement à une profondeur de 8 bits,
[libx264 @ 00000000055a9de0] profile High 4:2:2, level 4.0, 4:2:2 8-bit
et j'ai essayé
ffmpeg.exe -i input.mov -c:v libx264 -profile:v high10 -crf 20 -pix_fmt yuv422p output.mp4
et cela me donne l'erreur:
x264 [error]: high10 profile doesn't support 4:2:2
[libx264 @ 00000000051ead60] Error setting profile high10.
[libx264 @ 00000000051ead60] Possible profiles: baseline main high high10 high422 high444
Dans la documentation x264 --fullhelp, je trouve:
--profile <string> Force the limits of an H.264 profile
Overrides all settings.
[...]
- high10:
No lossless.
Support for bit depth 8-10.
- high422:
No lossless.
Support for bit depth 8-10.
Support for 4:2:0/4:2:2 chroma subsampling.
- high444:
Support for bit depth 8-10.
Support for 4:2:0/4:2:2/4:4:4 chroma subsampling.
Il peut donc faire 4: 2: 2 à 10 bits de profondeur, et même 4: 4: 4 à 10 bits apparemment, mais il n'y a aucune indication sur la façon de définir la profondeur de bits de sortie. Il y a une option --input-depth <integer> Specify input bit depth for raw input
mais rien pour la profondeur de bits de sortie.
Réponses:
x264 prend en charge les sorties 8 bits et 10 bits, et vous n'avez rien à faire de spécial.
ffmpeg
Si
ffmpeg
vous utilisez, vous pouvez voir quels formats de pixels et profondeurs de bits sont pris en charge par libx264:Les formats de pixels 10 bits sont: yuv420p10le, yuv422p10le, yuv444p10le.
x264
Vous pouvez également vérifier
x264
les profondeurs de bits prises en charge:Auparavant, vous deviez compiler x264 avec
--bit-depth=10
, puis lier votreffmpeg
à une libx264 8 bits ou 10 bits, mais ce n'est désormais plus nécessaire. Voir Unify CLI 8 bits et 10 bits et bibliothèques pour plus d'informations.la source
edit: J'ai réussi à faire un encodage 10 bits de Ducks Take Off .
Première façon: j'ai construit un binaire 10 bits x264 qui relie statiquement libx264.
(ultra rapide et de faible qualité car c'est une preuve de concept, pas un test de qualité.) Je ne l'ai pas compilé avec swscale. (Il était mécontent d'un fmt de pixels RVB dans libavutil ou quelque chose). Il génère des erreurs si l'espace colorimétrique d'entrée ne correspond pas
--output-csp i444
, ce qui est en fait bien si vous ne voulez pas accidentellement x264 sous-échantillonner la chrominance. Cela a bien fonctionné lorsque je l'ai alimenté en quelques imagesyuv444p14le.y4m
, produisant une sortie 10 bits. (Il peut tronquer la profondeur de bits, mais pas sous-échantillonner la chrominance sans swscale.)Deuxième méthode: utilisez
LD_LIBRARY_PATH
pour sélectionner une libx264.so 10 bitsVous pouvez utiliser le même binaire lié dynamique ffmpeg pour tout.
Évidemment, je n'ai pas essayé de voir quoi que ce soit visuellement avec ces paramètres de qualité. Je voulais juste qu'il fonctionne rapidement et ne gaspille pas beaucoup d'espace disque car je finis toujours par faire beaucoup de fichiers de sortie lorsque j'essaie de varier les choses.
Ne pas diriger les données massives y4m vers un processus x264 séparé l'a fait passer à 14 images par seconde au lieu de 12, donc une accélération décente pour ultra-rapide. Des encodages plus lents éclipseront cette surcharge.
Ma source est RVB 48 bits. J'ai trouvé que precise_rnd n'avait aucun effet sur la sortie mkv. (résultats identiques en bits avec non
-sws_flags
, avec-sws_flags +accurate_rnd
et-vf scale=flags=accurate_rnd
, à l'exception de quelques bits dans l'en-tête mkv, probablement l'UUID mkv aléatoire. Même avec-qp 0
, donc je ne le perdais pas en raison d'une erreur d'arrondi.cmp -l f1 f2 | less
pour comparer les fichiers binaires qui pourraient être le même après une différence initiale. Oussdeep -p
. Peutaccurate_rnd
- être est-ce la valeur par défaut maintenant?)Il y a un indicateur swfaler ffmpeg qui compte, si vous laissez ffmpeg sous-échantillonner votre chroma: lanczos au lieu du bicubique par défaut. (Je suppose que les lanczos sont toujours considérés comme le meilleur choix pour la haute qualité? Je n'ai pas lu depuis un moment.)
highdepth-ffmpeg -i in -pix_fmt yuv420p10le ...encode...opts...
-vf scale=flags=lanczos -sws_flags +accurate_rnd+print_info with_ld_path.420p10.accurate_rnd.lanczos.mkv
L'ajout
+lanczos
à-sws_flags
ne fonctionne pas:Si vous essayez de l'alimenter en entrée de plus de 10 bits, ffmpeg refuse.
En fait, le pilote libx264 de ffmpeg insiste toujours pour fournir à x264 exactement la profondeur de bits pour laquelle il a été compilé. par exemple avec
-pix_fmt yuv420p
:x264.h dit:
Je pense qu'en interne, x264 (CLI) doit toujours convertir les formats de pixels, le code n'a pas d'entrée 8 bits, versions de sortie 10 bits de chaque fonction. Et aussi, je pense que l'acceptation de différentes profondeurs de bits d'entrée se fait uniquement dans la CLI x264, pas dans l'API de la bibliothèque. Je suis curieux de savoir ce qui se passe lorsque vous alimentez l'entrée API où des bits plus élevés sont définis ... (ffpeg ne vous permet pas de le faire sans pirater le code, donc ce n'est pas quelque chose que personne ne doit s'inquiéter d'éviter).
Sans pix_fmt spécifié, ffmpeg choisit
yuv444p10le
lorsqu'il reçoit une entrée rgb. Ou aveclibx264rgb
, il alimente 8 bits rgb aux fonctions qui attendent 16 bits (dont 10 sont significatifs), et segfaults>. <. Je vais rapporter ça en amont ...Je signalerai cela en amont.
Quoi qu'il en soit, il s'est avéré qu'il était assez facile de me créer un environnement à double profondeur de bit pour ffmpeg ou tout autre programme que vous souhaitez exécuter avec des versions compilées à haute profondeur de libx264, libx265 et tout ce que vous voulez . (C'est pourquoi je l'ai appelé "highdepth", pas seulement "10bit" pour un nom plus court.)
fin du montage: ci-dessous voici mes divagations sans recompilation. Et un peu sur la façon de compiler de manière croisée ffmpeg pour win64
J'ai essayé cela moi-même, car vous n'avez pas essayé avec une cmdline qui a essayé de fournir une entrée à haute profondeur de bits à x264.
Les noms de format de pixel ffmpeg (
ffmpeg -pix_fmts
) ne spécifient pas seulement un arrangement, ils sont mappés sur un arrangement de bits exact, et donc chaque combo format + profondeur de bits a un nom différent. Je pense que vous vous attendiez-pix_fmt yuv422p
à dire "convertir en 422 dans la même profondeur de bits que mon entrée".wikipedia indique que le h.264 prend en charge la profondeur de 8-14 bits uniquement avec Hi444PP, d'autres ne sont que jusqu'à 10 bits. Hi444PP est le seul profil qui prend en charge le codage prédictif sans perte, que x264 utilise pour
-qp 0
ou-crf 0
. edit: AFAICT, x264 ne supporte toujours que la compilation pour 8, 9 ou 10 bits.Quoi qu'il en soit, voici un tas de sorties inutiles d'une commande qui ne fonctionne pas car je n'ai pas recompilé mon x264 local. (Mais cela devrait fonctionner avec les x264 recompilés. Je pourrais éditer cette réponse si je veux jouer avec.)
ffmpeg -v verbose -framerate 50 -f image2 -pattern_type glob -i ./3_DucksTakeOff_720p50_CgrLevels_SINC_FILTER_SVTdec05_/'*'.sgi -c:v libx264 -pix_fmt yuv420p10le -profile high10 yuv-high.mkv
Notez la
Incompatible pixel format 'yuv420p10le' for codec 'libx264', auto-selecting format 'yuv420p'
ligne.Je n'en avais probablement pas besoin
-profile
, et avec un x264 à profondeur de bits élevée, cela fonctionnerait tout simplement. (et potentiellement choisir 444 10 bits, que ffmpeg appelleyuva444p10le
.) Je pense que la profondeur de bits élevée x264 pourrait accepteryuv444p14le
, mais ne produirait tout de même que 10 bits h.264. La ligne de commandex264 --fullhelp
est assez explicite sur la profondeur de bits de sortie de 8 à 10, pas plus. Étrange qui-profile high10
est juste silencieusement ignoré par 8 bits x264.En interne, x264 compilé pour une profondeur de bits élevée utilise 16 bpp pour stocker toutes les données 10 bits, il effectue donc probablement une recherche de mouvement et ainsi de suite avec des valeurs 16 bits. Et le DCT pourrait être supérieur à 16 bits plutôt qu'à 10 bits, à moins qu'il n'y ait de la vitesse à gagner en ignorant 6 bits. Cela pourrait produire des coefficients DCT légèrement différents que si vous arrondissiez à 10 bits avant DCT. (Donc, vous obtenez potentiellement une sortie différente de la conversion en 10 bits avant de l'alimenter en x264, par rapport à 12, 14 ou 16 bits.) Je devrais essayer. regardez le code ou essayez-le avant de faire des trucs, cependant. Ne faites pas confiance à ce paragraphe. : P
(edit: ffmpeg n'alimentera pas x264-10bit plus de 10 bits par composant. Il utilisera swscale pour réduire la profondeur de bits elle-même.)
Je me demande à quel point il serait difficile de patcher x264 et x265 pour utiliser des noms différents pour les variables globales et les fonctions API, une fois compilés pour une grande profondeur de bits. Ensuite, vous pouvez créer les deux versions à la fois et avoir ffmpeg lié aux deux. Le ffmpeg
libx264
et leslibx264rgb
wrappers pourraient prendre soin d'appeler la version appropriée de l'API en fonction du flux d'entrée. (Sinon, vous auriez besoin-c:v libx264-deep
oulibx264rgb-deep
, pour un total de 4 "codecs" x264 différents dans ffmpeg.)Comment croiser compiler ffmpeg pour Windows
edit: Pour Windows, je ne pense pas qu'il y ait quelque chose d'aussi pratique que
LD_LIBRARY_PATH
pour une DLL libx264, donc votre meilleur pari est toujours de construire un binaire statique à grande profondeur de bits, et un autre pour une utilisation normale. La libx264 haute profondeur NE PEUT PAS produire de profondeur normale h.264. Pas seulement une pénalité de vitesse, cela ne peut tout simplement pas.La façon la plus simple de compiler votre propre ffmpeg (binaire statique) pour Windows est avec https://github.com/rdp/ffmpeg-windows-build-helpers . git clone le dépôt sur une machine Linux (ou peut-être un autre système avec un gcc fonctionnel, comme OS X?), puis lancez
./cross_compile_ffmpeg.sh --high-bitdepth=y --disable-nonfree=n --build-choice=win64
Cela a pris environ 8 heures pour la première exécution, car il a construit le GCC mingw-cross-compile à partir de la source, avec tout le reste. (gcc par défaut se reconstruit plusieurs fois pour démarrer, au cas où vous le compiliez à l'origine avec un mauvais compilateur.)
Vous pouvez mettre à jour le script de construction avec
git pull
, et le relancer tirera les dernières mises à jour git pour ffmpeg, x264, x265, et peut-être certains des autres projets qu'il compile à partir de la source. (Pour la plupart, il télécharge simplement les archives tar.)Mon bureau Linux montre son âge. J'ai une Nintendo que j'utilise principalement pour les jeux. Depuis que j'ai commencé à jouer avec l'encodage vidéo, je trouve son Sandybridge quadricœur assez utile pour cela aussi, en particulier. pour x265. Probablement, certaines des fonctions de x265 n'ont que des versions asm pour AVX / SSE4, donc elles retombent en C sur ma machine Linux SSSE3 (Conroe). Cela ou c'est plus visible à 1fps ...
la source
brew reinstall x264 --with-10-bit
et vous avez terminé, ffmpeg utilisera la nouvelle saveur x264 :)J'ai téléchargé le ffmpeg à partir du lien ci-dessous https://sourceforge.net/projects/ffmpeg-hi/?source=typ_redirect
Et entré la commande ci-dessous pour créer un fichier 4: 2: 2 10bit h.264. ffmpeg-hi10-heaac.exe -i "im.mp4" -c: v libx264 -pix_fmt yuv422p10le yuv-high-.ts
la source