viernes, 4 de febrero de 2011

Optimización de UMTS para servicios de video streaming

ÍNDICE

1 INTRODUCCIÓN AL PROYECTO

1.1 ASPECTOS MEDIOAMBIENTALES

2 STREAMING EN UMTS

2.1 TIPOS DE SERVICIO
2.2 CÓDECS UTILIZADOS
2.2.1 Códecs para audio y voz
2.2.2 Códecs para Vídeo
2.3 PARÁMETROS DE CALIDAD EN EL VÍDEO
2.4 ANÁLISIS DE CARACTERÍSTICAS DESDE TERMINALES ACTUALES
2.5 SOFTWARE DISPONIBLE PARA TRABAJAR CON VÍDEO PARA TERMINALES MÓVILES
2.5.1 Procedimientos para la codificación
2.6 EJEMPLOS DE CODIFICACIÓN

3 ENTORNO DEL SIMULADOR UMTS

3.1 BREVE DESCRIPCIÓN DEL SIMULADOR UMTS
3.2 SERVICIOS PORTADORES EN UMTS Y QOS
3.3 PRUEBAS INICIALES EN EL ESCENARIO
3.4 VARIACIÓN DEL NÚMERO DE ACK’S Y SU INFLUENCIA EN EL SDU ERROR RATIO Y
DELAY EXPERIMENTADO
3.4.1 Variación de la BLER/SDU Error ratio
3.4.2 Delays experimentados
3.5 VARIACIÓN TIMEOUT DE EXPIRACIÓN Y SU INFLUENCIA EN EL SDU ERROR RATIO Y
DELAY EXPERIMENTADO
3.5.1 Variación de la BLER/SDU Error ratio
3.5.2 Delays experimentados

4 DIFERENCIACIÓN DE LAS IMÁGENES EN EL FLUJO DE VÍDEO

4.1 JUSTIFICACIÓN DEL FILTRAJE VS ANÁLISIS DE LA FUENTE
4.2 ARQUITECTURA DE PROTOCOLOS PARA EL TRANSPORTE
4.2.1 Encapsulado especial meta-data Darwin Streaming Server (DSS)
4.3 DETALLES DE LA IMPLEMENTACIÓN DEL FILTRO
4.4 VERIFICACIÓN DEL FILTRO
4.5 RESULTADOS OBTENIDOS DIFERENCIANDO LOS PAQUETES

5 ADAPTACIÓN DE LAS RABS A UMTS

5.1 ESTADÍSTICAS OBTENIDAS DEL ANÁLISIS DEL STREAMING
5.2 CONFIGURACIÓN DEL SIMULADOR
5.2.1 Escenario de simulación
5.2.2 Generación de tráfico
5.2.3 Configuración de las RABS
5.3 RESULTADOS OBTENIDOS
5.3.1 Resultado referentes al escenario 1
5.3.2 Resultado referentes al escenario 2
5.3.2.1 Sin adaptación de la política de servicio
5.3.2.2 Adaptación de la política de servicio
5.3.3 Resultado referentes al escenario 3
5.3.4 Visión general de los resultados

6 CONCLUSIONES Y LÍNEAS FUTURAS

7 BIBLIOGRAFÍA

I. ANEXO I (FILTRO DE VÍDEO)

I.1. CLASIFICACIÓN DE LOS PAQUETES
I.2. ESTADÍSTICAS DEL FILTRO
I.3. PROGRAMA PRINCIPAL

II. ANEXO II (PROCEDIMIENTO PARA LA COMPARACIÓN DE LA CALIDAD DE DOS
VÍDEOS)

III. ANEXO III (SERVICIOS PORTADORES DE DATOS UMTS)

INTRODUCCIÓN
SERVICIOS PORTADORES DE DATOS EN UMTS
SOPORTE DE VÍDEO EN TERMINALES MÓVILES
ESQUEMA PROPUESTO
MONTAJE EXPERIMENTAL Y RESULTADOS PROVISIONALES

IV. ANEXO IV (ACRÓNIMOS)

atentamente: Julio Belinchón Hernández.

IV. Anexo IV (Acrónimos)

3GPP             Third Generation Partnership Project
AN                  Access Network
AP                  Access Point
BTS                Base Transceiver Station
CRRM            Common Radio Resource Management
CS                  Circuit Switched
DiffServ          Differentiated Services
E2E                End-to-End
EF                  Expedited Forwarding
GERAN          GSM/EDGE RAN
GGSN            Gateway GSN
GPRS            General Packet Radio Service
GSM               Global System for Mobile Communications
GTP                GPRS Tunnelling Protocol
HLR                Home Location Register
IMS                 IP-based Multimedia Services
IEEE               Institute of Electrical and Electronics Engineers
IETF               Internet Engineering Task Force
IntServ            Integrated Services
IP                    Internet Protocol
LAN                Local Area Network
LSA                Link State Advertisement
MAC               Medium Access Control
PDP               Policy Decision Point
PDP               Packet Data Protocol
QoS                Quality of Service
QOSPF          QoS OSPF
QPIM              QoS Policy Information Model
RAN               Radio Access Bearer
RAN               Radio Access Network
RSVP             Resource Reservation Protocol
SDP               Session Description Protocol
SDU               Service Data Unit
SGSN            Serving GSN
SLS                Service Level Specification
SNMP            Simple Network Management Protocol
TE                   Terminal
UE                  User Equipment
UMTS             Universal Mobile Telecommunications System
USIM              User Services Identity Module
UTRAN          UMTS Radio Access Channel
VLR                Visitor Location Register
WG                 Working Group
WLAN            Wireless LAN
WQB              Wireless QoS Broker

