Qual é a maneira correta de corrigir quadros-chave no FFmpeg for DASH?


38

Ao condicionar um fluxo para reprodução de DASH, os pontos de acesso aleatório devem estar exatamente no mesmo horário do fluxo de origem em todos os fluxos. A maneira usual de fazer isso é forçar uma taxa de quadros fixa e um comprimento GOP fixo (ou seja, um quadro-chave a cada N quadros).

No FFmpeg, a taxa de quadros fixa é fácil (-r NUMBER).

Mas para locais fixos de quadro-chave (comprimento GOP), existem três métodos ... qual deles é "correto"? A documentação do FFmpeg é frustrantemente vaga sobre isso.

Método 1: mexendo nos argumentos da libx264

-c:v libx264 -x264opts keyint=GOPSIZE:min-keyint=GOPSIZE:scenecut=-1

Parece haver algum debate se o cenário deve ser desativado ou não, pois não está claro se o "contador" do quadro-chave é reiniciado quando ocorre um corte na cena.

Método 2: definindo um tamanho fixo de GOP:

-g GOP_LEN_IN_FRAMES

Infelizmente, isso é documentado apenas de passagem na documentação do FFMPEG e, portanto, o efeito desse argumento não é muito claro.

Método 3: insira um quadro-chave a cada N segundos ( talvez? ):

-force_key_frames expr:gte(t,n_forced*GOP_LEN_IN_SECONDS)

Isso está explicitamente documentado. Mas ainda não está claro se o "contador de tempo" será reiniciado após cada quadro-chave. Por exemplo, em um GOP esperado de 5 segundos, se houver um scenecutquadro - chave injetado 3 segundos pela libx264, o próximo quadro-chave seria 5 segundos mais tarde ou 2 segundos depois?

De fato, a documentação do FFmpeg diferencia isso e a -gopção, mas na verdade não diz como essas duas opções acima são as menos diferentes (obviamente, -gisso exigirá uma taxa de quadros fixa).

Qual é certo?

Parece que -force_key_framesseria superior , pois não exigiria uma taxa de quadros fixa. No entanto, isso requer que

  • está em conformidade com as especificações GOP em H.264 ( se houver )
  • GARANTE que haja um quadro-chave em cadência fixa, independentemente dos scenecutquadros-chave libx264 .

Parece também que -gnão funcionaria sem forçar uma taxa de quadros fixa ( -r) , pois não há garantia de que várias execuções ffmpegcom argumentos de codec diferentes forneceriam a mesma taxa de quadros instantânea em cada resolução. Taxas de quadros fixas podem reduzir o desempenho da compactação (IMPORTANTE em um cenário DASH!).

Finalmente, o keyintmétodo parece apenas um hack . Espero contra a esperança que esta não seja a resposta correta.

Referências:

Um exemplo usando o -force_key_framesmétodo

Um exemplo usando o keyintmétodo

Seção de opções de vídeo avançadas do FFmpeg

Respostas:


27

TL; DR

Eu recomendaria o seguinte:

  • libx264: (e opcionalmente adicione-g X -keyint_min X-force_key_frames "expr:gte(t,n_forced*N)" )
  • libx265: -x265-params "keyint=X:min-keyint=X"
  • libvpx-vp9: -g X

onde Xé o intervalo em quadros e Né o intervalo em segundos. Por exemplo, para um intervalo de 2 segundos com um vídeo de 30fps, X= 60 eN = 2.

Uma observação sobre os diferentes tipos de quadros

Para explicar adequadamente esse tópico, primeiro precisamos definir os dois tipos de quadros I / quadros-chave:

  • Quadros Atualização instantânea do decodificador (IDR): permitem decodificação independente dos seguintes quadros, sem acesso aos quadros anteriores ao quadro IDR.
  • Quadros não IDR: requerem um quadro IDR anterior para que a decodificação funcione. Os quadros não IDR podem ser usados ​​para cortes de cena no meio de um GOP (grupo de fotos).

O que é recomendado para streaming?

