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, ffmpeg
nenhum 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 ffmpeg
descartar frames de forma mais agressiva? Os problemas acontecem quando o uso da memória atinge 1,9 GB, então tentei monit
reiniciar 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 -r
opçã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 -vsync
opção também parece fazer algo semelhante, tentando corresponder a uma taxa de quadros em vez de minimizar o buffer.
-frame_drop_threshold
parece 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 ffmpeg
descartar 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:
rtbufsize
inteiro (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.