Un tema que había quedado pendiente en la charla pasada sobre mplayer fue el de mencoder. Esto es el programa usado para generar videos.
#include <disclaimer.h> Nota importante: En este texto se describe como recomprimir un stream de video. Se da por supuesto que poseemos los derechos para realizar esta operación. Esto no es normalmente posible cuando la fuente es un DVD de una película. Estos conceptos pueden aplicarse a DVDs con videos nuestros u otras fuentes de video de las cuales poseemos los derechos y que necesitamos comprimir. |
Existen dos codecs disponibles: libavcodec (FFMPEG) y libencore (Project Mayo, DivX 5). Existen opciones para otros codecs pero no estos son los usables. Para el audio el codec más usado es el de lame.
Los avances en estos nuevos codecs, tanto en los codecs mismos, como en extensiones al formato que permiten mejor compresión, permiten lograr resultados muy superiores a los que se obtenían tan sólo unos meses atrás. Ambos codecs son de muy alta calidad y se pueden obtener excelentes resultados. Las diferencias más importantes entre estos codecs son:
Por estas razones se recomienda usar libavcodec. Otro detalle de importancia es que sólo libavcodec es verdaderamente free software. Los codecs del Project Mayo se distribuyen como binarios y los fuentes se liberan con una demora de meses cuando ya existe una versión que los reemplaza. Es bastante interesante este detalle, más teniendo en cuenta que libavcodec es de mejor calidad.
Uno de los temas sobre el cual es difícil obtener conclusiones definitivas es sobre que resolución utilizar para el archivo resultante. En mi opinión lo mejor es utilizar resoluciones más o menos altas. La razón es que el codec puede así dar mayor calidad, si no fuera posible el codec mismo se encargará de reducir la resolución al utilizar bloques más grandes. Un ejemplo son los textos (un ejemplo podrían ser los créditos de la grabación), en este caso si se utiliza una baja resolución los mismos serán ilegibles. La resolución recomendada es de 640 puntos de ancho (640x360 por ejemplo). La desventaja de esto es que el procesamiento necesario para descomprimir y post procesar las imágenes es mucho más alto. Hay que tener en cuenta que el procesamiento es proporcional a la cantidad de píxeles a procesar y estos aumentan cuadraticamente. Esto puede ser un problema si las máquinas a usar para reproducir el video son lentas o no corren GNU/Linux. El único codec que conozco para Windows que es capaz de reproducir videos creados con libavcodec es el de Project Mayo (DivX.com) versión 5.0.2. El problema es que estos codec son mucho más lentos que los de FFMPEG y para descomprimir imágenes de 640 puntos de ancho necesita un procesador muy rápido, aún cuando se usen niveles de post procesamiento bajos.
El mecanismo de compresión recomendado es el de tres pasadas. De esta manera se puede controlar muy bien el tamaño del archivo resultante y obtener una calidad excelente. La compresión en tres pasadas consiste en:
Este mecanismo es un poco lento pero los resultados obtenidos justifican su uso. Un detalle muy interesante es que los nuevos codecs cuando son usados de esta manera ya no generan la clásica estela de cuadraditos que solía acompañar a los movimientos rápidos de los DivX. Tampoco se observan salteos de cuadros. Por el contrario lo que hace el codec es analizar la complejidad del video en la pasada dos (primera de video) para luego decidir como distribuir el bit rate que siempre es variable. De esta manera en la tercer pasada (segunda de video) el codec "sabe" donde utilizar más o menos compresión. El ajuste de bitrate tiene límites y por esta razón en casos extremos es inevitable perder calidad, esto sólo pasa en casos extremos donde de todas maneras no se observa el problema salvo que se use la pausa.
Una recomendación importante para cuando se compriman fílmicos (no grabaciones con videocámaras) es la de tener en cuenta la cantidad de cuadros por segundo. Si el video se tomó con cámaras del tipo de las usadas en cine el frame rate es de 24 cuadros por segundo. Si este video se comprimió en un DVD el valor debió ser cambiado a 30 cuadros por segundo (asumiendo que se usó NTSC). Los cuadros extra no contienen información y por lo tanto no tiene sentido incluirlos. En este caso lo más recomendable es usar la opción para reducir el frame rate a 24.
Otro detalle a tener en cuenta es que no es posible saltar a cualquier punto de un video comprimido con MPEG (DivX por ejemplo). Esto se debe a que parte de la información se codifica usando como referencia los cuadros anteriores. Por esta razón sería imposible avanzar salteando unos segundos o a un punto cualquiera. Para evitar esto cada un número prefijado de cuadros se fuerza un nuevo cuadro de referencia. Este cuadro se llama keyframe y los codecs poseen una opción para indicar cada cuantos cuadros se colocará uno de ellos. Valores muy altos favorecen la compresión pero hacen que cuando avancemos lo tengamos que hacer en pasos más largos. El valor recomendado por los codecs es bastante razonable y es de 250 (saltos cada 10 segundos aprox.).
La compresión del audio normalmente se realiza en formato MPEG layer 3 (MP3), no tenemos información sobre el uso de OGG que probablemente arroje mejores resultados. Lamentablemente el formato MP3 es mucho menos eficiente que el MPEG v4/DivX usado para el video. Lo más común es que para mantener un audio de buena calidad se necesite aproximadamente 1 Mb por minuto de grabación. El codec de lame posee dos parámetros muy importantes:
El primer valor es recomendable que sea lo más bajo posible (0 o 1). Esto impacta en el tiempo necesario para la compresión y un poco en el tamaño. Con valores bajos el tiempo necesario es mucho mayor pero se obtiene buena calidad consumiendo algo menos de espacio. El segundo parámetro impacta directamente en el espacio necesario. Se recomiendan valores de 3 o 4. En cualquier caso se utiliza bit rate variable y no es raro que esta pasada sea casi tan lenta como una de las otras.
A continuación se muestra un ejemplo para ver las opciones de línea de comando que controlan cada cosa:
mencoder ORIGINAL -ofps 24 -ovc frameno -oac mp3lame -lameopts aq=1:q=4 -aid 128 -o frameno.avi -slang es -vobsubout subtitles -vobsuboutindex 0 -vobsuboutid es mencoder ORIGINAL -ofps 24 -vop scale=640:360 -sws 2 -ovc lavc -lavcopts vcodec=mpeg4:vpass=1:vhq:keyint=250:vbitrate=VALOR -oac copy -o SALIDA.AVI mencoder ORIGINAL -ofps 24 -vop scale=640:360 -sws 2 -ovc lavc -lavcopts vcodec=mpeg4:vpass=2:vhq:keyint=250:vbitrate=VALOR -oac copy -o SALIDA.AVI
El ORIGINAL es la fuente original de video (dvd://1 si fuera un DVD). La opción -ofps indica el frame rate de salida. Con -ovc frameno le indicamos que esa pasada no es para generar video. Con -oac mp3lame seleccionamos el codec de lame. La calidad algorítmica y del sonido se selecciona con -lameopts aq=1:q=4. En el caso de un DVD es posible que el stream contenga más de un canal de audio, en las pruebas se usó un snapshot de cvs del mencoder que automáticamente selecciona el último canal de audio disponible, esto normalmente no es lo que queremos y es necesario forzar el canal con -aid 128 que selecciona el primero. En la primer pasada el archivo de salida tiene que tener un nombre predeterminado que es frameno.avi para esto se usa -o frameno.avi. El resto de las opciones del ejemplo extraen los subtítulos en español del stream como imágenes. Las siguientes pasadas son idénticas la única diferencia es el parámetro vpass que cambia de 1 a 2. El bitrate usado se computa una vez realizada la primer pasada restando al espacio disponible el espacio usado por el audio (y/o subtítulos) y dividiéndolo por el largo del video:
Bit_Rate [kb/s] = Bytes_Disponibles * 8.0 / Largo_en_segundos /1000.0
En el ejemplo se cambia la escala del video a 640x360, este sería el caso de un DVD NTSC. La opción -vop indica que clase de post procesamiento queremos aplicar en este caso usamos scale=640:360 que es un cambio de escala. Si el video fue grabado con cámaras profesionales como las usadas en cine es probable que contenga barras negras que podríamos quitar con otro paso de post procesamiento. Para realizar el cambio de escala hay que usar algún algoritmo que reduzca el número de píxeles, la opción -sws 2 selecciona un algorítmo de alta calidad aunque un tanto lento. Las siguientes opciones: -ovc lavc -lavcopts vcodec=mpeg4:vpass=1:vhq:keyint=250:vbitrate=VALOR seleccionan el codec de FFMPEG para generar un DivX (MPEG4), usando alta calidad (VHQ), un intervalo entre keyframes de 250 y un bitrate promedio determinado. Como el audio ya fue generado en otra pasada basta con copiar esta información usando -oac copy.
La principal desventaja del proceso en tres etapas es que necesitamos comprimir el audio y luego con la información obtenida se realizan las otras dos. Esto es un poco incómodo ya que no es posible hacer el proceso sin intervención humana. Para resolver este problema hice un mini programa que realiza las tres etapas. El programa puede distribuirse bajo los términos de la licencia GPL. Está en inglés, constumbre de programar free soft para que lo use cualquiera. Como me gusta mostrar chiches de mi editor de texto acá está el fuente exportado como HTML (los colores son exactamente los mismos que se ven en pantalla).
Share and enjoy, and .... happy hacking! (como diría Tato Bores luego de escuchar a RMS ;-)