Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

p9

  • Loading branch information...
commit 95ba1d89fa79f99536224968f58e94770c0bd575 1 parent 7f9b1ce
@gootyfer authored
View
BIN  student/p9/img/control_de_volumen.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  student/p9/img/control_de_volumen_menu.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  student/p9/img/pipeline-audiotest.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  student/p9/img/pipeline-estructura.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  student/p9/img/pipeline0.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
551 student/p9/index.html
@@ -0,0 +1,551 @@
+<html>
+ <head>
+ <title>Aplicaciones Multimedia: Práctica GStreamer (II)</title>
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
+ <link rel="SHORTCUT ICON" href="http://www.uc3m.es/favicon.ico" />
+ <link href="http://www.it.uc3m.es/rcrespo/docencia/asignatura.css" rel="stylesheet" type="text/css" />
+ <link href="http://www.it.uc3m.es/estilo.css" rel="stylesheet" type="text/css" />
+ <link href="http://www.it.uc3m.es/rcrespo/docencia/amm/1112/p3/css/amm.css" rel="stylesheet" type="text/css" />
+ <link href="../css/classon.css" rel="stylesheet" type="text/css" />
+ <link href="../css/jquery-ui.css" rel="stylesheet" type="text/css" />
+
+ <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
+ <script type="text/javascript" src="../js/jquery.blockUI.js"></script>
+ <style type="text/css">
+ .code {
+ color: blue;
+ font-size: 80%;
+ }
+ </style>
+ </head>
+ <body>
+
+ <!-- BEGIN ADD, 21/05/09; to comply with UC3M corporate image requirements -->
+ <div class="headerBorderUc3mblue"></div>
+ <div class="header white">
+ <a href="http://www.uc3m.es/">
+ <img class="logos logoleft" src="http://www.it.uc3m.es/imag/EscudoLogoCorporativo.png" alt="Universidad Carlos III de Madrid" />
+ </a>
+ <a href="http://www.it.uc3m.es">
+ <img class="logos logoright" src="http://www.it.uc3m.es/imag/SpanishLogoIT.png" alt="Departamento de Ingeniería Telemática" />
+ </a>
+ </div>
+ <div class="headerBorderUc3mblue"></div>
+ <!-- END ADD 21/05/09 -->
+
+
+ <!-- Tabla encabezado departamento -->
+ <table width="100%" border="0" cellspacing="0" cellpadding="0" bgcolor="#000000">
+ <tr>
+ <td>
+ <table width="100%" border="0" cellspacing="1" cellpadding="0">
+ <tr>
+ <td bgcolor="#CCD0D6" width="2000" height="22">
+ <div align="right"><a href="http://www.it.uc3m.es/localizacion/localizacion.htm" class="azul">Localizaci&oacute;n</a>
+ | <a href="#"></a><a href="http://www.it.uc3m.es/personal/directorio.htm"><span class="rojo">Personal</span></a>
+ | <a href="http://www.it.uc3m.es/docencia/docencia.htm" class="azul">Docencia</a>
+ | <a href="http://www.it.uc3m.es/investigacion/investigacion.htm" class="azul">Investigaci&oacute;n</a>
+ | <a href="http://www.it.uc3m.es/novedades/novedades.htm" class="azul">Novedades</a>
+ | <a href="http://www.it.uc3m.es/intranet/intranet.htm" class="azul">Intranet</a>
+ &nbsp;&nbsp;</div>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+ <!-- Tabla encabezado departamento (fin) -->
+
+ <!-- Navegación -->
+ <nav>
+ <p class="nav"><a class="azul"
+ href="http://www.it.uc3m.es/index.html">Home</a> / <a class="azul"
+ href="http://www.it.uc3m.es/docencia/docencia.htm">Docencia</a> / <a
+ class="azul" href="http://www.it.uc3m.es/docencia/grado-audiovisuales.html">Grado en Ingeniería de Sistemas Audiovisuales</a> /
+ <a class="azul" href="http://www.it.uc3m.es/rcrespo/docencia/amm/1011/">Aplicaciones Multimedia</a>
+ </p>
+ </nav>
+ <!-- Navegación (fin) -->
+
+ <header>
+ <h1>Pr&aacute;ctica 9: Arquitectura GStreamer (II)</h1>
+ </header>
+ <section id="intro">
+ <h2>Introducci&oacute;n</h2>
+ <h3>Fundamentos tecnológicos</h3>
+
+ <p>
+ GStreamer es un entorno para creación de aplicaciones de
+ streaming multimedia.
+
+ El diseño de GStreamer está basado en tuberías
+ (<em>pipelines</em>), que definen el flujo de datos,
+ y <em>plugins</em>, elementos que proporcionan las distintas
+ funcionalidades y pueden interconectarse dentro de
+ un <em>pipeline</em>.
+
+ GStreamer permite procesar audio, vídeo y cualquier tipo de
+ flujo de datos.
+
+ Los formatos soportados incluyen: MP3, Ogg/Vorbis, MPEG-1/2,
+ AVI, Quicktime, mod, etc.
+ </p>
+
+ <p>
+ GStreamer proporciona más de 150 plugins, que pueden
+ clasificarse de acuerdo a la funcionalidad que implementan:
+ </p>
+ <ul>
+ <li>Gestión de protocolos</li>
+ <li>Fuentes</li>
+ <li>Formato: parsers, formateadores, muxers, demuxers, metadatos, subtítulos</li>
+ <li>Codecs: codificadores y decodificadores</li>
+ <li>Filtros: conversores, mixers, efectos, ...</li>
+ <li>Sumideros</li>
+ </ul>
+
+ <figure>
+ <img src="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/images/gstreamer-overview.png" />
+ <figcaption><p><em>Figura 1</em>: Arquitectura GStreamer</p></figcaption>
+ </figure>
+
+ <p>
+ </p>
+
+<!--
+* Tipos de datos: procesa audio, vídeo y cualquier tipo de flujos de datos.
+* Formatos soportados: MP3, Ogg/Vorbis, MPEG-1/2, AVI, Quicktime, mod, etc.
+* Aplicaciones:
+ - Reproducción multimedia
+ - Edición multimedia
+* Proporciona:
+ - API
+ - Arquitectura de plugins
+ - Arquitectura pipeline
+ - Mecanismo para procesamiento y negociación de tipos de medios
+ - Más de 150 plug-ins
+ - Conjunto de herramientas
+-->
+
+ <h3>Herramientas de línea de comandos</h3>
+ <p>
+ GStreamer proporciona una serie de herramientas de línea de comandos para acceder a información o construir y ejecutar pipelines:
+ </p>
+ <ul>
+ <li>
+ gst-launch - construye y ejecuta una tubería GStreamer
+ <br /> Ejemplo:
+ <pre class="code">
+rcrespo@armonia:~/doc/amm12/lab/gst2$ <b>gst-launch audiotestsrc ! autoaudiosink</b>
+Estableciendo el conducto a PAUSA ...
+El conducto está PREPARÁNDOSE ...
+El conducto está PREPARADO ...
+Estableciendo el conducto a REPRODUCIENDO ...
+New clock: GstPulseSinkClock
+</pre>
+ [Resultado: se oye un tono de audio]
+ </li>
+ <li>
+ gst-inspect - muestra información sobre un <em>plugin</em> o elemento GStreamer
+ <br /> Ejemplos:
+ <pre class="code">rcrespo@armonia:~/doc/amm12/lab/gst2$ <b>gst-inspect</b></pre>
+ [Resultado: muestra el listado de elementos GStreamer disponibles en el sistema] <br />
+ <pre class="code">rcrespo@armonia:~/doc/amm12/lab/gst2$ <b>gst-inspect audiotestsrc</b></pre>
+ [Resultado: muestra la información sobre el elemento audiotestsrc] <br />
+ Sugerencia: utiliza un paginador (<span class="code">less</span>, <span class="code">more</span>) para mostrar la salida pantalla a pantalla:
+ <pre class="code">rcrespo@armonia:~/doc/amm12/lab/gst2$ <b>gst-inspect audiotestsrc | less</b></pre>
+
+
+ </li>
+ <!-- <li>gst-inspect-gui - explorador de elementos GStreamer (GUI)</li> -->
+ <li>
+ gst-typefind - muestra el tipo MIME del fichero
+ </li>
+ </ul>
+
+ <h3>Estructura de un pipeline</h3>
+ <p>
+ La figura 2 representa la estructura básica de un pipeline, en
+ la que el flujo de datos parte de una fuente, experimenta una
+ serie de transformaciones y finaliza en un sumidero.
+ </p>
+ <figure>
+ <img src="img/pipeline-estructura.png" />
+ <figcaption><p><em>Figura 2</em>: Estructura básica de un pipeline.</p></figcaption>
+ </figure>
+ <p>
+ El comando <span class="code">gst-launch</span> permite crear y ejecutar un pipeline. Por ejemplo, el siguiente comando crea y ejecuta el pipeline representado en la figura 3:
+ </p>
+ <figure>
+ <img src="img/pipeline-audiotest.png" />
+ <figcaption><p><em>Figura 3</em>: Pipeline básico.</p></figcaption>
+ </figure>
+ <pre class="code">
+rcrespo@armonia:~/doc/amm12/lab/gst2$ <b>gst-launch audiotestsrc ! autoaudiosink</b>
+Estableciendo el conducto a PAUSA ...
+El conducto está PREPARÁNDOSE ...
+El conducto está PREPARADO ...
+Estableciendo el conducto a REPRODUCIENDO ...
+New clock: GstPulseSinkClock
+</pre>
+
+ <h3>Objetivo</h3>
+ <p>
+ En esta práctica utilizaremos GStreamer y las herramientas de
+ línea de comandos que proporciona para desarrollar algunas
+ aplicaciones multimedia básicas.
+ Definiremos diversos <em>pipelines</em> interconectando
+ algunos <em>plugins</em> proporcionados por el entorno, para
+ implementar algunas funcionalidades básicas:
+ </p>
+ <ul>
+ <li>Reproducción multimedia</li>
+ <li>Conversión de formatos</li>
+ <li>Generación de nuevos medios</li>
+ <!-- <li>Captura de audio</li> -->
+ </ul>
+ <p>
+ En concreto, extraeremos una secuencia de fotogramas de un vídeo y la
+ utilizaremos para generar un nuevo montaje combinándola con el audio
+ capturado del micrófono.
+ </p>
+ </section>
+
+ <section id="step1">
+ <h2>Paso 1: Extraer fotogramas de un vídeo</h2>
+ <p>
+ En este paso vamos a crear un pipeline que extraiga fotogramas de un
+ vídeo (formato Ogg) y los almacene en un conjunto de ficheros (formato
+ PNG). Puedes utilizar
+ el <a href="http://download.blender.org/peach/trailer/trailer_400p.ogg">trailer
+ de Big Buck Bunny</a> para las pruebas.
+ </p>
+ <ol>
+ <li>
+ En primer lugar, construye un pipeline básico para reproducir vídeo Ogg
+ (<a href="https://aulaglobal2.uc3m.es/mod/resource/view.php?id=683924">primera
+ práctica de GStreamer -paso 4-</a>).
+ </li>
+ <li>
+ En lugar de visualizar el vídeo en pantalla, queremos almacenar los
+ fotogramas en ficheros. Por tanto, habrá que cambiar el sumidero: busca
+ con gst-inspect un elemento sumidero que escriba la salida en un
+ conjunto de ficheros.
+ <p>
+ Nota: observa que el nombre por defecto para los archivos en que se
+ almacenan las imágenes sigue el patrón "%05d" (00001, 00002,
+ ...). Para especificar otro nombre, tendrás que utilizar la propiedad
+ location y definir el patrón adecuado. Por ejemplo, "frame-%05d.png"
+ (que generará los ficheros frame-00001.png, frame-00002.png, ...).
+ </p>
+ </li>
+ <li>
+ El flujo de datos en el pipeline es una señal de vídeo. Sin embargo, en
+ los ficheros queremos almacenar imágenes PNG. Tendremos por tanto que
+ intercalar el codificador adecuado antes del sumidero: busca con
+ gst-inspect el elemento adecuado para actuar como codificador PNG.
+ <p>
+ Nota: observa que el codificador PNG incluye una propiedad snapshot,
+ que envía una señal de fin de flujo (EOS = End Of Stream) tras
+ codificar un fotograma. Como en nuestro caso queremos almacenar varios
+ fotogramas, no debería enviarse dicha señal, por lo que esa propiedad
+ debe estar a <em>false</em>.
+ </p>
+ <p>
+ Nota: observa también que el decodificador Theora genera una señal
+ video/x-raw-yuv (espacio de colores YUV) mientras que el codificador
+ PNG trabaja con el espacio de colores RGB (como el sumidero
+ ximagesink), por lo que sigue siendo necesario un elemento que
+ convierta de un espacio de colores a otro.
+ </p>
+ </li>
+ </ol>
+
+ </section>
+
+
+ <section id="step2">
+ <h2>Paso 2: Superponer información sobre los fotogramas</h2>
+ <p>
+ En cada fotograma, vamos a superponer el tiempo de grabación
+ transcurrido así como la hora (reloj). Para ello, tendremos que
+ intercalar en el pipeline los elementos de procesamiento adecuados
+ (<a href="https://aulaglobal2.uc3m.es/mod/resource/view.php?id=683924">primera
+ práctica de GStreamer -paso 5-</a>).
+ </p>
+ </section>
+
+
+ <section id="step3">
+ <h2>Paso 3: Reproducción de vídeo a partir de una secuencia de imágenes</h2>
+
+ <p>
+ En este paso vamos a visualizar un montaje con las imágenes extraídas en
+ los pasos anteriores. Para ello tendremos que construir un reproductor,
+ similar a los vistos hasta ahora, sólo que usando como fuente de datos
+ un elemento que lea la información de un conjunto de ficheros (en vez de
+ un stream de vídeo directamente).
+ </p>
+ <p>
+ Busca el elemento adecuado y consulta su documentación con gst-inspect.
+ </p>
+ <p>
+ Observa que para indicar la ruta de los archivos con las imágenes
+ tendrás que utilizar un patrón de nombres similar al que utilizaste para
+ el sumidero (paso 1).
+ </p>
+ <p>
+ También tendrás que especificar el formato de la señal, utilizando la
+ propiedad <i>caps</i>:
+ </p>
+ <pre class="code">caps="image/png,framerate=\(fraction\)2/1"</pre>
+
+ </section>
+
+
+ <section id="step4">
+ <h2>Paso 4: Generación de medios a partir de una secuencia de imágenes</h2>
+ <p>
+ En este paso, en lugar de visualizar la secuencia de imágenes como un vídeo, vamos a almacenarla como un fichero en formato Ogg.
+ Para ello habrá que:
+ </p>
+ <ol>
+ <li>Insertar un elemento que codifique la señal de vídeo en formato
+ Theora (habitualmente utilizado para la imagen en el formato Ogg)</li>
+ <li>Insertar un multiplexor Ogg, puesto que dicho formato admite varios
+ canales, para que genere la información necesaria de acuerdo a las
+ especificaciones del formato.</li>
+ <li>Utilizar como sumidero un elemento que grabe la salida a
+ archivo.</li>
+ </ol>
+
+ </section>
+
+
+ <section id="step5">
+ <h2>Paso 5: Captura de audio</h2>
+
+ <p>
+ En este paso, vamos a generar un nuevo audio para el vídeo resultante de
+ la extracción de fotogramas. Para ello, seguiremos las instrucciones
+ del <em>paso 7 de
+ la <a href="https://aulaglobal2.uc3m.es/mod/resource/view.php?id=683924">primera
+ práctica de GStreamer</a></em>, que se reproducen a continuación.
+ </p>
+ <p>
+ Hasta ahora nos hemos limitado a reproducir la señal
+ multimedia procesada por el pipeline. Sin embargo, GStreamer
+ proporciona diversas fuentes para implementar distintas
+ acciones con la salida del pipeline: comprobar redundancia,
+ envío de fichero, envío de la señal mediante distintos
+ protocolos, almacenamiento en fichero (uno o varios), etc.
+ </p>
+ <p>
+ En este paso, vamos a guardar la señal de audio generada en un
+ fichero, en vez de reproducirla con la tarjeta de sonido.
+ Utiliza gst-inspect para identificar el elemento sumidero
+ adecuado, que almacene un flujo multimedia (la salida del
+ pipeline) en un archivo. Utiliza gst-inspect también para
+ revisar las propiedades de dicho elemento y, en concreto, cómo
+ especificar el nombre del fichero de salida.
+ </p>
+ <p>
+ Además, vamos a capturar la entrada de audio del micrófono, en
+ vez de procesar un archivo multimedia preexistente. Para
+ ello, utilizaremos la
+ fuente <span class="code">alsasrc</span>, que permite
+ utilizar como origen del flujo multimedia un dispositivo de
+ sonido del sistema (en este caso el micrófono).
+ </p>
+ <p>
+ <span class="code">alsasrc</span> requiere que se especifique
+ el dispositivo que se utilizará como origen. Puedes utilizar
+ el comando <span class="code">arecord -l</span> para listar
+ los dispositivos de captura disponibles en el
+ sistema. Deberías obtener una salida similar a:
+ </p>
+ <pre>
+bash$ arecord -l
+**** List of CAPTURE Hardware Devices ****
+card 0: Intel [HDA Intel], device 0: STAC92xx Analog [STAC92xx Analog]
+ Subdevices: 1/1
+ Subdevice #0: subdevice #0
+ </pre>
+ <p>
+ En nuestro caso, el micrófono está identificado como el
+ dispositivo <span class="code">hw:0</span>.
+ </p>
+ <p>
+ La señal del micrófono requiere algunas transformaciones antes
+ de poder almacenarla en un archivo multimedia válido. En
+ concreto, tendremos que convertirla al formato adecuado. En
+ este caso, queremos grabar el audio en formato Ogg Vorbis.
+ </p>
+ <!-- Este apartado se deja más abierto puesto que el alumno ya
+ ha trabajado paso a paso con varios pipelines -->
+ <p>
+ <b>Importante:</b> Utiliza el conector posterior para el
+ micrófono (el delantero no funciona). Asegúrate también de que
+ los controles no están silenciados, comprúebalo con el control
+ de volumen (ver figura 4).
+ </p>
+ <figure>
+ <img src="img/control_de_volumen_menu.png" />
+ <img src="img/control_de_volumen.png" />
+ <figcaption><p><em>Figura 4</em>: Control de volumen.</p></figcaption>
+ </figure>
+
+ </section>
+
+ <section id="step6">
+ <h2>Paso 6: Procesamiento de señales multicanal: combinación de múltiples señales en un único flujo multimedia</h2>
+
+ <p>
+ En este paso, vamos a combinar las señales de audio y vídeo generadas
+ previamente a partir del micrófono y la secuencia de imágenes,
+ respectivamente. Para ello, seguiremos las instrucciones del <em>paso 8
+ de
+ la <a href="https://aulaglobal2.uc3m.es/mod/resource/view.php?id=683924">primera
+ práctica de GStreamer</a></em>, que se reproducen a continuación.
+ </p>
+
+ <p>
+ Al igual que puede descomponerse un flujo multimedia en
+ múltiples canales, podemos también combinar múltiples señales
+ en un único flujo (por ejemplo, para integrar audio y
+ video). En este caso, el elemento necesario será un
+ multiplexor.
+ </p>
+
+ <p>
+ A continuación se muestra la estructura genérica de un
+ pipeline que integra dos canales de entrada (audio y video) en
+ un único flujo multimedia.
+ </p>
+ <pre class="code">
+ gst-launch fuente_video ! transformaciones_video ! codificador_video ! queue ! multiplexor name="muxer" \
+ fuente_audio ! transformaciones_audio ! codificador_audio ! queue ! muxer. \
+ muxer. ! procesamiento_flujo_multiplexado
+ </pre>
+
+ <p>
+ Observa que el nombre asignado al multiplexor es arbitrario,
+ aunque obviamente se recomienda que sea descriptivo y
+ significativo.
+
+ Observa también que hemos separado en varias líneas el comando
+ utilizando la barra de escape '\', pero es sólo por facilitar
+ la legibilidad (no es necesario).
+
+ Además, observa que para referirnos al multiplexor se utiliza
+ el nombre asignado a dicho elemento seguido de un punto ('.'),
+ con lo que puede reutilizarse en varios puntos del pipeline.
+ Verás que el multiplexor aparece tres veces en el pipeline:
+ </p>
+ <ul>
+ <li>la primera vez recibe como entrada la señal de vídeo</li>
+ <li>la segunda vez recibe como entrada la señal de audio</li>
+ <li>
+ la tercera vez para indicar que se utiliza su salida como
+ entrada para las siguientes etapas (presta atención que es
+ necesario repetirlo explícitamente)
+ </li>
+ </ul>
+
+ <p>
+ Fíjate que también aquí se utiliza un elemento <em>queue<em> en cada
+ entrada del multiplexor. Finalmente, observa que la
+ etapa <em>procesamiento_flujo_multiplexado</em> puede
+ sustituirse por la secuencia de elementos apropiada. Para
+ almacenar la señal generada en un fichero, simplemente se
+ utilizaría el sumidero adecuado. Si en cambio queremos
+ reproducir la señal generada, tendríamos que encadenar un
+ pipeline similar al construido en pasos anteriores (incluyendo
+ la etapa de demultiplexación).
+ </p>
+
+ <p>
+ Basándote en el esquema proporcionado, construye un pipeline que genere
+ un archivo Ogg combinando las señales de audio y vídeo generada en los
+ pasos anteriores.
+ </p>
+
+ </section>
+
+ <section id="bash">
+ <h2>Comandos bash útiles</h2>
+ <ul>
+ <li>
+ <span class="code">man</span>:
+ muestra la ayuda de un comando. Por ejemplo:
+ <pre class="code">man ls</pre>
+ Muestra la ayuda sobre el comando ls.
+ Para salir de la ayuda: pulsa la letra 'q'.
+ <br /><br />
+ </li>
+ <li>
+ <span class="code">ls</span>: lista los contenidos de un directorio
+ <br /><br />
+ </li>
+ <li>
+ <span class="code">cd</span>: (change directory) cambia de directorio
+ <ul>
+ <li><span class="code">.</span>: representa el directorio actual</li>
+ <li><span class="code">..</span>: representa el directorio padre</li>
+ </ul>
+ <br />
+ </li>
+ <li>
+ <span class="code">grep</span>:
+ filtra las líneas que incluyan un determinado texto. Por ejemplo:
+ <pre class="code">grep palabra nombre_fichero</pre>
+ filtra el fichero <em>nombre_fichero</em>, presentando sólo las líneas que incluyen el texto <em>palabra</em>.
+ <p>
+ Combinado con los <em>pipelines</em> de linux (¡no
+ confundir con los <em>pipelines</em> de GStreamer, aunque
+ la idea es similar!), permite filtrar la salida estandar generada por un comando.
+ Ejemplo:
+ </p>
+ <pre class="code">gst-inspect | grep sink</pre>
+ filtra el resultado del comando gst-inspect, presentando sólo las líneas que incluyen el texto <em>sink</em>.
+ <br />
+ </li>
+ </ul>
+ </section>
+
+ <section id="refs">
+ <a name="refs" />
+ <h2>Referencias</h2>
+ <ul>
+ <li><a href="http://gstreamer.freedesktop.org/documentation/">Documentación de GStreamer</a>
+ <ul>
+ <li><a href="http://gstreamer.freedesktop.org/documentation/plugins.html">Overview of all Plug-ins</a></li>
+ <li><a href="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/manual/html/index.html">GStreamer Application Development Manual (0.10.36)</a></li>
+ </ul>
+ <li><a href="https://aulaglobal2.uc3m.es/file.php/29384/Tema_8/Tema8._GStreamer_I_.pdf">Apuntes de la asignatura</a></li>
+ <li>Manual de bash</li>
+ <li>Documentación sobre Ogg
+ <ul>
+ <li><a href="http://es.wikipedia.org/wiki/Ogg">Información básica sobre el formato Ogg</a></li>
+ <li><a href="http://www.xiph.org/ogg/doc/">Documentación oficial de Ogg</a></li>
+ </ul>
+ </ul>
+ </section>
+
+ <footer>
+ <figure>
+ <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/es/">
+ <img alt="Licencia Creative Commons" style="border-width:0" src="http://i.creativecommons.org/l/by-sa/3.0/es/88x31.png" /></a>
+ <figcaption>Este <span xmlns:dct="http://purl.org/dc/terms/" href="http://purl.org/dc/dcmitype/Text" rel="dct:type">obra</span>
+ está bajo una <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/es/">licencia Creative Commons
+ Reconocimiento-CompartirIgual 3.0 España</a>.</figcaption>
+ </figure>
+ <details>
+ <summary>Recurso desarollado por Raquel M. Crespo (<a href="www.it.uc3m.es/rcrespo/">www.it.uc3m.es/rcrespo/</a>), data de <time datetime="2012-02-06">2012-02-06</time>.</summary>
+ </details>
+ <br /><br /><br />
+ </footer>
+ <script type="text/javascript" src="../js/socket.io.min.js"></script>
+ <script type="text/javascript" src="../js/classon.js?session=p3"></script>
+ </body>
+</html>
Please sign in to comment.
Something went wrong with that request. Please try again.