Como criar um AVI descompactado a partir de uma série de milhares de imagens PNG usando FFMPEG

31

Como posso criar um AVI descompactado a partir de uma série de milhares de imagens PNG usando o FFMPEG?

Eu usei este comando para converter um input.aviarquivo em uma série de quadros PNG:

ffmpeg -y -i input.avi  -an -vcodec png  -s 1024x768 pic%d.png`

Agora preciso saber como criar um vídeo AVI descompactado a partir de todos esses quadros PNG. Eu tentei isso:

ffmpeg -i pic%d.png -y -f avi -b 1150 -s 1024x768 -r 29.97 -g 12 -qmin 3 -qmax 13 -ab 224 -ar 44100 -ac 2 test.avi

Mas o vídeo resultante perde muita qualidade em relação ao AVI original.

Warren Young
fonte

Respostas:

77

Existem várias maneiras de obter um AVI "não compactado" ffmpeg, mas suspeito que você realmente queira dizer "sem perdas". Ambos os termos têm bastante espaço de manobra em suas definições, como você verá.

Vou ancorar essa discussão com a versão 720p em HD do Big Buck Bunny , já que é um vídeo disponível gratuitamente, com o qual todos podemos testar e obter resultados que podemos comparar. A taxa de dados brutos do vídeo de 1280 × 720p a 24 qps é quase igual à meta estabelecida de 1024 × 768 a 29,97 qps, então meus resultados devem ser um bom guia para as taxas de dados que você pode esperar nas suas imagens.

Listagem automática de opções disponíveis

O seguinte comando POSIX¹ fornece uma lista que² corresponde principalmente ao que discutimos abaixo:

$ ffmpeg -codecs 2> /dev/null | grep '^..EV..S ' | grep -vE 'bitmap|image'

Você pode querer executar esse comando em sua própria máquina para ver o que sua compilação do FFmpeg suportará. O FFmpeg raramente é criado com todos os codificadores possíveis ativados.

Agora vamos discutir essas opções.

Totalmente descomprimido

Se a sua definição de "descomprimido" é a forma que o vídeo está em direito antes de ser virou-se para fótons por um display digital, o mais próximo que eu vejo na ffmpeg -codecslista são -c:v r210, r10k, v410, v308, ayuve v408. Estas são todas substancialmente a mesma coisa, diferindo apenas na intensidade da cor , o espaço de cor , e alfa canal de apoio.

  • R210 e R10K são 4: 4: 4 RGB a 10 bits por componente (bpc), portanto, ambos exigem cerca de 708 Mbit / s para 720p em meus testes. (Isso é cerca de ⅓ TB por hora, amigos!)

    Esses codecs incluem os componentes de cores de 3 x 10 bits por pixel em um valor de 32 bits para facilitar a manipulação por computadores, como tamanhos de potência de 2. A única diferença entre esses codecs é em qual extremidade da palavra de 32 bits estão os dois bits não utilizados. Essa diferença trivial é sem dúvida porque eles vêm de empresas concorrentes, Blackmagic Design e AJA Video Systems , respectivamente.

    Embora sejam codecs triviais, você provavelmente precisará fazer o download dos codecs Blackmagic e / ou AJA para reproduzir arquivos usando-os no seu computador. Ambas as empresas permitirá que você baixar seus codecs sem ter comprado o seu hardware primeiro, pois eles sabem que você pode estar lidando com arquivos produzidos por clientes que fazem tem algum do seu hardware.

  • V410 é essencialmente apenas a versão YUV do R210 / R10K; suas taxas de dados são idênticas. No entanto, esse codec pode codificar mais rapidamente, porque ffmpegé mais provável que haja um caminho de conversão acelerada do espaço de cores entre o espaço de cores dos quadros de entrada e esse espaço de cores.

    Entretanto, não posso recomendar esse codec, pois não consegui reproduzir o arquivo resultante em qualquer software que tentei, mesmo com os codecs AJA e Blackmagic instalados.

  • O V308 é a variante de 8 bpc do V410, portanto chega a 518 Mbit / s nos meus testes. Assim como na V410, não consegui reproduzir esses arquivos no software normal do player de vídeo.

  • AYUV e V408 são essencialmente a mesma coisa que V308, exceto que incluem um canal alfa, se é necessário ou não! Se o seu vídeo não usar transparência, isso significa que você paga a penalidade de tamanho dos codecs R210 / R10K de 10 bpc acima, sem obter o benefício do espaço de cores mais profundo.

    O AYUV tem uma virtude: é um codec "nativo" no Windows Media, portanto não requer software especial para ser reproduzido.

    O V408 deveria ser nativo do QuickTime da mesma maneira, mas o arquivo V408 não seria reproduzido no QuickTime 7 ou 10 no meu Mac.

Então, reunindo tudo isso, se seus PNGs tiverem nome frame0001.pnge assim por diante:

$ ffmpeg -i frame%04d.png -c:v r10k output.mov
  ...or...                -c:v r210 output.mov
  ...or...                -c:v v410 output.mov
  ...or...                -c:v v408 output.mov
  ...or...                -c:v v308 output.mov
  ...or...                -c:v ayuv output.avi

Observe que eu especifiquei AVI no caso do AYUV, já que é praticamente um codec apenas para Windows. Os outros podem funcionar no QuickTime ou no AVI, dependendo de quais codecs estão na sua máquina. Se um formato de contêiner não funcionar, tente o outro.

Os comandos acima - e também os abaixo - assumem que os quadros de entrada já têm o mesmo tamanho que você deseja para o seu vídeo de saída. Caso contrário, adicione algo parecido -s 1280x720ao comando, antes do nome do arquivo de saída.

RGB compactado, mas também sem perdas

Se, como suspeito, você quer dizer "sem perdas" em vez de "não compactado", uma escolha muito melhor do que qualquer uma das opções acima é o Apple QuickTime Animation , via-c:v qtrle

Sei que você disse que queria um AVI, mas o fato é que você provavelmente precisará instalar um codec em uma máquina Windows para ler qualquer um dos formatos de arquivo baseados em AVI mencionados aqui, enquanto no QuickTime há uma chance do vídeo O aplicativo de sua escolha já sabe como abrir um arquivo de animação do QuickTime. (O codec AYUV acima é a única exceção que eu conheço, mas sua taxa de dados é muito alta, apenas para obter o benefício do AVI.)

ffmpegirá encher qtrleum contêiner AVI para você, mas o resultado pode não ser muito compatível. Nos meus testes, o QuickTime Player se queixa um pouco desse arquivo, mas ele é reproduzido. Estranhamente, porém, o VLC não o reproduz, embora seja baseado em parte ffmpeg. Eu me ateria aos contêineres QT desse codec.

O codec do QuickTime Animation usa um esquema RLE trivial ; portanto, para animações simples, ele deve funcionar tão bem quanto o Huffyuv abaixo. Quanto mais cores em cada quadro, mais se aproximará da taxa de bits das opções totalmente descompactadas acima. Nos meus testes com Big Buck Bunny, consegui ffmpegme fornecer um arquivo de 165 Mbit / s no modo RGB 4: 4: 4, via -pix_fmt rgb24.

Embora esse formato seja compactado, ele fornecerá valores de pixel de saída idênticos aos seus arquivos de entrada PNG, pelo mesmo motivo que a compactação sem perdas do PNG não afeta os valores de pixel.

A ffmpegimplementação do QuickTime Animation também suporta -pix_fmt argb, o que permite obter RGB 4: 4: 4: 4, o que significa que possui um canal alfa. De uma maneira bastante grosseira, é o equivalente do QuickTime -c:v ayuvmencionado acima. Devido à compressão sem perdas, porém, chega a apenas 214 Mbit / s , menos que ⅓ a taxa de dados do AYUV com perda zero de qualidade ou recursos.

Existem variantes do QuickTime Animation com menos de 24 bits por pixel, mas elas são melhor usadas para estilos de animação progressivamente mais simples. ffmpegparece suportar apenas um dos outros formatos definidos pela especificação -pix_fmt rgb555be, o que significa RGB big-endian de 15 bpp. É tolerável para alguns vídeos e é bom para a maioria das capturas de tela e animações simples. Se você pode aceitar a dizimação do espaço de cores, a taxa de dados de 122 Mbit / s pode ser atraente.

Juntando tudo isso:

$ ffmpeg -i frame%04d.png -c:v qtrle -pix_fmt rgb24    output.mov
  ...or...                           -pix_fmt argb     output.mov
  ...or...                           -pix_fmt rgb555be output.mov

Efetivamente sem perdas: o truque do YUV

Agora, o problema do RGB e do 4: 4: 4 YUV é que essas codificações são muito fáceis de processar pelos computadores, mas ignoram um fato sobre a visão humana, que é que nossos olhos são mais sensíveis às diferenças de preto e branco do que às diferenças de cores .

Portanto, os sistemas de armazenamento e entrega de vídeo quase sempre usam menos bits por pixel para informações de cores do que para informações de luminância. Isso é chamado de subamostragem de croma . Os esquemas mais comuns são 4: 2: 0 e 4: 2: 2.

A taxa de dados de 4: 2: 0 YUV é apenas 50% superior à do vídeo não compactado em preto e branco (somente Y) e ½ da taxa de dados de 4: 4: 4 RGB ou YUV.

4: 2: 2 é um tipo de ponto intermediário entre 4: 2: 0 e 4: 4: 4. É duas vezes a taxa de dados do vídeo somente em Y e ⅔ a taxa de dados de 4: 4: 4.

Às vezes, você também vê 4: 1: 1, como no antigo padrão da câmera DV . 4: 1: 1 tem a mesma taxa de dados não compactada que 4: 2: 0, mas as informações de cores são organizadas de maneira diferente.

O ponto de tudo isso é que, se você estiver iniciando com um arquivo H.264 4: 2: 0, recodificá-lo para RGB descompactado 4: 4: 4, não comprará absolutamente nada sobre YUV sem perdas 4: 2: 0 compactado. Isso é verdade mesmo se você souber que seu fluxo de trabalho é de 4: 4: 4 RGB, pois é uma conversão trivial; O hardware e o software de vídeo fazem essas conversões dinamicamente rotineiramente.

Você realmente só precisa de 4: 4: 4 quando está espiando os pixels ou está fazendo alterações de cor no nível de pixel no vídeo e precisa preservar os valores exatos dos pixels. O trabalho de efeitos visuais (VFX) é mais fácil de fazer com um formato de pixel 4: 4: 4, por exemplo, portanto, as casas VFX de alta qualidade geralmente estão dispostas a tolerar as taxas de dados mais altas necessárias.

Efetivamente sem perdas: opções de codec

Depois que você se abre para os codecs YUV com dizimação de cores, suas opções também se abrem. ffmpegpossui muitos codecs efetivamente sem perdas .

Huffyuv

A opção mais amplamente compatível é o Huffyuv . Você consegue isso via -c:v huffyuv.

O codec original do Windows Huffyuv suporta apenas dois formatos de pixel: RGB24 e YUV 4: 2: 2. (Na verdade, ele suporta dois tipos de YUV 4: 2: 2, diferindo apenas na ordem dos bytes no disco.)

As versões mais antigas do codec FFmpeg Huffyuv não incluíam suporte a RGB24; portanto, se você tentar e o FFmpeg diz que usará o yuv422pformato de pixel, é necessário atualizar.

O FFmpeg também possui um codec da variante Huffyuv chamado FFVHuff, que suporta YUV 4: 2: 0. Essa variante não é compatível com o codec do Windows DirectShow Huffyuv, mas deve ser aberta em qualquer software baseado em libavcodec, como o VLC.

  • RGB24 - RGB 4: 4: 4 é essencialmente a mesma coisa que a opção de espaço de cores RGB24 do QuickTime Animation. Os dois codecs diferem um pouco na compactação de um determinado arquivo, mas geralmente estarão próximos.

    Também é essencialmente a mesma coisa que o modo YUV 4: 4: 4 usado pela opção V308 acima. A diferença do espaço de cores não faz diferença prática, pois é fácil fazer a conversão do espaço de cores em tempo real.

    Devido à compactação sem perdas do Huffyuv, consegui um vídeo de teste para comprimir cerca de 251 Mbit / s no modo RGB24, com qualidade visual idêntica à que você obteria do V308 ou do AYUV. Se AVI é um absoluto must para você, instalar o codec Huffyuv é provavelmente menos doloroso do que pagar o custo da taxa de dados 3 × de AYUV.

  • YUV 4: 2: 2 - Esse modo é muito mais prático para o vídeo do que o RGB24, o que é sem dúvida o motivo pelo qual os ffmpegdesenvolvedores escolheram implementá-lo primeiro. Como seria de esperar da redução teórica discutida acima, meu arquivo de teste foi codificado para 173 Mbit / s . Isso é exatamente ⅔, se você levar em conta o fato de que a faixa de áudio permaneceu inalterada entre esses dois testes.

  • YUV 4: 2: 0 - Esta opção dizima as informações de cores mais do que 4: 2: 2, reduzindo a taxa de dados para 133 Mbit / s nos meus testes.

Juntando tudo isso:

$ ffmpeg -i frame%04d.png -c:v huffyuv -pix_fmt rgb24   output.avi
  ...or...                             -pix_fmt yuv422p output.avi
  ...or...                -c:v ffvhuff -pix_fmt yuv420p output.avi

Embora o ffvhuffcodec seja padronizado como 4: 2: 0 enquanto escrevo isso, e de fato suporte apenas o formato de pixel na versão de lançamento que estou usando, isso está mudando ; portanto, você deve incluir o sinalizador caso este padrão mude.

Ut Video

Uma opção mais recente, no mesmo espírito que Huffyuv e FFVHuff, é o Ut Video . Como o Huffyuv, existe um codec de vídeo do Windows, o que significa que qualquer programa do Windows que possa reproduzir um filme pode reproduzir vídeos usando esse codec com o codec instalado. Ao contrário do Huffyuv, também há um codec de vídeo para Mac, portanto você não está restrito ao software baseado no FFmpeg ou libavcodecpara ler esses arquivos nos Macs.

Esse codec é muito flexível em termos de espaços de cores, portanto, darei apenas alguns exemplos de espaços de cores comuns:

  • 4: 4: 4 RGB via -f avi -c:v utvideo -pix_fmt rgb24fornece saída de 178 Mbit / s

  • 4: 4: 4 YUV via -f avi -c:v utvideo -pix_fmt yuv444p153 Mbit / seg saída

  • 4: 2: 2 YUV via -f avi -c:v utvideo -pix_fmt yuv422p123 Mbit / seg saída

  • 4: 2: 0 YUV via -f avi -c:v utvideo -pix_fmt yuv420pfornece saída de 100 Mbit / s

Eu suspeito que o YUV 4: 4: 4 é melhor que o RGB 4: 4: 4 neste teste, apesar de esses dois serem tecnicamente equivalentes porque o vídeo de origem é YUV 4: 2: 0, portanto, organizar os dados no formato YUV permite uma melhor compactação sem perdas agrupando os canais U e V parcialmente redundantes no arquivo.

FFV1

Outra opção interessante nesse espaço é o FFV1codec do FFmpeg . Isso é usado principalmente como um codec de arquivamento, em vez de um codec de reprodução ou edição, mas como tanto software é baseado na libavcodecbiblioteca subjacente ao FFmpeg ou pode ser amarrado libavcodecatravés de ferramentas como ffdshowessa, pode ser útil para você de qualquer maneira.

Por padrão, ffmpegpreservará o espaço de cores dos arquivos de entrada ao usar um codec flexível como o FFV1, de modo que, se você alimentá-lo com um dos arquivos MP4 Big Buck Bunny oficiais, que usam YUV 4: 2: 0, é isso que você obtém a menos que você dê uma -pix_fmtbandeira para ffmpeg. Isso resulta em um arquivo de saída de 63 Mbit / s .

Se você forçar o FFV1 a usar um espaço de cores YUV 4: 4: 4 -pix_fmt yuv444p, o tamanho do arquivo será de apenas 86 Mbit / s , mas não nos comprará nada neste caso, pois estamos codificando um original 4: 2: 0 . No entanto, se você alimenta em um conjunto de PNGs em vez disso, como na pergunta original, o arquivo de saída é provável que use o bgraou bgr0espaço de cor, que são apenas rearranjos dos argbe rgb24cor espaços levantadas acima.

H.264 sem perdas

Outra alternativa interessante é o Lossless H.264 . Isso é praticamente uma coisa apenas de x264 no momento da redação deste documento, mas aqueles que usam FFmpeg no lado da codificação provavelmente estão usando outro software que também inclui libx264o lado da decodificação , como o VLC.

A maneira mais simples de obter esse arquivo é:

$ ffmpeg -i frame%04d.png -c:v libx264 -qp 0 -f mp4 output.mp4

O -qp 0sinalizador é a chave: valores mais altos causam compactação com perdas. (Você também pode dar -crf 0para obter o mesmo efeito.)

Assim como o FFV1, ffmpegtentará adivinhar o melhor espaço de cores de saída, considerando o espaço de cores de entrada. Portanto, para comparação com os resultados acima, executei várias passagens de codificação no arquivo de origem Big Buck Bunny com diferentes espaços de cores:

  • yuv444p : É isso ffmpegque você escolhe quando você fornece um fluxo PNG RGB, como na pergunta original, e resulta em um arquivo de 44 Mbit / s com nosso arquivo de teste

  • yuv422p : Isso é semelhante ao espaço de cores padrão do Huffyuv, mas temos um arquivo de 34 Mbit / s nesse caso, uma grande economia!

  • yuv420p : Esse é o padrão para os MP4s oficiais do Big Buck Bunny com os quais estou testando e resulta em um arquivo de 29 Mbit / s .

Lembre-se de que você está negociando muita compatibilidade para obter tamanhos de arquivo tão pequenos. É por isso que eu nem tentei colocar isso em um contêiner AVI ou MOV. Está tão intimamente ligado ao x264 que você também pode usar seu tipo de contêiner padrão (MP4). Você também pode usar algo como Matroska para isso.

Você pode trocar parte dessa taxa de bits por um tempo de codificação mais rápido adicionando -preset ultrafast. Isso aumentou a taxa de bits do meu arquivo de teste para 44 Mbit / s no modo YUV 4: 2: 2, mas codificou muito mais rapidamente, conforme prometido. Os documentos afirmam que -preset veryslowtambém vale a pena, mas resultou em um tempo de codificação muito mais longo, economizando apenas um pouquinho de espaço; Eu não posso recomendar.

Outras

ffmpegtambém suporta o modo somente decodificação para Lagarith e o modo somente codificação para JPEG sem perda . Esses dois codecs são realmente um pouco semelhantes e devem fornecer arquivos um pouco menores que o Huffyuv com a mesma qualidade. Se os ffmpegdesenvolvedores adicionarem a codificação Lagarith, seria uma alternativa forte ao Huffyuv. Porém, não posso recomendar o JPEG sem perda, pois ele não possui amplo suporte à decodificação.

Perceptualmente sem perdas: Ou, você provavelmente pode se safar com alguma perda

Depois, existem os codecs que são perceptivamente sem perdas. A menos que você esteja espiando pixels, você quase certamente não pode dizer que eles oferecem resultados visuais diferentes dos dois grupos anteriores. Ao desistir da ideia de uma mudança absolutamente nula entre o sensor de captura de vídeo e o dispositivo de exibição, você obtém economias consideráveis:

  • Apple ProRes :-c:v proresou-c:v prores_ks- ProRes é um codec baseado em perfil, o que significa que existem várias variantes, cada uma com uma troca de qualidade versus espaço diferente:

    • O ProRes 4444 codifica nosso vídeo de teste usando apenas 114 Mbit / s , mas é de qualidade VFX . Atualmente, existem trêsprores*codecsdiferentesno FFmpeg, mas apenasprores_kssuporta o ProRes 4444, enquanto escrevo isso, através da-profile:v 4444opção.

      Se você está se perguntando por que se incomodaria em usar o ProRes 4444 em vez do Lossless H.264, tudo se resume à compatibilidade, velocidade de decodificação, previsibilidade e canal alfa.

    • O ProRes 422 economiza ainda mais espaço, precisando de apenas 84 Mbit / s para obter um resultado que você pode ver no ProRes 4444 apenas pela visualização de pixels. A menos que você precise do canal alfa oferecido pelo ProRes 4444, provavelmente não há motivo para insistir no ProRes 4444.

      O ProRes 422 é um concorrente mais próximo da opção Lossless H.264 acima, pois nenhum dos dois suporta um canal alfa. Você desejará tolerar a taxa de bits mais alta do ProRes se precisar de compatibilidade com aplicativos de vídeo profissionais da Apple, uma sobrecarga de CPU mais baixa para codificação e decodificação ou taxas de bits previsíveis. Este último é importante com codificadores de hardware, por exemplo. Por outro lado, se você conseguir lidar com os problemas de compatibilidade do Lossless H.264, terá a opção de usar o espaço de cores 4: 2: 0, o que não é uma opção de nenhum perfil ProRes.

      Todos os três codificadores ProRes no FFmpeg suportam o perfil ProRes 422; portanto, a opção mais simples é usar -c:v prores, em vez de -c:v prores_ks -profile hq, ou depender do recurso de perfil automático prores_kspara fazer a coisa certa.

    Existem perfis ProRes ainda mais parcimoniosos, mas são destinados a vídeos em SD ou como proxies para arquivos de resolução completa.

    O principal problema do ProRes é que ele ainda não possui amplo suporte fora dos mundos Apple e Pro Video.

  • O DNxHD da Avid é um codec semelhante ao ProRes, mas não está vinculado ao mundo dos vídeos profissionais da Apple. A Avid oferece codecs para download gratuito para Windows e Macintosh, e o FFmpeg agora é compatível com ele-c:v dnxhd.

    Como o DNxHD é um codec baseado em perfil como o ProRes, você escolhe o perfil no conjunto predefinido e informa ao codec qual tamanho de quadro, taxa de quadros e taxa de bits usar. Para o arquivo de teste Big Buck Bunny, o -b:v 60Mperfil é mais apropriado. Sem surpresa, o arquivo resultante é de cerca de 59 Mbit / s .

  • MJPEG de baixa perda :-vcodec mjpeg -qscale:v 1- Isso é muito mais comum que o JPEG sem perda. Na verdade, esse era um codec de edição de vídeo bastante comum, e ainda é frequentemente usado por coisas como câmeras de vídeo em rede. Toda essa história significa que é fácil encontrar um software que o suporte.

    Espere uma grande variabilidade nas taxas de dados desse codec. Um teste que acabei de fazer aqui me deu 25 Mbit / s para vídeo em 720p. Essa compressão é alta o suficiente para me deixar nervoso com perdas, mas me pareceu muito bom. Com base apenas na taxa de dados, eu diria que provavelmente está no nível da qualidade de 12 Mbit / s MPEG-2 ou 6 Mbit / s H.264.

Juntando tudo isso:

$ ffmpeg -i frame%04d.png -c:v prores_ks -profile:v 4444 output.mov
  ...or...                -c:v prores_ks -profile:v hq   output.mov
  ...or...                -c:v prores                    output.mov
  ...or...                -c:v dnxhd -b:v 60M            output.mov
  ...or...                -c:v mjpeg -qscale:v 1         output.avi

O ponto principal desses métodos é que, a menos que você esteja fazendo algo muito exigente, "bom o suficiente" realmente é bom o suficiente.


Notas de rodapé e digressões

  1. O comando deve funcionar como indicado no Linux, macOS, BSDs e Unix. Se você estiver no Windows, poderá obter uma linha de comando do POSIX via Cygwin ou WSL .

  2. Há várias razões pelas quais a lista produzida por esse comando não corresponde perfeitamente ao conjunto de codecs que escolhi discutir acima:

    • O segundo grepdestina-se a filtrar codificadores inapropriados, como os bmpque não são codecs de "vídeo", apesar de serem marcados Vnesta lista. Embora tecnicamente você possa colocar muitos deles em um contêiner como AVI, MP4 ou MKV para obter um vídeo de arquivo único, esse arquivo provavelmente não poderá ser lido por qualquer coisa, exceto por um programa baseado em ffmpegou libavcodec.

      Existem algumas exceções, como a que -f avi -c:v ljpegpode ser chamada de "MJPEG sem perdas", mas, como regra, não estamos interessados ​​em colocar muitos arquivos de imagens estáticas em um contêiner A / V aqui para fazer um filme. Queremos codecs de vídeo amplamente reconhecidos aqui, não truques semânticos.

    • O comando falha atualmente para filtrar alguns codificadores inadequados, como GIF, porque eles não estão descritos na ffmpeg -codecssaída como bitmapou imageformatos de arquivo.

      O GIF é um caso interessante: ele suporta vários quadros de imagem em um único arquivo GIF com informações de tempo para reprodução de movimento, mas por vários motivos, é totalmente inadequado para a nossa discussão aqui.

    • A algumas das opções que são mostrados são obsoletos ou nunca realmente tem muita tração, tais como flashsv, dirace snow, por isso, não vale a pena discuti-los acima.

    • Algumas das opções nessa lista destinam-se apenas ao uso em pipelines entre ffmpeginstâncias ou entre ffmpege outro programa, como rawvideoe wrapped_avframe, e, portanto, são inadequadas para nossos propósitos aqui.

    • Perto do final da discussão acima, amplio criteriosamente o escopo da pergunta para incluir algumas opções com perdas cuidadosamente escolhidas, para que elas não passem o primeiro grepfiltro no comando acima.

Warren Young
fonte
1
Depois de experimentar muitos formatos não compactados / sem perdas para encontrar um que o After Effects importaria, o seu Quicktime finalmente o fez. Para referência, foi ffmpeg -i input.avi -c:v qtrle -pix_fmt rgb24 output.mov.
Feltro #
9

Então acabei fazendo minha própria resposta por muito tempo.
Resumo TL; DR: Para armazenar sem perdas uma sequência de imagens, use libx264ou libx264rgbcom -preset ultrafast -qp 0. É quase tão rápido quanto o ffvhuff, com taxa de bits muito mais baixa e decodifica mais rapidamente. huffyuvé muito mais suportado fora do ffmpeg, mas não suporta tantos formatos de pixel quanto ffvhuff. Portanto, esse é outro motivo para usar o h.264, supondo que suas outras ferramentas possam lidar com o High 4:4:4 Predictiveperfil h.264 que o x264 usa no modo sem perdas. O x264 pode fazer intra-somente se for necessário um acesso aleatório rápido a quadros arbitrários.

Cuidado com um bug do ffmpeg que afeta a libx264rgb ao ler de um diretório de imagens. (e quem sabe quais outros casos.) Teste a ausência de perdas em sua configuração antes de usar. (fácil com ffmpeg -i in -pix_fmt rgb24 -f framemd5fonte e compactado sem perdas))

edit: utvideocodifica e decodifica rapidamente, e é um codec muito mais simples que o h.264. É basicamente um moderno huffyuv, com suporte para espaços de cores mais úteis. Se você tiver algum problema com o h.264, tente o utvideo a seguir para obter arquivos temporários.

edit2: PNG como codec RGB parece funcionar bem, pelo menos no trailer do Sintel.

Veja também minha resposta semelhante a uma pergunta semelhante: https://superuser.com/a/860335/20798

Há muitas informações na resposta de Warren Young sobre vários formatos e codecs brutos. Eu acho que a resposta seria mais útil se fosse mais curta, então estou fazendo uma nova resposta. Se você estiver trabalhando com software que não suporta x264 ou ffvhuff sem perdas, algumas dessas informações provavelmente ainda serão úteis.

A definição mais útil de "sem perdas" nesse contexto é que você pode recuperar a entrada bit por bit. Não se preocupe com a degradação da qualidade da codificação de vídeo, independentemente do que você faz.

http://en.wikipedia.org/wiki/Chroma_subsampling

Idealmente, evite várias conversões de espaço de cores. Os erros de arredondamento podem potencialmente se acumular. Se você deseja operar seu vídeo com filtros que funcionam no espaço de cores RGB, mantê-lo RGB faz sentido, desde que as taxas de bits mais altas não sejam um problema. Você provavelmente produzirá um yuv 4:2:0vídeo, mas manter a resolução extra de croma é potencialmente útil, dependendo de quais filtros você aplicará.

De qualquer maneira, x264 sem perdas e ffvhuff tanto apoio RGB e YUV 4:4:4, 4:2:2e 4:2:0. Eu sugeriria x264, pois é rápido para decodificar. Se você estiver tentando reproduzir vídeo RGB HD em tempo real, tente opengl em vez de xv, pois o xv no meu sistema aceita apenas entrada yuv. O mplayer estava gastando tempo extra na CPU para fazer uma conversão no espaço de cores.

Origem dos seguintes testes de codificador: https://media.xiph.org/ . https://media.xiph.org/sintel/sintel_trailer-1080-png.tar.gz Eles esqueceram de compactar com gzip os arquivos y4m do trailer sintel, para que o png tarball seja realmente muito menor.

ffmpeg -i 1080/sintel_trailer_2k_%4d.png -i sintel_trailer-audio.flac \
-c:a copy -c:v libx264rgb -preset ultrafast -qp 0 \
frompng.sintel.264rgb.mkv

por exemplo

peter@tesla:/mnt/GP1TB/p/encoder-sample/sintel$ time ffmpeg -i 1080/sintel_trailer_2k_%4d.png -i sintel_trailer-audio.flac -c:a copy -c:v libx264rgb -preset ultrafast -qp 0 frompng.sintel.264rgb.mkv
ffmpeg version N-67983-g2b358b4 Copyright (c) 2000-2015 the FFmpeg developers
  built on Jan 10 2015 05:32:37 with gcc 4.8 (Ubuntu 4.8.2-19ubuntu1)
  configuration: --enable-gpl --enable-version3 --enable-nonfree --disable-doc --disable-ffserver --enable-libx264 --enable-libx265 --enable-libmp3lame --enable-libopus --enable-libwebp --enable-libvpx --disable-outdev=oss --disable-indev=oss --disable-encoder=vorbis --enable-libvorbis --enable-libfdk-aac --disable-encoder=aac --disable-decoder=jpeg2000
  libavutil      54. 16.100 / 54. 16.100
  libavcodec     56. 20.100 / 56. 20.100
  libavformat    56. 18.100 / 56. 18.100
  libavdevice    56.  3.100 / 56.  3.100
  libavfilter     5.  7.100 /  5.  7.100
  libswscale      3.  1.101 /  3.  1.101
  libswresample   1.  1.100 /  1.  1.100
  libpostproc    53.  3.100 / 53.  3.100
Input #0, image2, from '1080/sintel_trailer_2k_%4d.png':
  Duration: 00:00:50.12, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: png, rgb24, 1920x1080 [SAR 72:72 DAR 16:9], 25 fps, 25 tbr, 25 tbn, 25 tbc
Input #1, flac, from 'sintel_trailer-audio.flac':
  Duration: 00:00:52.00, start: 0.000000, bitrate: 721 kb/s
    Stream #1:0: Audio: flac, 48000 Hz, stereo, s16
File 'frompng.sintel.264rgb.mkv' already exists. Overwrite ? [y/N] y
No pixel format specified, rgb24 for H.264 encoding chosen.
Use -pix_fmt yuv420p for compatibility with outdated media players.
[libx264rgb @ 0x2770760] using SAR=1/1
[libx264rgb @ 0x2770760] using cpu capabilities: MMX2 SSE2Fast SSSE3 Cache64 SlowShuffle
[libx264rgb @ 0x2770760] profile High 4:4:4 Predictive, level 4.0, 4:4:4 8-bit
[libx264rgb @ 0x2770760] 264 - core 144 r2525+2 6a4fca8 - H.264/MPEG-4 AVC codec - Copyleft 2003-2014 - http://www.videolan.org/x264.html - options: cabac=0 ref=1 deblock=0:0:0 analyse=0:0 me=dia subme=0 psy=0 mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip=0 chroma_qp_offset=0 threads=3 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=0 keyint=250 keyint_min=25 scenecut=0 intra_refresh=0 rc=cqp mbtree=0 qp=0
Output #0, matroska, to 'frompng.sintel.264rgb.mkv':
  Metadata:
    encoder         : Lavf56.18.100
    Stream #0:0: Video: h264 (libx264rgb) (H264 / 0x34363248), rgb24, 1920x1080 [SAR 72:72 DAR 16:9], q=-1--1, 25 fps, 1k tbn, 25 tbc
    Metadata:
      encoder         : Lavc56.20.100 libx264rgb
    Stream #0:1: Audio: flac ([172][241][0][0] / 0xF1AC), 48000 Hz, stereo (16 bit)
Stream mapping:
  Stream #0:0 -> #0:0 (png (native) -> h264 (libx264rgb))
  Stream #1:0 -> #0:1 (copy)
Press [q] to stop, [?] for help
frame= 1253 fps= 18 q=-1.0 Lsize=  834790kB time=00:00:51.96 bitrate=131592.5kbits/s
video:830198kB audio:4575kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.002025%
[libx264rgb @ 0x2770760] frame I:6     Avg QP: 0.00  size:612470
[libx264rgb @ 0x2770760] frame P:1247  Avg QP: 0.00  size:678787
[libx264rgb @ 0x2770760] mb I  I16..4: 100.0%  0.0%  0.0%
[libx264rgb @ 0x2770760] mb P  I16..4: 50.3%  0.0%  0.0%  P16..4: 12.0%  0.0%  0.0%  0.0%  0.0%    skip:37.6%
[libx264rgb @ 0x2770760] coded y,u,v intra: 71.1% 68.2% 70.0% inter: 22.8% 22.8% 23.2%
[libx264rgb @ 0x2770760] i16 v,h,dc,p: 50% 48%  1%  1%
[libx264rgb @ 0x2770760] kb/s:135693.94

Note que eu esqueci de especificar -r 24fps, para não manter a sincronização av com o áudio. (e os números de taxa de bits (mas não o tamanho do arquivo) também estarão desativados. ffmpeg assume o padrão de 25 fps). A CPU nesta máquina é um core2duo de 2,4 GHz (E6600) de 1ª geração (conroe).

resultados:

4.5M    sintel_trailer-audio.flac  # this is muxed in to every mkv
948M    1080  # the directory of PNGs
940M    /var/tmp/dl/sintel_trailer-1080-png.tar.gz
7434M   sintel.y4m  # yuv444, uncompressed.  mplayer gets the colors wrong?
2342M   qtrle.mkv   # encode went at 16fps, so qtrle is slower and worse filesize
2105M   sintel.huff.mkv  # ffvhuff with default options, rgb pix fmt
1228M    sintel.utvideo.mkv  # muxed without audio, I should update the others this way
946M    png-copy.mkv  # -codec copy makes a MPNG stream.  Use -codec png for non-png sources, but it won't make PNGs as small.  Decodes very fast
824M    lossy.prores_ks.mov # yuv444p10le extremely slow to encode (2.3fps), and worse bitrate.
816M    frompng.sintel.264rgb.mkv
735M    sintel.x264rgb.medium.nocabac.mkv  # encode went at 3.3 fps instead of 18.  Better gain than for live-action, though
626M    sintel_trailer.rgb.lossless.veryslow.mkv # 1.1fps.  With CABAC, 16 ref frames, etc. etc.
512M    lossy.prores.mov # yuv422p10le, 12fps
341M    sintel.yuv420.x264.lossless.mkv
21M     lossy.rgb.crf26.preset=medium.mkv
13M     lossy.yuv420.crf26.preset=medium.mkv  # remember this is WITH 4.5MB audio

Observe que mediainfonão conhece o RGB h.264, mas ainda diz que os arquivos são YUV.

Verifique se realmente não havia perdas:

ffmpeg -i 1080/sintel_trailer_2k_%4d.png -f framemd5 png.framemd5
ffmpeg -i fromhuff.sintel.264rgb.mkv -an -sn -pix_fmt rgb24  -f framemd5 x264rgb.framemd5
diff -s *.framemd5
Files png.framemd5 and x264rgb.framemd5 are identical

Assim, você pode recuperar a entrada PNG original dessa maneira, ou seja, você pode criar PNGs com dados de imagem idênticos.

Observe o -pix_fmt rgb24para o teste x264. O decodificador h.264 do ffmpeg gera saída gbrp (planar, não compactada), de modo que os bits são os mesmos, mas em uma ordem diferente. O framemd5 "contêiner" não impõe nenhum tipo de restrição de formato, mas você só obterá o mesmo md5 se os bits forem organizados da mesma maneira. Eu apenas olhei o que o ffmpeg disse que estava usando para um pix fmt quando eu o alimentei com PNGs, depois o usei como argumento -pix_fmtpara decodificar. Aliás, esse é o motivo pelo qual o vlc não reproduz arquivos RGB h.264 (até a próxima versão ou as compilações noturnas atuais): Ele não suporta o formato de pixel gbrp.

Para uso yuv libx264, não libx264rgb. Você não precisa instalar uma versão RGB do x264, a biblioteca real suporta ambos. É apenas o ffmpeg que o implementou como dois codificadores com nomes diferentes. Eu acho que se eles não tivessem feito isso, o comportamento padrão seria deixar a entrada rgb como rgb e rodar muito lentamente enquanto produzia uma saída de taxa de bits muito mais alta para a mesma qualidade. (às vezes você ainda precisa usar -pix_fmt yuv420pse quiser, em 420vez da 444saída h.264.

A menos que você esteja criando arquivos para armazenamento a longo prazo, use sempre o -preset ultrafastx264 sem perdas. Mais quadros de referência e pesquisa de movimento quase não fazem diferença para perda, para material não animado com qualquer ruído. O CABAC usa uma quantidade enorme de CPU em taxas de bits sem perdas, mesmo para decodificar. Use apenas para fins de arquivamento, não para arquivos de rascunho. (ultra-rápido desativa o CABAC). O CABAC economiza de 10 a 15% na taxa de bits.

Se você precisar que cada quadro seja um quadro-chave, defina -keyint 1. Em seguida, o software de edição de vídeo que deseja apenas cortar quadros-chave ou w / e não o limitará.

Para responder à pergunta original: Isto é o que você deve fazer para pesquisar arquivos temporários enquanto tenta as coisas em etapas (por exemplo, um desentrelaçamento lento, salvando uma saída sem perdas antes de tentar outras coisas):

ffmpeg -i dv-video-source.ts -vf yadif=2:1,mcdeint=3:1:10 -c:a copy -c:v libx264 -preset ultrafast -qp 0 deinterlaced.mkv

Se você realmente precisa da sua saída em arquivos de imagem que podem ser modificados com ferramentas de imagem estática, decodifique para png. Você não perderá nada além do talvez menos significativo dos 8 bits para cada um dos valores Y, Cb e Cr para cada pixel.

O x264 sai MUITO bom nisso porque há muitos quadros em preto com um pouco de texto, um desvanecimento e um desvanecimento e perfeita semelhança entre grandes áreas de muitos quadros, dos quais ele consegue tirar vantagem -preset ultrafast. Em live-action, ainda vejo x264 na metade do tamanho do arquivo ffvhuff (yuv420).

Para qualquer pessoa curiosa: A codificação rgb sem perda de tempo da CPU tinha (x264 core 144 r2525):

[libx264rgb @ 0x35b97a0] frame I:27    Avg QP: 0.00  size:604367
[libx264rgb @ 0x35b97a0] frame P:1226  Avg QP: 0.00  size:517512
[libx264rgb @ 0x35b97a0] mb I  I16..4..PCM: 46.3% 38.1% 15.7%  0.0%
[libx264rgb @ 0x35b97a0] mb P  I16..4..PCM: 24.3%  5.4%  4.5%  0.0%  P16..4: 10.5%  3.3%  5.7%  0.0%  0.0%    skip:46.3%
[libx264rgb @ 0x35b97a0] 8x8 transform intra:17.3% inter:46.1%
[libx264rgb @ 0x35b97a0] coded y,u,v intra: 81.6% 77.5% 80.0% inter: 28.0% 27.7% 28.1%
[libx264rgb @ 0x35b97a0] i16 v,h,dc,p: 35% 64%  1%  0%
[libx264rgb @ 0x35b97a0] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 31% 49% 13%  2%  1%  1%  1%  1%  1%
[libx264rgb @ 0x35b97a0] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 31% 37%  5%  5%  6%  5%  5%  4%  3%
[libx264rgb @ 0x35b97a0] Weighted P-Frames: Y:41.1% UV:40.7%
[libx264rgb @ 0x35b97a0] ref P L0: 74.5%  4.2%  9.1%  4.1%  2.1%  1.7%  1.2%  0.8%  0.6%  0.5%  0.3%  0.2%  0.2%  0.2%  0.2%  0.1%
[libx264rgb @ 0x35b97a0] kb/s:99721.66

Observe a fração realmente alta de quadros p ponderados e também a fração realmente alta de ignorar macroblocos. Toda transição de cena é um desbotamento, não um corte, e o x264 tira vantagem se você tiver tempo de CPU para descobrir como.

notas adicionais (codecs com perdas para edição):

Para esfregar os clipes para frente / trás nos clipes, geralmente são preferidos os codecs intra-somente (utvideo, ffvhuff, mjpeg, jpeg2000, pró-res, AVC-Intra). Eu imaginaria que o AVC comum com GOPs curtos (1/2 a 1 s) também esfregaria muito bem, desde que o software soubesse o que estava fazendo (decodifique o quadro mais próximo ao quadro ao esfregar rapidamente, decodifique dentro do GOP para obter um quadro intermediário, se você tiver ampliado o suficiente em uma linha do tempo para que isso seja necessário).

Publiquei algumas coisas negativas sobre isso e https://video.stackexchange.com/ sobre pró-res, como "qual é o objetivo, se for uma compactação mais lenta e pior do que um codec sem perdas", mas ele tem alguns recursos interessantes. A Apple diz que pode decodificar em meia resolução usando apenas 1/3 do tempo de CPU da decodificação de rez total.

A implementação dos preços do ffmpeg provavelmente não é tão otimizada para velocidade quanto a da Apple, e é por isso que meus testes com o ffmpeg fizeram com que parecesse lento. Provavelmente não vale a pena usar se você tiver um fluxo de trabalho de software livre com ferramentas baseadas em ffmpeg, mas pode valer a pena tentar se você estiver usando software comercial.

Não faço muita edição de vídeo, principalmente apenas codificação, por isso não tenho uma boa noção de quais testes seriam apropriados para codecs como pro-sores. Eu acho que talvez o mjpeg seja uma boa alternativa rápida, se o short-GOP x264 não funcionar bem. Existem implementações asm-aceleradas de jpeg nas distribuições Linux, e é um codec bastante simples. Você pode aumentar ou diminuir a qualidade, conforme necessário, para trocar qualidade versus tamanho do arquivo + velocidade de codificação / decodificação. É antigo, mas se você quiser um codec intra-somente muito rápido, pode bater x264.

Para x264, eu tentaria algo como x264 --crf 10 --keyint=1 --preset superfast --tune fastdecode (somente intra, sem qualquer outra coisa que --avcintra-classdefine). Nota superfast(sem CABAC) ou provavelmente fasternão ultrafasté melhor para operações com perdas. Eu acho que o ultrarrápido perde muita qualidade sem ser muito mais rápido. Quanto mais baixa qualidade (maior crf) você usa, mais vale a pena gastar um pouco mais de tempo na CPU para encontrar uma codificação melhor. Muito disso provavelmente não é relevante com o tamanho do GOP = 1, no entanto.

Com tamanho GOP> 1, se você estiver jogando tantos bits no código, uma melhor inter-previsão não economizará muitos bits ao codificar os resíduos (porque o ruído / granulação / alterações sutis entre os quadros estão sendo preservados com muita precisão), então apenas super rápido provavelmente está bom. Caso contrário, com --keyint=30ou algo assim, provavelmente --preset veryfast --crf 12seria interessante.

Em teoria, a qualidade em uma determinada configuração de CRF deve ser constante entre as predefinições. Se você estiver procurando por arquivos menores (decodificações mais rápidas), faz sentido trocar alguma qualidade e algum tempo de codificação.

Peter Cordes
fonte
Só queria agradecer por essa lista com os tamanhos de arquivo; grandes coisas para referência rápida .. Saúde!
Sdaau
@sdaau Observe que o vídeo de origem é MUITO diferente dos vídeos comuns feitos com câmeras. É uma renderização 3D, com letterboxing e com muitos desbotamentos entre cenas curtas. E uma fração decente de quadros totalmente imóveis com texto. Os quadros totalmente estáticos são todos intra-compressíveis, mas ainda favorece codecs com quadros intermediários (como x264) mais do que eu imagino que a compactação sem perdas de imagens da câmera (com qualquer ruído) faria.
Peter Cordes
+1: eu não fazia ideia do Lossless H.264. Eu adicionei informações sobre isso na minha resposta. Sinta-se livre para tirar algumas idéias de minha apresentação breve para resolver o seu tl; dr problema. Quanto à minha própria resposta, ela deve ser abrangente, em vez de tentar apresentar a Solução Única e Verdadeira para o problema. Temos tantos codecs diferentes porque nenhum codec único atende às necessidades de todos.
Warren Young
2

Acho que o ffmpeg realmente suporta a conversão para vídeo não compactado.
Eu usei ffmpeg -i input.mp4 -vcodec rawvideo out.avi e o .avi resultante era aproximadamente o tamanho correto do arquivo. O Windows Media Player não parecia capaz de reproduzi-lo corretamente, mas poderia ser lido pelo VirtualDub e não vi nenhuma perda na qualidade da imagem.

jmnben
fonte