Anexo III: Transmisión diferenciada de vídeo MPEG-4 sobre UMTS

Área de interés: Sistemas y Tecnologías de Radiocomunicaciones

Resumen. En este artículo se analiza la sensibilidad de los diferentes tipos de
información que componen un servicio de video streaming MPEG4 (e.g.
descomposición en tramas I y P) y se propone un esquema de transmisión sobre
UMTS basado en la utilización de múltiples servicios portadores (múltiples
contextos PDP) adaptados a los componentes principales de dicho servicio. Dicha
solución permite aumentar considerablemente el número de usuarios de video
streaming en la red frente a la solución habitual de transportar un determinado
servicio a través de un único servicio portador (i.e. contexto PDP) con los
parámetros de QoS adecuados. El estudio se ha realizado con la ayuda de un
emulador de UMTS y herramientas de estimación subjetiva de la calidad de video.

Introducción

El rápido crecimiento de las redes móviles, como 802.11 o las redes celulares,
unido a una gran demanda de servicios audiovisuales por parte de los usuarios,
está impulsando a ofrecer servir contenidos multimedia en cualquier lugar,
momento y adaptándose a los diferentes dispositivos “anytime ,anywhere,
any device”. En este contexto, la red celular de tercera generación UMTS
representa un claro exponente en la provisión de servicios audiovisuales como la
video llamada o la descarga en streaming de vídeos.

Partiendo de los modelos clásicos de capas, como el modelo OSI, las redes de
comunicaciones móviles han tenido que reformar los protocolos de red existentes,
pensados para redes de cableado fijo, para adaptarse a las redes móviles
caracterizadas por altos retardos, perdidas elevadas, limitaciones en
capacidad computacional de los terminales y un largo etcétera que ha concluido
con una arquitectura multicapa poco optimizada en algunas ocasiones. Por otro
lado gran demanda de servicios de audiovisuales esta provocando la aparición de
soluciones (modelos cross-layer) destinadas a mejorar este modelo multicapa,
donde se debe optimizar cada elemento de la cadena para poder ofrecer con
calidad el mayor número de servicios posibles minimizando los recursos de red
necesarios para ofrecer dicho servicio.

Centrándonos en las aplicaciones de vídeo encontramos diferentes servicios como
la videollamada, descarga en streaming de pequeños contenidos multimedia,
video vigilancia y toda una serie de servicios donde intervienen una gran cantidad
de elementos a optimizar. Para optimizar estos servicios de video poseemos dos a
aternativas básicas de trabajo: optimizar el algoritmo de compresión, y optimizar el
transporte de la información durante el transporte por la red, siendo la segunda
alternativa el objeto de estudio del presente estudio.

En el artículo se hace hincapié en los estándares de compresión de vídeo
recomendados por el 3GPP contrastando las recomendaciones con las propuestas
por de los fabricantes de terminales móviles.

También se incluye algunas el análisis de las especificaciones técnicas de algunos
terminales para enmarcar las recomendaciones analizadas. Así pues, partiendo
del formato de la información a servir y con el objetivo de seguir las
recomendaciones se propone un modelo donde se optimiza la prestación de
servicios audiovisuales, maximizando la calidad observada por el usuario,
relacionándolo los recursos de red necesarios para ofrecer dicha calidad,
centrándonos en especial en la tecnología de tercera generación
(UMTS) para terminales móviles.

Servicios Portadores de datos en UMTS

Los servicios portadores de datos ofrecidos por UMTS admiten múltiples
configuraciones (clase de servicio, tasas binarias, etc.) a la hora de establecer
cómo un determinado servicio (e.g. video streaming) puede soportarse en la red.
A modo de ejemplo en la Tabla 1 se ilustran las clases de servicio especificadas
en UMTS junto con los parámetros de QoS más relevantes de cara a habilitar la
provisión de un determinado tipo de servicio.


Tabla 1. Ejemplo de configuraciones típicas de servicios portadores en
UMTS.

Los servicios portadores se gestionan mediante los denominados contextos PDP
(Packet Data Protocol). Un contexto PDP es la información almacenada en los
distintos elementos involucrados en un momento dado en el trayecto de
comunicación asociado a una sesión de datos entre el móvil y la pasarela de la
red UMTS (GGSN). En el establecimiento del contexto PDP se indican los
parámetros de QoS necesarios así como los filtros de tráfico que van a identificar
qué información debe encaminarse a través de dicho contexto.

Un esquema habitual suele ser transportar un determinado servicio únicamente a
través de un servicio portador (e.g. un contexto PDP) con los parámetros de QoS
adecuados. No obstante, no toda la información enviada a través de un único
servicio portador tiene porque tener la misma relevancia a la hora de determinar la
calidad con la que se ofrece el servicio y, por tanto, las características de QoS del
servicio portador deben adaptarse a las restricciones de la información más
sensible dentro del flujo de datos.

Soporte de vídeo en terminales móviles.

Los fabricantes de teléfonos móviles y los proveedores de contenidos han
redactado una serie de normativas a través del 3GPP para definir los formatos de
la información que han de soportar los dispositivos móviles. A continuación
realizamos un breve resumen en formato tabla de los aspectos más importantes a
la hora de codificar audio y video.

Conversational Streaming Interactive Background

Tabla 2. Resumen de códecs soportados.


Analizando la tabla anterior podemos concluir que el códec utilizado y
recomendado por ambas entidades es el H.263 perfil 0. El perfil 0 nos define
unas restricciones en cuanto a las herramientas técnicas a utilizar para la
compresión del video, resumiéndose en las siguientes características.

  • Perfil muy sencillos y de baja complejidad.
  • Posibilidad de predicción mediante frames del tipo I y P, únicamente.
  • No se necesitan buffer para la posible decodificación.

