viernes, mayo 19, 2006

El Canvas más rápido del oeste

Esta semana Mario y yo hemos estado trabajado para optimizar al máximo MonoCanvas. La idea es lograr un rendimiento similar a Dia. Creo que hasta el momento se ha avanzado bastante. Yo he estado portando lo que ya estaba de GDI+ a Cairo directamente. Mario está haciendo una re-implementacion usando widgets de Gtk#. Lo interesante de este enfoque es que se aprovecha toda la lógica, ya bastante optimizada a través de los tiempos, que ya usa GTK+.

Para las pruebas con Cairo, he usado una pequeña aplicación Gtk# con 100, 200 o más widgets. He hecho pruebas con Dia y  empieaza a flaquear más o menos al mover 200 formas simultaneamente. Con este número de formas, la taza de actualización del canvas se reduce drásticamente, a menos de 4 repintadas por segundo. Los resultados con el nuevo canvas basado en Cairo son similares a los de Dia, sin embargo, hay que tener en cuenta que la versión de Cairo usa antialiasing y transparencias mientras que Dia no. La verdad es que estoy muy satisfecho y creo que incluso hay potencial para optimizar más.

Aquí hay unos pantallazos de MonoCanvas basado en Cairo y Dia:

Pantallazo de Mono Canvas Test Pantallazo de Dia

Por supuesto la versión de Cairo no es simplemente un cambio de GDI+ por Cairo, también son varios cambios que hacen más óptimo el programa. Dibujar a través de Gtk.DotNet es bastante lento. Y no sólo se trata de que el API System.Drawing esté basada en libgdiplus que a su vez esta implementada encima de Cairo, sino que el procedimiento de obtener un Drawing.Graphics de un Gdk.Drawable no es el más eficiente. He aquí un pedazo del código de Gtk.DotNet.Graphics:

public static System.Drawing.Graphics FromDrawable(Gdk.Drawable drawable, bool double_buffered)
{
...
Type graphics = typeof (System.Drawing.Graphics);
MethodInfo mi = graphics.GetMethod ("FromXDrawable", BindingFlags.Static | BindingFlags.NonPublic);
if (mi == null)
throw new NotImplementedException ("In this implementation I can not get a graphics from a drawable");
object [] args = new object [2] { (IntPtr) gdk_x11_drawable_get_xid (drawable.Handle), (IntPtr) display };
object r = mi.Invoke (null, args);
System.Drawing.Graphics g = (System.Drawing.Graphics) r;
...
return g;
}

Este método es el que se llama cada vez que se repinta  parte del canvas cuando se usa Gtk.DotNet. El cual se debe llamar, además de todas las operaciones de dibujo, unas 40 veces por segundo para lograr un movimiento fluido. Rápidamente se pueden observar dos problemas de rendimiento. Por un lado, el uso de System.Reflection para encontrar el método FromXDrawable y por el otro, la creación del objeto args.

Cuando se usa Cairo, en cambio, se usa el método Gdk.CairoHelper.Create que está basado en la implementación nativa que viene con el nuevo GTK+ 2.8, por lo tanto las cosas se hacen considerablemente más rápido.

La clave del rendimiento es dibujar lo menos posible. Definitivamente las operaciones de dibujo son las que más tardan, hay que hacer todo lo posible por no dibujar lo que no es necesario. Otras operaciones que puede pensarse son lentas, como las iteraciones a largas listas, en realidad no influyen mucho. Algo a tener en cuenta es que dibujar donde no se ve, es decir, fuera del QueueDrawArea también influye en el rendimiento, hay que evitarlo.

Otra cosa bastante curiosa es que el rendimiento depende bastante de la forma que se esté dibujando. Por ejemplo, una elipse es más lenta que un rectágunlo. Pero mucho más curioso es que una elipse con borde y sin relleno, es casi tres veces más lenta que una con relleno y sin borde. Algo similar pasa con los rectángulos.

El API de Cairo me ha gustado bastante. Es bastane parecido a OpenGL, por lo que es bastante familiar para mi. Aunque tiene alguas cosas raras, me ha gustado mucho más que System.Drawing, creo que es mucho más flexible.

Pronto uniremos el trabajo de Mario con el mio en la versión definitiva de MonoCanvas.

domingo, mayo 14, 2006

Edición de Vídeo Digital en Linux

Estoy adentrándome en la edición de vídeo digital con Linux y software de código abierto. Hasta ahora la experiencia no ha sido la mejor. A Linux le falta bastante para convertirse en una plataforma decente para edición de vídeo digital. Sin embargo, el futuro pinta bien, al menos se ve que hay trabajo en la dirección correcta.

Hasta ahora he hecho pocas pruebas de edición de vídeo con Linux. El punto de comparación será Windows, el cuál he vuelto a instalar en mi PC (sólo con propósitos comparativos :P). La verdad es que la experiencia de vídeo digital en Windows es bastante buena. No quiero ni imaginar qué tan buena sería en Mac OS X. En Linux toca por el lado difícil.

Bien, aquí está un compendio de las herramientas que he usado:

Dvgrab. En Windows, se prende la cámara, se conecta al puerto firewire, e inmediatamente sale un diálogo que dice: "Parece que ha conectado una cámara de video Samsung SCD 180, haga click aquí para capturar el video". En un Linux out of the box simplemente no sucede nada cuando se conecta la cámara. Es necesario bajar una herramienta con interfaz de comandos, Dvgrab , para poder capturar el vídeo desde la cámara. Dvgrab es una herramienta bastante flexible y fácil de usar (para alguien acostumbrado a la línea de comandos, claro está), además, está bien adecuada para la automatización a través de scripts. Me gustaría bastante ver algo con HAL y DBus que permitiera mostrar un mensaje en la misma manera que lo hace Windows.

