Hoy cumplo 22

July 13th, 2010

0×22h es el lo que cumplo…… ¡maldita sea, 34 tacos!. Y lo peor de todo….¡aún no salgo en la revista Fortune!
Solo conseguí esta otra portadaportada_con_mi_foto.
¡Hay tantas cosas que pensé que se conseguirían para este año!,cosas que de pequeño pensé que se conseguirían para el 2010.
Los coches no vuelan, no conseguí ser astronauta,no hemos viajado a otros planetas, en casa los teléfonos no tienen vídeo conferencia (malditos móviles, no se me pasaron por la cabeza), no somos inmortales, y así un largo etcétera de sueños no cumplidos :-)
Pero bueno, el caso es que sigo aquí, ¡dando guerra!, y con mis dos hijos y mi mujer (eso tampoco lo imaginaba) y espero que por muchos años…

Programación extrema en Madrid

June 18th, 2010

Una vez más, la historia se repite, plazos obscenamente cortos y muchas lineas por delante. Este mezcla es como el último chupito que hace potar a Amy Whinehouse, ¡horrible!.
Llevo unas tres semanitas con jornadas interminables de programación in-situ además de presión del cliente(o incluso tu jefe de proyecto) que viene cada dos por tres a prenguntar eso de “¿que tal va?”,mira un poco la pantalla (como si supiese que estoy haciendo :-) ), tuerce el morro, hace alguna mueca más, se vá y vuelve al de un rato. Y así durante varios dias.
Pero bueno, ya lo tengo asumido, no hay mal que cien años dure y todo eso….. de momento me basta con descargame en el blog ;-)

Libros de primavera

May 17th, 2010

Una vez más el ajedrez ha copado parte de mi tiempo libre. En esta ocasión he terminado “Aprenda Tácticas de Ajedrez” de John Nunn.
Aprenda Tácticas
Se trata de un libro bastante básico (demasiado para mi gusto, será que estoy mejorando algo) donde se exponen los temas tácticos más frecuentes y se plantean a continuación problemas para que el lector vaya resolviéndolos.
Lo bueno, están muy bien explicados (tampoco es necesaria mucha prosa para explicar táctica) y muestran como terminó la partida después del golpe táctico. Además son todo partidas reales y relativamente recientes.
Lo malo, son pocos ejercicios. Si lo que buscas, como es mi caso, es un libro para entrenar, te vendrá mucho mejor cualquiera de los libros de 1001 problemas de Fred Reinfeld. Estos libritos tienen muchos ejercicios y además son libros pequeñitos y ligeros que puedes llevar contigo a cualquier parte, metro, avión, etc. Cualquier sala de espera se convertirá en una improvisada sesión de entrenamiento táctico.

Libros de primavera

April 19th, 2010

Sigo con los episodios nacionales, en este caso “El 19 de marzo y el 2 de mayo”,la tercera novela de la primera serie. Continúa con la historia de Gabriel, también protagonista de los dos anteriores episodios.
En este episodio Gabriel será testigo del Motín de Aranjuez del 19 de Marzo día en el que Godoy cae desgracia, también intervendrá en el levantamiento del 2 de Mayo contra los franceses en el que es fusilado.

Ya llegó la rumba

March 9th, 2010

Recientemente hemos comprado un pequeño robot que barre la casa iRobot, la verdad es que es un ahorro de tiempo considerable, personalmente recomiendo encarecidamente este robotito a cualquier persona que tenga poco tiempo para las tareas del hogar.
Por supuesto no es la panacea, ¿alguien se esperaba que abra puertas o que mueva cajas del suelo?, pero hace bastante bien su tarea. De hecho, ¡estamos pensando en comprar el que friega y seca!.

Se puede adquirir en Internet, en el corte ingles y empieza a aparecer en algunos comercios de electrodomésticos.

Ya comentaré algo cuando compremos el que friega.

Conceptos de streaming para andar por casa

February 22nd, 2010