Para o caso de streaming, você deseja:

  • Verifique se todos os quadros IDR estão em posições regulares (por exemplo, 2, 4, 6,… segundos) para que o vídeo possa ser dividido em segmentos de igual comprimento.
  • Ative a detecção de corte de cena, para melhorar a eficiência / qualidade da codificação. Isso significa permitir que os quadros I sejam colocados entre os quadros IDR. Ainda é possível trabalhar com a detecção de corte de cena desativada (e isso faz parte de muitos guias ainda), mas não é necessário.

O que os parâmetros fazem?

Para configurar o codificador, precisamos entender o que os parâmetros do quadro-chave fazem. Eu fiz alguns testes e descobriu o seguinte, para os três codificadores libx264, libx265e libvpx-vp9em FFmpeg:

  • libx264:

    • -g define o intervalo do quadro-chave.
    • -keyint_min define o intervalo mínimo do quadro-chave.
    • -x264-params "keyint=x:min-keyint=y"é o mesmo que -g x -keyint_min y.
    • Nota: Ao definir os dois para o mesmo valor, o mínimo é definido internamente para a metade do intervalo máximo mais um, conforme visto no x264código:

      h->param.i_keyint_min = x264_clip3( h->param.i_keyint_min, 1, h->param.i_keyint_max/2+1 );
      
  • libx265:

    • -g não está implementado.
    • -x265-params "keyint=x:min-keyint=y" trabalho.
  • libvpx-vp9:

    • -g define o intervalo do quadro-chave.
    • -keyint_min define o intervalo mínimo do quadro-chave
    • Nota: Devido ao modo como o FFmpeg funciona, -keyint_minsó é encaminhado para o codificador quando é o mesmo que -g. No código do libvpxenc.cFFmpeg, podemos encontrar:

      if (avctx->keyint_min >= 0 && avctx->keyint_min == avctx->gop_size)
          enccfg.kf_min_dist = avctx->keyint_min;
      if (avctx->gop_size >= 0)
          enccfg.kf_max_dist = avctx->gop_size;
      

      Isso pode ser um bug (ou falta de recurso?), Pois libvpxdefinitivamente suporta a configuração de um valor diferente para kf_min_dist.

Você deveria usar -force_key_frames?

A -force_key_framesopção insere forçosamente quadros-chave no intervalo especificado (expressão). Isso funciona para todos os codificadores, mas pode interferir no mecanismo de controle de taxa. Especialmente para o VP9, ​​notei fortes flutuações de qualidade, portanto não posso recomendar o uso neste caso.


Obrigado! Este é um ótimo feedback. Uma pergunta que tenho é como você gerou essa tabela impressionante. Eu poderia usar totalmente algo assim.
Mark Gerolimatos

(Parece que não há como escrever diretamente para você) Você pode me indicar links para qualquer tópico nesta discussão da ITU-T? Obrigado!
Mark Gerolimatos

2
Acabei de fazer isso no Excel, colando a saída obtida de três execuções ffprobe -i input.mp4 -select_streams v -show_frames -of csv -show_entries frame=pict_typee colorindo as células. Receio que não haja discussões públicas, mas vou ver se consigo descobrir alguns dos links que encontrei na época.
slhck

Você poderia tentar novamente seu experimento com o -force_key_frames expr:gte(t,n_forced*GOP_LEN_IN_SECONDS)formulário? Eu apenas tentei e descobri que, embora houvesse quadros I adicionais no fluxo, ele parecia cumprir minha regra. Um programa PERL seguirá como uma "resposta", pois você aparentemente não pode usar a marcação nos comentários.
Mark Gerolimatos

Interessante. Acredito que vale a pena uma resposta "real" separada, se você descobriu que funciona. (Os sites do Stack Exchange não são realmente bons para esta resposta no estilo de discussão.) A última vez que verifiquei, -force_key_framesnão funcionou para mim e, portanto, nunca tentei novamente. Isso foi há mais de um ano. Talvez tenha sido um bug. Vou tentar novamente em breve.
Slhck

12

Aqui estão meus cinquenta centavos para o caso.

Método 1:

mexendo com os argumentos da libx264

-c: v libx264 -x264opts keyint = GOPSIZE: min-keyint = GOPSIZE: scenecut = -1

Gere iframes apenas nos intervalos desejados.

