[Jderobot-dev] RTSP y MJPEG sin delay en Android

Roberto Calvo rocapal en libresoft.es
Jue Mar 28 14:57:36 CET 2013



El mié, 27-03-2013 a las 23:59 +0100, Oscar Garcia escribió:
> El 27/03/13 12:30, Roberto Calvo escribió:
> > Cuando queréis mostrar un vídeo por RTSP o MJPEG en Android utilizando
> > un VideoView o MediaPlayer, siempre tiene un delay excesivo (en torno a
> > 10seg). Parece un delay añadido en código a bajo nivel dificil de
> > saltarse.
> 
> 
> Esto se debe a la naturaleza de las conexiones TCP y de los códecs 
> usados en el streaming. En el streaming de vídeo no puede faltar ningún 
> paquete de datos debido a que se envían fotogramas estimados a partir de 
> los anteriores en la gran parte del tiempo. La pérdida de un fotograma 
> estropearía la imagen de vídeo hasta el siguiente fotograma completo 
> (sin dependencias de los anteriores) recibido.
> 
> Para evitar parones debido a que un paquete se ralentice más de lo 
> normal se suele almacenar en memoria una serie de fotogramas (casi 
> siempre una o dos secuencias completas de fotograma completo más los 
> estimados en el tiempo) para minimizar cualquier tipo de parada en la 
> reproducción. Así que realmente el problema está en el reproductor, una 
> mínima parte de la culpa está en el transmisor.

Si y no Oscar :-) 

VLC o mplayer contra un vídeo streaming por RTSP no tiene más de 1-2
segundos de delay (tanto en Android como en Desktop). Es lo normal y es
a lo que estamos acostumbrados con una conexión normal.

El problema es que si programas en nativo en Android utiliando el
componente VideoView que permite reproducir streaming RTSP, siempre
siempre siempre tiene un delay de 10seg, independientemente de los
paquetes, red y conexión. Está ya más que documentado este bug (feature
para otros) en Android, pero de momento sigue así.

Está claro la ventaja de UDP contra TCP en este tipo de aplicaciones,
pero el delay de 10seg en Android utilizando VideoView está hardcodeado
y es una faena.

[sigo más abajo]
> 
> 
> 
> > He encontrado un par de opciones que os pueden venir bien si
> > necesitáis mostrar video en vuestras apps:
> >
> > MJPEG:
> > En el siguiente enlace podéis encontrar el código para descargar y
> > mostrar un video por streaming usando MJPEG. Tiene un delay de 1-2
> > segundos y funciona bastante bien. La pega es que tiene que ir sobre
> > http y no sobre rtsp
> > http://stackoverflow.com/questions/10550139/android-ics-and-mjpeg-using-asynctask
> 
> 
> Esta tarde he agregado soporte de vídeo a una implementación remota de 
> sensores y cámara en Android y este es el resultado:
> http://www.youtube.com/watch?v=3UHwSxOfxqw
> 
> Subiré el código a mi repositorio en cuanto pueda (mañana temprano salgo 
> de vacaciones y no es tema de acostarme tarde :).
> 
> La gran ventaja de MJPEG es que cada fotograma es un fotograma completo, 
> no depende del anterior, por lo que no pasa nada si se pierde alguno, 
> podría enviarse por UDP uno a uno los fotogramas y evitaríamos el 
> problema de la congestión de una conexión TCP, pero si se usa HTTP como 
> transporte entonces hay que implementar algo en el transmisor para 
> detectar que el receptor está bien o está congestionado y debe saltarse 
> fotogramas.
> 
> Como podéis ver en mi implementación hay menos de un segundo de retardo 
> entre la imagen real y la mostrada en el navegador web. De vez en cuando 
> hay un parón debido a la pérdida de algún paquete en la red WiFi, por lo 
> que mi aplicación servidor (que usa un buffer de transmisión muy pequeño 
> y NIO como API de comunicaciones Java) detecta la congestión rápidamente 
> y evita seguir haciendo streaming hasta que se recupere el receptor.
> 
> En mi implementación de cameraserver en Android no es necesario control 
> de congestión debido a que el cliente solicita un fotograma y no 
> solicita el siguiente hasta haber recibido el anterior. Eso es 
> contraproducente debido a que se está limitando la cantidad de imágenes 
> por segundo a la latencia de la red y el tiempo de 
> codificación/decodificación:
> http://www.youtube.com/watch?v=_d_8pzFQOZ4
> 
> En streaming de fotogramas la ventaja es que puede haber en tránsito más 
> de un fotograma en un momento dado o estar empezando a llegar un 
> fotograma en el lado del cliente cuando se empieza a codificar el 
> siguiente en el lado del servidor.
> 
> Si comparamos ambos vídeos, en la página web del vídeo de MJPEG se está 
> mostrando streaming de imágenes de 640x480 al igual que el segundo 
> ejemplo (el de la segunda mitad del vídeo de cameraserver, el que va 
> lento). Es notable la diferencia entre ambos.

La implementación que has hecho de MJPEG en android es estándar? Es
decir, da igual si lo enganchamos a un cameraserver o a una webcam que
exporte video usando MJPEG ¿funciona?

Sería ideal que cameraserver exportara imágenes o vídeo de una manera
estándar para poder utilizar los clientes que quisieramos. Hay veces
donde JDEROBOT no podemos integrarlo donde quisieramos (por ejemplo en
una webcam IP) y entonces los clientes no se puede utilizar. Yo lo vi
claro con mi PFC del Máster, donde si no estaba JDEROBOT por medio, no
podía visualizar ningúna webcam.


> 
> Un saludo y que disfrutéis del puente de semana santa.

Igualmente, a descansar!


> _______________________________________________
> Jde-developers mailing list
> Jde-developers en gsyc.es
> http://gsyc.escet.urjc.es/cgi-bin/mailman/listinfo/jde-developers


-- 
Roberto Calvo Palomino        | Libre Software Engineering Lab (GSyC) 
R&D Android Mobile Engineer   | Universidad Rey Juan Carlos
Tel: (+34) 91 488 87 73       | Edif. Biblioteca - Despacho B103

Twitter: @rocapal 
Linkedin: http://www.linkedin.com/in/rocapal



More information about the Jde-developers mailing list