Todos los códecs anteriormente mencionados se basan en el aprovechar modelos
de predicción temporales y espaciales, con lo que finalmente codifican toda la
información utilizando códigos entrópicos, con lo que se reduce el número de bits
necesarios para codificar la información.

Del proceso de codificación se obtienen los flujos elementales “ES”. Si nos
centramos en el ES visual se generan las imágenes intra (I) e inter (P o B). Las
imágenes I son fotogramas de gran longitud que contienen en ellos mismos toda
la información necesaria par decodificarse. Por el contrario los frames tipo P
codifican información diferencial respecto las imágenes I. Estas características
justifican la necesidad de proteger los fotogramas I respecto P.

Esquema propuesto

En el presente trabajo se propone la transmisión de un servicio de streaming de
video MPEG4 sobre varios contextos PDP adaptados a las diferentes
características del contenido transportado. La solución planteada propone
descomponer el video en varios flujos en función de la importancia que represente
el contenido del paquete para la calidad final del vídeo. Una vez conocido el
contenido del paquete mediante un filtraje, cada paquete es transportado por el
contexto PDP que mejor se adapte a sus necesidades.

En la Ilustración 1 se presenta el contenido de un vídeo como una combinación de
audio, imágenes comprimidas e información adicional. También se puede observar
una diferencia entre el tipo de imagen generada, factor que permitirá diferenciar el
tipo de imagen y priorizarla en función de la importancia que representa dicha
imagen para la calidad final del vídeo.



Ilustración 1- Arquitectura propuesta para servicios de video sobre UMTS.

Dicha separación permite acomodar mejor las características de los servicios
portadores a la relevancia de la información transportada. Dicha optimización es
especialmente relevante en la componente del servicio portador ofrecida sobre la
red de acceso radio UTRAN, denominada Radio Access Bearer (RAB), donde
una relajación de las restricciones de QoS necesarias deriva directamente en un
aumento de capacidad.

Montaje experimental y Resultados provisionales

En la Ilustración 2 – Escenario de pruebas se muestra el montaje
experimental utilizado en el presente estudio. A continuación presentamos cada
uno de los componentes, especificando brevemente sus funciones a realizar.

Para servir los contenidos en formato streaming se ha empleado el Darwin
Streaming Server (DSS). El DSS es un servidor de video que soporta los
diferentes formatos utilizados en los servicios de video sobre terminales móviles
como MPEG4, H.263, H.261. El servidor era el encargado de trocear el contenido
y encapsularlo en RTP siguiendo el formato especificado del RFC 3640. En el otro
extremo se ha utilizado el cliente de streaming QuickTime, cuyas funcionalidades
rescindían la negociación inicial del vídeo y la representación por pantalla del
contenido del vídeo.

A continuación el tráfico es conducido hacia un emulador de UMTS donde se
intercepta el tráfico correspondiente a una comunicación y se aplica, a cada
paquete, las condiciones de contorno que debe experimenta un usuario si
estuviese realizando dicho servicio sobre UMTS, Para dichas simulaciones la
configuración del escenario implementa diferentes RABs para servir el vídeo. El
emulador de UMTS ha estado desarrollado en el proyecto IST ARROWS
enmarcado en un proyecto de innovación para sistemas de comunicaciones
móviles de 3ª generación, teniendo como objetivo proporcionar datos del
comportamiento del sistema UMTS delante de implementaciones de algoritmos
para la gestión de recursos radio (RRM). El emulador tiene la capacidad de
simular escenario UMTS con un número determinado de usuarios, cada uno de
ellos con unas características definidas. Destacar que el proyecto IST ARROWS
ha sido financiado por la UE ¡Error! No se encuentra el origen de la referencia.

Una vez el trafico ha travesado el simulador UMTS el cliente de streaming recibe
el flujo y empieza el proceso de decodificación del video influido por las perdidas
de paquetes y retardos experimentadas durante la transmisión y el procesado en
el simulador. Finalmente para valorar la calidad observada por el usuarios, se han
realizado capturas del video que presentado por el cliente de streaming, para
pasarlo posteriormente a una herramienta de valoración de calida.
2 RFC titulado “RTP Payload Format for Transport of MPEG-4
Elementary Streams”

El software encargado de la valoración de la calidad es una implementación de los
modelos de percepción de la calidad definidos por las recomendaciones de la
ITU-T [5][6], el nombre del cual es Video Quality Metrics (VQM) [7]. VQM
implementa diferentes algoritmos que estiman la calidad en comparar dos vídeos
obteniendo diferentes parámetros como PSNR o valor de MOS (Mean Opinión
Store) de dicha comparación.


Ilustración 2 – Escenario de pruebas.

Mediante la combinación de todos los elementos anteriormente citados
procedemos al estudio del efecto de filtro avanzado de contenidos y su efecto en
el sistema UMTS. Una de las opciones para diferenciar el tipo de imagen que
trasporta el paquete RTP implementada por el DSS, es la negociación mediante
RTSP de meta información transportada en el payload de cada paquete RTP.
Fijando como objetivo diferenciar el tipo de frame que viaja en el payload de RTP
nos centramos en el campo “Frame Type” el cual puede coger los siguientes
valores, con lo que puede permitir diferenciar los frames de forma sencilla:

  • 0 representa un frame desconocido.
  • 1 representa un key frame o frame tipo I.
  • 2 representa un frame tipo B
  • 3 representa un frame tipo P.