Exemplo 1:

ffmpeg -i test.mp4 -codec:v libx264 \
-r 23.976 \
-x264opts "keyint=48:min-keyint=48:no-scenecut" \
-c:a copy \
-y test_keyint_48.mp4

Gere iframes conforme o esperado:

Iframes     Seconds
1           0
49          2
97          4
145         6
193         8
241         10
289         12
337         14
385         16
433         18
481         20
529         22
577         24
625         26
673         28
721         30
769         32
817         34
865         36
913         38
961         40
1009        42
1057        44
1105        46
1153        48
1201        50
1249        52
1297        54
1345        56
1393        58

O método 2 é depreciado. Omitido.

Método 3:

insira um quadro-chave a cada N segundos (TALVEZ):

-force_key_frames expr: gte (t, n_forced * GOP_LEN_IN_SECONDS)

Exemplo 2

ffmpeg -i test.mp4 -codec:v libx264 \
-r 23.976 \
-force_key_frames "expr:gte(t,n_forced*2)"
-c:a copy \
-y test_fkf_2.mp4

Gere um iframes de uma maneira ligeiramente diferente:

Iframes     Seconds
1           0
49          2
97          4
145         6
193         8
241         10
289         12
337         14
385         16
433         18
481         20
519         21.58333333
529         22
577         24
625         26
673         28
721         30
769         32
817         34
865         36
913         38
931         38.75
941         39.16666667
961         40
1008        42
1056        44
1104        46
1152        48
1200        50
1248        52
1296        54
1305        54.375
1344        56
1367        56.95833333
1392        58
1430        59.58333333
1440        60
1475        61.45833333
1488        62
1536        64
1544        64.33333333
1584        66
1591        66.29166667
1632        68
1680        70
1728        72
1765        73.54166667
1776        74
1811        75.45833333
1824        75.95833333
1853        77.16666667
1872        77.95833333
1896        78.95833333
1920        79.95833333
1939        80.75
1968        81.95833333

Como você pode ver, coloca iframes a cada 2 segundos E em cena (segundos com parte flutuante), o que é importante para a complexidade do fluxo de vídeo na minha opinião.

Os tamanhos de arquivo gerado são praticamente os mesmos. Muito estranho que, mesmo com mais quadros-chave no método 3, ele às vezes gere menos arquivos que o algoritmo de biblioteca x264 padrão.

Para gerar vários arquivos de taxa de bits para o fluxo HLS, escolhemos o método três. É perfeitamente alinhado com 2 segundos entre os pedaços, eles têm iframe no início de cada pedaço e têm iframes adicionais em cenas complexas, o que proporciona uma melhor experiência para usuários que possuem dispositivos desatualizados e não podem reproduzir x264 perfis de alto nível.

Espero que ajude alguém.


Fantástico, obrigado por seus 50 centavos!
BrunoFenzl 12/10

7

A resposta, portanto, parece ser:

  • O método 1 é verificado para funcionar, mas é libx264específico e tem o custo de eliminar a scenecutopção muito útil emlibx264 .
  • O método 3 funciona a partir da versão do FFMPEG de abril de 2015, mas você deve verificar seus resultados com o script incluído na parte inferior desta postagem, pois a documentação do FFMPEG não é clara quanto ao efeito da opção. Se funcionar, é a superior das duas opções.
  • NÃO USE o método 2, -gparece estar obsoleto. Ele não parece funcionar, nem está explicitamente definido na documentação, nem é encontrado na ajuda, nem parece ser usado no código. A inspeção de código mostra que a -gopção provavelmente se destina a fluxos MPEG-2 (existem até estrofes de código referentes a PAL e NTSC!).

Além disso:

  • Os arquivos gerados com o método 3 podem ser um pouco maiores que o método 1, pois quadros I intersticiais (quadros-chave) são permitidos.
  • Você deve definir explicitamente o sinalizador "-r" nos dois casos, mesmo que o Método 3 coloque um quadro I no próximo intervalo de quadros no ou após o tempo especificado. A falha em definir o sinalizador "-r" coloca você à mercê do arquivo de origem, possivelmente com uma taxa de quadros variável. Transições DASH incompatíveis podem resultar.
  • Apesar dos avisos na documentação do FFMPEG, o método 3 NÃO é menos eficiente que outros. De fato, os testes mostram que pode ser um pouco MAIS eficiente que o método 1.

