Logo Studenta

UC3M _ Máster en Ingeniería de Telecomunicaciones _ Servicios Multimedia Avanzados_ Parte I _ Parte1_zip

Esta es una vista previa del archivo. Inicie sesión para ver el archivo original

Parte1/.DS_Store
__MACOSX/Parte1/._.DS_Store
Parte1/01-comunicaciones_multimedia.pdf
Transportando 
multimedia 
Comunicaciones multimedia 
Tipos de comunicación multimedia 
 Según forma de distribución 
 Broadcast 
 Switched digital video ~ multicast 
 On-demand ~ unicast 
 Según forma de comunicación: Interactiva / 
no-interactiva 
 No-interactivo: predomina one-way vídeo 
 No interactiva, según quién provee 
 IPTV: el proveedor que conecta ‘la última milla’ 
 Ej: Movistar Plus (antes Movistar TV, antes Imagenio)… 
 OTT (Over The Top): provee otro distinto del 
proveedor last-mile 
 Ej: YouTube, RTVE, Netflix … 
 
Comunicaciones multimedia 
¿Qué tecnología? 
Principalmente one-
way vídeo, OTT 
Comunicaciones multimedia 
Tecnología para one-way video, 
versión #1 
/* nos centramos en el transporte */ 
file = open (fileName , O_RDONLY); 
socketTCP = sock (…); 
/* establece sesion TCP */ 
 
while (datosEnviado < tamanoFich) 
{ 
 read (file, memor, TAM_BLOQ); 
 write (socketTCP, memor, TAM_BLOQ); 
 /* actualiza datosEnviados */ 
} 
/* nos centramos en el transporte */ 
socketTCP = sock (…); 
/* establece sesion TCP */ 
 
 
while (datosRecibidos< tamanoFich) 
{ 
 read (socketTCP, memor, TAM_BLOQ); 
 /* actualiza datosRecibidos */ 
} 
 
/* configura dispositivo de video */ 
videoDevice = open (/dev/… ); 
 
while (datosReprod < tamanoFich) 
{ 
 write (videoDevice, memor, TAM_BLOQ); 
 /* actualiza datosReprod */ 
} 
 
Servidor de video Cliente de video 
#1 = transferencia contenido completo, luego reproducción 
Comunicaciones multimedia 
Tecnología para one-way 
video, versión #1 
Propiedades de TCP respecto a 
- Servicio de entrega de datos 
- Flujo 
- Congestión 
- Retardos 
/* nos centramos en el transporte */ 
file = open (fileName , O_RDONLY); 
socketTCP = sock (…); 
/* establece sesion TCP */ 
 
while (datosEnviado < tamanoFichero) 
 { 
read (file, memor, TAM_BLOQ); 
write (socketTCP, memor, TAM_BLOQ); 
/* actualiza datos enviados */ 
} 
/* nos centramos en el transporte */ 
socketTCP = sock (…); 
/* establece sesion TCP */ 
 
 
while (datosRecibidos< tamanoFichero) 
 { 
read (socketTCP, memor, TAM_BLOQ); 
/* actualiza datos recibidos */ 
} 
 
/* configura dispositivo de video */ 
videoDevice = open (/dev/… ); 
 
while (datosReproducidos < tamanoFichero) 
{ 
write (videoDevice, memor, TAM_BLOQ); 
/* actualiza datosReproducidos */ 
} 
 
#1 = transferencia 
contenido completo, 
luego reproducción 
Comunicaciones multimedia 
#1: ¿cumple parámetros 
de calidad? 
ITU-T G.1010: ‘Categorías de calidad de servicio para los 
usuarios de extremo de servicios multimedios’, 2001 
 
Medium 
Application Degree of 
symmetry 
Typical data 
rates 
Key performance parameters and target values 
 
 One-way 
delay 
Delay 
variation 
Information loss 
(Note 2) 
Other 
Audio 
 
Conversational 
voice 
 
Two-way 4-64 kbit/s <150 ms 
preferred (Note 1) 
<400 ms limit 
(Note 1) 
< 1 ms < 3% packet loss 
ratio (PLR) 
 
Audio 
 
 
Voice messaging 
 
Primarily 
one-way 
4-32 kbit/s < 1 s for playback 
< 2 s for record 
 
< 1 ms 
 
< 3% PLR 
Audio 
 
 
 
High quality 
streaming audio 
 
Primarily one-way 16-128 kbit/s 
(Note 3) 
< 10 s 
 
<< 1 ms 
 
< 1% PLR 
 
 
Video 
 
 
Videophone Two-way 16-384 kbit/s < 150 ms 
preferred (Note 4) 
<400 ms limit 
 BAJA (< 
1ms) 
< 1% PLR 
 
Lip-synch: 
< 80 ms 
Video One-way One-way 16-384 kbit/s < 10 s BAJA (< 1ms) < 1% PLR 
NOTE 1 – Assumes adequate echo control. 
NOTE 2 – Exact values depend on specific codec, but assumes use of a packet loss concealment algorithm to minimise effect of packet loss. 
NOTE 3 – Quality is very dependent on codec type and bit-rate. 
NOTE 4 – These values are to be considered as long-term target values which may not be met by current technology. 
Jitter 
#1 = transferencia 
contenido completo, 
luego reproducción 
Comunicaciones multimedia 
#1: ¿cumple parámetros 
de calidad? 
ITU G.1010: ‘Categorías de calidad de servicio para los 
usuarios de extremo de servicios multimedios’, 2001 
 
Medium 
Application Degree of 
symmetry 
Typical data 
rates 
Key performance parameters and target values 
 
 One-way 
delay 
Delay 
variation 
Information loss 
(Note 2) 
Other 
Audio 
 
Conversational 
voice 
 
Two-way 4-64 kbit/s <150 ms 
preferred (Note 1) 
<400 ms limit 
(Note 1) 
< 1 ms < 3% packet loss 
ratio (PLR) 
 
Audio 
 
 
Voice messaging 
 
Primarily 
one-way 
4-32 kbit/s < 1 s for playback 
< 2 s for record 
 
< 1 ms 
 
< 3% PLR 
Audio 
 
 
 
High quality 
streaming audio 
 
Primarily one-way 16-128 kbit/s 
(Note 3) 
< 10 s 
 
<< 1 ms 
 
< 1% PLR 
 
 
Video 
 
 
Videophone Two-way 16-384 kbit/s < 150 ms 
preferred (Note 4) 
<400 ms limit 
 BAJA (< 
1ms) 
 
< 1% PLR 
 
Lip-synch: 
< 80 ms 
Video One-way One-way 16-384 kbit/s < 10 s BAJA (< 1ms) < 1% PLR 
NOTE 1 – Assumes adequate echo control. 
NOTE 2 – Exact values depend on specific codec, but assumes use of a packet loss concealment algorithm to minimise effect of packet loss. 
NOTE 3 – Quality is very dependent on codec type and bit-rate. 
NOTE 4 – These values are to be considered as long-term target values which may not be met by current technology. 
#1 = transferencia contenido completo, luego reproducción 
#1 = transferencia 
contenido completo, 
luego reproducción 
Comunicaciones multimedia 
#1: ¿cumple parámetros 
de calidad? 
 ¿Retardos de reproducción aceptables? 
 ¿Pérdida de paquetes en reproducción? 
 
Problema #1.1: retardo de inicio 
 Intrínseco al diseño inicial: primero descarga el 
fichero entero, luego lo reproduce 
 
#1 = transferencia 
contenido completo, 
luego reproducción 
Comunicaciones multimedia 
Tecnología para one-way video, versión #2 
/* nos centramos en el transporte */ 
file = open (fileName , O_RDONLY); 
socketTCP = sock (…); 
/* establece sesion TCP */ 
 
while (datosEnv < tamanoFich) 
{ 
 read (file, memor, TAM_BLOQ); 
 write (socketTCP, memor, TAM_BLOQ); 
 /* actualiza datosEnv */ 
} 
/* nos centramos en el transporte */ 
socketTCP = sock (…); 
/* establece sesion TCP */ 
/* configura dispositivo de video */ 
videoDisp = open (/dev/… ); 
 
 
while (datosRec< tamanoFich) 
{ 
 read (socketTCP, mem, TAM_BLOQ); 
 /* actualiza datosRec */ 
 write (videoDisp, mem, TAM_BLOQ); 
} 
 
 
 
 
Servidor de video Cliente de video 
#2 = reproduce bloque de datos nada más recibirlo 
Comunicaciones multimedia 
#2: ¿cumple parámetros 
de calidad? 
 ¿Control de flujo? 
 
 ¿Pérdida de paquetes en reproducción? 
 ¿Retardos aceptables en reproducción? ¿Se puede mantener 
‘delay variation’? 
 
La RED no es ideal, y afecta 
 ¿Causas de pérdida de paquetes? 
 ¿Causas de retardos de paquetes? 
 ¿Puedo cuantificar el retardo máximo? 
 
 
 
#2 = reproduce bloque 
de datos nada más 
recibirlo 
Comunicaciones multimedia 
Pérdidas y retardos en la red 
 ¿Causas de pérdida de paquetes? 
 ¿Cómo son las pérdidas si utilizo TCP? 
 ¿Causas de retardos de paquetes? 
 ¿Puedo cuantificar el retardo máximo ‘one-way’? 
 ¿Cómo es el retardo si utilizo TCP? 
 ¿Cómo varía retardo / pérdida de paquetes 
con la distancia? 
 
Conmutador / 
Router 
Líneas de entrada Líneas de salida
Comunicaciones multimedia 
#2: ¿cumple 
parámetros de calidad? 
 Supongamos que de media, hay ancho de banda 
suficiente, pero puede haber variaciones en transitorio 
 Si de media no hay ancho de banda suficiente, hay que 
REDUCIR la calidad del vídeo 
 
 Problema #2.1: ¿cumple JITTER? 
¿estoy seguro de que tendré datos suficientes para reproducir 
en cada momento? 
 
 Solución #2.1: que la red tenga “mejor 
comportamiento” 
 Soluciones de Calidad de Servicio 
 Versión #3: acumular datos en el cliente antes de 
empezar la reproducción 
 BUFFERING 
#2 = reproduce bloque 
de datos nada más 
recibirlo 
Comunicaciones multimedia 
Tecnología para one-way video, versión #3 
(aka progressive download) 
/* nos centramos en el transporte */ 
file = open (fileName , O_RDONLY); 
socketTCP = sock (…); 
/* establece sesion TCP */ 
 
while (datosEnviado < tamanoFichero) 
{ 
 read (file, mem, TAM_BLOQ); 
 write (socketTCP, mem, TAM_BLOQ); 
 /* actualiza datosEnviado */ 
} 
/* nos centramos en el transporte */ 
socketTCP = sock (…); 
/* establece sesion TCP */ 
/* configura dispositivo de video */ 
videoDisp = open (/dev/… ); 
 
memIni = mem; 
 
while (datosRec < tamanoFichero) 
{ 
 read (socketTCP, mem, TAM_BLOQ); 
 /* actualiza datos recibidos */ 
 if (datosRec > BUFFER_INICIAL) 
 { 
 write (videoDisp, memIni, TAM_BLOQ); 
 } 
} 
/* Cuando termina de recibir, quedan 
datos que hay que terminar de 
reproducir*/ 
 
