Acredito que a libx264 agora é capaz de fazer codificações de 10 bits 4: 2: 2, mas não consigo fazê-la funcionar. Estou usando o ffmpeg (informações abaixo) e também tentei o codificador x264 diretamente. eu tentei
ffmpeg.exe -i input.mov -c:v libx264 -profile:v high422 -crf 20 -pix_fmt yuv422p output.mp4
e isso produz uma saída agradável de 4: 2: 2, mas apenas com profundidade de 8 bits,
[libx264 @ 00000000055a9de0] profile High 4:2:2, level 4.0, 4:2:2 8-bit
e eu tentei
ffmpeg.exe -i input.mov -c:v libx264 -profile:v high10 -crf 20 -pix_fmt yuv422p output.mp4
e isso me dá o erro:
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
Na documentação x264 --fullhelp, encontro:
--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.
Portanto, ele pode executar 4: 2: 2 na profundidade de 10 bits e até 4: 4: 4 em 10 bits, aparentemente, mas não há indicação de como definir a profundidade do bit de saída. Existe uma opção, --input-depth <integer> Specify input bit depth for raw input
mas nada para a profundidade de bits de saída.
Respostas:
O x264 suporta saídas de 8 e 10 bits, e você não precisa fazer nada de especial.
ffmpeg
Se estiver usando,
ffmpeg
você poderá ver quais formatos de pixel e profundidade de bits são suportados pela libx264:Os formatos de pixel de 10 bits são: yuv420p10le, yuv422p10le, yuv444p10le.
x264
Você também pode verificar
x264
as profundidades de bits suportadas:Anteriormente, era necessário compilar o x264
--bit-depth=10
e vincular o seuffmpeg
a uma libx264 de 8 ou 10 bits, mas isso agora é desnecessário. Consulte Unificar CLI e bibliotecas de 8 e 10 bits para obter mais informações.fonte
editar: fiz com sucesso uma codificação de 10 bits do Ducks Take Off .
Primeira maneira: criei um binário x264 de 10 bits que vincula estaticamente a libx264.
(qualidade ultra-rápida e baixa, porque é uma prova de conceito, não um teste de qualidade.) Não o compilei com escala de sws. (Foi infeliz sobre um pix pix fmt no libavutil ou algo assim). Ele errará se o espaço de cores de entrada não corresponder
--output-csp i444
, o que é realmente bom se você não quiser acidentalmente reduzir a amostra x264 no chroma. Funcionou bem quando eu alimentei alguns quadros deyuv444p14le.y4m
, produzindo uma saída de 10 bits. (Ele pode truncar a profundidade do bit, mas não reduz a amostra do croma sem escala de escala.)Segunda maneira: use
LD_LIBRARY_PATH
para selecionar um libx264.so de 10 bitsVocê pode usar o mesmo binário vinculado dinâmico ffmpeg para tudo.
Obviamente, não tentei ver nada visualmente com essas configurações de qualidade. Eu só queria que ele fosse rápido, e não desperdiçasse muito espaço em disco, pois eu sempre acabava criando muitos arquivos de saída ao tentar variações nas coisas.
O fato de não canalizar os enormes dados do y4m para um processo x264 separado fez com que ele ficasse em 14 fps em vez de 12, portanto, uma aceleração decente para ultra-rápido. Codificações mais lentas superam essa sobrecarga.
Minha fonte é 48bit RGB. Descobri que o preciso_rnd não teve efeito sobre a saída mkv. (resultados idênticos a bit com no
-sws_flags
, with-sws_flags +accurate_rnd
e-vf scale=flags=accurate_rnd
, exceto por alguns bits no cabeçalho mkv, provavelmente o UUID mkv aleatório. Mesmo com-qp 0
, então eu não estava perdendo por erro de arredondamento.cmp -l f1 f2 | less
para comparar arquivos binários que podem ser os mesmo depois de alguma diferença inicial. Oussdeep -p
talvezaccurate_rnd
seja o padrão agora?)Existe um sinalizador ffmpeg swscaler que importa, se você estiver deixando o ffmpeg reduzir a amostra do seu chroma: lanczos em vez do bicúbico padrão. (Presumo que os lanczos ainda sejam considerados a melhor opção para alta qualidade? Não leiam há um tempo.)
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
Adicionar
+lanczos
a-sws_flags
não funciona:Se você tentar alimentá-lo com mais de 10 bits, o ffmpeg recusa.
Na verdade, o driver libx264 do ffmpeg sempre insiste em alimentar o x264 exatamente a profundidade de bits para a qual ele foi compilado. por exemplo, com
-pix_fmt yuv420p
:x264.h diz:
Eu acho que internamente x264 (a CLI) sempre precisa converter os formatos de pixel, o código não tem entrada de 8 bits, versões de saída de 10 bits de todas as funções. Além disso, acho que a aceitação de várias profundidades de bits de entrada está apenas na CLI x264, não na API da biblioteca. Estou curioso para saber o que acontece quando você alimenta a entrada da API onde há bits maiores definidos ... (o ffpeg não permite que você faça isso sem hackear o código, portanto, isso não é algo que ninguém precise se preocupar em evitar.)
Sem pix_fmt especificado, o ffmpeg escolhe
yuv444p10le
quando recebe entrada rgb. Ou entãolibx264rgb
, alimenta 8 bits rgb a funções que esperam 16 bits (10 das quais são significativas) e segfaults>. <. Vou reportar isso a montante ...Vou relatar isso a montante.
De qualquer forma, foi muito fácil criar um ambiente de profundidade de bit duplo para o ffmpeg, ou qualquer outro programa que você queira executar com versões compiladas de alta profundidade de libx264, libx265 e qualquer outra coisa que você queira . (Foi por isso que chamei de "profundidade profunda", não apenas "10 bits" para um nome mais curto.)
fim da edição: abaixo estão minhas divagações sem recompilar. E um pouco sobre como compilar o ffmpeg para o win64
Tentei isso sozinho, já que você não tentou com um cmdline que tentou alimentar a entrada de profundidade de bits alta para x264.
Os nomes de formato de pixel ffmpeg (
ffmpeg -pix_fmts
) não apenas especificam um arranjo, eles mapeiam para um arranjo exato de bits e, portanto, cada combinação de formato + profundidade de bits tem um nome diferente. Eu acho que você esperava-pix_fmt yuv422p
significar "converter para 422 na mesma profundidade de bits que minha entrada".A wikipedia diz que o h.264 suporta profundidade de 8 a 14 bits apenas no Hi444PP, enquanto outros têm apenas 10 bits. Hi444PP é o único perfil que suporta codificação preditiva sem perdas, que o x264 usa para
-qp 0
ou-crf 0
. edit: AFAICT, x264 ainda suporta apenas a compilação de 8, 9 ou 10 bits.Enfim, aqui está um monte de saída inútil de um comando que não funciona porque eu não recompilei meu x264 local. (Mas deve funcionar com o x264 recompilado. Talvez eu edite esta resposta se quiser brincar com ela.)
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
Observe a
Incompatible pixel format 'yuv420p10le' for codec 'libx264', auto-selecting format 'yuv420p'
linha.Provavelmente eu não precisava
-profile
, e com um x264 de alta profundidade de bits, funcionaria. (e, potencialmente, escolha 444 10 bits, que o ffmpeg chamayuva444p10le
.) Acho que a profundidade de bits alta x264 poderia aceitaryuv444p14le
, mas ainda produziria apenas 10 bits h.264. O cmdlinex264 --fullhelp
é bastante explícito sobre a profundidade do bit de saída de 8 a 10, e não mais. Estranho que-profile high10
é silenciosamente ignorado por 8bit x264.Internamente, o x264 compilado para alta profundidade de bits usa 16bpp para armazenar dados de 10 bits, por isso provavelmente faz pesquisa de movimento e assim por diante com valores de 16 bits. E pode DCT maior que 16 bits em vez de 10 bits, a menos que haja velocidade a ser obtida ao ignorar 6 bits. Isso pode produzir coeficientes de DCT ligeiramente diferentes do que se você arredondasse para 10 bits antes do DCT. (Portanto, você potencialmente obtém uma saída diferente da conversão para 10 bits antes de alimentar x264, em comparação com 12, 14 ou 16 bits.) Eu deveria tentar. veja o código ou tente antes de inventar coisas. Não confie neste parágrafo. : P
(edit: ffmpeg não alimenta x264-10bit com nada mais que 10 bits por componente. Ele usará swscale para reduzir a profundidade de bits.)
Gostaria de saber como seria difícil corrigir o x264 e o x265 para usar nomes diferentes para variáveis globais e funções da API, quando compiladas para obter profundidade de bits alta. Em seguida, você pode criar as duas versões ao mesmo tempo e ter o ffmpeg vinculado a ambas. O ffmpeg
libx264
e oslibx264rgb
wrappers podem chamar a versão apropriada da API, dependendo do fluxo de entrada. (Caso contrário, você precisaria-c:v libx264-deep
oulibx264rgb-deep
, para um total de 4 "codecs" x264 diferentes em ffmpeg.)Como cruzar a compilação do ffmpeg para windows
edit: Para Windows, não acho que exista algo tão conveniente quanto
LD_LIBRARY_PATH
para uma DLL libx264; portanto, sua melhor aposta ainda é criar um binário estático de alta profundidade de bits e outro para uso normal. A libx264 de alta profundidade NÃO PODE produzir a profundidade normal h.264. Não é apenas uma penalidade de velocidade, simplesmente não pode.A maneira mais fácil de compilar seu próprio ffmpeg (binário estático) para o Windows é com https://github.com/rdp/ffmpeg-windows-build-helpers . O git clona o repositório em uma máquina Linux (ou talvez em outro sistema com um gcc ativo, como o OS X?), depois execute
./cross_compile_ffmpeg.sh --high-bitdepth=y --disable-nonfree=n --build-choice=win64
Isso levou cerca de 8 horas para a primeira execução, uma vez que ele criou o GCC mingw-cross-compile a partir da fonte, junto com todo o resto. (o gcc assume o padrão de se reconstruir várias vezes para iniciar, caso você o tenha compilado originalmente com um compilador incorreto.)
Você pode atualizar o script de construção
git pull
e, ao executá-lo, obterá as atualizações mais recentes do git para ffmpeg, x264, x265 e talvez alguns dos outros projetos que ele compila a partir do código-fonte. (Para a maioria, basta baixar tarballs.)Minha área de trabalho Linux está mostrando sua idade. Eu tenho um wintendo que uso principalmente para jogos. Desde que comecei a mexer com a codificação de vídeo, acho o seu Sandybridge quad-core bastante útil para isso também. para x265. Provavelmente, algumas das funções do x265 possuem apenas versões ASM para AVX / SSE4, portanto, estão voltando ao C na minha máquina Linux SSSE3 (Conroe). Isso ou é mais perceptível a 1fps ...
fonte
brew reinstall x264 --with-10-bit
e pronto, o ffmpeg usará o novo sabor x264 :)Eu baixei o ffmpeg no link abaixo https://sourceforge.net/projects/ffmpeg-hi/?source=typ_redirect
E inseriu o comando abaixo para criar o arquivo 4: 2: 2 10bit h.264. ffmpeg-hi10-heaac.exe -i "im.mp4" -c: v libx264 -pix_fmt yuv422p10le yuv-high-.ts
fonte