Script para a -force_key_framesopção

Aqui está um pequeno programa PERL que usei para verificar a cadência de quadros I com base na saída da sugestão ffprobe do slhck. Parece verificar que o -force_key_framesmétodo também funcionará e tem o benefício adicional de permitirscenecut quadros. Não tenho absolutamente nenhuma idéia de como o FFMPEG faz isso funcionar, ou se de alguma forma tive sorte porque meus fluxos estão bem condicionados.

No meu caso, codifiquei a 30fps com um tamanho esperado de GOP de 6 segundos ou 180 quadros. Eu usei 180 como o argumento gopsize deste programa verificou um quadro I em cada múltiplo de 180, mas defini-lo como 181 (ou qualquer outro número que não seja múltiplo de 180) fez com que ele se queixasse.

#!/usr/bin/perl
use strict;
my $gopsize = shift(@ARGV);
my $file = shift(@ARGV);
print "GOPSIZE = $gopsize\n";
my $linenum = 0;
my $expected = 0;
open my $pipe, "ffprobe -i $file -select_streams v -show_frames -of csv -show_entries frame=pict_type |"
        or die "Blah";
while (<$pipe>) {
  if ($linenum > $expected) {
    # Won't catch all the misses. But even one is good enough to fail.
    print "Missed IFrame at $expected\n";
    $expected = (int($linenum/$gopsize) + 1)*$gopsize;
  }
  if (m/,I\s*$/) {
    if ($linenum < $expected) {
      # Don't care term, just an extra I frame. Snore.
      #print "Free IFrame at $linenum\n";
    } else {
      #print "IFrame HIT at $expected\n";
      $expected += $gopsize;
    }
  }
  $linenum += 1;
}

Apenas uma observação: como este é um site de perguntas e respostas e não um fórum de discussão em que as postagens são ordenadas cronologicamente, é melhor colocar todas as informações em uma resposta, para que as pessoas que procuram uma solução tenham apenas que ler uma postagem e não procurar em quem postou o quê, quando :) Mesclei suas respostas e dei +1 a você também. Como a postagem cruzada não é permitida , sugiro que você exclua sua pergunta no site de vídeo. As pessoas encontrarão a (s) resposta (s) aqui.
slhck

1
Eu só tinha mais um pensamento (na verdade, ele foi levantado na lista de discussão do FFmpeg). Quando você usa force_key_frames, ele meio que atrapalha o algoritmo de alocação de x264 bits, por isso pode oferecer uma qualidade pior do que simplesmente definir um intervalo fixo de quadro-chave.
slhck 5/05

Caralho. Ainda mais um motivo para o FFMPEG fornecer uma maneira não específica de codec para fazer isso, um argumento que "faria o melhor para o codec em questão". Tentei registrar um ticket para isso com o trac do FFMPEG, mas o
retorno

@slhck: Você poderia dar mais detalhes, por favor? Procurei nos arquivos da lista de endereços em maio de 2015, mas não consegui encontrar nada. O ponto principal seria esquecer o "Método 3" e seguir o "Método 1".
schieferstapel

3
@ MarkGerolimatos: about -g, você diz: "Ele não parece funcionar, ... nem parece ser usado no código". Eu verifiquei e da entrada da gé armazenada em avctx->gop_sizee que libx264 faz uso dela: x4->params.i_keyint_max = avctx->gop_size;. Quando analiso este arquivo de teste gerado ffmpeg -i a-test-file.mp4 -g 37 -t 15 gtest.mp4:, recebo quadros-chave exatamente 0,37,74,111,148,185,222,259,296,333,370. Um GOP pode ser encurtado se a mudança de cena for acionada e, para isso, -sc_thresholdpode ser definido, o que também é captado por x264.
Gyan

4

Eu queria adicionar algumas informações aqui, pois meu pesquisador puxou bastante essa discussão em minha busca para encontrar informações sobre como tentar encontrar uma maneira de segmentar minha codificação DASH da maneira que eu queria, e nenhuma das informações que encontrei estava totalmente correta.