Una vez evaluada la alternativa se ha descartado por no obtener un resultado
positivo en la configuración del escenario, solucionándolo la problemática
mediante la implementación una aplicación específica cuya funcionalidad era
clasificar en función del contenido del paquete RTP. La implementación del filtraje
se basa en la captura de los paquetes de streaming, los cuales están
encapsulados mediante el RFC3 3640.

Recorriendo el payload del paquete RTP y con la ayuda de las secuencias definidas
en MPEG4 podemos identificar el tipo de información y redireccionarla
adecuadamente. A modo de resultados provisionales a continuación se
proporcionan resultados que demuestran la validez del esquema propuesto.
Concretamente, y como paso previo a la configuración de los servicios portadores
sobre el emulador de UMTS, se estudio la sensibilidad en términos de pérdidas de
paquetes que presentan las diferentes componentes del video MPEG4. Para ello
se realizo un montaje del filtro comentado al que se añadió además funciones de
gestión de colas de cara a forzar unas determinadas tasas de pérdidas en
cada componente. En la ilustración 3 se muestra de forma esquemática dicho
montaje.


Ilustración 3- Esquema del filtraje propuesto.

Partiendo de esta implementación se ha configurado un escenario donde la tasa
de pérdidas en las colas por donde se envían las tramas I es diferente del resto de
información donde se encuentran por ejemplo las tramas P. Con este escenario
definido se ha realizado la valoración de la calidad observada mediante software
especializado siguiendo las recomendaciones de la ITU y se han obtenido los
resultados mostrados en la siguiente figura.


En el eje horizontal de la gráfica siguiente tenemos situada la variable de perdidas en
formato porcentual exceptuando el canal por el que se transmiten los frames del
tipo I. Con todo ello encontramos una disminución de la calidad observada a
medida que aumentan las pérdidas en el canal, comportamiento esperado que se
verifica en entornos reales. En el caso que se protejan las imágenes tipo I,
transmitiéndolas por un canal mejor, encontramos que la calidad MOS aumenta
considerablemente para valores de pérdidas de paquetes altos (15-20%), con una
mejora considerable en el funcionamiento de servicio de video streaming.
Destacar que la información transmitida por el canal de frames tipo I representa
porcentajes bajos respecto la información transmitida por canales destinados a la
transmisión de frames tipo P u otras topologías. Si se aplican porcentajes de
perdidas con valores aproximados de un 5% se observa una disminución de la
calidad respecto a canales con 0% de perdidas para frames tipo I, pero a su vez
una mejora respecto canales donde no se hace ningún tipo de distinción.

Concluyendo el resumen y después de las experiencias realizadas pasamos a
trasladar estas experiencias para entornos como UMTS donde la implementación
de los diferentes canales mediante la configuración de diferentes RABs para un
mismo servicio, puede tener diferentes consecuencias a nivel de sistema,
analizadas en el articulo completo.

ANEXOS

OPTIMIZACIÓN DE UMTS PARA SERVICIOS DE VÍDEO STREAMING.

I. Anexo I (Filtro de vídeo)

A continuación se muestra el código implementado para la
clasificación de los paquetes IP.

I.1. Clasificación de los paquetes.

