Estoy creando un sistema que, entre otras cosas, tiene un sensor de imágenes que emite video digital a 30 fps y un sistema de pantalla que se muestra en un monitor a 60 fps. El sistema actualmente utiliza un controlador de búfer de cuadros que he implementado en una memoria FPGA y fuera de chip. El lector (monitor) lee desde el búfer a voluntad y el escritor (cámara) bombea datos al búfer a voluntad (es un controlador totalmente asíncrono). Hay suficiente memoria para almacenar algunos marcos de datos. El sistema funciona bien. Puedo visualizar el video de la cámara en un monitor sin ningún problema.
El problema al que me estoy enfrentando es que el lector / escritor tiene diferentes velocidades / resoluciones de reloj y, por lo tanto, diferentes fps. Lo que esto implica es que, en algún momento, el monitor muestra datos del marco de imagen actual, pero debido a que consume datos más rápido que la cámara produce datos, la cámara se “ejecuta” y comienza a mostrar datos desde un marco de cámara obsoleto. Esto está bien siempre que la cámara no se mueva muy rápido o que la misma escena se visualice una y otra vez. Sin embargo, si la cámara se mueve rápidamente o algo en la escena se mueve rápidamente (por ejemplo, las cosas en la escena se mueven más rápido que la frecuencia de muestreo de la cámara), entonces está claro que el cuadro actual será sustancialmente diferente del cuadro anterior. Eso significa que el monitor puede mostrar partes de ambos cuadros al mismo tiempo, lo que se manifiesta en una línea que "se mueve" hacia abajo en la pantalla.
Entonces, respondiendo a mi pregunta, me pregunto cuál es la mejor manera de resolver este problema. El monitor y la cámara tienen dos relojes independientes, que son asíncronos entre sí. Tengo control (genero) el reloj de píxeles para el monitor, pero el reloj de píxeles de la cámara es 100% asíncrono al sistema (sale de un deserializador IC). Algunos detalles más: el FPGA está sincronizado a 100 MHz desde un oscilador. Utilizo un DCM en el interior para generar el reloj de píxeles de 40 MHz para el monitor y tengo varias otras piezas del sistema funcionando a 100MHz. El reloj de píxeles de la cámara es de aproximadamente 13 MHz (pero puede ir hasta 27 MHz). La cámara FPS generalmente se atasca a 30 FPS, pero puede ir más lento dependiendo del control de exposición.
Podría hacer algo como mostrar siempre el mismo fotograma dos veces para que el monitor esté haciendo 60 fps, pero 30 fotogramas distintos por segundo. Eso funcionaría bien, pero si alguna vez cambio la velocidad de fotogramas de la cámara a algo arbitrario que no se divide bien en 60, entonces no tengo suerte. Quizás lo más importante es que si cambio los fps de mi monitor, esto funciona mal. Como una extensión más robusta de esta idea, podría pensar en formas de mostrar solo "marcos enteros". En otras palabras, no comience a leer un nuevo marco de imagen hasta que esté completamente escrito (o de forma más sólida hasta que sepa que no va a ejecutar la cámara en ese marco). Esto significaría que no todos los cuadros de imagen obtienen la misma cantidad de cuadros de visualización, pero tal vez eso esté bien.
¿Alguna sugerencia? ¿Cómo manejan típicamente los sistemas comerciales este problema? En particular, ¿cómo manejan esto las cámaras USB? Eso parece un análogo bastante apropiado. Presumiblemente, transfieren datos a un búfer en el lado de la máquina y el software de pantalla tiene que procesar los datos / volcarlos en el controlador de gráficos (estoy pensando en algo como una llamada a glutswapbuffers).