Primeiro vários equívocos para se livrar:

  1. Nem todos os quadros I são iguais. Há grandes quadros em "I" e pequenos quadros em "i". Ou para usar a terminologia correta, quadros I-IDR e quadros I não-IDR. Os quadros I do IDR (às vezes chamados de "quadros-chave") criarão um novo GOP. Os quadros não-IDR não serão. Eles são úteis para ter dentro de um GOP, onde há uma mudança de cena.

  2. -x264opts keyint=GOPSIZE:min-keyint=GOPSIZE← Isso não faz o que você pensa que faz. Demorei um pouco para descobrir. Acontece que min-keyinto código é limitado. Não é permitido que seja maior que (keyint / 2) + 1. Portanto, atribuir o mesmo valor a essas duas variáveis ​​resulta no valor de min-keyintser derrubado pela metade ao codificar.

Eis o seguinte: o corte de cena é realmente ótimo, especialmente em vídeos com cortes rápidos. Ele o mantém bonito e nítido, por isso não quero desativá-lo, mas ao mesmo tempo não consegui obter um tamanho fixo de GOP desde que estivesse ativado. Eu queria ativar o corte de cena, mas usar apenas quadros I não IDR. Mas não estava funcionando. Até eu descobrir (a partir de muita leitura) sobre o equívoco # 2.

Acontece que eu precisava definir o keyintdobro do tamanho GOP desejado. Isso significa que min-keyintpode ser definido para o tamanho GOP desejado (sem o código interno cortando-o ao meio), o que impede que a detecção de corte de cena use quadros I IDR dentro do tamanho GOP porque a contagem de quadros desde o último quadro I IDR é sempre menos que min-keyinit.

E, finalmente, definir a force_key_frameopção substitui o tamanho duplo keyint. Então, aqui está o que funciona:

Eu prefiro segmentos em pedaços de 2 segundos, então meu GOPSIZE = Taxa de quadros * 2

ffmpeg <other_options> -force_key_frames "expr:eq(mod(n,<GOPSIZE>),0)" -x264opts rc-lookahead=<GOPSIZE>:keyint=<GOPSIZE * 2>:min-keyint=<GOPSIZE> <other_options>

Você pode verificar usando o ffprobe:

ffprobe <SRC_FLE> -select_streams v -show_frames -of csv -show_entries frame=coded_picture_number,key_frame,pict_type > frames.csv

No arquivo CSV gerado, cada linha informará frame, [is_an_IDR_?], [frame_type], [frame_number]:

frame,1,I,60  <-- frame 60, is I frame, 1 means is an IDR I-frame (aka KeyFrame)
frame,0,I,71  <-- frame 71, is I frame, 0 means not an IDR I_frame

O resultado é que você só verá os quadros I de IDR em GOPSIZEintervalos fixos , enquanto todos os outros quadros I são quadros I não-IDR inseridos conforme necessário pela detecção de corte de cena.


isso foi fantástico! Também foi altamente contra-intuitivo, obrigado por se esforçar. E, para resumir, suponho que sua definição de "quadros I" e "quadros i" seja conceitual (ou seja, não explicitamente configurável na libx264) e que o "max * 2" tenha sido o modo como você a aplicou?
Mark Gerolimatos

Sim, isso foi conceitual, embora eu tenha visto pessoas usarem "I" vs "i" para distinguir entre quadros I IDR e não IDR. E sim, definir keyinit para o tamanho desejado de gop * 2 é uma maneira de forçar todos os quadros I dentro do gop a serem quadros I não IDR. Em seguida, o ffmpeg -force-key-frames substitui o key-init nos x264opts. Basicamente, é realmente uma maneira inversa de obter o resultado desejado que seria possível se o código x264 permitisse definir min-keyinit e keyinit para o mesmo valor.
Reuben

... enquanto também é capaz de manter a detecção de corte de cena ativada e obter um tamanho GOP fixo.
Reuben

obrigado novamente por seu trabalho incrível! Parece que precisamos de um menor "para trás" maneira de realizar isso
Mark Gerolimatos

