Diga ao ffmpeg para descartar frames para reduzir o uso de memória?

Diga ao ffmpeg para descartar frames para reduzir o uso de memória?

Estou transcodificando imagens em tempo real de uma câmera de segurança de MJPEG para MPEG2, usando o formato ffmpeg.

Infelizmente, a máquina que faz a transcodificação não consegue acompanhar (100% de uso da CPU), mas é "boa o suficiente" e não me importo com a perda ocasional de quadros. Mas, por algum motivo, ffmpegnenhum quadro está sendo perdido, então o uso de memória continua aumentando à medida que o processo fica atrasado em relação aos quadros recebidos, e então a máquina fica sem memória e o vídeo começa a ficar gravemente corrompido.

Existe alguma maneira de ffmpegdescartar frames de forma mais agressiva? Os problemas acontecem quando o uso da memória atinge 1,9 GB, então tentei monitreiniciar o processo quando a memória ultrapassa 1,5 GB, porém ele é reiniciado a cada 10 minutos, o que quebra a duração preferida de 15 minutos de cada arquivo transcodificado.

Este é o comando que estou usando:

ffmpeg -overrun_nonfatal 1 -y -i udp://1.2.3.4
    -c mpeg2video -b:v 2M -vf transpose=2
    -preset ultrafast -an -r 30
    out.mkv

A página de manual diz que a -ropção pode ser usada como uma opção de saída para descartar quadros, mas estou fazendo isso e parece que ele apenas descarta quadros para corresponder à taxa de quadros de saída (30fps aqui) em vez de descartar quadros para acompanhar o fluxo de entrada.

A -vsyncopção também parece fazer algo semelhante, tentando corresponder a uma taxa de quadros em vez de minimizar o buffer.

-frame_drop_thresholdparece mais promissor, mas, novamente, parece tratar-se de descartar quadros para acompanhar os carimbos de data e hora, em vez de tentar acompanhar a codificação em tempo real.

Existe alguma outra opção que eu possa usar para ffmpegdescartar quadros conforme necessário, a fim de evitar o uso de tanta memória? Imagino que isso estaria nas opções em tempo real/streaming/baixa latência, mas não consigo encontrar nada!

Responder1

Eu descobri que isso é um problema para o meu ambiente ao capturar da câmera e transmitir em FULL HD e enquanto a rede atinge algum gargalo, o ffmpeg rtbufsize é preenchido rapidamente e o ffmpeg começa a perder quadros. Esta parece ser a solução para o seu problema.

A biblioteca libavformat fornece algumas opções globais genéricas, que podem ser configuradas em todos os muxers e demuxersock:

rtbufsizeinteiro (entrada)

    Defina a memória máxima usada para armazenar quadros em tempo real.

Fonte:Documentação de formatos FFmpeg

Supondo que você queira um buffer limitado de 150 MB, tente isto:

ffmpeg -rtbufsize 150M -overrun_nonfatal 1 -y -i udp://1.2.3.4 -c mpeg2video -b:v 2M -vf transpose=2 -preset ultrafast -an -r 30 out.mkv

Isso significa que, enquanto a máquina não consegue acompanhar, ela começa a preencher os dados que chegam à RAM, enchendo assim o buffer, que quando atingir o limite começará a diminuir fortemente os frames.

informação relacionada