Servidor de video Cliente de video 
#3 = buffering, acumula algunos datos antes de comenzar reproducción 
Comunicaciones multimedia 
Progressive download vs streaming 
Progressive download: 
 Mandar todo el vídeo al destino 
 Muy simple para el servidor que envía, muy 
fácil de implementar con TCP 
 Forward sólo hasta parte de contenido recibida 
Streaming: 
 El cliente pide explícitamente bloques para 
reproducir 
 Facilita forward 
 
Comunicaciones multimedia 
Version #3 
 TCP no permite uso de multicast 
  
Comunicaciones multimedia 
Transporte de video one-way 
 
 
Transporte de comunicaciones 
interactivas 
Comunicaciones multimedia 
Comunicaciones Interactivas 
¡El contenido se genera en tiempo real 
Cloud gaming requiere 
respuesta en <120 ms. 
Comunicaciones multimedia 
Comunicación interactiva, versión #1 
Ejemplo típico: 
 Audio generado a 
8000 muestras por 
segundo, 1 byte por 
muestra 
 T=20 ms (160 bytes) 
 Retardo de 
codificación (codec 
delay): T 
 Depende de tamaño 
de paquete 
 Siempre presente 
(aunque lo obviamos 
en el resto de la 
discusión) 
Usuario 1 Usuario 2 
tiempo 
T 
T 
Retardo 
de red 
Empieza a 
grabar 
Comunicaciones multimedia 
Comunicación interactiva, 
versión #1 
 Análisis de datos disponibles en la memoria del cliente 
Usuario 1 Usuario 2 
tiempo 
datos disponibles en cliente (bytes) 
Cantidad de datos recibidos 
en un paquete 
Velocidad de 
reproducción 
#1 = reproduce bloque 
de datos nada más 
recibirlo 
Comunicaciones multimedia 
Comunicación interactiva, 
versión #1 
 Comunicación con retardos variables en la red 
tiempo 
datos disponibles en cliente Usuario 1 Usuario 2 
#1 = reproduce bloque 
de datos nada más 
recibirlo 
Comunicaciones multimedia 
#1: ¿cumple parámetros de 
calidad? 
ITU G.1010: ‘Categorías de calidad de servicio para los 
usuarios de extremo de servicios multimedios’, 2001 
 
Medium 
Application Degree of 
symmetry 
Typical data 
rates 
Key performance parameters and target values 
 
 One-way 
delay 
Delay 
variation 
Information loss 
(Note 2) 
Other 
Audio 
 
Conversationa
l voice 
 
Two-way 4-64 kbit/s <150 ms 
preferred (Note 
1) 
<400 ms limit 
(Note 1) 
< 1 ms < 3% packet 
loss ratio 
(PLR) 
 
Audio 
 
 
Voice messaging 
 
Primarily 
one-way 
4-32 kbit/s < 1 s for playback 
< 2 s for record 
 
< 1 ms 
 
< 3% PLR 
Audio 
 
 
 
High quality 
streaming audio 
 
Primarily one-way 16-128 kbit/s 
(Note 3) 
< 10 s 
 
<< 1 ms 
 
< 1% PLR 
 
 
Video 
 
 
Videophone Two-way 16-384 kbit/s < 150 ms preferred 
(Note 4) 
<400 ms limit 
 BAJA (< 
1ms) 
 
< 1% PLR 
 
Lip-synch: 
< 80 ms 
Video One-way One-way 16-384 kbit/s < 10 s BAJA (< 
1ms) 
< 1% PLR 
NOTE 1 – Assumes adequate echo control. 
NOTE 2 – Exact values depend on specific codec, but assumes use of a packet loss concealment algorithm to minimise effect of packet loss. 
NOTE 3 – Quality is very dependent on codec type and bit-rate. 
NOTE 4 – These values are to be considered as long-term target values which may not be met by current technology. 
#1 = reproduce bloque 
de datos nada más 
recibirlo 
Comunicaciones multimedia 
#1: ¿cumple parámetros de 
calidad? 
Delay variation <1 ms 
 
 
 
 
 
Necesitamos Versión #2: BUFFERING 
#1 = reproduce bloque 
de datos nada más 
recibirlo 
Comunicaciones multimedia 
Comunicación interactiva, 
versión #2 
Usuario 1 Usuario 2 
tiempo 
datos disponibles en cliente 
Comienza representación 
#2= buffering, acumula 
algunos datos antes de 
comenzar reproducción 
Comunicaciones multimedia 
#2: ¿cumple parámetros 
de calidad? 
One-way delay 
 <150 ms preferred 
 <400 ms limit 
#2= buffering, acumula 
algunos datos antes de 
comenzar reproducción 
Comunicaciones multimedia 
Versión #2: ¿cumple 
parámetros de calidad? 
Retardo medido en orden de magnitud del 
deseado 
 ¡Cuidado con tamaño de buffering! 
RTT (=ida y vuelta) en 
función de distancia 
Medido para jugadores 
de Halo-3. 
En rojo, retardo de 
transmisión (RTT) mínimo 
Agarwal, Lorch [Sigcomm09] 
#2= buffering, acumula 
algunos datos antes de 
comenzar reproducción 
Comunicaciones multimedia 
#2: ¿cumple parámetros 
de calidad? 
Suponemos que utilizábamos TCP 
 Problemas con one-way delay 
 TCP puede empezar lento (control de congestión) 
 TCP puede incorporar retardos si se pierden 
paquetes 
Retardo por pedir retransmisión 
Bajada de velocidad por mecanismo de control de 
congestión 
 Toleramos ‘< 3% packet loss ratio’, pero no retardos 
grandes 
 Recordar que los problemas de retardos se agravan 
con la distancia 
 Solución #3: utilizar UDP 
 Nota: TCP puede funcionar, hay quien lo utiliza 
para comunicaciones interactivas 
 
 
#2= buffering, acumula 
algunos datos antes de 
comenzar reproducción 
Comunicaciones multimedia 
#3: ¿cumple parámetros de 
calidad? 
One-way delay 
 <150 ms preferred 
 <400 ms limit 
Buffering incrementa one-way delay  
 
 ¿Cuánto buffering? 
#3= UDP con 
buffering, 
Comunicaciones multimedia 
Comunicación interactiva, 
versión #3 
Otra forma de verlo 
 constant bit 
 rate transmission 
time 
variable 
network 
delay 
client 
reception 
 constant bit rate 
 playout at client 
b
u
ff
e
re
d
 
v
id
e
o
 
Computer Networking: A Top Down Approach, 6th ed,, J. Kurose, K. Ross 
One-way delay 
buffer delay 
#3= UDP con 
buffering, 
Network delay 
Comunicaciones multimedia 
#3: ¿cumple parámetros 
de calidad? 
Solución #3.1: dimensionar correctamente 
buffering inicial 
#3= UDP con 
buffering, 
Comunicaciones multimedia 
Dimensionamiento del buffer 
 Buffer delay: se establece para el primer paquete 
 Idealmente, depende del 
 Retardo máximo de la red 
 Retardo del primer paquete 
 constant bit 
 rate transmission
time 
MAXIMUM network delay 
 constant bit rate 
 playout at client 
150 ms 
delay first packet buffering 
Comunicaciones multimedia 
Dimensionamiento del buffer 
 ¿Puedo conocer retardo one-way máximo? 
 ¿De qué depende? 
 
 Pregunta previa: ¿puedo MEDIR el retardo one-
way? 
 Requiere relojes sincronizados en FRECUENCIA y 
OFFSET 
 ¿Alguna estimación del retardo one-way? 
Comunicaciones multimedia 
#3 y pérdidas de paquetes 
En solución basada en TCP, no nos 
teníamos que preocupar de pérdidas de 
paquetes 
 Pero UDP no gestiona esto 
 
 TCP hacía control de flujo… 
 ¿Puedo perder paquetes en #3 por ‘problemas 
de control de flujo’? 
 
#3= UDP con 
buffering, 
Comunicaciones multimedia 
#3 y pérdidas de paquetes 
 Estrategia frente a pérdidas de paquetes en la red 
 Pérdidas puntuales 
 La aplicación pide retransmisión 
Si el retardo es muy bajo 
 La fuente introduce redundancia 
Enviar más datos 
 ‘Maquillar’ pérdidas puntuales 
 Interpolación de paquetes adyacentes, ruido blanco… 
 Pérdidas continuadas: Reducir calidad ante pérdidas 
continuadas (posible congestión) 
 Receptor detecta pérdidas continuadas 
 Receptor transmite evento a fuente 
 Fuente cambia codec 
 Necesitamos NUMERAR LOS PAQUETES para 
detectar pérdidas 
 UDP no numera los paquetes 
#3= UDP con 
buffering, 
Comunicaciones multimedia 
#3 y medios ‘no continuos’ 
 Medio es ‘continuo’: el tiempo de 
reproducción está implícito en los datos 
 Ejemplo, al ‘echar datos seguidos’ a la tarjeta de 
sonido, la tarjeta de sonido sabe qué hacer con 
ellos 
 Medio ‘no continuo’: el tiempo de 
reproducción no está implícito en el flujo de 
datos 
 Audio con silencios: ¿cuándo termina el silencio? 
 Sincronización de un flujo de video y de subtítulos 
 Para medios no continuos, hacen falta 
MARCAS de TIEMPO 
 Ni UDP ni TCP incluyen esta información 
 
#3= UDP con 
buffering, 
Comunicaciones multimedia 
Arquitectura de un sistema de VoIP 
 
Detector de 
silencios 
(VAD) 
Codificador 
audio 
Paquetiza
ción 
Generador de 
redundancia 
Estimación 
retardo y 
jitter 
Buffer de 
reproducci
ón 
Decodificador 
de audio 
Tratamiento 
de pérdidas 
Estimación de 
pérdidas y 
realimentación 
Entrada 
de audio 
Salida 
de audio 
Fuente Receptor 
Comunicaciones multimedia 
[NOTA al margen] 
 También con one-way video puede tener 
sentido una estrategia de envío controlada 
 Reduce memoria en cliente 
 Muchos vídeos no se terminan, absurdo gastar 
servidor y ancho de banda en enviarlo 
Consumo de datos 
en reproducción 
Comunicaciones multimedia 
 
RTP 
Comunicaciones multimedia 
Introducción RTP 
 La mayoría de las aplicaciones multimedia en red usan 
números de secuencia y marcas de tiempo 
 RTP ofrece este servicio de forma estandarizada 
 Diseñado para poder usarse en una grandísima variedad de 
escenarios 
 Desde audioconferencias punto a punto a distribución de 
contenidos multimedia a miles de usuarios 
 Permite transportar formatos comunes PCM, GSM, MP3, … 
para sonido y MPEG, H.263, H.264, etc., para video 
 También transporta formatos propietarios 
 Es el estándar utilizado para transporte de datos en muchas 
arquitecturas: SIP, H.323, RTSP… 
 RTP 
 No gestiona QoS (no tiene que ver con la infraestructura de red) 
 No garantiza entrega fiable ni ordenada 
 Va acompañado del intercambio de información de control: 