O rc-lookahead é necessário aqui? Afeta o mbtree e o VBV, mas afeta a geração do i-frame?
Alexander Svetkin

0

Parece que essa sintaxe nem sempre funciona. Eu testei bastante em nosso conteúdo VOD, bem como em conteúdo ao vivo (despejos de arquivos) e, às vezes, o cenário não funciona e aciona um iframe entre:

Sintaxe para uma conversão ascendente i50-> p50, 2 seg gop / segmento, IDR no início, iframes entre, se necessário

ffmpeg.exe -loglevel verbose -i avc_50i.ts -pix_fmt yuv420p -filter_complex yadif=1,scale=1920:1080 -vcodec libx264 -preset fast -x264-params "rc-lookahead=100:keyint=200:min-keyint=100:hrd=1:vbv_maxrate=12000:vbv_bufsize=12000:no-open-gop=1" -r 50 -crf 22 -force_key_frames "expr:eq(mod(n,100),0)" -codec:a aac -b:a 128k -y target.ts

0

Twitch tem um post sobre isso. Eles explicam que decidiram usar seu próprio programa por vários motivos; uma delas era que o ffmpeg não permite executar diferentes instâncias x264 em diferentes threads, mas dedica todos os threads especificados a um quadro em uma saída antes de passar para a próxima saída.

Se você não estiver transmitindo em tempo real, terá mais luxo. A maneira 'correta' provavelmente é codificar em uma resolução com apenas o tamanho GOP especificado com -g e, em seguida, codificar as outras resoluções forçando quadros-chave nos mesmos locais.

Se você quiser fazer isso, use o ffprobe para obter os tempos do quadro-chave e, em seguida, use um script de shell ou uma linguagem de programação real para convertê-lo em um comando ffmpeg.

Mas, para a maioria dos conteúdos, há pouca diferença entre ter um quadro-chave a cada 5 segundos e dois quadros-chave a cada 5 segundos (um forçado e outro do scenecut). Trata-se do tamanho médio do quadro I versus o tamanho dos quadros P e quadros B. Se você usa x264 com configurações típicas (a única razão pela qual acho que você deve fazer algo para afetá-las é se você definir -qmin, como uma maneira pobre de impedir que x264 use taxa de bits em conteúdo fácil; isso limita todos os tipos de quadro ao mesmo valor , Acho) e obtenha um resultado como o tamanho médio do quadro I de 46 kB, o quadro P 24 kB, o quadro B 17 kB (metade da frequência dos quadros P) e, em seguida, um quadro I extra a cada segundo a 30 fps é apenas um aumento de 3% no tamanho do arquivo. A diferença entre h264 e h263 pode ser composta por um monte de reduções de 3%, mas uma única não é muito importante.

Em outros tipos de conteúdo, os tamanhos dos quadros serão diferentes. Para ser justo, trata-se de complexidade temporal e não espacial, por isso não é apenas um conteúdo fácil versus um conteúdo rígido. Mas, geralmente, os sites de streaming de vídeo têm um limite de taxa de bits e o conteúdo com quadros I relativamente grandes é um conteúdo fácil que será codificado com alta qualidade, independentemente de quantos quadros-chave extras sejam adicionados. É um desperdício, mas esse desperdício geralmente não será percebido. O caso mais inútil é provavelmente um vídeo que é apenas uma imagem estática que acompanha uma música, onde cada quadro-chave é exatamente o mesmo.

Uma coisa que não tenho certeza é como os quadros-chave forçados interagem com o limitador de taxa definido com -maxrate e -bufsize. Acho que até o YouTube teve problemas recentes ao definir corretamente as configurações do buffer para fornecer qualidade consistente. Se você estiver usando apenas configurações médias de taxa de bits, como pode ser visto em alguns sites (já que você pode inspecionar as opções do x264 no cabeçalho / mov atom? Com ​​um editor hexadecimal), o modelo do buffer não é um problema, mas se você exibindo conteúdo gerado pelo usuário, a taxa de bits média incentiva os usuários a adicionar uma tela preta no final do vídeo.