Dado que existe cierta confusión sobre los conceptos básicos de video, audio, formatos, contenedores,muxers y demás parafernalia vamos a comentar lo más básico por lo menos para entender algo cuando leemos documentos.

Streams, Muxers, Codecs, Contenedores y demas parafernalia

¿Qué es un codec?

Es imprescindible para sobrevivir en esta maraña de conceptos entender la diferencia entre un codec y un contenedor.

Un codec es un algoritmo de compresión que se utiliza para reducir el tamaño de los datos a transmitir (video, audio o lo que sea), llamados streams.

Tenemos codecs para audio como por ejemplo el conocido MP3 o el ogg-vorbis

Tenemos codecs para video como por ejemplo el DivX el MPEG-1,MPEG-2 o MPEG-4.

¿Qué es un contenedor?

Pongamos una analogía para simplificar las cosas. Pensemos en un contenedor como si fuese un paquete postal, la típica caja de embalar, con algo dentro. Cuando recibes la caja piensas:

- ¡mola!, una caja, pero, quiero lo de dentro

No nos importa la caja en si, queremos obtener el contenido, ¿como?, coges un cutter y la abres.

El formato contenedor sigue, básicamente, el mismo principio. Contiene dentro uno o varios streams (recuerda, son los datos de audio o video) comprimidos con un codec. Lo más habitual es que dentro de la caja (el contenedor) haya un stream de audio y otro de video.

Contenedores habituales son, AVI, Ogg, MOV, ASF, MP4.

Los streams que van dentro del contenedor estarán comprimidos con diferents codecs. En un mundo ideal podríamos poner cualquier stream comprimido con cualquier codec en cualquier formato contenedor. Pero, lamentablemente, esto no es así y hay incompatibilidades por lo que no todo contenedor puede llevar cualquier stream.

¿Que es un muxer?

Supongamos que queremos enviar una caja con un video y un audio dentro. Veamos como hacerlo:

  • Obtienes un stream de video y un stream de audio
  • Codificas cada stream con un codec
  • Multiplexas (muxer) ambos streams en un solo fichero
  • Metes en la caja de embalar la mezcla

Reproducción del video

Ahora recibimos la caja, la abrimos, separamos los streams (demux) en archivos diferentes, audio, video, subtitulos, etc. Este proceso no transforma ni procesa los streams.

Despues, se utiliza el decoder adecuado para descomprimir cada stream y reproducir el conjunto. Esto lo hará un software concreto, como el windows media player, el VLC, Apple QuickTime, etc.

¿Qué es un Renderizador (Renderer)?

Nos falta un paso que hemos omitido en el proceso. Este paso es el de reproducir el stream en un dispositivo hardware. Esto lo hara un renderizador que suelen implementar los players.

Un Renderizador es similar a un Codec pero la salida final no es otro stream sino una pantalla, una tarjeta de video, etc.

Confusiones con MPEG

MPEG es un tanto especial y origina mucha confusión por lo siguiente:

  • MPEG es un codec y hay varias versiones MPEG-1,MPEG-2,MPEG-4,…
  • MPEG también es un formato contenedor. A veces se le denomina como sistema MPEG. Hay diferentes tipos: ES,PS y TS.

Al grano, el Streaming

Una vez aclarados conceptos básicos vamos a hablar del streaming propiamente dicho.

El streaming consiste en reproducir streams en tiempo real y recibiéndolos, generalmente, a través de Internet.
Ahora bien, un stream de video suele ser algo pesado(ocupa mucho) para recibirlo entero y reproducirlo, imagina que para ver un video de YouTube esperas a descargarlo entero, tardarías (dependiendo de tu ancho de banda) minutos antes de comenzar a verlo. O supongamos un caso peor, quieres hacer videoconferencia, no es posible recibir el stream completo puesto que se está generando mientras dos personas hablan y se ven, se supone que se va generando y recibiendo en ambos extremos y en tiempo real.