RTCP 
Comunicaciones multimedia 
Filosofía RTP 
 Para datos multimedia, nadie mejor que la aplicación para saber 
qué hacer si se pierden paquetes o llegan tarde o cuáles son 
sus prioridades relativas 
 No poner funciones a nivel de transporte que no sean 
universalmente necesarias 
 El protocolo de transporte no debe implementar recuperación ante 
errores, control de flujo, ... 
 Application level framing: La aplicación delimita en bloques la 
información que se envía (bloques que puedan procesarse 
de forma completa e independiente) 
 Un mensaje (nivel de aplicación) debe empaquetarse en un paquete 
(nivel de red) 
Con application level framing Sin application level framing 
Comunicaciones multimedia 
Filosofía RTP 
 RTP funciona extremo a extremo: los nodos 
intermedios no interpretan RTP 
 Necesita de un protocolo de transporte por debajo 
para multiplexación 
 RTP viaja preferentemente encima de UDP 
 Conceptualmente, se puede entender como un 
servicio de transporte 
 Aunque la frontera con aplicación no está clara 
 Respecto a su implementación, se suele integrar 
como parte del procesamiento a nivel de la 
aplicación que lo usa, en espacio de usuario, por 
encima del interfaz de sockets 
 Lo implementa el programador de la aplicación, o éste 
utiliza librerías que compila con su programa 
 No es un servicio del sistema operativo 
Comunicaciones multimedia 
Repaso: multicast en IP 
 Direcciones entre 224.0.0.0 y 239.255.255.255 
 Sólo se pueden utilizar como dirección destino 
 ¿Qué tiene que hacer un nodo para enviar a un grupo 
multicast? 
 ¿Qué tiene que hacer un nodo para recibir de un grupo 
multicast? 
224.10.10.15 
224.10.10.15 
224.10.10.15 
Comunicaciones multimedia 
Sesión RTP 
 Sesiones “ligeras”: no hay control estricto ni centralizado sobre quién está 
en la sesión 
 Se ajusta bien al modelo multicast de IP 
 Sesión RTP es una asociación entre un conjunto de participantes que se 
comunican con RTP 
 Indica los parámetros de destino de los paquetes, y está definida por 
 Direcciones IP de los participantes 
 IP multicast 
 o lista de direcciones unicast 
 Puerto RTP: Puerto destino (UDP), en general un número par, 
 En general, lo utilizan TODOS los participantes (aunque podrían 
definirse puertos distintos para cada destino) 
 Puerto por defecto: 5004 
 Puerto RTCP: Puerto destino (UDP) de los mensajes de control (RTCP), 
en general impar 
 En general, lo utilizan TODOS los participantes (aunque podrían 
definirse puertos distintos para cada destino) 
 En general, puerto RTCP = puerto RTP asociado + 1 
 RTP no dice cómo establecer las sesiones, determinar los parámetros que 
las definen 
 Esto se hace a través de otros protocolos, ej. SIP 
Comunicaciones multimedia 
Sesión RTP 
 Si un nodo participa en una sesión, es porque 
quiere recibir los datos (RTP) que se envían ahí 
 Además, alguno de los que participa puede mandar 
datos (RTP) 
 Roles posibles: ‘Receptor de datos’, ‘Emisor+Receptor 
de datos’ 
 Los roles pueden cambiar dinámicamente (uno puede 
mandar un momento, y luego sólo recibir) 
 Todos los nodos mandan y reciben información de 
control (RTCP) 
 También los que no mandan datos 
 
Comunicaciones multimedia 
Ejemplos de uso de RTP 
 Conferencia de audio multicast: 
 4 participantes 
 1 sesión RTP: dirección multicast 224.10.10.15, puerto RTP 5004, 
puerto RTCP 5005 
 El audio se muestrea en cada equipo de usuario y se envía en paquetes 
RTP 
 Cada paquete RTP se envía en 1 paquete UDP, con dirección destino 
224.10.10.15 y puerto destino 5004 
 
 
224.10.10.15 
224.10.10.15 
224.10.10.15 
Paquete RTP: 
-Tipo de codificación (e.g. PCM) 
-Marca de tiempo 
-Número de secuencia 
-Audio muestreado 
 
El usuario habla, y 
la voz se muestrea 
(e.g. con PCM, 
ADPCM o LPC) 
Comunicaciones multimedia 
Formato de Mensaje RTP 
 
Sequence Number Ve 
Timestamp 
Synchronization Source (SSRC) Identifier 
0 4 16 31 
P X CC 
8 9 
M 
Payload 
Type 
Contributing Source (CSRC) Identifier #1 
. . . . 
Contributing Source (CSRC) Identifier #n 
Contenido Multimedia
Comunicaciones multimedia 
Profiles y payload types 
Perfil (profiles): contextos en los que se define de forma más detallada cómo usar 
RTP 
 Ejemplos: 
 RTP/AVP (Audio Video Profile): Perfil genérico para conferencias de audio/vídeo con 
mínimo control (RFC3551: “RTP Profile for Audio and Video Conferences with Minimal 
Control”) 
 RTP/I Para whiteboards, y medios interactivos 
 Para transporte de audio y vídeo con retransmisión, … 
 Todas las aplicaciones que pertenecen a una misma sesión RTP deben utilizar el 
mismo perfil 
 Un perfil define 
 Números de payload, que tienen significados distintos en cada perfil 
 Se ‘reutiliza’ el mismo número en distintos perfiles, con significados diferentes 
 Cómo se empaqueta la información multimedia para cada tipo de payload (cómo se 
calcula el Timestamp, cuántos datos meter por paquete…) 
 También puede haber documentos específicos en los que se especifica el payload format 
 Incluso refinar el comportamiento de RTP/RTCP en ese perfil 
 Cambiar intervalo de generación de paquetes RTCP 
 Añadir nuevos tipos de paquete RTCP 
 Definir extensiones para RTP 
 ... 
 Nótese que NO hay un ‘identificador de perfil’ que viaje con los paquetes 
Comunicaciones multimedia 
Algunos documentos de “profiles” 
RTP Profile for Audio and Video Conferences with Minimal Control (RFC 3551) 
The Secure Real-time Transport Protocol (SRTP) (RFC 3711) 
Extended Secure RTP Profile for Real-time Transport Control Protocol (RTCP)-Based 
Feedback (RTP/SAVPF) (RFC 5124) 
Extended RTP Profile for Real-time Transport Control Protocol (RTCP)-Based Feedback 
(RTP/AVPF) (RFC4585) 
 
RTP Payload Format for JPEG-compressed Video (RFC 2035) obsoleted by RFC 2435 
RTP Payload format for H.261 video streams (RFC 2032) 
RTP Payload Format for MPEG1/MPEG2 Video (RFC 2038) obsoleted by RFC 2250 
RTP Payload Format of Sun's CellB Video Encoding (RFC 2029) 
RTP Payload Format for H.263 Video Streams (RFC 2190) 
RTP Payload for Redundant Audio Data (RFC 2198) 
RTP Payload Format for MPEG1/MPEG2 Video (RFC 2250) 
RTP Payload Format for Bundled MPEG (RFC 2343) 
RTP Payload Format for the 1998 Version of ITU-T Rec. H.263 Video (H.263+) (RFC 2429) 
RTP Payload Format for BT.656 Video Encoding (RFC 2431) 
RTP Payload Format for JPEG-compressed Video (RFC 2435) 
An RTP Payload Format for Generic Forward Error Correction (RFC 2733) 
RTP Payload for Text Conversation (RFC 2793) 
RTP Payload for DTMF Digits, Telephony Tones and Telephony Signals (RFC 2833) 
RTP Payload Format for Real-Time Pointers (RFC 2862) 
RTP payload format for MPEG-4 Audio/Visual streams (RFC 3016) 
RTP Payload Format for ITU-T Recommendation G.722.1 (RFC 3047) 
A More Loss-Tolerant RTP Payload Format for MP3 Audio (RFC 3119) (37796 bytes) 
RTP Payload Format for DV Format Video (RFC 3189) (25991 bytes) 
RTP Payload Format for 12-bit DAT, 20- and 24-bit Linear Sampled Audio (RFC 3190) (34977 bytes) 
RTP payload format and file storage format for the Adoptive Multi-Rate (AMR) and Adaptive Multi-RTP 
Payload for Comfort Noise (RFC 3389) (17018 bytes) 
… 
 
Comunicaciones multimedia 
Negociación de perfiles y ‘payload 
types’ 
 Se pueden utilizar distintos protocolos para 
negociar el perfil (nota: ‘fuera’ de RTP) 
 SDP (Session Description Protocol, RFC 4556), 
define un formato en el que se especifican los 
parámetros de la sesión multimedia 
 
m=audio 49232 RTP/AVP 0 
 
 
 O también 
 
m=audio 49232 RTP/AVP 98 
a=rtpmap:98 L16/16000/2 
 
