Velocidad de fotogramas durante la transmisión de pantalla

0

Estoy tratando de grabar la pantalla usando ffmpeg con el siguiente comando:

ffmpeg -f x11grab -s 1366x768 -framerate 30 -i :0.0 -c:v libx264 -b:v 1000k out.mp4

que aprendí de aquí .

Pero no puedo entender lo que frameratesignifica en este contexto.

Esto es lo que pienso :

Si estuviéramos convirtiendo un conjunto de imágenes almacenadas en un directorio a un video como se menciona aquí , una velocidad de fotogramas de 30habría significado: 'Mostrar las primeras 30 imágenes en el primer segundo del video, las siguientes 30 imágenes en el siguiente segundo y así hasta que se agoten todas las imágenes ' .
Hasta ahora, por ejemplo, si tuviéramos 90 imágenes, la duración del video resultante habría sido de 3 segundos.

De la misma manera, durante el screencasting, debería ocurrir lo siguiente:

Suponiendo que la frecuencia de actualización de mi pantalla es de 60 Hz, se generan y almacenan 60 imágenes por segundo en un búfer.
Pero, dado que ffmpegse le ha dado una velocidad de cuadro de 30, toma las primeras 30 imágenes (imágenes # 1 - # 30) del búfer y produce 1 segundo de video, luego toma las imágenes # 31 - # 60 y produce el siguiente segundo de video .
Eso significa que, durante 1 segundo de grabación, se producirían 2 segundos de video.


Para probar esta teoría, realicé el siguiente experimento:

Ejecuté un cronómetro gráfico en la pantalla y lo hice funcionar durante exactamente 10 segundos, mientras simultáneamente grababa el cronómetro del 1 al 10.

Según mi teoría, o el video producido debería haber sido de 20 segundos y haber mostrado un conteo completo de cronómetro de 1 a 10, o , para mantener el tiempo de video igual al tiempo de grabación, ffmpeg habría generado un video de 10 segundos y mostrado solo la mitad del cronómetro cuenta de 1 a 5 (los primeros 30 * 10 = 300 cuadros de un total de 600 cuadros generados por la tarjeta gráfica durante el mismo tiempo).

Pero, ninguno de los dos casos anteriores sucedió. En cambio, la duración del video fue de 10 segundos y el contenido fue exactamente el mismo que el aspecto de la pantalla durante la grabación, es decir, el conteo del cronómetro va de 1 a 10.

Repetí el mismo experimento usando una velocidad de fotogramas de 10 en lugar de 30, y encontré los mismos resultados, es decir, la duración del video es de 10 segundos y el recuento del cronómetro se muestra de 1 a 10.

Entonces, ¿qué tiene de malo mi teoría?


La única otra teoría en la que he podido pensar y que es consistente con mis observaciones es esta:

Dado que ffmpeg tiene que grabar a una velocidad de cuadro de 30 dada una corriente de entrada de 60 Hz, omite cualquier otra imagen durante la producción de video.
Es decir, utiliza la imagen # 1, # 3, # 5 ... # 60 para producir 1 segundo de video.

Pero no estoy seguro de si esto es correcto.


Mi configuración del sistema:

  • SO: Ubuntu 16.04

  • versión ffmpeg:
    ffmpeg version 2.8.6-1ubuntu2 Copyright (c) 2000-2016 the FFmpeg developers built with gcc 5.3.1 (Ubuntu 5.3.1-11ubuntu1) 20160311 configuration: --prefix=/usr --extra-version=1ubuntu2 --build-suffix=-ffmpeg --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --cc=cc --cxx=g++ --enable-gpl --enable-shared --disable-stripping --disable-decoder=libopenjpeg --disable-decoder=libschroedinger --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librtmp --enable-libschroedinger --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxvid --enable-libzvbi --enable-openal --enable-opengl --enable-x11grab --enable-libdc1394 --enable-libiec61883 --enable-libzmq --enable-frei0r --enable-libx264 --enable-libopencv libavutil 54. 31.100 / 54. 31.100 libavcodec 56. 60.100 / 56. 60.100 libavformat 56. 40.101 / 56. 40.101 libavdevice 56. 4.100 / 56. 4.100 libavfilter 5. 40.101 / 5. 40.101 libavresample 2. 1. 0 / 2. 1. 0 libswscale 3. 1.101 / 3. 1.101 libswresample 1. 2.101 / 1. 2.101 libpostproc 53. 3.100 / 53. 3.100

Anmol Singh Jaggi
fuente
1
Tu segunda teoría es correcta. FFmpeg busca preservar las relaciones temporales, por lo que una alimentación de 60 fps configurada para recibir 30 fps dará como resultado la caída de la mitad de los cuadros.
Gyan
Gracias @Mulvya. ¿Me puede decir una cosa más? Las dos salidas de video (con fps 30 y 10) tienen el mismo tamaño de archivo. Entiendo que esto podría deberse al hecho de que ambos videos tienen la misma tasa de bits. Pero, ¿eso significa que en el video de 10 fps, los bits / fotograma son más y, por lo tanto, cada fotograma será más nítido (más profundidad de color) que el de 30 fps?
Anmol Singh Jaggi
En general si. Pero si la tasa de bits es lo suficientemente alta y el movimiento es poco frecuente, no notará una gran diferencia.
Gyan
Como tengo mi respuesta, quiero cerrar la pregunta. ¿Quieres escribir la respuesta o debería hacerlo yo mismo?
Anmol Singh Jaggi

Respuestas:

1

FFmpeg es un procesador de medios basado en el tiempo y, como tal, se esfuerza por mantener una relación temporal de la entrada a menos que se indique lo contrario.

La framerateopción para el x11grabdispositivo establece la velocidad de cuadro de captura. Si se suministran menos o más fotogramas por segundo, ffmpeg duplicará o eliminará la diferencia, respectivamente.

Gyan
fuente