A opção -f do Ffmpeg, ou qualquer outra opção de codificador usada, é mapeada para a opção específica do codificador. Portanto, '-x264-params keyint = GOPSIZE' é equivalente a '-g GOPSIZE'.

Um problema com o uso da detecção de cena é se você prefere quadros-chave próximos a números específicos por qualquer motivo. Se você especificar quadros-chave a cada 5 segundos e usar a detecção de cena, e houver uma alteração de cena em 4,5, ela deverá ser detectada, mas o próximo quadro-chave será em 9,5. Se o tempo continuar aumentando assim, você poderá terminar com quadros-chave em 42,5, 47,5, 52,5 etc., em vez de 40, 45, 50, 55. Por outro lado, se houver uma mudança de cena em 5,5, haverá um quadro-chave em 5 e 5,5 será muito cedo para outro. O Ffmpeg não permite que você especifique "faça um quadro-chave aqui se não houver mudança de cena nos próximos 30 quadros". Alguém que entende C pode adicionar essa opção, no entanto.

Para vídeo com taxa de quadros variável, quando não estiver transmitindo ao vivo como o Twitch, você poderá usar as mudanças de cena sem converter permanentemente em taxa de quadros constante. Se você usar o filtro 'select' no ffmpeg e usar a constante 'scene' na expressão, a saída de depuração (-v debug ou pressione '+' várias vezes durante a codificação) exibirá o número de alteração da cena. Provavelmente, isso é diferente e não é tão útil quanto o número usado por x264, mas ainda pode ser útil.

O procedimento, então, provavelmente seria fazer um vídeo de teste apenas para alterações no quadro-chave, mas talvez pudesse ser usado para dados de controle de taxa, se estiver usando 2 passagens. (Não tenho certeza se os dados gerados são úteis para diferentes resoluções e configurações; os dados da árvore de macroblocos não serão.) Converta-os em vídeo com taxa de quadros constante, mas veja este bug sobre a interrupção da produção ao reduzir pela metade a taxa de quadros, se você decidir para usar o filtro fps para outros fins. Execute o x264 com o quadro-chave desejado e as configurações de GOP.

Em seguida, use esses tempos de quadro-chave com o vídeo de taxa de quadros variável original.

Se você permitir conteúdo maluco gerado pelo usuário com um intervalo de 20 segundos entre os quadros, para a codificação de taxa de quadros variável, poderá dividir a saída, usar o filtro fps, de alguma forma usar o filtro de seleção (talvez crie uma expressão realmente longa que tenha a cada momento do quadro-chave) ... ou talvez você possa usar o vídeo de teste como entrada e decodificar apenas quadros-chave, se essa opção ffmpeg funcionar, ou usar o filtro selecionar para selecionar quadros-chave. Em seguida, redimensione-o para o tamanho correto (há até um filtro scale2ref para isso) e sobreponha o vídeo original. Em seguida, use o filtro de intercalação para combinar esses quadros-chave a serem forçados com o vídeo original. Se isso resultar em dois quadros separados por 0,001 s que o filtro de intercalação não impede, então resolva esse problema com outro filtro de seleção. Lidar com os limites do buffer de quadro para o filtro de intercalação pode ser o principal problema aqui. Tudo isso poderia funcionar: use algum tipo de filtro para proteger o fluxo mais denso (filtro fifo?); consulte o arquivo de entrada várias vezes para que seja decodificado mais de uma vez e os quadros não precisem ser armazenados; use o filtro 'streamselect', o que eu nunca fiz, exatamente nos horários dos quadros-chave; melhore o filtro de intercalação alterando seu comportamento padrão ou adicionando uma opção para gerar o quadro mais antigo em um buffer em vez de soltar um quadro. o que nunca fiz, exatamente nos momentos dos quadros-chave; melhore o filtro de intercalação alterando seu comportamento padrão ou adicionando uma opção para gerar o quadro mais antigo em um buffer em vez de soltar um quadro. o que nunca fiz, exatamente nos momentos dos quadros-chave; melhore o filtro de intercalação alterando seu comportamento padrão ou adicionando uma opção para gerar o quadro mais antigo em um buffer em vez de soltar um quadro.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.