O que significa 'Duração passada X.XXX muito grande'?

142

Ao codificar o H.264 usando o ffmpeg, recebo o seguinte tipo de aviso em massa:

Past duration 0.603386 too large
Past duration 0.614372 too large
Past duration 0.606377 too large

O que eles querem dizer? Não encontrei nada claro online ou na documentação do ffmpeg.

Erik
fonte
2
Dirija as perguntas do ffmpeg para video.stackexchange.com beta. Veja a descrição da tag ffmpeg.
Ondra Žižka
34
@Ondra Ainda outra stackexchange? Estou ficando confuso com esses mais de 100 subsites, não tenho certeza se essa é uma direção positiva para a qual a troca de pilha está indo.
Mxmlnkn
1
@mxmlnkn Concordo, fá-lo por muito tempo para tempos mais simples ... :)
Erik
4
Eu acho que é. StackOverflow é para programação, isso não é programação. Existe um site de perguntas e respostas para o processamento de vídeo. Essa é uma pergunta sobre o processamento de vídeo. O que não há para entender?
Ondra Žižka
Leia também a descrição da tag.
Ondra Žižka

Respostas:

23

Eu estava recebendo milhares desses avisos com uma codificação específica. Eu estava diminuindo o tamanho do vídeo 1080p para 480p. Em um ponto de edição, onde havia algum vídeo desonesto devido a um defeito no disco a laser de origem, essas mensagens começaram a aparecer e apareceram, penso eu, para todos os quadros subsequentes. Eles continuaram, como este pequeno trecho:

Past duration 0.901115 too large=  535031kB time=00:54:15.06 bitrate=1346.5kbits/s dup=0 drop=19 speed=1.15x    
    Last message repeated 31 times
Past duration 0.901115 too large=  535031kB time=00:54:15.62 bitrate=1346.3kbits/s dup=0 drop=19 speed=1.15x    
    Last message repeated 34 times
Past duration 0.901115 too large=  535031kB time=00:54:16.21 bitrate=1346.0kbits/s dup=0 drop=19 speed=1.15x    
    Last message repeated 36 times
Past duration 0.901115 too large=  535338kB time=00:54:16.83 bitrate=1346.5kbits/s dup=0 drop=19 speed=1.15x    
    Last message repeated 39 times

A invocação ffmpeg original era a seguinte:

ffmpeg -i input.mp4 -s 720x480 -c:v libx264 -preset slower -crf 17 -c:a copy -y output.mkv

Seguindo as sugestões aqui, adicionei -framerate 60000/1001 à entrada. Isso não melhorou nada. Mantive -framerate e adicionei -r 60000/1001 à saída. Isso ainda não melhorou nada. Mantendo os dois, finalmente adicionei -async 1 -vsync 1. Isso resultou no recebimento de um único aviso, e é tudo. Essa invocação foi:

ffmpeg -i input.mp4 -framerate 60000/1001 -s 720x480 -c:v libx264 -preset slower -crf 17 -c:a copy -y output.mkv -r 60000/1001 -async 1 -vsync 1

A única diferença que encontrei em um despejo detalhado do MediaInfo foi a remoção dessa linha encontrada na invocação original, mas não na segunda:

Delay relative to video                  : -33ms

No entanto, verifiquei a sincronização A / V perto do início dos arquivos e perto do final, e não havia diferença discernível na sincronização entre os dois arquivos. Os tempos de execução também eram os mesmos, mas isso foi medido apenas no segundo mais próximo, no VLC. Então eu verifiquei a contagem de quadros usando ffmpeg da seguinte forma:

ffmpeg -i output.mkv -map 0:v:0 -c copy -f null -

e procurando "frame = #" próximo ao final da saída.

Acontece que o vídeo de origem tinha 375226 quadros, a invocação original rendeu 375195 quadros e a segunda invocação rendeu 375200. Portanto, a segunda invocação, com muito menos mensagens de aviso, também caiu 5 menos quadros.

Os testes subsequentes mostraram que -framerate e -r eram desnecessários, e apenas o uso dos dois sinalizadores de sincronização era suficiente. Isso produziu resultados idênticos à segunda invocação acima, portanto, a terceira e mais simples descoberta que resolvi para resolver o problema é a seguinte:

ffmpeg -i input.mp4 -s 720x480 -c:v libx264 -preset slower -crf 17 -c:a copy -y output.mkv -async 1 -vsync 1

E ainda outro arquivo posteriormente produziu um monte desses avisos, mesmo com os sinalizadores de sincronização, mas a adição dos sinalizadores de taxa "o corrigiu" (apenas dois em vez de milhares de avisos). Às vezes, a segunda invocação funciona quando a terceira não. Para meus propósitos imediatos, vou me contentar com a segunda invocação e espero que ela resolva a maioria desses problemas.

Isso foi tudo com o ffmpeg versão 4.0.

larryy
fonte
2
Obrigado por isso! Depois de dias com problemas, -async 1 -vsync 1consertei para mim.
Offek
1
Obrigado por esta análise @larryy very helpful #
deepelement 26/06/19
90

Um dos mantenedores do projeto DVDStyler no SourceForge disse o seguinte :

As versões do FFMpeg após 15 de janeiro de 2015 costumam exibir esse aviso. Ele foi adicionado para avisar sobre uma possível distorção no controle da taxa, caso contrário não causará nenhum dano.

Josh Davis
fonte
'distorção do controle de taxa' está relacionado à codificação (principalmente de vídeo) e não tem relação com esse aviso, que é sobre se o timestamp de saída difere muito (relativamente) em comparação com o timestamp de entrada
Gyan
Nas primeiras vezes em que recebi o aviso, encerrei a conversão, mas esse conselho me fez deixá-lo em execução e os avisos pararam depois de um tempo e a conversão foi concluída com êxito. Obrigado.
IRTFM 12/04
58