Kino, un editor de vídeo digital para Gnome. Es del mismo creador de Dvgrab. Mi experiencia con Kino no ha sido la mejor. La interfaz de captura de vídeo funciona cuando le da la gana y cuando captura curiosamente el vídeo no se ve, es bastante raro. La interfaz de Kino es bastante rara y confusa, a veces realizar simples tareas es un misterio. Aplicar ciertos filtros tarda toda una eternidad.

Pantallazo de Kino:

Kino Cut Tab

Diva. ¡Esta es la promesa de edición de vídeo digital en Linux! Diva es un proyecto para crear un editor de vídeo fácil de usar y escalable (a través de una arquitectura de plugins). Apenas está naciendo, pero es muy prometedor. Lo que lo hace prometedor es que han comenzado a hacer las cosas en la forma correcta. Diva está siendo desarrollada con Mono (obviamente :P) y esta siendo construida encima del asombroso GStreamer. Más interesante aún es el enfoque hacia la facilidad de uso que tiene Diva. Algunas personas como Miguel de Icaza han catalogado a Diva como la aplicación gráfica más pulida que hayan visto. Creo que estas apreciaciones se deben al fantástico widget de línea de tiempo que tiene, el cual ha sido creado en forma muy meticulosa usando Cairo y las nuevas características de GTK+ 2.8. Diva pinta muy bien, demasiado bien.

Pantallazos de Diva:

Diva Main Window Diva New Project

Diva Editing Window

Diva Export Dialog

Bueno, de todos modos mi experiencia con Diva no ha sido color de rosa, de hecho apenas hasta hace pocos días pude hacerla funcionar. Como dije antes, Diva es un proyecto que apenas está naciendo y, por supuesto, siempre está bleeding the edge. Una prueba de esto es que Diva necesita la versión CVS de GStreamer, y no sólo eso, necesita una versión parchada.

Después de bajar, parchar, compilar e instalar todo lo que necesitaba, mi experiencia al intentar usar Diva fue un horrible, muy horrible "Segmentation Fault". Afortunadamente, como en todo proyecto de código abierto que ser respete, encontré un gran apoyo en la comunidad. Después de comentar el problema y cacharrear, la respuesta que obtengo de todo el mundo en #diva es "your problem IS very strange". Luego de algunos días y gracias a la valiosa ayuda de Michael Dominic y al glorioso gdb, se pudo identificar el problema. Primero pensábamos que era Diva, de Diva pasamos a GStreamer, y de GStreamer pasamos al verdadero culpable: Libdv. Al final pude ingeniar una solución temporal. Sin embargo, la solución final estará dada cuando se arregle el bug que reporté a Fedora. Ya Jarod Wilson está trabajando en. ¡La comunidad del software libre es lo mejor!

Todo el cuento del bug en libdv me sirve para comentar un punto interesante. Varias veces atrás he escrito acerca de mi inconformidad con el método de instalar software usando los paquetes tradicionales de Linux. Bien, la experiencia con Diva me ha traído otro argumento más, que he denominado forks egoístas. Para entenderlo hay que analizar el caso de libdv. Libdv es una pieza de software algo vieja (teniendo en cuenta los estándares del código abierto), lleva dos años y medio sin actualizarse. Como era de esperarse, es difícil compilar libdv. Yo no pude hacerlo en mi Fedora Core 5. Tiene a gtk+ 1.x como dependencia (¡uich!). ¿Cómo hacen entonces los empaquetadores para compilarlo? Sencillo, le aplican a libdv una serie de parches que sirven para que se pueda compilar en sistemas modernos. Hasta ahí todo va bien. El problema radica en que estos parches son aplicados individual y aisladamente por cada distro o línea de distros. Los empaquetadores no se preocupan por integrar el parche al proyecto original, o apropiarse de él, si está abandonado, sino que lo aplican egoistamente al paquete de su distro. El resultado son pequeños forks de un proyecto.

En la vida real, la prueba de la existencia de los forks egoístas se puede apreciar en libdv. Para el paquete libdv, algunas distros usan unos parches y otras usan otros. Por ejemplo, en Fedora y Gentoo (pude comprobarlo gracias a que Travis Hansen, un gentooero, tenía el mismo problema) se aplican unos parches y en Debian y Ubuntu otros. Es por esta razón que en Fedora y Gentoo ocurría el bug con Diva y en Debian y Ubuntu no. No es que se trate de un insignificante parche, son bastantes cambios los que se hacen. Tampoco es que unos parches sólo sirvan para la configuración de determinada distro porque el problema lo solucioné usando los parches de Debian. Pienso que lo correcto es que estos parches vayan al repositorio oficial de libdv y todos puedan beneficiarse por igual.

De tanto hablar de paquetes y bugs me desvié del hilo principal de este post, la edición de vídeo digital. ¿Por qué estoy probando en este campo? La respuesta es que tengo pensado filmar y producir la cuarta versión de Semilla de Libertad, una serie de documentales sobre software libre en Colombia que ha realizado mi amigo Gustavo Gonzales. La idea es hacer el documental en la próximas Jornadas de Software Libre en Agosto. Quiero intentar editar la película con software libre. Ojalá se pueda.

Por cierto, también estoy probando la edición de vídeo con software propietario (para comparar vuelvo y repito :P). Ya bajé e instalé Adobe Premiere 7.0 Pro (La última versión, la 2.0, necesita un equipo más potente). Me parece que la interfaz es enredada y complicada, aún no aprendo a manejarlo. Windows Movie Maker, aunque modesto, me ha parecido muy fácil de usar, la interfaz no tiene pierde. Hay que seguir probando otras alternativas...