El truco está en no esperar a recibir todo el stream e ir reproduciendo los trocitos que van llegando poco a poco. Como siempre veremos que hay varias formas de conseguir el mismo objetivo, es aquí donde entran en juego los protocolos.

Confusión típica

Hay que tener bien claro lo siguiente, al hacer streaming no se envia el fichero en disco, por ejemplo un fichero .mov. Se envian los streams de audio y video y en el formato en el que estén estos codificados. Recordemos que un contenedor puede alojar streams en diferentes formatos.

Esto se debe tener en cuenta a la hora de transmitir porque no todos los formatos son soportados por todos los reproductores. Al hacer uso de protocolos como RTP los formatos soportados suelen ser limitados.

Los protocolos para el streaming

Tradicionalmente lo que ha interesado en la transmisión de datos es que las dos partes reciban una copia exacta de los datos,¿alguien querría un texto incompleto?. Ahora bien, hablando de vídeo, no resulta tan importante el que se pierda un fotograma como el que el vídeo tenga que dar saltos parándose cada dos por tres porque no han llegado absolutamente todos los datos. Es por este motivo por el que para transmitir vídeo se priorizará el que sea ágil su reproducción antes que esta sea completa (no perdamos fotogramas).
Por estos motivos se han ideado protocolos de transmisión de datos en los que prima la velocidad y estos son los que usaremos para hacer streaming.

HTTP y FTP, y en general todos los que funcionan sobre TCP son protocolos que priman la exactitud de la información y no la velocidad (garantizan que se entregan los datos y además el orden en que se entregan). Por ello, generalmente, se evita usar estos protocolos para hacer streaming. En su lugar se usarán protocolos basados en UDP, que no garantiza la entrega ni el orden de entrega, pero que es más rápido. Apoyándose en este protocolo (UDP) se ha ideado un estándar en Internet para la retransmisión de audio y vídeo, el protocolo RTP.

El protocolo RTP

RTP nos proporcionara entrega de datos en tiempo real independientemente del protocolo subyacente (TCP o UDP), aunque generalmente usaremos UDP.
RTP pude usarse como unicast(uno sirve a otro) o como multicast(uno sirve a muchos). Si lo utilizamos como unicast, copias separadas de los datos son entregadas a cada destinatario. Si usamos multicast los datos se envían desde el servidor solo una vez y la red es responsable de transmitir esos datos a múltiples destinos. El multicast es la forma más eficiente para muchas aplicaciones, como la videoconferencia.

Servicios RTP

RTP te permite identificar el tipo de datos que se está transmitiendo, determinar el orden en que los paquetes debieran ser presentados y sincronizar los streams de diferentes fuentes.
Los paquetes RTP no tienen garantizado el orden de entrega, es más, no está garantizado que lleguen todos. Es tarea del receptor reconstruir la secuencia enviada por el servidor y detectar las pérdidas de datos.
Dado que RTP no proporciona un mecanismo para asegurar la entrega a tiempo u otras garantías de calidad del servicio, se acompaña de un protocolo de control (RTCP) que nos permite monitorizar la calidad de la distribución de datos. RTPC También nos proporciona mecanismos de control e identificación de las transmisiones RTP.

Arquitectura RTP

Una sesión RTP es una asociación entre un grupo de aplicaciones comunicandose con RTP. Una sesión se identifica por una dirección de red y un par de puertos. Un puerto se usa para transmitir los datos y el otro se usa para el control (RTCP).

Un participante es una máquina que, valga la redundancia, participa en la sesión. Participar en la sesión puede consitir, en la simple recepción pasiva de datos(receptor), en transmitir datos de forma activa(servidor), o ambos.

Cada medio (audio, video) se transmite en una sesión diferente. Por ejemplo, si en una conferencia se va a usar audio y video, se usará una sesión para transmitir audio y otra para transmitir video. Esto permite a los participantes elegir que medios quieren reproducir, por ejemplo, uno de los participantes con poco ancho de banda pudiera querer solo recibir el audio.

El protocolo de control RTCP