puerto UDP Usar RTP con ‘profile’ AVP (Audio-
Vídeo Profile, es decir, RFC3551) 
Utilizar payload type 0 
según AVP (u-law PCM…) 
Utilizar payload type 98 (según 
AVP, ‘dynamic’, es decir que 
puede tener distintos usos 
Defino lo que es 
‘98’ para este uso 
L16 = codificación lineal de 16 bits (definido 
en RFC3551), 16000 es la frecuencia de 
muestreo, 2 es el número de canales 
Comunicaciones multimedia 
Formato de Mensaje RTP 
 Marca de tiempo (timestamp): 
 Permite sincronización y cálculo de jitter de 
paquete (útil para RTCP) 
 … ¿con qué formato? (con qué precisión…) 
 Ej: poner texto de subtítulos en instante 19.025 s, 
siguiente en 27.145 s 
 Empezar a reproducir paquete de audio en 0 s, siguiente 
en 1/3 de segundo, luego 2/3 de segundo… 
0.33333333333333 s ? 
 Diferentes formatos de marca de tiempo en función de 
perfil y payload 
 No debe requerir sincronización entre relojes: sólo 
indica valores de tiempo relativos entre paquetes 
 Difícil requerir sincronización de offset entre relojes 
(razonable pedir una frecuencia similar) 
Comunicaciones multimedia 
Formato de Mensaje RTP 
 Marca de tiempo (timestamp): 32 bits 
 Como es dependiente del perfil, consideremos ejemplo de 
‘audio’ en RFC3551 
 Timestamp indica el instante de reproducción del primer 
octeto de datos contenido en el paquete RTP 
 Emplea el reloj (virtual) de muestreo del audio (NO reloj del 
sistema operativo, ni CPU) 
No tiene sentido pedir a la tarjeta de sonido un dato “en medio” 
de un periodo de muestreo. Tampoco iniciar una reproducción 
ahí (después de un silencio, por ejemplo) 
 
 
 
Ejemplo: en audio sin comprimir el tiempo pasa en 1 unidad 
en cada periodo de muestreo 
• Suponer paquete de 2048 bytes, 2 bytes por muestra (16 bits 
mono) 
ts=340 ts=1364 
tiempo=2388 
ts=2561 
t 
Comunicaciones multimedia 
Formato de Mensaje RTP 
 Marca de tiempo (timestamp): 32 bits 
 Valor inicial es aleatorio (como el número de secuencia) 
 Ejemplos de otros perfiles 
 En video, paquetes del mismo frame (porque no quepan 
en un único paquete), llevan igual timestamp 
 MPEG marca de forma no monótona creciente 
(interpolados se envían después) 
Comunicaciones multimedia 
Formato de Mensaje RTP 
 SSRC (Synchronization Source Identifier): 32 bits 
 Generado aleatoriamente por la fuente 
 Identificador único a nivel RTP de una fuente para una sesión 
 Permite mantener la temporización de la reproducción de cada 
fuente 
 Los números de secuencia también tienen sólo sentido para 
una fuente dada 
SSRC=1 
SSRC=2 
TS: 100, SSRC=2 
TS: 2200, SSRC=1 
TS: 2190, SSRC=1 
TS: 20, SSRC=2 
Tiempo (proceso de reproducción) 
SSRC Ultimo 
seq 
Último 
ts 
1 367 2190 
2 1207 20 
… … … 
Comunicaciones multimedia 
“Sesión ligera” en RTP 
 Las sesiones RTP son “muy” ligeras, como es el control de 
IP multicast 
 Cualquiera puede unirse sin que nos enteremos 
 Si queremos restringir, puede hacerse cifrando y distribuyendo 
las claves con otros protocolos de nivel superior 
 El emisor no sabe cuántos destinatarios hay 
 ¡Puede ocurrir que no haya ninguno! 
 Parece conveniente dar algún tipo de realimentación a los 
participantes – sobre todo a los emisores => RTCP 
224.10.10.15 
224.10.10.15 
224.10.10.15 
RTP 
Comunicaciones multimedia 
RTCP (Real Time Control Protocol) 
 Funciones 
 Monitorización de la congestión y del QoS 
 Se envían informes sobre lo recibido de cada participante 
en una sesión 
 Permite medir jitter, y RTT, y calcular tiempo de buffering 
 Identificación 
 Identificador de la fuente mediante una cadena de 
caracteres 
 Puede utilizarse para asociar flujos de diferentes sesiones 
 También permite enviar el nombre del usuario y otros 
parámetros textuales de tipo informativo 
 Control de sesión mínimo 
 Abandono de sesión 
 Conocer el número de participantes 
Comunicaciones multimedia 
Paquetes RTCP 
 Cinco tipos 
 Sender Report (SR) 
 Indica lo que ha enviado el nodo (y deberían haber 
recibido los demás) + lo que ha recibido el nodo 
 Receiver Report (RR) 
 Informa sobre lo que ha recibido el nodo 
 Source Description (SDES) 
 Descripción de la fuente: CNAME
(canonical name), 
NAME, EMAIL, PHONE, LOC, TOOL, ... 
 BYE 
 Opcional, indica que un equipo abandona la sesión, y la 
razón por la que la abandona 
 Específico de aplicación 
 Opcional, permite añadir funcionalidades sin necesidad 
de definir nuevos paquetes en el protocolo 
Comunicaciones multimedia 
Cálculo del Round Trip Time 
 ‘j’ es un ‘sender’, ‘k’ puede ser cualquier cosa 
 ’k’ manda información relevante en Rec Report Block 
 Cada emisor recibe estimación de RTT con cada uno 
de los miembros de la sesión 
j k 
Mide 
tiempo T0 
Guarda T0 y lo asocia con fuente j 
Inicia temporizador DLSRj 
Al enviar paquete a j (cuando le toque!) 
 detiene temporizador DLSRj y mete su valor en 
 DLSR 
 mete valor de T0 en campo LSR 
Mide tiempo T2. 
Resta T2-T0 – DLRSj 
Mide 
tiempo T1 
Comunicaciones multimedia 
Cálculo del Round Trip Time 
 ‘j’ no tiene que almacenar estado 
 ‘k’ sólo guarda por emisor RTP: 
 valor del campo NTP del último paquete recibido, 
 tiempo en el que recibió el último paquete 
j k 
Mide tiempo T2. 
Resta T2-T0 – DLRSj 
DLRSj T2-T0 
Comunicaciones multimedia 
RTCP y Round Trip 
Cálculo del Round Trip entre fuente j y k 
 j envía mensaje RTCP SR a k 
 instante T0 codificado en NTP (64 bits) 
 k envía un tiempo después mensaje RTCP RR a j 
 Delay since Last SR (DLSRj): tiempo desde que se 
recibió el mensaje de j hasta que k envía de vuelta a j 
 Time of Last Sender Report (LSR): tiempo de 
generación del primer mensaje en j según j (ahora en 
otro formato: 32 bits centrales del NTP) 
 Round trip: j recibe paquete de k en T 
 Round trip = T-LSR - DLSR 
Comunicaciones multimedia 
Estado en los receptores 
 Cada receptor debe mantener estado PARA CADA FUENTE 
de la que ha recibido ‘recientemente’ 
 SSRC de la fuente, 
 RTP timestamp del último paquete recibido, asociado a un tiempo 
‘local’ en el que se debe haber reproducido 
 Si no, no sabrá cuándo tiene que reproducir los contenidos de los 
paquetes de datos 
 Número de secuencia del último paquete recibido y del último 
paquete enviado antes de enviar el último mensaje SR o RR 
 Para poder calcular ‘fraction lost’, y saber si el siguiente paquete 
esperado se ha perdido o no… 
 DLSR asociado al último mensaje RTCP recibido de la fuente 
 Tiempo NTP recibido en el último mensaje RTCP recibido de la 
fuente 
 … 
Comunicaciones multimedia 
Puertos en paquetes UDP 
RFC 3550 hace referencias sobre el puerto 
de destino de un paquete RTP o RTCP 
 Ej: dice que por defecto para RTP sea 5004, 
 En cualquier caso recomienda que el puerto 
para RTP sea par, y el de RTCP = RTP+1 
 El puerto origen podría ser cualquiera 
Sobre el puerto origen, RFC4961 sugiere 
que sea igual que el destino (tanto para 
RTP como para RTCP) 
 Ej: si capturáramos un paquete “en tránsito”: 
 Dir orig: 163.117.140.180, puerto orig: 5004, dir 
dest: 225.10.0.3, puerto dest: 5004 
__MACOSX/Parte1/._01-comunicaciones_multimedia.pdf
Parte1/01.5 - programación en C.pdf
Repaso de 
programación en C 
Introducción a la programación en C 2 
Programación en C 
 C es un lenguaje imperativo (= le decimos paso a paso 
lo que tiene que hacer) 
 Maneja 
 Variables de distintos tipos 
 En general C es MUY ESTRICTO con los tipos: no deja mezclar 
 … salvo con punteros 
 Constantes 
 Funciones = bloque de código al que se le puede pasar 
varios parámetros y devuelve resultados 
 Nos facilita reutilizar código: escribo algo que se comporta de 
forma levemente distinta según los argumentos de entrada 
 Estructuras de control: if, bucles, … 
 Escribimos uno o varios ficheros de texto, y con unas 
herramientas (compilador y enlazador) obtenemos UN 
fichero ejecutable 
Introducción a la programación en C 3 
Ejemplo 
 Fichero: holaMundo.c 
 
 #include <stdio.h> 
 #include <stdlib.h> 
 
 int main (void) 
 { 
 printf(“Hello World\n”); 
 exit(0); 
 } 
 
 (En Linux) se compila usando gcc 
gcc –o holaMundo holaMundo.c 
 Se ejecuta con 
 ./holaMundo 
 
Introducción a la programación en C 4 
Entendiendo el ejemplo 
 Todo programa en C tiene una función llamada 
main, que es donde comienza la ejecución 
 Puede ser de la siguiente forma 
 
int main (void) { /* código */... }, 
 
 
 
 
 Opcionalmente, el programa puede tener otras 
funciones que son llamadas desde el interior de 
main 
 Si no son llamadas desde main, no se ejecutan 
 
Información recibida por la función 
Información que 
retornará la función 
Introducción a la programación en C 5 
Entendiendo el ejemplo 
 Hay cosas que C NO sabe hacer (ni nosotros tampoco): 
 Acceder a ficheros, escribir cosas en la pantalla, leer del teclado… 
 ¡C sólo sabe hacer operaciones matemáticas sencillas y mover/copiar datos 
de un lado a otro! 
 Para solucionarlo utilizamos librerías del sistema: 
 Funciones que han escrito otros (ej., los que han hecho el Sistema 
Operativo, los que han hecho el compilador…) 
 Las funciones están declaradas en ficheros *.h (ficheros de cabeceras) 
 Hay que incorporar las declaraciones de las funciones en nuestro fichero 
 #include <stdio.h> 
 #include <stdlib.h> 
 #include sustituye la línea en la que está por el fichero completo 
 Gracias a 
 stdio.h, el compilador sabe que hay una función llamada printf(), que sirve 
para escribir cosas por la pantalla 
 stdlib.h, conoce la función exit() que sirve para terminar y devolver un valor a 
la línea de comando (típicamente -1 si ha habido un error, 0 en caso contrario) 
 El #include sólo indica la declaración de la función (= el nombre, el valor que 
devuelve, y los argumentos que toma) 
 Más ficheros que declaran funciones en /usr/include 
 El compilador sabe encontrar el código que *realmente* hace el trabajo de 
printf y exit 
 Está en una librería llamada glibc, que el compilador conoce sin necesidad de que 
le tengamos que decir nada 
 
Introducción a la programación en C 6 
Tipos de datos y operadores 
 Tipos de datos básicos 
 Tipos: char, int, float, double 
 char es un byte. 
 Recordar que los números representan caracteres (según ASCII) 
 Calificadores: short (16 bit), long (64 bit), unsigned, signed, 
const 
 Ejemplo de declaración de variables 
 unsigned int variable1, variable2; 
 Declaro y asigno valor inicial 
int indice = 0; 
 Asignación 
variable1 = 2; variable2 = variable1 + 9; 
 Aritmética: +, -, *, /, % 
 Sólo con números, y sólo entre números del mismo tipo 
 Otro tipo de aritmética con funciones; ejemplo 
log (3.4556) /*logaritmo decimal, utilizando función 
definida en #include math */ 
 variable1++ ; /* es igual que 
 variable1 = variable1 + 1 */ 
Introducción a la programación en C 7 
Tipos de datos y operadores 
 Constantes 
 #define constante1 0x1234 
 #define texto “Cadena de caracteres” 
 Relaciones y lógica: <, >, <=, >=, ==, !=, &&, || 
 (1 && 0) es igual a 0 
 Ojo: ASIGNACIÓN es =, COMPARACION es == 
 Cuidado con asignar cuando se quiere comparar! 
 if ( a = 3 ) … ¡Siempre verdadero! 
 
Introducción a la programación en C 8 
Aritmética entera 
 ¡Cuidado con orden de las operaciones! 
int resultado; 
resultado = 30*400/1000; 
 /*resultado es 12, lo que queríamos*/ 
resultado = 30/1000*400 
 /* resultado es 0, no deseado */ 
Dividir siempre al final 
 Con aritmética flotante, el orden de las 
operaciones es menos relevante, pero en 
aritmética entera sí lo es 
Introducción a la programación en C 9 
Arrays 
 Un array es una serie de N elementos del mismo tipo 
