Reduz a taxa de quadros de vídeo sem perder quadros úteis

3

Eu tenho um vídeo de uma câmera de segurança que foi originalmente gravada em uma baixa taxa de quadros, talvez 15 qps, talvez 10 qps, talvez até menos. Ele já foi convertido por outra pessoa para 25 fps (sem alterar a duração). Presumo que quadros extras duplicados tenham sido adicionados e, possivelmente, isso também tenha distorcido um pouco a hora exata em que os quadros originais são exibidos.

Eu quero recodificar o vídeo com ffmpeg para sua taxa de quadros original, sem perder nenhum dos quadros úteis do movimento real. Se eu apenas usar o filtro fps , ele não será seletivo sobre quais quadros ele mantém, e presumo que, devido a erros de arredondamento, ele pode acabar mantendo alguns dos quadros duplicados e permanentemente perdendo quadros úteis, tornando as coisas piores. De qualquer forma, não sei qual o número para informar o filtro porque não sei exatamente qual foi a taxa de quadros original!

Como posso proceder para reparar este vídeo com o ffmpeg?

ffmpeg -i "orig.mp4" -an -vcodec h264 -vf "fps=???" "fixed.mp4"
    
por Boann 18.02.2016 / 16:49

2 respostas

4

Consegui consertar meu arquivo. Encontrei o filtro mpdecimate , que elimina quadros duplicados ou quase duplicados de um fluxo de vídeo. Primeiro eu tentei:

ffmpeg -loglevel debug -i orig.mp4 -an -vf "mpdecimate" test.mp4

Adicionei -loglevel debug para obter mais informações durante a transcodificação. As informações mostravam o que o mpdecimate estava fazendo com os quadros, o que era muito e muito desse padrão:

lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:44032 pts_time:3.44 drop_count:1
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:44544 pts_time:3.48 drop_count:2
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:45056 pts_time:3.52 drop_count:3
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:45568 pts_time:3.56 drop_count:4
781>=hi keep pts:46080 pts_time:3.6 drop_count:-1
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:46592 pts_time:3.64 drop_count:1
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:47104 pts_time:3.68 drop_count:2
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:47616 pts_time:3.72 drop_count:3
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:48128 pts_time:3.76 drop_count:4
821>=hi keep pts:48640 pts_time:3.8 drop_count:-1
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:49152 pts_time:3.84 drop_count:1
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:49664 pts_time:3.88 drop_count:2
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:50176 pts_time:3.92 drop_count:3
lo:0<217 lo:0<-2147483648 lo:0<-2147483648 drop pts:50688 pts_time:3.96 drop_count:4
793>=hi keep pts:51200 pts_time:4 drop_count:-1

Ou seja, ele consistentemente descartava 4 quadros seguidos como duplicados e mantinha a cada 5. Isso mostrou que a taxa de quadros original era 1/5 do que era agora. Tive sorte! Como os 25 fps atuais do vídeo eram um múltiplo da taxa de quadros original, não deveria haver um problema com o desalinhamento temporal dos quadros mantidos e descartados. Por isso, retranscrevo o vídeo original com nada mais complexo que -vf "fps=5" , e a saída parece estar bem. Só para ter certeza, eu canalizei a saída através do filtro mpdecimate , e detectei todos os quadros restantes como um "keep". Então o arquivo original não foi tão confuso como eu pensava.

    
por 18.02.2016 / 20:42
2

Se os quadros extras forem duplicados e não interpolações, o seguinte poderá funcionar:

ffmpeg -i orig.mp4 -an -vf "select='gt(scene\,0.001)',setpts=N/(10*TB)" -r 10 fixed.mp4

A idéia é selecionar todos os quadros não duplicados do quadro anterior. Então, os PTS são regenerados de acordo com a taxa de saída especificada. Você pode ter que ajustar o valor da cena para cima ou para baixo para obter o filtro de detecção correto. Se o vídeo aparecer mais rápido ou mais lento que o tempo real, diminua ou aumente a taxa (e definiremos o valor do denominador) respectivamente.

    
por 18.02.2016 / 19:23