Cada participante en la sesión recibirá periodicamente paquetes RTCP. Estos paquetes RTCP pueden contener información sobre la calidad del servicio, información sobre la fuente del contenido que se esta transmitiendo y estadísticas sobre los datos que se están transmitiendo.

Tenemos los siguientes tipos de paquetes RTCP:

  • Reporte del remitente(Sender Report - SR)
  • Reporte del receptor (Receiver Report - RR)
  • Descripción de la fuente (Source DEScription - SDES)
  • Bye
  • Específicos de la aplicación

Los paquetes RTCP son “apilables” de forma que se envía siempre un paquete compuesto que contiene al menos dos de estos paquetes descritos, un report y una descripción de la fuente.

Todos los participantes en la sesión mandan paquetes RTCP. Un participante que ha enviado paquetes de datos mandará un reporte del remitente(SR). El SR contiene el número total de paquetes y bytes enviados así como información que puede utilizarse para sincronizar los streams de diferentes sesiones.

Los participantes en la sesión mandan periodicamente Reportes del receptor (RR) a todas las fuentes de las que están recibiendo datos. Un RR contiene información sobre el número de paquetes perdidos, el número de secuencia más alto recibido y una marca de tiempo que puede utilizarse para estimar el retardo de ida y vuelta entre el emisor y el receptor.

El primer paquete en un paquete compuesto RTCP tiene que ser un paquete de reporte, incluso si no se han enviado o recibido datos, en cuyo caso se envía un RR vacío.

Todos los paquetes compuesto RTCP deben incluir una descripción del origen (Source DEScription) que contiene el nombre canónico (CNAME) que identifica el origen. Se puede añadir información aicional en el SDES como el nombre de la fuente, el email, número de teléfono, localización geográfica, nombre de la aplicación o un mensaje describiendo el estado actual del origen.

Cuando un origen se va a desconectar,manda un paquete BYE. El paquete BYE puede incluir el motivo por el que el participante abandona la sesión.

Los paquetes de aplicación proporcionan un mecanismo para que la aplicación defina y mande información a medida a través de este canal de control.

El protocolo RTSP

El protocolo RTSP (Real Time Streaming Protocol) permite controlar streams multimedia que se distribuyan, por ejemplo, via RTP. El control incluye posicionamiento en el stream, grabación e incluso control del dispositivo.

Un escenario de uso podría ser este:

rtsp_escenarioEl cliente accedería a un servidor seb, obtendría un meta-file con indicaciones de como reproducir el video/audio y luego se establecería una conexión RTSP para el control del streaming y una conexión RTP para la distribución del contenido en si.

Veamos un posible intercambio de mensajes entre cliente y servidor. Se puede apreciar en rojo el tipo de mensajes de RTSP como SETUP,PLAY,PAUSE y CLOSE.

rtsp_dialogoPodemos hacer una analogía entre RTSP y el mando del video, el mando simplemente ordena al video que empieze, que pare, que avance, etc. Pero es el video en sí el que reproduce y el canal de transmisión de imágenes no es el del mando.

Formato de contenedor para móviles 3gp

3GP responde a estándar de vídeo de tercera generación.

Es un contenedor multimedia definido por 3GPP para su uso en teléfonos móviles de tercera generación. Es una versión simplificada de MPEG-4 Parte 14 (MP4). Los ficheros 3GP tienen la extensión .3gp o .3g2.

3GP almacena los streams de vídeo como MPEG-4 o H.263 y los streams de audio como AMR-NB o AAC-LC. 3GP describe los tamaños de la imagen y el ancho de banda de forma que los contenidos sean correctamente adaptados a las pantallas de los móviles.

Resoluciones habituales

Cuando hablamos de resoluciones(ancho x alto) las siglas más habituales con las que nos encontraremos (en el mundo de los móviles) son:

  • VGA (640×480)
  • CIF (352×288)
  • QVGA ( 320×240) (Un cuarto de VGA)
  • QCIF( 176×144) (Un cuarto de CIF)