#ifndef _PAQUET_CHEK
#define _PAQUET_CHEK
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>
#ifndef _FPAQUETE
#include "fpaquete.h"
#endif
#ifndef vat_packet_h
#include "vat.h"
#endif
#ifndef _FTUN
#include "ftun.h"
#endif
#ifndef _STATISTICS_H_
#include "statistics.h"
#endif
#define LogFILTER 1
#ifndef MAX_TYPE
#define MAX_TYPES 6
#endif
#ifndef TUN_DEVICES
#define TUN_DEVICES 2
#endif
#define TUN_HEADER_SIZE 4
#define PAQ_SIZE 1600
enum {RTP,RTCP,VATC,VATD};
enum {ICMP,UDP,TCP,OTHER};
typedef enum {I,P,B,AUDIO,UNK,R} type_media;
typedef u_int32 member_t;
struct cola
{
int num_paquetes_cola;
int max_bytes_cola;
int max_bytes_bucket;
struct _Paquete *paq;
unsigned long last_ts;
unsigned int last_marker_bit;
float bucket;
int bit_rate;
float ulp;
float p,q;
float clp;
int estado_malo;
int max_paquetes;
int new_frame;
struct stats_cola sts;
};
static struct
{
char *enc; /* encoding name */
int rate; /* sampling rate for audio; clock rate for video */
int ch; /* audio channels; 0 for video */
}
pt_map[256];
static struct
{
rtcp_sdes_type_t t;
char *name;
}
map[] = {
{RTCP_SDES_END, "end"},
{RTCP_SDES_CNAME, "CNAME"},
{RTCP_SDES_NAME, "NAME"},
{RTCP_SDES_EMAIL, "EMAIL"},
{RTCP_SDES_PHONE, "PHONE"},
{RTCP_SDES_LOC, "LOC"},
{RTCP_SDES_TOOL, "TOOL"},
{RTCP_SDES_NOTE, "NOTE"},
{RTCP_SDES_PRIV, "PRIV"},
{11, "SOURCE"},
{0,0}
};
/*void log_Printf(int channel ,char *str)
{
printf("%s\n",str);
}*/
//////////////////
static int parse_control(FILE *out, char *buf, int len);
int PacketCheck_IP(FILE *out,struct _Paquete *Paquete_tun);
type_media parse_type_image(char *buff);
int parse_header(char *buf);
void hex(FILE *out, char *buf, int len);
void set_market_ts(char *buf,struct cola *cola);
int parse_data(FILE *out, char *buf, int len);
int PacketCheck_IP(FILE *out,struct _Paquete *Paquete_tun)
{
int gotinfo; /* true if IP payload decoded */
int cproto; /* P_* protocol type if (gotinfo) */
int estab, syn, finrst; /* TCP state flags if (gotinfo) */
unsigned short sport, dport; /* src, dest port from packet if (gotinfo)
*/
int len; /* bytes used in dbuff */
int didname; /* true if filter header printed */
char dbuff[100];
char *temp=((char *)(Paquete_tun->contenido+TUN_HEADER_SIZE));
struct ip *pip=(struct ip*)temp;
const char *ptop = (const char *) pip + (pip->ip_hl << 2);
int datalen; /* IP datagram length */
/*
* Deny any packet fragment that tries to over-write the header.
* Since we no longer have the real header available, punt on the
* largest normal header - 20 bytes for TCP without options, rounded
* up to the next possible fragment boundary. Since the smallest
* `legal' MTU is 576, and the smallest recommended MTU is 296, any
* fragmentation within this range is dubious at best
*/
Paquete_tun->ip_hdr=(struct ip*)temp;
len = ntohs(pip->ip_off) & IP_OFFMASK; /* fragment offset */
if (len > 0)
{ /* Not first fragment within datagram */
if (len < (24 >> 3))
{ /* don't allow fragment to over-write header */
fprintf(out, " error: illegal header\n");
return OTHER;
}
}
cproto = gotinfo = estab = syn = finrst = didname = 0;
sport = dport = 0;
datalen = ntohs(pip->ip_len) - (pip->ip_hl << 2);
switch (pip->ip_p)
Anexo I (Filtro de vídeo) 60
{
case IPPROTO_ICMP:
cproto = ICMP;
Paquete_tun->IP_type=ICMP;
if (datalen < 8)
{ /* ICMP must be at least 8 octets */
fprintf(out, " error: ICMP must be at least 8 octets\n");
return OTHER;
}
Paquete_tun->icmp_hdr = (struct icmp *) ptop;
sport = Paquete_tun->icmp_hdr->icmp_type;
estab = syn = finrst = -1;
snprintf(dbuff, sizeof dbuff, " ICMP sport = %d", sport);
break;
case IPPROTO_UDP:
cproto = UDP;
if (datalen < 8)
{ /* UDP header is 8 octets */
fprintf(out, " error: UDP must be at least 8 octets\n");
return OTHER;
}
Paquete_tun->IP_type=UDP;
Paquete_tun->longitud=datalen-sizeof(struct udphdr);
Paquete_tun->udp_hdr = (struct udphdr *) ptop;
Paquete_tun->first_data_byte=(char*) ptop + sizeof(struct udphdr);
sport = ntohs(Paquete_tun->udp_hdr->source);
dport = ntohs(Paquete_tun->udp_hdr->dest);
estab = syn = finrst = -1;
snprintf(dbuff, sizeof dbuff, "UDP sport = %d, dport = %d",
sport, dport);
break;
case IPPROTO_TCP:
cproto = TCP;
Paquete_tun->IP_type=TCP;
Paquete_tun->tcp_hdr = (struct tcphdr *) ptop;
/* TCP headers are variable length. The following code
* ensures that the TCP header length isn't de-referenced if
* the datagram is too short
*/
if (datalen < 20 || datalen < (Paquete_tun->tcp_hdr->doff << 2))
{
fprintf(out, " error: TCP header incorrect\n");
return OTHER;
}
Paquete_tun->first_data_byte=(char*) ptop + sizeof(struct tcphdr);
Paquete_tun->longitud=datalen-sizeof(struct tcphdr);
sport = ntohs(Paquete_tun->tcp_hdr->source);
dport = ntohs(Paquete_tun->tcp_hdr->dest);
//estab = (th->th_flags & TH_ACK);
//syn = (th->th_flags & TH_SYN);
//finrst = (th->th_flags & (TH_FIN|TH_RST));
snprintf(dbuff, sizeof dbuff, "TCP sport = %d, dport = %d",
sport, dport);
/*if (!estab)
snprintf(dbuff, sizeof dbuff,
"TCP flags = %02x, sport = %d, dport = %d",
th->th_flags, sport, dport);
else
*dbuff = '\0';*/
break;
default:
Paquete_tun->IP_type=OTHER;
fprintf(out, " error: unknown protocol\n");
return OTHER; /* We'll block unknown type of packet */
}
fprintf(out,"%s\n",dbuff);
return cproto;
}
type_media parse_type_image(char *buff)
{
unsigned char b1=buff[0];
unsigned char b2=buff[1];
unsigned char b3=buff[2];
unsigned char b4=buff[3];
unsigned char b5=(buff[4])&0xC0;
//printf("== %02x %02x %02x %02x %02x ==\n",b1,b2,b3,b4,b5);
if(b1==0x00 && b2==0x00 && b3==0x01 && b4==0xB6)
{
switch(b5)
{
case 0x00:
//printf("tipo I\n");
return I;
case 0x40:
//printf("tipo P\n");
return P;
case 0x80:
printf("tipo B\n");
return B;
default:
//printf("tipo OTHER\n");
return UNK;
}
}
else if (b1==0x00 && b2==0x10 )
{
//printf("tipo Audio\n");
return AUDIO;
}
else return UNK;
}
int parse_type(int type,char *buf)
{
if (type == 0)
{
rtp_hdr_t *r = (rtp_hdr_t *)buf;
return r->version == RTP_VERSION ? RTP : VATD;
}
else
{
rtcp_t *r = (rtcp_t *)buf;
return r->common.version == RTP_VERSION ? RTCP : VATC;
}
} /* parse_type */
/*
* Return header length of RTP packet contained in 'buf'.
*/
int parse_header(char *buf)
{
rtp_hdr_t *r = (rtp_hdr_t *)buf;
int hlen = 0;
if (r->version == 0)
{
vat_hdr_t *v = (vat_hdr_t *)buf;
hlen = 8 + v->nsid * 4;
}
else if (r->version == RTP_VERSION)
{
hlen = 12 + r->cc * 4;
}
return hlen;
} /* parse_header */
void hex(FILE *out, char *buf, int len)
{
int i;
for (i = 0; i < len; i++)
Anexo I (Filtro de vídeo) 62
{
fprintf(out, "%02x", (unsigned char)buf[i]);
}
} /* hex */
void set_market_ts(char *buf,struct cola *cola_k)
{
unsigned long x;
rtp_hdr_t *r = (rtp_hdr_t *)buf;
x=(unsigned long)ntohl(r->ts);
cola_k->last_ts=x;
cola_k->last_marker_bit=(unsigned int)r->m;
//printf("%lu Timestamp, %d marker\n",x,r->m);
}
/*
* Return header length.
*/
int parse_data(FILE *out, char *buf, int len)
{
rtp_hdr_t *r = (rtp_hdr_t *)buf;
rtp_hdr_ext_t *ext;
int i, ext_len=0;
int hlen = 0;
/* Show vat format packets. */
if (r->version == 0)
{
vat_hdr_t *v = (vat_hdr_t *)buf;
fprintf(out, "nsid=%d flags=0x%x confid=%u ts=%u\n",
v->nsid, v->flags, v->confid, v->ts);
hlen = 8 + v->nsid * 4;
buf=buf+hlen+ext_len;
}
else if (r->version == RTP_VERSION)
{
hlen = 12 + r->cc * 4;
if (len < hlen)
{
fprintf(out, "RTP header too short (%d bytes for %d CSRCs).\n",
len, r->cc);
return hlen+ext_len;
}
fprintf(out,
"v=%d p=%d x=%d cc=%d m=%d pt=%d (%s,%d,%d) seq=%u ts=%lu ssrc=0x%lx ",
r->version, r->p, r->x, r->cc, r->m,
r->pt, pt_map[r->pt].enc, pt_map[r->pt].ch, pt_map[r->pt].rate,
ntohs(r->seq),
(unsigned long)ntohl(r->ts),
(unsigned long)ntohl(r->ssrc));
for (i = 0; i < r->cc; i++)
{
fprintf(out, "csrc[%d] = %0lx ", i, r->csrc[i]);
}
if (r->x)
{ /* header extension */
ext = (rtp_hdr_ext_t *)((char *)buf + hlen);
ext_len = ntohs(ext->len);
fprintf(out, "ext_type=0x%x ", ntohs(ext->ext_type));
fprintf(out, "ext_len=%d ", ext_len);
if (ext_len)
{
fprintf(out, "ext_data=");
hex(out,((char *)(ext+1)),(ext_len*4));
}
}
buf=buf+(hlen+ext_len);
hex(out,buf,6);
return hlen+ext_len;
}
else
{
fprintf(out, "RTP version wrong (%d).\n", r->version);
}
return hlen+ext_len;
} /* parse_data */
#endif