Essa mensagem de aviso aparece ao tentar codificar uma fonte de alta taxa de quadros para uma saída de baixa taxa de quadros, o que significa que os quadros precisam ser descartados.


Eu tive esse erro porque queria converter uma série de imagens em um vídeo:

ffmpeg -i %05d.png -r 24 -c:v libx264 -crf 5 out.mkv

O problema parece ser que, se nenhuma taxa de quadros for fornecida para a entrada, será assumida uma taxa de quadros de 25 fps:

Input #0, image2, from 'frames/%04d.bmp':
  Duration: 00:00:15.96, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: bmp, bgra, 920x650, 25 fps, 25 tbr, 25 tbn, 25 tbc

Isso também pode ser visto no número total de quadros codificados. Eu tinha 400 imagens, mas o comando acima codificou apenas 384:

frame=  384 fps= 68 q=-1.0 Lsize=   10931kB time=00:00:15.91 bitrate=5626.1kbits/s dup=0 drop=15    
video:10928kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.033807%

As mensagens de erro desaparecem definindo a taxa de quadros de entrada, se a taxa de quadros de saída. A taxa de quadros de saída será automaticamente escolhida para ser a da entrada. Além disso, nas versões mais recentes do ffmpeg, você deve prestar atenção, porque ao usar imagens PNG com a -iopção ou melhor, com o formato image2ou de v4l2entrada, você deve usar, em -frameratevez de -r, consulte a documentação da -ropção .

ffmpeg -framerate 24 -i %05d.png -c:v libx264 -crf 5 out.mkv

Também é possível especificar a taxa de quadros de entrada e saída separadamente:

ffmpeg -framerate 25 -i %05d.png -r 10 -c:v libx264 -crf 5 out.mkv

Nesse caso, apenas 161/400 quadros serão codificados. Os outros quadros provisórios serão eliminados. Além disso, a mensagem de erro desaparece, acho que, para não desacelerar o ffmpeg enviando spam para o stdout, consulte:

mxmlnkn
fonte
3
"porque somente ao usar imagens PNG com a opção -i, é necessário usar -framerate em vez de -r" - isso resolveu meu problema completamente, obrigado!
Anônimo
1
Ao tentar converter um wmv para mp4, usei -rtrabalhou onde -frameratenão.
1934286
+1 e sugiro que você mova seu "resumo" no topo. Mais, como resolveu meu caso de converter imagens em vídeo e tentar aumentar a taxa de quadros da saída e acelerar a saída também. Comecei a partir desta ffmpeg -pattern_type glob -i '*.jpg' -filter:v "setpts=0.25*PTS" -r 50 "$( date "+%Y-%m-%d_%H%M%S")-timelapse-x4-50fps.mp4"a este com não mais aviso ffmpeg -framerate 50 -pattern_type glob -i '*.jpg' -filter:v "setpts=0.25*PTS" -r 50 "$( date "+%Y-%m-%d_%H%M%S")-timelapse-x4-50fps.mp4"(note o -framerate 50agregado para entrada)
el-Teedee
49

Observando o código fonte , parece que a diferença entre o tempo de apresentação (pontos) no fluxo de entrada difere do tempo no fluxo de saída em mais de um limite fixo definido como 0,6.

Trechos da fonte:

    delta0 = sync_ipts - ost->sync_opts;
    delta  = delta0 + duration;

...

        if (delta0 < 0 &&
        delta > 0 &&
        format_video_sync != VSYNC_PASSTHROUGH &&
        format_video_sync != VSYNC_DROP) {
        double cor = FFMIN(-delta0, duration);
        if (delta0 < -0.6) {
            av_log(NULL, AV_LOG_WARNING, "Past duration %f too large\n", -delta0);
        } else
            av_log(NULL, AV_LOG_DEBUG, "Cliping frame in rate conversion by %f\n", -delta0);
        sync_ipts += cor;
        duration -= cor;
        delta0 += cor;
    }

Esta é apenas uma rápida olhada, então fique à vontade para aprofundar.

Erik
fonte
Existe algo que possamos fazer para "corrigir" esse problema ou definir explicitamente os pontos de saída?
Baodad
1
Não me lembro dos detalhes que cercam esse problema, mas se "corrigindo" você quer se livrar do aviso, com base no código acima, pode procurar a opção format_video_sync = VSYNC_DROPou format_video_sync = VSYNC_PASSTHROUGHver se uma delas é viável no seu caso de uso.
Erik
Obrigado. Eu descobri a configuração da taxa de quadros explicitamente usando o -rinterruptor "corrigido" esses avisos.
Baodad 02/03/19
1
Apenas algo da experiência pessoal: eu tive o problema de spam de mensagens de "duração passada" e corrigi isso forçando a taxa de quadros de entrada com -r 25, mas então comecei a deixar o áudio muito fora de sincronia. A remoção da opção -r e o uso de "-async 1 -vsync 1" para impedir a dessincronização de áudio impediram o problema de áudio, mas o spam de "duração passada" parece ter desaparecido também.
Jason Lang
Na v 4.1 e posterior, o nível do log foi atualizado, portanto, não aparecerá no nível do log padrão.
Gyan 19/01
1

O comando deve realmente ser:

ffmpeg -loglevel quiet -i input_file.xyz ...

Não há prefixo "-" para o parâmetro "quiet", pois não é uma opção, e sim um valor para a opção "-loglevel".

Gordon McCrae
fonte