Libros de Invierno

February 9th, 2010

chess_reinfeld Ya veis, el vicio me puede…. En mis viajes de metro a lo largo de unos dos años he finalizado este librito de 1001 problemas de Ajedrez. He tardado tanto por dos motivos, el primero es que soy un paquete de jugador, y el segundo, porque tan solo dispongo de unos quince minutos en cada trayecto, así que, si el problema es complicado, no me da tiempo a resolverlo por lo que hay días que tan solo hago un problema. ¡Imaginad para terminar los 1001 problemas!.
Tiene pocos fallos y es muy pequeñito, lo que permite llevarlo encima de forma cómoda. Muy recomendable. Lo único que le echo en falta es que los problemas no están ordenados por dificultad sino por temática de forma que te puedes encontrar algunos super sencillos y de repente uno muy complejo.
Bueno, en cualquier caso, es un libro genial.

Principios de diseño V

February 4th, 2010

Hoy veremos como resolver el problema de la herencia que vimos en el anterior post.
Para ello vamos a usar un nuevo concepto, el de delegación, vamos a delegar funcionalidad en otra clase.

yingyang La Delegación consiste en dejar la responsabilidad de una funcionalidad concreta a otra clase.

Veamos como se traduce esto a código, seguiremos con el ejemplo del otro día:
——-
Tablero
——-
Altura: int
Anchura: int
Hexagonos: Hexagono[Anchura][Altura]
————————————–
getHexagono(int,int): Hexagono
setUnit(Unit,int,int)
deleteUnit(Unit,int,int)
getUnit(int,int): Unit

Pero ahora vamos a entrar en el mundo de las 3D sin heredar. Lo que vamos a hacer es que el tablero 3D se cree mediante múltiples tableros 2D a diferentes alturas:

———-
Tablero3D
———-
profundidad: int (coordenada Z)
Capas: Tablero[profundidad]
—————————————————–
getHexagono(int,int,int):Hexagono
setUnit(Unit,int,int,int)
deleteUnit(Unit,int,int,int)
getUnit(int,int,int): Unit

De esta forma cuando se haga una petición cualquiera se usará la coordenada “Z” para acceder al array de Tableros 2D y luego las coordenadas “X” e “Y” para acceder al tablero 2D seleccionado.
De esta forma hemos evitado usar la herencia y violar el principio LSP.

Usaremos la delegación cuando queremos usar la funcionalidad de otra clase sin cambiar un ápice su comportamiento.

En el próximo post veremos que esta asociación que hemos hecho entre dos clases tiene matices, entraremos un poco más en detalles y hablaremos de agregación y composición que son dos sutilezas sobre un mismo concepto.

Principios de diseño IV

February 1st, 2010

Hoy hablaré de el principio de sustitución de Liskov (LSP), podeis encontrar más información en wikipedia, más concretamente en este enlace.

Este sencillo principio reza así:
yingyang Los subtipos deben ser sustituibles por sus tipos base.

¡Y ya esta!, sencillo y claro.
Este principio tiene que ver con la herencia, pero herencia bien diseñada. Esto implica que cuando heredas de una clase base, debes ser capaz de sustituir tu nueva clase por la clase base sin que ocurran cosas terriblemente malas, de lo contrario, has diseñado incorrectamente tu jerarquía.

Veamos un ejemplo de clase mal diseñada:
Supongamos una clase base llamada “Tablero” ideada para crear un juego de estrategia, esta clase pudiera ser algo como lo siguiente:
——-
Tablero
——-
Altura: int
Anchura: int
Hexagonos: Hexagono[Anchura][Altura]
————————————–
getHexagono(int,int): Hexagono
setUnit(Unit,int,int) -> Pone una unidad(tanque,soldado,etc) en un hexagono
deleteUnit(Unit,int,int)
getUnit(int,int): Unit