I.2. Estadísticas del filtro.

#ifndef STATS
#define STATS
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <sys/time.h>
#include <time.h>
#include <signal.h>
#ifndef MAX_TYPE
#define MAX_TYPES 6
#endif
#ifndef TUN_DEVICES
#define TUN_DEVICES 2
#endif
#define time_to_ms(tv) ((tv)->tv_sec*1000 + (tv)->tv_usec / 1000.0)
#include "statistics.h"
#include "Paquet_check.c"
double actual_time;
double initial_time=0;
struct timeval temp_tv;
FILE *stats_file[TUN_DEVICES][MAX_TYPES];
struct stats_cola *stats;
extern struct cola cola[TUN_DEVICES][MAX_TYPES];
/* Estructura con el contador de tiempo */
struct itimerval contador;
/* Valor inicial del contador */
struct timeval tiempoInicial;
/* Tiempo de repetición del contador */
struct timeval tiempoRepeticion;
void tratamiento_estadistico_final (int);
void tratamiento_estadistico_inst (int);
double get_actual_time()
{
if(initial_time==0)
//INIT
{
gettimeofday(&temp_tv,NULL);
initial_time=time_to_ms(&temp_tv);
}
gettimeofday(&temp_tv,NULL);
actual_time=time_to_ms(&temp_tv);
return actual_time - initial_time;
}
void print_header_inst()
{
printf("T_TIME INC_TIME N_PAQ L_PAQ %%P_FRAG L_P_FRAG %%P_PERD TASA\n");
}
void print_header_inst_FILE(FILE *canal)
{
Anexo I (Filtro de vídeo) 64
fprintf(canal,"T_TIME INC_TIME N_PAQ L_PAQ %%P_FRAG L_P_FRAG %%P_PERD
TASA\n");
fflush(canal);
}
void print_results(int canal,struct stats_cola *st)
{
printf("%.1f %.1f %.0f %.0f %.2f %.2f %.3f %.2f\n",st-
>acumulated_time,st->time_last_computed,st->num_medio_paquetes_inst,st-
>long_media_paq_inst,st->num_medio_paq_fragmentados_inst,st->long_media_frag_inst,st-
>num_medio_paquetes_inst_perdidos,st->bitrate_medio_inst);
}
void print_results_to_file(FILE *canal,struct stats_cola *st)
{
fprintf(canal,"%.1f %.1f %.0f %.0f %.2f %.2f %.3f %.2f\n",st-
>acumulated_time,st->time_last_computed,st->num_medio_paquetes_inst,st-
>long_media_paq_inst,st->num_medio_paq_fragmentados_inst,st->long_media_frag_inst,st-
>num_medio_paquetes_inst_perdidos,st->bitrate_medio_inst);
fflush(canal);
}
void print_results_FINAL_to_file(FILE *canal,struct stats_cola *st)
{
fprintf(canal,"MUESTRAS=%.0f B_RATE=%.2f %%LOST=%3f L_MED_PAQ=%.0f %%P_FRAG=%.2f
L_MEDI_FRAG=%.1f PAQ_TOTALES=%.0f\n",st->num_periodos_muestreados-1,st-
>bitrate_medio,st->num_medio_paquetes_totales_perdidos,st->long_media_paq_total,st-
>num_medio_paq_fragmentados,st->long_media_frag_media,st->num_medio_paquetes_totales);
fflush(canal);
}
void print_results_FINAL(struct stats_cola *st)
{
printf("MUESTRAS=%.0f B_RATE=%.2f %%LOST=%3f L_MED_PAQ=%.0f %%P_FRAG=%.2f
L_MEDI_FRAG=%.1f PAQ_TOTALES=%.0f\n",st->num_periodos_muestreados-1,st-
>bitrate_medio,st->num_medio_paquetes_totales_perdidos,st->long_media_paq_total,st-
>num_medio_paq_fragmentados,st->long_media_frag_media,st->num_medio_paquetes_totales);
}
void init_stats(struct stats_cola *st)
{
st->bitrate_medio=0;
st->bitrate_medio_inst=0;
st->long_media_frag_inst=0;
st->long_media_frag_media=0;
st->long_media_paq_inst=0;
st->long_media_paq_total=0;
st->max_long=0;
st->min_lon=1500;
st->num_medio_paq_fragmentados=0;
st->num_medio_paq_fragmentados_inst=0;
st->num_medio_paquetes_inst_perdidos=0;
st->num_medio_paquetes_totales_perdidos=0;
st->num_medio_paquetes_inst=0;
st->num_medio_paquetes_totales=0;
st->tiempo_entre_llegadas_medio=0;
st->tiempo_entre_llegadas_medio_inst=0;
st->num_periodos_muestreados=1;
st->acumulated_time=0;
if(initial_time==0)
//INIT
{
gettimeofday(&temp_tv,NULL);
initial_time=time_to_ms(&temp_tv);
}
}
void clear_inst(struct stats_cola *st)
{
st->bitrate_medio_inst=0;
st->long_media_frag_inst=0;
st->long_media_paq_inst=0;
st->num_medio_paq_fragmentados_inst=0;
st->num_medio_paquetes_inst_perdidos=0;
st->num_medio_paquetes_inst=0;
st->tiempo_entre_llegadas_medio_inst=0;
}
//TIMER PART
//SET AND START THE TIMER
void init_timer()
{
int tun,u;
char buffer[30];
/* Se rellena el tiempo inicial del contador con 2 segundos */
tiempoInicial.tv_sec=5;
tiempoInicial.tv_usec=0;
/* Se rellena el tiempo de repetición con 5 segundos */
tiempoRepeticion.tv_sec=0;
tiempoRepeticion.tv_usec=5000000;
/* Se rellenan los datos del contador */
contador.it_value=tiempoInicial;
contador.it_interval=tiempoRepeticion;
/* Se cambia el tratamiento de la señal por defecto para que llame a
* nuestra función tratamientoSenhal */
for(tun=0;tun<TUN_DEVICES;tun++)
{
for(u=0;u<MAX_TYPES;u++)
{
sprintf(buffer,"stats_%d_%d.txt",tun,u);
stats_file[tun][u]=fopen(buffer,"w+");
print_header_inst_FILE(stats_file[tun][u]);
}
}
print_header_inst();
signal (SIGALRM, tratamiento_estadistico_inst);
signal (SIGINT,tratamiento_estadistico_final);
/* Se pone en marcha el contador.
* La primera vez tardará 2 segundos en saltar, según indicamos en
* tiempoInicial. Luego saltará automáticamente cada medio segundo, como
* indicamos en tiempoRepeticion. */
setitimer (ITIMER_REAL, &contador, NULL);
}
void tratamiento_estadistico_inst (int signal)
{
int u;
int tun;
printf("\n\n\n");
print_header_inst();
for(tun=0;tun<TUN_DEVICES;tun++)
{
printf("STATISTICS FOR TUN=%d\n",tun);
for(u=0;u<MAX_TYPES;u++)
{
//update_stadistics
stats=&cola[tun][u].sts;
//Add for final calculus
stats->time_last_computed=get_actual_time()-stats->acumulated_time;//-
stats->time_last_computed;
stats->acumulated_time+=stats->time_last_computed;
stats->bitrate_medio_inst=stats->long_media_paq_inst*8/stats-
>time_last_computed;
stats->long_media_frag_inst=stats->long_media_frag_inst/stats-
>num_medio_paq_fragmentados_inst;
stats->long_media_paq_inst=stats->long_media_paq_inst/stats-
>num_medio_paquetes_inst;
stats->num_medio_paq_fragmentados_inst=stats-
>num_medio_paq_fragmentados_inst/stats->num_medio_paquetes_inst;
stats->num_medio_paquetes_inst_perdidos=stats-
>num_medio_paquetes_inst_perdidos/stats->num_medio_paquetes_inst;
//ADD MEANS TO GLOBAL MEANS
Anexo I (Filtro de vídeo) 66
stats->bitrate_medio=(stats->bitrate_medio*(stats-
>num_periodos_muestreados-1) + stats->bitrate_medio_inst)/stats-
>num_periodos_muestreados;
stats->long_media_frag_media=(stats->long_media_frag_media*(stats-
>num_periodos_muestreados-1) + stats->long_media_frag_inst)/stats-
>num_periodos_muestreados;
stats->long_media_paq_total=(stats->long_media_paq_total*(stats-
>num_periodos_muestreados-1) + stats->long_media_paq_inst)/stats-
>num_periodos_muestreados;
stats->num_medio_paq_fragmentados=(stats-
>num_medio_paq_fragmentados*(stats->num_periodos_muestreados-1) + stats-
>num_medio_paq_fragmentados_inst)/stats->num_periodos_muestreados;
stats->num_medio_paquetes_totales_perdidos=(stats-
>num_medio_paquetes_totales_perdidos*(stats->num_periodos_muestreados-1) + stats-
>num_medio_paquetes_inst_perdidos)/stats->num_periodos_muestreados;
stats->num_medio_paquetes_totales+=stats->num_medio_paquetes_inst;
print_results_to_file(stats_file[tun][u],stats);
print_results((int)stdout,stats);
stats->num_periodos_muestreados++;
clear_inst(stats);
}
}
}
void tratamiento_estadistico_final(int signal)
{
int tun,u;
//printf("Muestreados %d periodos\n",stats.num_periodos_muestreados);
printf("HAS APRETADO CRTL+C\n");
for(tun=0;tun<TUN_DEVICES;tun++)
{
printf("STATISTICS FOR TUN=%d\n",tun);
for(u=0;u<MAX_TYPES;u++)
{
stats=&cola[tun][u].sts;
print_results_FINAL_to_file(stats_file[tun][u],stats);
print_results_FINAL(stats);
fclose(stats_file[tun][u]);
}
}
exit (0);
}

I.3. Programa principal.

r=tun_read(tun_paquet.contenido,&l,NON_BLOCKING);
if(l>0)
{
//RECONIGSE PACKET
switch(PacketCheck_IP(out,&tun_paquet))
{
case ICMP:
actual_index=UNK;
break;
case UDP:
if((port=ntohs(tun_paquet.udp_hdr->dest))>1024) //no son puertos reservados
{
switch(parse_type(port%2,((char *)(tun_paquet.first_data_byte))))
{
case RTP:
len=parse_data(out,((char
*)(tun_paquet.first_data_byte)),tun_paquet.longitud);
//hex(out,tun_paquet.first_data_byte+port,6);
actual_index=parse_type_image(((char *)(tun_paquet.first_data_byte+len)));
//can be I,P,B,S or AUDIO
//CHECK IF THE RETURN VALUE WAS UNK BUT IT IS A CONTINUATION OF NEW FRAME
if(actual_index!=UNK)
{
cola[r][actual_index].new_frame=TRUE;
set_market_ts(((char
*)(tun_paquet.first_data_byte)),&cola[r][actual_index]);
}
else
{
//recorrer los tipos I,P,B a ver si estan lo del timestamp
//SI los time stamp son iguales
ultemp=(unsigned long) ntohl(((rtp_hdr_t *)(tun_paquet.first_data_byte))-
>ts);
//printf("watching for %lu",ultemp);
for(k=0;k<MAX_TYPES;k++)
{
ultemp=(unsigned long) ntohl(((rtp_hdr_t
*)(tun_paquet.first_data_byte))->ts);
//printf ("ts %ul for %d type and marker
%d\n",cola[r][k].last_ts,k,cola[r][k].last_marker_bit);
if((cola[r][k].last_ts==ultemp)&&!(cola[r][k].last_marker_bit))
{
actual_index=k;
cola[r][k].sts.long_media_frag_inst++;
if(cola[r][k].new_frame==TRUE)
{
cola[r][k].sts.num_medio_paq_fragmentados_inst++;
cola[r][k].sts.long_media_frag_inst++;
}
cola[r][k].new_frame=FALSE;
}
}
}
break;
case RTCP:
actual_index=R;
break;
default:
actual_index=UNK;
break;
}
}//Final del IF del UDP
break;
case TCP:
actual_index=UNK;
break;
default:
actual_index=UNK;
break;
}
//printf("Actual index %d\n",actual_index);
cola[r][actual_index].sts.num_medio_paquetes_inst++;
cola[r][actual_index].sts.long_media_paq_inst+=l-TUN_HEADER_SIZE;
num_paquetes_totales++;

II. Anexo II (Procedimiento para la comparación
de la calidad de dos vídeos)

Para poder comparar dos en streaming se realizaba el siguiente
Procedimiento:

  • Se inicia la petición desde el cliente de streaming.

  • En el cliente el video reproduce el contenido por pantalla. En este
momento se captura el vídeo mostrado mediante un programa
dedicado. En nuestro caso el programa utilizado era el.

  • Una vez obtenemos el video en formato YUV guardado en un
fichero avi, se procede a realizar una alineación temporal de los
frames, para evitar errores provocados por la comparación de frames
desalineados.

  • El video capturado que contiene el mismo número de frames
del original se procede a comparar el video con el software VQM.
Para realizar dicho procedimiento se han seguido los pasos
explicados en el manual del programa.


Fig. II.1 Esquema del montaje realizado para el streaming de video.