Creo que libx264 ahora es capaz de hacer codificaciones 4: 2: 2 de 10 bits, pero parece que no puedo hacer que funcione. Estoy usando ffmpeg (información a continuación), y también probé el codificador x264 directamente. He intentado
ffmpeg.exe -i input.mov -c:v libx264 -profile:v high422 -crf 20 -pix_fmt yuv422p output.mp4
y eso produce una buena salida 4: 2: 2, pero solo a una profundidad de 8 bits,
[libx264 @ 00000000055a9de0] profile High 4:2:2, level 4.0, 4:2:2 8-bit
y lo he intentado
ffmpeg.exe -i input.mov -c:v libx264 -profile:v high10 -crf 20 -pix_fmt yuv422p output.mp4
y eso me da el error:
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
En la documentación de x264 --fullhelp encuentro:
--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.
Por lo tanto, puede hacer 4: 2: 2 a 10 bits de profundidad, e incluso 4: 4: 4 a 10 bits aparentemente, pero no hay indicación de cómo configurar la profundidad de bits de salida. Hay una opción --input-depth <integer> Specify input bit depth for raw input
pero nada para la profundidad de bits de salida.
Respuestas:
x264 admite salidas de 8 bits y 10 bits, y no tiene que hacer nada especial.
ffmpeg
Si lo usa
ffmpeg
, puede ver qué formatos de píxeles y profundidades de bits son compatibles con libx264:Los formatos de píxeles de 10 bits son: yuv420p10le, yuv422p10le, yuv444p10le.
x264
También puede verificar
x264
las profundidades de bits admitidas:Anteriormente tenía que compilar x264 con
--bit-depth=10
, y luego vincularloffmpeg
a una libx264 de 8 o 10 bits, pero eso ahora es innecesario. Consulte Unify CLI y bibliotecas de 8 y 10 bits para obtener más información.fuente
editar: Hice con éxito una codificación de 10 bits de Ducks Take Off .
Primera forma: construí un binario de 10 bits x264 que vincula estáticamente libx264.
(ultrarrápido y de baja calidad porque es una prueba de concepto, no una prueba de calidad). No lo compilé con swscale. (No estaba contento con un RGB pix fmt en libavutil o algo así). Se produce un error si el espacio de color de entrada no coincide
--output-csp i444
, lo cual es realmente bueno si no desea que x264 muestree el croma accidentalmente. Funcionó bien cuando le di algunos fotogramasyuv444p14le.y4m
, produciendo una salida de 10 bits. (Puede truncar la profundidad de bits, pero no reducir la cantidad de croma sin swscale).Segunda forma: use
LD_LIBRARY_PATH
para seleccionar un libx264.so de 10 bitsPuede usar el mismo binario dinámico vinculado ffmpeg para todo.
Obviamente no intenté ver nada visualmente con esos ajustes de calidad. Solo quería que se ejecute rápido y no desperdicie un montón de espacio en disco, ya que siempre termino haciendo muchos archivos de salida cuando intento variaciones en las cosas.
El hecho de no canalizar los datos masivos de y4m a un proceso x264 separado lo hizo ir a 14 fps en lugar de 12, por lo que una aceleración decente para ultrarrápido. Codificaciones más lentas empequeñecerán esa sobrecarga
Mi fuente es 48bit RGB. Descubrí que accurate_rnd no tenía ningún efecto en la salida mkv. (resultados idénticos a los bits con no
-sws_flags
, con-sws_flags +accurate_rnd
y-vf scale=flags=accurate_rnd
, a excepción de algunos bits en el encabezado mkv, probablemente el UUID mkv aleatorizado. Incluso con-qp 0
, así que no lo estaba perdiendo por error de redondeo.cmp -l f1 f2 | less
para comparar archivos binarios que podrían ser el igual después de alguna diferencia inicial. O ¿ssdeep -p
Tal vezaccurate_rnd
es el valor predeterminado ahora?)Hay una marca ffmpeg swscaler que importa, si está dejando que ffmpeg reduzca la cantidad de su chroma: lanczos en lugar del bicúbico predeterminado. (¿Asumo que lanczos todavía se considera la mejor opción para la alta calidad? No he leído por un tiempo).
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
Agregar
+lanczos
a-sws_flags
no funciona:Si intenta alimentarlo con una entrada de más de 10 bits, ffmpeg se niega.
En realidad, el controlador libx264 de ffmpeg siempre insiste en alimentar x264 exactamente la profundidad de bits para la que está compilado. por ejemplo con
-pix_fmt yuv420p
:x264.h dice:
Creo que internamente x264 (la CLI) siempre tiene que convertir los formatos de píxeles, el código no tiene versiones de entrada de 8 bits, salida de 10 bits de cada función. Y también, creo que la aceptación de varias profundidades de bits de entrada es solo en la CLI x264, no en la API de la biblioteca. Tengo curiosidad por saber qué sucede cuando alimentas la entrada de la API donde hay más bits establecidos ... (ffpeg no te permite hacer esto sin hackear el código, por lo que esto no es algo de lo que alguien deba preocuparse por evitar).
Sin pix_fmt especificado, ffmpeg elige
yuv444p10le
cuando se le da entrada rgb. O conlibx264rgb
, alimenta 8bit rgb a funciones que esperan 16bit (10 de las cuales son significativas), y segfaults>. <. Iré a informar eso río arriba ...Informaré eso río arriba.
De todos modos, resulta que fue bastante fácil crear un entorno de doble profundidad de bits para ffmpeg, o cualquier otro programa que desee ejecutar con versiones compiladas de alta profundidad de bits de libx264, libx265 y cualquier otra cosa que desee . (Es por eso que lo llamé "alta profundidad", no solo "10 bits" para un nombre más corto).
Fin de la edición: a continuación, aquí están mis divagaciones sin recompilar. Y un poco sobre cómo compilar cruzadamente ffmpeg para win64
Probé esto yo mismo, ya que no probaste con una cmdline que intentaba alimentar la entrada de alta profundidad de bits a x264.
Los nombres de formato de píxel ffmpeg (
ffmpeg -pix_fmts
) no solo especifican una disposición, sino que se asignan a una disposición de bits exacta y, por lo tanto, cada combinación de formato + profundidad de bits tiene un nombre diferente. Creo que esperaba-pix_fmt yuv422p
significar "convertir a 422 en la misma profundidad de bits que mi entrada".Wikipedia dice que h.264 admite una profundidad de 8-14 bits solo con Hi444PP, otras solo tienen hasta 10 bits. Hi444PP es el único perfil que admite la codificación predictiva sin pérdidas, que x264 utiliza para
-qp 0
o-crf 0
. editar: AFAICT, x264 todavía solo es compatible con la compilación de 8, 9 o 10 bits.De todos modos, aquí hay un montón de resultados inútiles de un comando que no funciona porque no recompilé mi x264 local. (Pero debería funcionar con x264 recompilado. Podría editar esta respuesta si quiero jugar con ella).
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
Tenga en cuenta la
Incompatible pixel format 'yuv420p10le' for codec 'libx264', auto-selecting format 'yuv420p'
línea.Probablemente no lo necesitaba
-profile
, y con un x264 de alta profundidad de bits, simplemente funcionaría. (y potencialmente elegir 444 10 bits, que llama ffmpegyuva444p10le
). Creo que la profundidad de bits alta x264 podría aceptaryuv444p14le
, pero todavía solo produciría 10 bits h.264. El cmdlinex264 --fullhelp
es bastante explícito sobre la profundidad de bits de salida de 8 a 10, no mayor. Extraño que-profile high10
es ignorado silenciosamente por 8bit x264.Internamente, x264 compilado para alta profundidad de bits utiliza 16 bpp para almacenar cualquier dato de 10 bits, por lo que probablemente realice una búsqueda de movimiento, etc. con valores de 16 bits. Y puede que DCT sea superior a 16 bits en lugar de 10 bits, a menos que se obtenga velocidad al ignorar 6 bits. Esto podría producir coeficientes DCT ligeramente diferentes que si se redondea a 10 bits antes de DCT. (Por lo tanto, puede obtener una salida diferente al convertir a 10 bits antes de alimentar a x264, en lugar de darle 12, 14 o 16 bits). Debería probar. sin embargo, mira el código o pruébalo antes de inventarlo. No confíes en este párrafo. :PAGS
(editar: ffmpeg no alimentará x264-10bit nada más que 10 bits por componente. Utilizará swscale para reducir la profundidad de bits en sí).
Me pregunto qué tan difícil sería aplicar un parche a x264 y x265 para usar diferentes nombres para variables globales y funciones de API, cuando se compila para una profundidad de bits alta. Luego, podría compilar ambas versiones a la vez y vincular ffmpeg contra ambas. El ffmpeg
libx264
y loslibx264rgb
wrappers podrían encargarse de llamar a la versión apropiada de la API dependiendo de la secuencia de entrada. (De lo contrario, necesitaría-c:v libx264-deep
olibx264rgb-deep
, para un total de 4 "códecs" x264 diferentes en ffmpeg).Cómo cruzar compilar ffmpeg para windows
editar: para Windows, no creo que haya algo tan conveniente como
LD_LIBRARY_PATH
para una DLL libx264, por lo que su mejor opción es construir un binario estático de alta profundidad de bits y otro para uso normal. La libx264 de alta profundidad NO PUEDE generar la profundidad normal h.264 en absoluto. No es solo una penalización de velocidad, simplemente no puede.La forma más fácil de compilar su propio ffmpeg (binario estático) para Windows es con https://github.com/rdp/ffmpeg-windows-build-helpers . git clone el repositorio en una máquina Linux (¿o tal vez otro sistema con un gcc que funcione, como OS X?), luego ejecute
./cross_compile_ffmpeg.sh --high-bitdepth=y --disable-nonfree=n --build-choice=win64
Esto tomó alrededor de 8 horas para la primera ejecución, ya que construyó Mingw-cross-compile GCC desde la fuente, junto con todo lo demás. (gcc por defecto se reconstruye varias veces a sí mismo en bootstrap, en caso de que originalmente lo estuvieras compilando con un mal compilador).
Puede actualizar el script de compilación
git pull
y, al volver a ejecutarlo, obtendrá las últimas actualizaciones de git para ffmpeg, x264, x265 y quizás algunos de los otros proyectos que compila desde la fuente. (Para la mayoría, solo descarga tarballs).Mi escritorio de Linux está mostrando su edad. Tengo una Nintendo que uso principalmente para juegos. Desde que comencé a jugar con la codificación de video, encuentro que su Sandybridge de cuatro núcleos es muy útil para eso, especialmente, especialmente. para x265. Probablemente algunas de las funciones de x265 solo tienen versiones asm para AVX / SSE4, por lo que está volviendo a C en mi máquina SSSE3 Linux (Conroe). Eso o es más notable a 1 fps ...
fuente
brew reinstall x264 --with-10-bit
y listo, ffmpeg usará el nuevo sabor x264 :)Descargué el ffmpeg del siguiente enlace https://sourceforge.net/projects/ffmpeg-hi/?source=typ_redirect
E ingresó el siguiente comando para crear un archivo h.264 4: 2: 2 de 10 bits. ffmpeg-hi10-heaac.exe -i "im.mp4" -c: v libx264 -pix_fmt yuv422p10le yuv-high-.ts
fuente