Pongamos que ahora queremos ampliar la clase para crear un tablero en 3D así que heredamos de la clase tablero:
———-
Tablero3D
———-
profundidad: int (coordenada Z)
Hexagonos3D: Hexagono[Anchura][Altura][profundidad]
—————————————————–
getHexagono(int,int,int):Hexagono
setUnit(Unit,int,int,int)
deleteUnit(Unit,int,int,int)
getUnit(int,int,int): Unit

Como vemos hemos añadido una tercera coordenada a los métodos, todo parece que marcha, ¿verdad?.
Pues no, ¡error!, intentemos sustituir las llamadas a nuestro tablero 3D por las llamadas originales a la clase base. Ninguno de los métodos de la clase Tablero funciona correctamente en un entorno 3D. Llamar por ejemplo a setUnit(soldado,2,5) no tiene sentido para un tablero 3D. Esto viola el principio LSP.

Tablero tablero = new Tablero3D();
Unit unit = tablero.getUnit(4,5); // ¿que significa esto exactamente?

Es difícil entender el código que utiliza mal la herencia, ¿como se comporta la llamada a “getUnit” con solo dos parámetros cuando estamos en un tablero 3D?, ¿coge por defecto algún valor?, ¿coge el valor más alto o el más bajo?. De aquí no podemos obtener nada bueno, probablemente acabemos con ciertos métodos de nuestra superclase los necesitemos o no.

¿Que opciones tenemos entonces?…… pues la delegación. Veremos en el próximo post que es “delegar” y hablaremos también sobre la composición y la agregación.

Principios de diseño III

January 28th, 2010

Hoy veremos un principio estrechamente relacionado con la cohesión, se trata del principio de responsabilidad única (no se si es una traducción muy correcta del ingles Single Responsability Principle o SRP).

De lo que se trata es de que cada objeto que diseñemos tenga una única responsabilidad. De esta forma, cuando algo relacionado con esa responsabilidad cambia sabremos exactamente donde buscar para realizar esos cambios.

Enunciemos el principio:
yingyang
El Principio de Responsabilidad Única implica que cada objeto en nuestro sistema debiera tener una única responsabilidad, y todos los servicios que proporcione el objeto debieran orientarse a llevar a cabo esa responsabilidad.

Sabremos si hemos implementado correctamente este principio cuando cada uno de nuestros objetos tenga un solo motivo para cambiar. Una buena forma de comprobar si todo está en orden consiste en hacer una ficha asociada al objeto y responder a las preguntas de la ficha.
Ejemplo:
Analisis SRP para la clase ______________
La clase ________ puede ______ por si misma
La clase ________ puede ______ por si misma
La clase ________ puede ______ por si misma
La clase ________ puede ______ por si misma

Rellenaremos los huecos con el nombre de la clase y los métodos:
Analisis SRP para la clase Automovil
La clase Automovil puede arrancar por si misma
La clase Automovil puede parar por si misma
La clase Automovil puede cambiarRuedas por si misma
La clase Automovil puede Conducir por si misma

En este caso, las dos primeras son correctas y las dos últimas erroneas. Un coche no puede conducirse por si mismo y no puede cambiarse las ruedas, probablemente necesite ayuda de una clase Mecanico y de otra Conductor. De ahi deducimos que nuestro diseño es algo pobre, habrá que darle unos retoques.

En mi experiencia diaria no suelo usar este tipo de fichas de comprobación, por dos motivos, el primero es que a simple golpe de vista ya sueles darte cuenta (una vez que tienes cierta experiencia) de que algo huele mal en una clase. El segundo es que previamente a la implementación yo suelo usar tarjetas CRC (Class-Responsability-Card) para afrontar mi diseño y estas tarjetas me ayudan a elegir la funcionalidad de cada clase desde un primer momento.

He aquí un pantallazo de las tarjetas que suelo usar en el curro, yo las imprimo y trabajo con papel (no uso un software de tarjetas CRC) porque me permite llevármelas a una reunión, agruparlas, tacharlas, subrayarlas, hacer una bola y tirarlas y todo de forma muy rápida.
crc_card