int x[4]; /* existen cuatro variables de tipo
entero, referibles como x[0], 
x[1], x[2] y x[3] */ 
 ¡NO existe x[4]! 
char texto[10]; 
 Los arrays son muy útiles para utilizar con estructuras de control 
‘repetitivas’ (bucles…) sobre datos del mismo tipo 
 
 Strings son cadenas de caracteres (arrays de char) especiales: 
siempre terminadas en un 0 (byte con valor 0 en uno de los char) 
 El valor (numérico) 0 se escribe en una variable de tipo ‘carácter’ como ‘\0’ 
 texto[0]=‘h’; texto[1]=‘o’, texto[2]=‘l’, 
 texto[3]=‘a’; texto[4]=‘\0’; /* ‘backslash’ cero */ 
 
¡El espacio necesario para almacenar una palabra de 4 caracteres (‘hola’) son 
CINCO chars! 
 
 printf trabaja con strings 
 printf ("%s", texto); /* imprime ‘hola’ */ 
 
 
Introducción a la programación en C 10 
Condiciones 
 /* defino una función que compara un número con 10. 
La función indica si es mayor/menor/igual devolviendo 
‘1’ si es igual, ‘0’ en caso contrario */ 
 
 int comparaCon10 (int a) { 
 if (a < 10) { 
 printf(“a es menor que 10\n”); 
 return 0; /* no es igual que 10 */ } 
 else if (a == 10) { 
 printf(“a es igual a 10\n”); 
 return 1; 
 else { 
 printf(“a es mayor que 10\n”); 
 return 0; 
 } 
 } 
 
 
== 
Introducción a la programación en C 11 
Bucles 
while (n != 10) { 
 … /* haz cosas */ 
} 
 
 
do { 
 … /* haz cosas */ 
} while (m < 20); 
 
Introducción a la programación en C 12 
Bucles 
for (i = 0; i < MAXVAL; i++) { 
 … /* haz cosas */ 
} 
 
Es una abreviatura para 
i = 0; 
while (i < MAXVAL) { 
… /* haz cosas */ 
i++;} 
Introducción a la programación en C 13 
Funciones 
 Los argumentos de las funciones SIEMPRE se pasan en C por valor 
= al entrar en la función se copia el valor, la función NO modifica la variable original 
 
int i=10; 
int resultado; 
 
main () {… 
resultado = elevaASiMismo(i); 
 printf ("%d elevado a si mismo es %d", i, resultado); 
 /* i sigue valiendo 10? O vale 100? */ 
} 
 
 
int elevaASiMismo (int n) { 
 int i, resultado=1; 
 for (i = 0; i < n; i++) { resultado = resultado * n;} 
 n = resultado; 
 return n; 
} 
 
Introducción a la programación en C 14 
Funciones 
int i=10; 
int resultado; 
 
main () {… 
 
 resultado = elevaASiMismo(i); 
 printf ("%d elevado a si mismo 
 es %d", i, resultado); 
} 
 
 
int elevaASiMismo (int n) { 
 int i, resultado = 1; 
 for (i = 0; i < n; i++) { 
 resultado = resultado * n;} 
 n = resultado; 
 return n; 
} 
 
Contenido 
10 
????? 
global_i 
global_resultado 
Nombre 
variable 
Introducción a la programación en C 15 
Funciones 
Contenido 
10 
????? 
global_i 
global_resultado 
elevaASiMismo_n 10 
Nombre 
variable 
elevaASiMismo_i 0, 1, … 
1, 10, … elevaASiMismo_ 
 resultado 
int i=10; 
int resultado; 
 
main () {… 
 
 resultado = elevaASiMismo(i); 
 printf ("%d elevado a si mismo 
 es %d", i, resultado); 
} 
 
 
int elevaASiMismo (int n) { 
 int i, resultado = 1; 
 for (i = 0; i < n; i++) { 
 resultado = resultado * n;} 
 n = resultado; 
 return n; 
} 
 
Copia al entrar en la función 
Introducción a la programación en C 16 
Funciones 
Contenido 
10 
????? 
10000000000 
Nombre 
variable 
9 
10000000000 
int i=10; 
int resultado; 
 
main () {… 
 
 resultado = elevaASiMismo(i); 
 printf ("%d elevado a si mismo 
 es %d", i, resultado); 
} 
 
 
int elevaASiMismo (int n) { 
 int i, resultado = 1; 
 for (i = 0; i < n; i++) { 
 resultado = resultado * n;} 
 n = resultado; 
 return n; 
} 
 
global_i 
global_resultado 
elevaASiMismo_n 
elevaASiMismo_i 
elevaASiMismo_ 
 resultado 
Introducción a la programación en C 17 
Funciones 
Contenido 
10 
10000000000 
elevaASiMismo_n 
Nombre 
variable 
elevaASiMismo_i 
10000000000 
9 
100 elevaASiMismo_ 
 resultado 
return copia valor 
int i=10; 
int resultado; 
 
main () {… 
 
 resultado = elevaASiMismo(i); 
 printf ("%d elevado a si mismo 
 es %d", i, resultado); 
} 
 
 
int elevaASiMismo (int n) { 
 int i, resultado = 1; 
 for (i = 0; i < n; i++) { 
 resultado = resultado * n;} 
 n = resultado; 
 return n; 
} 
 
global_i 
global_resultado 
Introducción a la programación en C 18 
Funciones 
 A veces quiero que la función PUEDA CAMBIAR el 
valor de la variable que utilizo al llamarla 
 Porque quiero que la función devuelva varios resultados 
(y no sólo uno, como permiten las funciones de C en 
general) 
 Porque quiero que devuelva algún resultado complejo, y 
las funciones sólo pueden retornar tipos sencillos (int, 
float…) 
 Para esto utilizo PUNTEROS 
 Los punteros también se utilizan para más cosas 
(estructuras de datos complejas como listas enlazadas, 
etc.), … 
 En nuestro proyecto sólo los utilizaremos para 
pasar/retornar valores al llamar a funciones 
Introducción a la programación en C 19 
Punteros 
 Para cualquier tipo T, podemos formar un ‘puntero a (tipo T)’ 
 El valor del puntero es la primera dirección de la zona de memoria 
que ocupa la variable de tipo T 
 Ejemplos de declaraciones de punteros: 
 int *i; 
 char *x; 
 Operadores de punteros: 
* puntero 
 obtiene el valor de un puntero (retorna el 
 valor al que apunta el puntero) 
& variable 
 obtiene la dirección de una variable (retorna la 
 primera dirección de memoria de la posición en la que 
 está almacenada una variable – 
 la variable no tiene por qué ser un puntero, y en 
 general no lo es) 
Introducción a la programación en C 21 
Punteros 
int res; 
int *y; 
int x; 
 
x = 4; 
y = &x; 
res = *y+1; /* da 5*/ 
 
x++; 
res = *y+1 /* da 6 */ 
 
Dirección 
0x300 
0x304 
Contenido 
0x308 
4 
0x300 
No usado 
x 
y 
res 5 
Estado en este punto 
Nombre 
variable 
Para los ejemplos, supongo que valores int y punteros 
ocupan todos 4 bytes. Esto no tiene por qué ser así. 
Introducción a la programación en C 22 
Punteros y Arrays 
 Un identificador de un array es equivalente a un puntero que 
apunta al primer elemento del array 
int array[5]; 
int *ptr; 
ptr = &array[0] es equivalente a ptr = array; 
 Si una función se define como 
int func (int *ptr_dato); 
Entonces también vale llamarla con func(array); 
 Aritmética de punteros y arrays 
 array[2] es igual que *(ptr + 2), 
 El compilador asume que (ptr+2) significa apuntar a 2 objetos del tipo 
de lo apuntado (int) más allá de ptr 
Introducción a la programación en C 23 
void * 
 void * es un tipo de datos especial que no 
admite 
 el operador * 
 ni la aritmética de punteros 
Símplemente, apunta a un sitio 
 Puedo aplicar aritmética de punteros si ‘fuerzo’ un 
tipo al puntero 
 A esto se le llama hacer un cast 
 
void * punt_void; 
int * numero; 
punt_void = 0x…; /* apunto a una dirección */ 
numero = (int *) punt_void + 2; 
/* apunta a un espacio ‘dos enteros después’ del espacio 
inicial punt_void */ 
 
Introducción a la programación en C 24 
¡Cuidado con los punteros! 
 Valores apuntados inesperados 
 En C, al definir una variables lo que se hace es reservar una zona de 
memoria para la variable 
 Pero NO se borra el contenido de la variable 
 Puede haber valores previos (distintos de 0) 
 Punteros a zonas erráticas 
 Cuando definimos un puntero, el puntero puede tener un valor 
 Puede apuntar a una zona de memoria reservada para otra cosa, o 
 A una zona de memoria que está prohibida para la aplicación
 Si accedemos en Linux, vemos error ‘Segmentation fault’ (o ‘Violación de 
segmento’) 
 Entonces, es mala práctica hacer 
int *puntero; 
*puntero = 3; /* escribo un 3… ¡no sé en dónde! */ 
 Precaución: Valor especial de un puntero: NULL (ó 0 ) 
 Indica que el puntero todavía no está apuntado a nada 
 Útil porque… Puedo preguntar al puntero si está apuntando válidamente a algún sitio 
o no 
if (puntero == NULL) … 
 Si se referencia (*), da error ‘Segmentation fault’ 
 Al menos, está claro cuál es el problema 
 (pero cuando declaras un puntero… NO se inicializa como NULL – hay que hacerlo 
explícitamente, si se desea) 
Introducción a la programación en C 25 
Punteros 
 Hay que apuntar el puntero a una zona de memoria que esté 
asociada de forma única con el uso que queremos dar al puntero 
 Dos formas 
 Declaro variable (creo el espacio) y apunto puntero a variable 
int a; 
int *ptrInt; 
ptrInt = &a; 
*ptrInt = 7; /* lo escribe en el espacio de la variable ‘a’ */ 
 
 Crear espacio de memoria dinámica, utilizando llamada al SO: 
 malloc (void *malloc(size_t size) ); 
 Ejemplo 
char *ptrChar; 
ptrChar = (char *) malloc (10); /* crea espacio para guardar 10 
caracteres */ 
 
 La memoria dinámica hay que eliminarla antes de terminar el programa (no se 
elimina automáticamente) 
 free (ptrChar); 
 La memoria dinámica permite definir en tiempo de ejecución espacio de memoria 
(~ variables) para ser usado por el programa 
 (char *) es un cast – una conversión de tipos explicitada por el programador 
 “compilador, hazme caso porque sé lo que estoy haciendo, supón que el void * 
que devuelve malloc en realidad es un char *” 
• Si no hago el cast, el compilador genera un warning 
• NO queremos warnings 
Introducción a la programación en C 26 
Tamaños de variables 
 A veces necesitamos conocer el tamaño de un tipo o una variable: 
operador sizeof() 
tamano = sizeof(int); 
 ¡Puede variar según el equipo! (4, 8…) 
tamano = sizeof (struct xxx); 
 Devuelve el tamaño ocupado por una estructura struct xxx que 
habremos definido antes 
 
char buffer_1[100]; 
tamano = sizeof(buffer_1); 
 Devuelve 100 
char * buffer_2; 
buffer_2 = malloc(100); 
tamano = sizeof (buffer_2); 
 Devuelve…4 bytes, ¡el tamaño del puntero! 
 sizeof no funciona aquí como esperábamos, porque es un operador que se 
aplica en tiempo de compilación (y el tamaño de buffer_2 se define en 
tiempo de ejecución) 
 ¡Cuidado en su código con esto! 
Introducción a la programación en C 27 
Copiando memoria 
#include <string.h> 
 
void *memcpy(void *dest, const void *orig, size_t n); 
 Copia n bytes contando a partir de posición de memoria apuntada 
por orig a posición de memoria apuntada por dest 
 Devuelve un puntero a dest 
 El modificador const de const void * orig indica que la 
función NO cambia nada en las posiciones de memoria apuntadas 
por orig (el compilador asegura esto) 
 
char *strcpy(char *dest, const char *orig); 
 Espera un string: copia hasta que encuentra un ‘\0’ 
 ¡Bastante distinto a memcpy! 
 
Introducción a la programación en C 28 
Estructuras 
 Forma de definir variables que tienen diferentes partes (diferentes 
componentes) 
struct servicio {int direccion, short int puerto}; 
struct servicio web; /* variable de tipo struct servicio 
*/ 
web.direccion = 0xA3758B80; /* 163.177.139.128 en un 
entero de 32 bits, en formato hexadecimal */ 
web.puerto = 80; 
 
 Y con punteros 
struct servicio *ptrServicio; 
ptrServicio = &web; 
if ( (ptrServicio ->puerto) == 80) {ptrServicio->puerto 
= 8080;} /*cambia a https */ 
 
 Nota (prtServicio -> puerto) es una abreviatura C de 
((*ptrServicio).puerto) 
 Las funciones que manipulan estructuras declaran como 
parámetros punteros a la estructura 
Introducción a la programación en C 29 
Estructuras 
 C permite ‘tocar’ los bits 
 
typedef struct { 
 unsigned int version:2; /* protocol version */ 
 unsigned int p:1; /* padding flag */ 
 unsigned int x:1; /* header extension flag */ 
 unsigned int cc:4; /* CSRC count */ 
 unsigned int m:1; /* marker bit */ 
 unsigned int pt:7; /* payload type */ 
 unsigned int seq:16; /* sequence number */ 
 u_int32 ts; /* timestamp */ 
 u_int32 ssrc; /* synchronization source */ 
} rtp_hdr_t; 
 
 
rtp_hdr_t miCabecera; /* si no hubiera utilizado typedef, tendria 
 que haber declarado esta variable como 
 struct rtp_hdr_t miCabecera; */ 
miCabecera.version = 2; 
miCabecera.pt = 8; /* payload type 8 */ 
… 
Introducción a la programación en C 30 
Pasando parámetros por referencia 
struct tiempo { 
 int segundos, 
 int miliseg }; 
 
main () { … 
 struct tiempo tiempoAhora; 
 tomaTiempo (&tiempoAhora); 
} 
 
void tomaTiempo (struct tiempo 
 *ptrTiempo) 
{ 
 (*ptrTiempo).segundos = 
 /* accedo a hw…*/; 
 (*ptrTiempo).miliseg = /*…*/ 
} 
 
 
Direc 
0x300 
0x304 
Contenido 
0x308 
??? 
??? 
main_tiempoAhora 
Nombre 
variable 
Introducción a la programación en C 31 
Pasando parámetros por referencia 
struct tiempo { 
 int segundos, 
 int miliseg }; 
 
main () { … 
 struct tiempo tiempoAhora; 
 tomaTiempo (&tiempoAhora); 
} 
 
void tomaTiempo (struct tiempo 
 *ptrTiempo) 
{ 
 (*ptrTiempo).segundos = 
 /* accedo a hw…*/; 
 (*ptrTiempo).miliseg = /*…*/ 
} 
 
 
Direc 
0x300 
0x304 
Contenido 
0x308 
??? 
??? 
main_tiempoAhora 
Nombre 
variable 
0x300 tomaTiempo_ 
 ptrTiempo 
Introducción a la programación en C 32 
Pasando parámetros por referencia 
struct tiempo { 
 int segundos, 
 int miliseg }; 
 
main () { … 
 struct tiempo tiempoAhora; 
 tomaTiempo (&tiempoAhora); 
} 
 
void tomaTiempo (struct tiempo 
 *ptrTiempo) 
{ 
 (*ptrTiempo).segundos = 
 /* accedo a hw…*/; 
 (*ptrTiempo).miliseg = /*…*/ 
} 
 
 
Direc Contenido 
2078 
??? 
main_tiempoAhora 
Nombre 
variable 
0x300 tomaTiempo_ 
 ptrTiempo 
(*ptrTiempo).segundos 
(*ptrTiempo).miliseg 
Introducción a la programación en C 33 
Pasando parámetros por referencia 
struct tiempo { 
 int segundos, 
 int miliseg }; 
 
main () { … 
 struct tiempo tiempoAhora; 
 tomaTiempo (&tiempoAhora); 
} 
 
void tomaTiempo (struct tiempo 
 *ptrTiempo) 
{ 
 (*ptrTiempo).segundos = 
 /* accedo a hw…*/; 
 (*ptrTiempo).miliseg = /*…*/ 
} 
 
 
Direc Contenido 
2078 
389 
main_tiempoAhora 
Nombre 
variable 
0x300 tomaTiempo_ 
 ptrTiempo 
Introducción a la programación en C 34 
Ejemplo de aritmética de punteros 
 Supongamos que queremos construir un paquete RTP para ser 
enviado: necesito una zona de memoria consecutiva en la que 
 Los 12 primeros bytes sean la cabecera RTP 
 Los 128 (por ejemplo) siguientes bytes sean datos de audio 
 
 
void * paquete; 
rtp_hdr_t *cabeceraRTP; 
char * datosAudio; 
 
 
 
paquete = malloc (140); 
cabeceraRTP = (rtp_hdr_t *) paquete; 
(*cabeceraRTP).version = 2; 
 /* relleno cabecera… */ 
datosAudio = ((char *) paquete) + sizeof (rtp_hdr_t); 
 /* copio datos o llamo a read(…, datosAudio,…) 
 
 
 
 
 
NO 
sizeof(cabeceraRTP) 
Introducción a la programación en C 35 
Ejemplo de aritmética de punteros 
void * paquete; 
rtp_hdr_t *cabeceraRTP; 
char * datosAudio; 
 
paquete = malloc (140); 
cabeceraRTP = (rtp_hdr_t *) 
paquete; 
(*cabeceraRTP).version = 2; 
/* relleno cabecera… */ 
datosAudio = ((char *) paquete) 
+ sizeof (rtp_hdr_t); 
/* copio datos o llamo a read(…, 
datosAudio,…)
Direc Contenido 
main_cabeceraRTP 
Nombre 
variable 
??? 
??? 
main_paquete 
main_datosAudio 
0x100 
0x100 
Introducción a la programación en C 36 
Ejemplo de aritmética de punteros 
void * paquete; 
rtp_hdr_t *cabeceraRTP; 
char * datosAudio; 
 
paquete = malloc (140); 
cabeceraRTP = (rtp_hdr_t *) 
paquete; 
(*cabeceraRTP).version = 2; 
/* relleno cabecera… */ 
datosAudio = ((char *) paquete) 
+ sizeof (rtp_hdr_t); 
/* copio datos o llamo a read(…, 
datosAudio,…) 
 
 
Direc Contenido 
main_cabeceraRTP 
Nombre 
variable 
0x100 
??? 
main_paquete 
main_datosAudio 
0x100 
0x100 
2 
*cabeceraRTP 
Introducción a la programación en C 37 
Ejemplo de aritmética de punteros 
void * paquete; 
rtp_hdr_t *cabeceraRTP; 
char * datosAudio; 
 
paquete = malloc (140); 
cabeceraRTP = (rtp_hdr_t *) 
paquete; 
(*cabeceraRTP).version = 2; 
/* relleno cabecera… */ 
datosAudio = ((char *) paquete) 
+ sizeof (rtp_hdr_t); 
/* copio datos o llamo a read(…, 
datosAudio,…) 
 
 
Direc Contenido 
main_cabeceraRTP 
Nombre 
variable 
0x100 
0x10B 
main_paquete 
main_datosAudio 
0x100 
0x100 
2 
0x10B 
char * es como decir 
‘puntero a byte’ 
Introducción a la programación en C 38 
printf 
 Permite combinar ‘texto fijo’ con variables 
 Indicación de sustituir por una variable 
 %d - variable de tipo entero, imprimir en formato 
decimal 
 %s - variable de tipo string (char *, terminado por un 
caracter ‘\0’) 
 Más formatos disponibles (ver man 3 printf) 
printf ("Volumen de reproducción: %d. 
Numero de bits por muestra: %d", vol, 
bits); 
 Numero variable de argumentos, pero 
 Tiene que haber tantas %_ como variables 
 El tipo indicado en %_ tiene que corresponderse con el 
de la variable ‘que le toca’ 
 Si hay variables ‘char *’, tienen que ser cadenas de 
caracteres, es decir, terminar en ‘\0’ 
Introducción a la programación en C 39 
Generando un ejecutable 
 Utilizaremos la herramienta gcc (GNU C Compiler) 
 En realidad, son varias herramientas: 
 Compilador: coge 1 fichero .c y lo convierte en 1 fichero .o que está en formato 
‘código objeto’ 
 También ejecuta un preprocesador: sustituye #include… 
 Enlazador: coge uno o varios ficheros .o y los junta en 1 ejecutable (posiblemente, 
juntando código de otras funciones del sistema – printf, exit, open…) 
 El ejecutable no suele llevar extensión 
 Por motivos de seguridad, el ejecutable lo deberá invocar como 
 ./nombreEjecutable 
 Al compilar, gcc tiene que entender todos los términos que 
aparezcan en el programa 
 O son variables definidas, o funciones definidas dentro o en un #include… 
 Al enlazar, gcc tiene que encontrar el código (.o o .so) de todas 
las funciones utilizadas 
 Parte de este código (el de printf, exit, open…) está en ‘librerías’ 
 P.ej, printf está en glibc (/usr/lib…/libc-2.13.so) 
 Si está en glibc, no tengo que decir nada al compilador 
 Si está en otra librería, tengo que decirle el nombre de la librería 
 Ejemplo: log está en libm. Al compilador hay que decirle –lm (= "enlaza con 
libm") 
 
Introducción a la programación en C 40 
Escribiendo código 
 Puede escribir su código en varios ficheros 
 Facilita que varias personas trabajen en el mismo programa 
 En su caso, yo doy varios ficheros hechos! 
 Facilita reutilizar código 
 Se puede utilizar fácilmente algunas funciones en otros programas 
 Permite estructurar mejor el código 
 Cuando se utilizan varios ficheros 
 En *.h se ponen la declaración de las funciones 
 Se pueden definir tipos, constantes… siempre que sean importantes para otros 
ficheros que vayan a utilizar estas funciones 
 En *.c se pone la cabecera de la función (otra vez)… y el código que lo 
hace (de verdad) 
 Si un fichero uno.c utiliza funciones de otro dos.c, uno.c tiene que tener 
un #include dos.h 
 Puede compilar cada .c por separado 
gcc –c fichero.c -- genera un fichero.o 
 Sólo puede haber 1 main entre todos los ficheros 
 Cuando están todos los .o disponibles, se pueden enlazar en un ejecutable 
gcc –o ejecutable fich1.o fich2.o fich3.o … 
 
Introducción a la programación en C 41 
Compilando 
 Usuarios avanzados utilizan make 
 Pero NO merece la pena ‘pegarse’ con él 
 
Alternativa 
 Cree un fichero compila que contiene una línea 
gcc –o audioSimple audioSimple.c audioSimpleArgs.c 
configureSndcard.c … -Wall -lm 
 Todos los .c que necesita 
 -Wall: chequeo más estricto 
 -lm: enlazar con librería matemática 
 En audioSimple no hace falta, pero puede hacerle falta; no hace daño 
 Ejecute 
# chmod 755 compila 
 Cada vez que quiera compilar, 
# ./compila 
Introducción a la programación en C 44 
Si quiero utilizar una función 
‘estándar’… 
 ¿cómo sé qué argumentos toma y que valores 
devuelve? 
 ¿cómo sé qué fichero tengo que incluir? 
 Ejecutar ‘man funcion’ 
 man exp 
 También se detalla 
cómo se usa la 
función 
Introducción a la programación en C 45 
Sobre #include 
 Si se quiere incluir una cabecera estándar, 
utilizar 
#include <cabecera.h> 
 El compilador sabe en qué directorios buscar estas 
cabeceras 
 Si se quiere incluir una cabecera desarrollada 
por nosotros 
#include "cabecera.h" 
 Si está en el mismo directorio que el fichero que lo 
incluye 
#include "/home/…/cabecera.h" 
 Si está en otro directorio que el fichero que lo incluye 
 
Introducción a la programación en C 46 
Capturando argumentos de la línea de 
comandos 
 ¿Cómo sabe el programa que al llamar a conf 
utilicé los argumentos second –y11 
163.117.144.10? 
 C dice que en la función main se define como 
int main (int argc, char *argv[]) 
 ‘mágicamente’, cuando el código se ejecute, en la 
variable argc y argv está la información para 
recuperar los argumentos 
 No damos valor a estas variables, sino que el valor sale 
de ‘la ejecución’ 
Introducción a la programación en C 47 
Capturando argumentos de la línea de 
comandos 
 ESTO NO LO TENEIS QUE HACER VOSOTROS 
 Ya lo damos hecho (pero…) 
 La función main está declarada como 
 
 int main (int argc, char *argv[]) { ... } 
 
 
 Tipo de argv se ‘lee’ aplicando la regla de ‘apretar el tornillo’ 
 Declaraciones complejas se pueden analizar con herramienta cdecl (o en web 
http://www.lemoda.net/c/cdecl/ 
$ cdecl explain char *argv[] 
declare argv as array of pointer to char 
 aunque main también se puede utilizar como 
 int main (void) 
 C es muy estricto con las declaraciones… ¡salvo con las de main! 
 El intérprete de la línea de comandos deja en 
 argc el número de argumentos del comando 
 argv un puntero a un array de punteros a strings 
 argv[0] es el nombre de programa, con que argc es siempre al menos 1. 
 
http://www.lemoda.net/c/cdecl/
Introducción a la programación en C 48 
Capturando argumentos de la línea de 
comandos 
./audiosimple play –v100 music 
argc = 4, 
argv = <direcc 0> 
‘a’‘u’‘d’‘i’‘o’‘S’‘i’‘m’‘p’‘l’‘e’‘\0’ 
argv: 
[0] <dir 1> 
[1] <dir 2> 
[2] <dir 3> 
[3] <dir 4> 
[4] NULL 
‘-’‘v’‘1’‘0’‘0’‘\0’ 
‘p’‘l’‘a’‘y’‘\0’ 
‘m’‘u’‘s’‘i’‘c’‘\0’ 
Introducción a la programación en C 49 
Ejercicio: compilar práctica 0 
 Analizar el código de los ficheros 
audioSimpleArgs.h y audioSimpleArgs.c 
__MACOSX/Parte1/._01.5 - programación en C.pdf
Parte1/02-programacion - parte 1.pdf
Técnicas de 
programación de 
software 
multimedia 
(parte 1) 
Técnicas de programación de sw multimedia 2 
Acceso a los dispositivos en Linux 
 Abstracción común para los dispositivos en Linux 
(Unix): los dispositivos aparecen como ficheros 
 En /dev/… 
 Nota: algunos dispositivos
también pueden ser accesibles a 
través de APIs (posiblemente con “más capacidades” o “más 
fácilmente” que con el interfaz de ficheros) 
 Los ficheros tienen unas operaciones comunes: 
 open, close 
 read, write 
 ioctl 
 La semántica de las operaciones se adapta a cada dispositivo 
 Pensar en disco duro, línea serie, control de un LED, … tarjeta 
de sonido 
Técnicas de programación de sw multimedia 3 
Tarjeta de sonido 
Output Mixer Input Mixer 
Conversor D/A Conversor A/D 
Sintetizador FM CD-ROM 
Bus 
/dev/dsp 
/dev/sequencer /dev/cdrom 
/dev/dsp 
/dev/dsp (o /dev/mixer) 
 
/dev/dsp (o /dev/mixer) 
analógico 
analógico 
analógico 
digital 
Técnicas de programación de sw multimedia 4 
Tarjeta de sonido (para nosotros) 
Output Mixer Input Mixer 
Conversor D/A Conversor A/D 
/dev/dsp /dev/dsp 
/dev/dsp (o /dev/mixer) 
/dev/dsp (o /dev/mixer) 
Técnicas de programación de sw multimedia 5 
Referencias para programación de tarjeta 
de sonido 
Referencia para programar tarjeta de sonido 
según API de OSS (Open Sound System): 
http://www.4front-tech.com/pguide/index.html 
 
Definiciones en fichero soundcard.h 
 Ejecuta locate soundcard.h para saber dónde 
está 
 
Técnicas de programación de sw multimedia 7 
Dispositivo /dev/dsp 
 /dev/dsp: conversión analógica/digital 
(muestreo y cuantificación) y digital/analógica 
 Generalmente hay UN dispositivo en un equipo 
 Sólo puede tenerlo abierto UN programa a la vez 
 Programas que lo necesitan esporádicamente lo abren, 
lo usan, y lo cierran inmediatamente 
 read obtiene datos del conversor analógico/digital 
(= graba datos) 
 write vuelca datos en el conversor 
digital/analógico ( = reproduce datos) 
Técnicas de programación de sw multimedia 8 
Dispositivo /dev/dsp 
 ioctl a /dev/dsp permite configurar los parámetros básicos de 
funcionamiento de la tarjeta 
 Frecuencia de muestreo (8000 Hz, 44100 Hz) 
 Número de canales (1, 2, 5.1) 
 Formato de la muestra para cada canal 
 Número de bits por muestra (8 o 16 bits) 
 Tipo de codificación (uniforme o con algún tipo compresión) 
 Puede hacerse por software o por hardware 
 
 
 
 
 
 
 
 
 
 
 
 Los parámetros usados al ejecutar read o write son los últimos 
configurados en el dispositivo /dev/dsp 
 = la tarjeta de sonido mantiene estado 
 
Lógica hardware 
de 32 bits 
16 bits 16 bits 
 Ejemplo de grabación 
de dos canales de 16 
bits cada uno 
 0111000011011011 0001110000101011 
 
Técnicas de programación de sw multimedia 9 
Fragmentos 
 La tarjeta dispone de una zona de memoria 
interna 
 Esta memoria está gestionada en bloques de igual 
tamaño llamados “fragmentos” 
 El tamaño del fragmento es configurable, aunque debe 
ser potencia de 2 
128, 256, 512 … bytes 
 Interesante configurar explícitamente el tamaño de 
los fragmentos si trabajamos con select y la 
aplicación es sensible a los bloqueos 
Técnicas de programación de sw multimedia 10 
Bloqueos en la tarjeta de sonido 
 
 Lectura (read) esporádica: el proceso solicitante se 
bloquea hasta obtener la cantidad de datos 
correspondiente al un número de fragmentos necesarios 
para obtener esa cantidad de datos 
 No hasta obtener los datos, sino más (si el fragmento > datos 
solicitados)! 
 Mínimo tiempo de bloqueo si el número de datos que se solicita 
en el read es igual que el tamaño del fragmento 
read(256) 
fragmento 256 bytes 
proceso bloqueado 
read(256) 
fragmento 256 bytes 
programa 
 Kernel (driver tarjeta…), 
otras tareas… 
tarjeta de sonido 
Interrupción (hw) Interrupción (hw) 
Retorna read(256) Retorna read(256) 
Técnicas de programación de sw multimedia 11 
Bloqueos en la tarjeta de sonido 
 Lectura si el tamaño solicitado es distinto del tamaño del 
fragmento 
 Ej: tamaño de fragmento = 128 bytes. 
 Se solicita lectura de 230 bytes 
 Tarjeta bloquea durante el tiempo necesario para leer 2 fragmentos de 
128 bytes (=256 bytes, potencia de 2 inmediatamente superior a 230 
bytes) 
 La operación de lectura devuelve 230 bytes 
read(230) 
fragmento 128 bytes 
proceso bloqueado 
programa 
 Kernel (driver tarjeta…), 
otras tareas… 
Interrupción (hw) 
Tiempo requerido para 230 bytes 
Retorna read(230) 
tarjeta de sonido 
Técnicas de programación de sw multimedia 12 
Bloqueos en la tarjeta de sonido 
 No obstante, si la lectura es frecuente, y la cantidad de datos 
solicitados es menor que un fragmento, la tarjeta devuelve datos 
que habían sido leídos con anterioridad 
 Ej: fragmento 256 bytes, lecturas (read) que solicitan 128 bytes 
 En este caso, algunas lecturas no son bloqueantes 
 No obstante, conviene evitar este funcionamiento: para el tipo de 
aplicaciones que queremos, introduce un retardo indeseado (algunas 
lecturas de 128 bytes tardan como leer 256) 
read(128) 
fragmento 256 bytes 
proceso bloqueado 
read(128) 
fragmento 256 bytes 
programa 
 Kernel (driver tarjeta…), 
otras tareas… 
Interrupción (hw) Interrupción (hw) 
read(128) – no bloquea y recibe 
 datos leídos justo antes 
Retorna read(128) 
tarjeta de sonido 
Lectura frecuente 
Técnicas de programación de sw multimedia 13 
Bloqueos en la tarjeta de sonido 
 La escritura es no bloqueante: mientras haya 
memoria suficiente en la tarjeta de sonido 
 La escritura es bloqueante si la memoria de la 
tarjeta de sonido asociada a escritura está 
llena, en cuyo caso bloquea 
 El proceso se desbloquea cuando hay memoria 
suficiente para almacenar los datos de la solicitud 
de escritura 
 
Técnicas de programación de sw multimedia 14 
Modo dúplex 
 Modo Dúplex: 
 La tarjeta puede grabar y reproducir A LA VEZ 
 
 
 
 
 
 
 
 
 Ej: el código puede hacer un read e inmediatamente después 
un write… y la tarjeta graba y reproduce simultaneamente 
 Nota: si el ‘ancho’ del conversor A/D, D/A es de 32 bits, cada 
sentido sólo puede disponer de 16 bits, limitando las opciones 
a 
 1 canal de 16 bits 
 2 canales de 8 bits 
Lógica de 32 bits 
16 bits 16 bits 
 0111000011011011 0001110000101011 
 
Técnicas de programación de sw multimedia 20 
/* Truco de programación */ 
 Comprobar siempre resultados de llamadas al Sistema 
Operativo 
 ¡pueden haber salido mal! 
 Habitualmente, las llamadas que salen mal devuelven -1 
 Leer siempre la página de manual de la llamada, para ver cómo se 
codifica el éxito o fallo en la llamada al SO (si devuelven un 
puntero, el error se notifica devolviendo NULL) 
 Automatizando el chequeo del éxito en llamadas al SO 
 Macro C que comprueba si una llamada al SO devuelve -1 => 
mensaje de error y detiene la ejecución de la función 
 #define CALL(v,m) {if ( (v)==-1) {perror (m); 
printf (“Error number: %d, %s\n", errno, strerror 
(errno)); exit (1); }}; 
 Ejemplo de uso 
 CALL (callX (argumento1, argumento2..), “La 
llamada a callX fracasó después de haberse 
ejecutado…”); 
Técnicas de programación de sw multimedia 21 
Configurando parámetros 
 int ioctl_arg; /* argumentos para ioctl */ 
 
 /* abrimos dispositivo de audio */ 
 CALL ( 
 (descSnd = open("/dev/dsp", O_RDWR), 
 "Fallo en apertura de /dev/dsp“ 
 ); 
 
 /* fijar parametros de muestreo */ 
 ioctl_arg = formato; 
 /* Ej: 8 es PCM (con cuantificación lineal de 8 bits); 
 16 es PCM con 16 bits little endian con signo; 
 ver /usr/include/linux/soundcard.h para más posibilidades */ 
CALL( 
 ioctl(descSnd, SNDCTL_DSP_SETFMT, &ioctl_arg), 
 “Fallo en establecimiento del formato de grabac/reproduc” 
 ); 
 if (ioctl_arg != formato) 
 perror("Imposible seleccionar codificación pedida"); 
¡Comprobar si la tarjeta hizo
lo que se le pedía! 
Técnicas de programación de sw multimedia 22 
Configurar parámetros conversión A/D y D/A: ioctl… 
 SNDCTL_DSP_SETFMT – número de bits por muestra y 
codificación (ver soundcard.h para qué codificaciones) 
 SNDCTL_DSP_CHANNELS – número de canales 
 SNDCTL_DSP_SPEED – frecuencia de muestreo 
 
Duplex: CALL (ioctl (descSnd, SNDCTL_DSP_SETDUPLEX, 
0), "Fallo al poner la tarjeta de sonido en 
modo DUPLEX"); 
 
Configurando el volumen 
 CALL (ioctl (descSnd, MIXER_WRITE (SOUND_MIXER_MIC), 
&volFinal), "Fallo en onfiguración volumen del microfono"); 
 volFinal: 8 bits más signif= canal derecho / 8 menos significativos canal izquierdo 
 
 CALL (ioctl (descSnd, MIXER_WRITE (SOUND_MIXER_PCM), 
&volFinal), "Fallo en configuración volumen de la salida"); 
 
Programando la tarjeta de sonido 
Técnicas de programación de sw multimedia 23 
Programando la tarjeta de sonido: 
tamaño de fragmento 
 Ajustar el tamaño del fragmento al tiempo de respuesta 
requerido por la aplicación 
 La llamada al ioctl que ajusta el tamaño de los fragmentos 
tiene que hacerse ANTES de otros ioctls, read, write… 
 Si se quiere cambiar el tamaño del fragmento, hay que cerrar y 
abrir otra vez el dispositivo 
 Datos: requestedFragmentSize es el número de bytes que 
se quieren manejar en la tarjeta. 
Código obtiene tamaño en bytes que es potencia de 2 
inmediatamente inferior al solicitado (función logaritmo). 
Configura tarjeta para que el fragmento sea de ese tamaño 
 Es decir, 
 Si queremos tamaño de fragmento 32, hay que utilizar 5 como argumento 
 Tamaño de fragmento 64, hay que utilizar 6 como argumento 
 Tamaño de fragmento 43… tendremos que poner 5, y el tamaño de 
fragmento real será 32 (argumento=5) 
Referencia: http://www.4front-tech.com/pguide/audio2.html 
Técnicas de programación de sw multimedia 24 
Programando la tarjeta de sonido 
void configSndcard (int *descSnd, struct structSndQuality *datosQosSnd, int 
*requestedFragmentSize) { 
unsigned int frgmArg, requestedFrgmArg; /* local variables for fragment conf */ 
/* Argument to construct: 0xMMMMSSSS , being MMMM fragments (MMMM=number of 
fragments) of size 2^SSSS (SSSS= log2 of the size of the fragments. 
We set the size of the fragments, and we do not request anything about the number of 
fragments */ 
requestedFrgmArg = floor_log2 (*requestedFragmentSize); /* floor_log2 is defined at 
the end of this file. Sets ‘SSSS’ part of fragment argument */ 
 
requestedFrgmArg = requestedFrgmArg | 0x7FFF0000 ; /* this value is used to request 
the soundcard not to limit the number of fragments available. Sets ‘MMMM’ part of 
fragment argument */ 
 
frgmArg = requestedFrgmArg ; 
CALL (ioctl ( (*descSnd), SNDCTL_DSP_SETFRAGMENT, & frgmArg ), "Failure when setting 
the fragment size\n"); 
if (frgmArg != requestedFrgmArg ) 
 { printf ("Fragment size could not be set to the requested value: requested argument was %d, 
resulting argument is %d\n", requestedFrgmArg, frgmArg); exit (-1);} 
/* returns configured fragment value, in bytes, so it performs 2^frgmArg by shifting 
one bit the appropriate number of times */ 
* requestedFragmentSize = 1 << frgmArg; /* returns actual configured value of the 
fragment size, in bytes*/ 
} 
Referencia: http://www.4front-tech.com/pguide/audio2.html 
Técnicas de programación de sw multimedia 25 
Programando la tarjeta de sonido: datos 
en el buffer de escritura 
int bytes; 
 
ioctl(soundcard, SNDCTL_DSP_GETODELAY, 
&bytes); 
 
 Indica el número de bytes que quedan por 
reproducir en la tarjeta de sonido en el 
momento en el que se hace la llamada 
Convertir en segundos= 
bytes / (sample_rate * num_of_channels * 
sample_size_in_bytes) 
Técnicas de programación de sw multimedia 27 
Reproductor/Grabador de Audio 
fich = open (“FicheroAudio”,... 
tarjeta = open (“/dev/dsp”, ... 
 
while ( ) { 
 numLecturas = read (fich, datos, 
4096); 
 numEscrituras= write (tarjeta, 
 datos, 4096); 
} 
audioSimple play / record ... (bits, 
estereo, duración, frecuencia ...) 
Buffer 
En la página de web hay un programa sencillo para grabar y 
reproducir audio (ver Práctica 0) 
__MACOSX/Parte1/._02-programacion - parte 1.pdf
Parte1/03-practica_conf.pdf
Introducción a la práctica: 
conf 
Introducción a las prácticas de SMA 2 
Prácticas introductorias 
 Práctica 0: probar herramientas básicas para el 
desarrollo de las siguientes prácticas 
 Sobre todo, LEER transparencias de programación, y 
código 
 Familiarizarse con el funcionamiento y programación de 
la tarjeta de sonido 
 Práctica 1: pruebas más exhaustivas de 
funcionamiento de la tarjeta de sonido 
 Ejemplo de cómo analizar el comportamiento de un 
dispositivo o herramienta de programación 
 
 Ni Práctica 0 ni Práctica 1 generan ningún resultado 
evaluable 
Introducción a las prácticas de SMA 3 
Aplicación conf 
Aplicación de audioconferencia 
 Tarjeta de sonido en modo duplex 
 Dos modos en la aplicación para permitir el inicio de 
comunicación 
 Modo first (primero – en ser arrancado desde la línea de 
comandos), espera a recibir datos de algún nodo (no tiene por 
qué conocer su dirección). 
 Cuando recibe el primer dato, “aprende” qué dirección IP tiene 
su interlocutor, y le empieza a enviar a datos 
 Modo second (segundo), directamente datos a una dirección 
especificada en la línea de comandos 
 Podría ser utilizada en entorno multicast 
 Aunque cada aplicación está preparada para tener sólo un 
vecino 
 ¡No se puede utilizar TCP! 
Introducción a las prácticas de SMA 4 
Aplicación conf 
 Dos formas de arrancar first y second 
 Comunicación unicast 
equipo1> ./conf first 
equipo2> ./conf second 163.117... 
 First escucha en multicast 
equipo1> ./conf first –m227.1… 
equipo2> ./conf second 227.1… 
conf, escucha en dir unicast 
conf, escucha 
en dir multicast 
rtpdump, escucha 
en dir multicast 
Introducción a las prácticas de SMA 5 
Aplicación conf 
 T viene determinado por el formato y el tamaño del 
paquete 
first 
second 
T 
T 
T 
T 
T 
T 
T 
T 
Espera x paquetes (buffer) 
y comienza reproducción 
./conf primero … 
./conf segundo formato 
 tamanho paquete… 
Introducción a las prácticas de SMA 6 
Aplicación conf 
 Es necesario desacoplar 
1. Recepción de paquetes de audio 
2. Reproducción de los paquetes de audio recibidos 
3. Grabación y envío de audio local 
4. Generación y envío de mensajes RTCP 
5. Recepción y tratamiento de mensajes RTCP 
Cualquier retardo en los 3 primeros procesos resulta en un retardo que 
puede hacer que un contenido no se pueda reproducir en su momento 
 Para desacoplar recepción de paquetes y reproducción 
(1 y 2) se utiliza select + buffer circular 
 
Lee paquetes 
de la red y los 
deja en el buffer 
circular 
Lee paquetes 
del buffer 
circular y los 
deja en la tarjeta 
de sonido 
Introducción a las prácticas de SMA 7 
Aplicación conf 
 Su aplicación se debe encargar de construir la 
cabecera RTP en el envío de paquetes 
 Rellena estructura en C 
 Lee los datos de la tarjeta de sonido, y los deja a 
continuación 
 El mensaje resultante es empaquetado con UDP y IP 
 Esta tarea la realiza el SO, a través de la interfaz de 
sockets (haciendo sendto) 
 Puerto estándar para RTP=5004; puerto estándar para 
RTCP=5005 
 La tarjeta de red añade por hardware la cabecera y la 
cola para Ethernet 
RTP Datos (audio) UDP IP Eth. Eth. 
Generado por su código 
Introducción a las prácticas de SMA 8 
Aplicación conf 
 Optimice la reproducción configurando los fragmentos 
de la tarjeta de sonido 
 De esta forma se evitan añadir retardos innecesarios 
 Implemente

Continuar navegando