ffmpeg: Como o ffmpeg decide quais quadros escolher quando o valor de fps é especificado?

1

Estou usando o ffmpeg para extrair 3 quadros por segundo usando este comando

ffmpeg -i input.flv -f image2 -vf fps=fps=3 out%d.png

Eu estou querendo saber se eu definir o valor de fps, então como o ffmpeg seleciona 3 quadros em um segundo. É aleatório ou leva os primeiros 3 quadros naquele segundo? Alguma ajuda?

    
por diggy 21.11.2014 / 17:53

1 resposta

3

Ele faz isso redimensionando os valores de timestamp da base de tempo de entrada (ou seja, FPS como uma fração, por exemplo, 24fps se tornaria 1/24) para a base de tempo de saída.

Primeiro, a base de tempo é definida com base no FPS solicitado:

link->time_base = av_inv_q(s->framerate);

Durante a filtragem, o número de quadros de saída é calculado com base no número de quadros de entrada no buffer, escalando esse número entre os dois intervalos de tempo, então basicamente quadros × entrada / saída . Observe que buf->pts - s->first_pts aparentemente é um número de quadros, não uma diferença real no tempo PTS.

/* number of output frames */
delta = av_rescale_q_rnd(buf->pts - s->first_pts, inlink->time_base,
                         outlink->time_base, s->rounding) - s->frames_out ;

Assim, por exemplo, a base de tempo de entrada é 0.042 (24 fps), a saída 0.33 (3 fps) e você tem 12 quadros de entrada no buffer, você terá 12 × 0.042 / 0.33 frames, que é arredondado para o inteiro mais próximo 2 - então dois frames devem ser gerados. Se você tem 24 quadros, obtém, claro, três quadros. Para 35 quadros no buffer de entrada, você obtém quatro quadros de saída.

Se esse delta for menor que 1, os quadros no buffer podem ser eliminados porque nenhum quadro é necessário neste intervalo de tempo. Se, por outro lado, o delta for maior que um, é o número de quadros que precisam ser enviados para o buffer de entrada.

Para novos quadros, o valor PTS é dimensionado com base nas bases de tempo de entrada e saída:

buf_out->pts = av_rescale_q(s->first_pts, inlink->time_base,
                                outlink->time_base) + s->frames_out;

Na prática, isso significa que você terá que olhar para o PTS do seu vídeo de entrada, fazer os cálculos de quantos quadros por segundo sua saída pode ter e distribuí-los igualmente, descartando os quadros conforme necessário. Se você quiser ser super preciso, recomendo depurar o código-fonte com alguns vídeos de teste que você tem.

Eu tenho medo de não ter uma solução mais prática do que a resposta que eu postado aqui recentemente , no qual eu explico como mostrar o PTS de cada quadro em um vídeo cuja taxa de quadros foi alterada:

ffmpeg -i input.mp4 -t 10 -filter:v "fps=fps=25, showinfo" -f null - 2>&1 grep pts_time | awk '{print $6}' | cut -d: -f2

Esses registros de data e hora pertencem a cada quadro de saída e a sua hora de entrada PTS correspondente.

    
por 21.11.2014 / 20:52