Estudio de viabilidad técnica e implementación de un sistema de

Anuncio
PROYECTO FINAL DE CARRERA
Estudio de viabilidad técnica e
implementación de un sistema de
transmisión de video adaptativo
H264/SVC sobre TCP
Estudios: INGENIERIA SUPERIOR DE TELECOMUNICACIONES
Autor: MANEL GRAU GRACIA
Tutor: DR. JORGE MATA DÍAZ
JUNIO 2014
Sistema de video adaptativo H264/SVC sobre TCP
2
3
Sistema de video adaptativo H264/SVC sobre TCP
Índice general
Agradecimientos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Resum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Resumen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Abstract . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.1.
1.2.
1.3.
1.4.
JSVM y OpenSVCDecoder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Proyectos similares . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Medidas objetivas de calidad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Introducción a H264 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.4.1. Predicción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
1.4.2. Transformación y cuantificación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
1.4.3. Codificación entrópica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2. H264/SVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.1.
Conceptos de escalabilidad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.1.1. Escalabilidad temporal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.1.2. Escalabilidad espacial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.1.3. Escalabilidad de calidad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.1.4. Escalabilidad híbrida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.2. Cabecera de las unidades NAL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.3. Sintaxis de las unidades NAL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
2.3.1. Unidades NAL non-VCL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
2.3.1.1. Supplemental Enhancement Information . . . . . . . . . . . . . . . . . 34
2.3.1.2. Sequence Parameter Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
2.3.1.3. Picture Parameter Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
2.3.2. Unidades NAL VCL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
2.3.2.1. Coded Slice of non-IDR Picture . . . . . . . . . . . . . . . . . . . . . . . . . . 36
2.3.2.2. Coded Slice of an IDR Picture . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
2.3.2.3. Coded Slice Extension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3. Filtrado adaptativo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
3.1.
Filtrado de unidades NAL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
3.1.1. Reglas de dependencia en el filtrado de unidades NAL . . . . . . . . . . . . . 38
3.1.1.1. Reglas con escalabilidad espacial y temporal . . . . . . . . . . . . . . 39
3.1.1.2. Reglas con escalabilidad de SNR y uso de MGS . . . . . . . . . . . . . 39
3.1.2. Algoritmo de filtrado de unidades NAL . . . . . . . . . . . . . . . . . . . . . . . . . . 40
3.1.2.1. Algoritmo de extracción sin usar MGS . . . . . . . . . . . . . . . . . . . . 40
Sistema de video adaptativo H264/SVC sobre TCP
4
3.1.2.2. Algoritmo de extracción usando MGS . . . . . . . . . . . . . . . . . . . . 42
3.2. Filtrado adaptativo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
3.2.1. Orden de transmisión de flujo de datos H264/AVC . . . . . . . . . . . . . . . . 46
3.2.2. Orden de transmisión de flujo de datos H264/SVC . . . . . . . . . . . . . . . . 50
3.2.3. Parámetros de diseño del filtrado adaptativo . . . . . . . . . . . . . . . . . . . . 52
4. Estimación del ancho de banda de transmisión . . . . . . . . . . . . . . . . . . 55
4.1.
Protocolo de control de Transporte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
4.1.1. Cabecera TCP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
4.1.2. Control de congestión . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
4.2. Estimación del ancho de banda de transmisión . . . . . . . . . . . . . . . . . . . . . . 61
4.2.1. Tamaño de las capas de extracción en tiempo real . . . . . . . . . . . . . . . . 61
4.2.2. Velocidad de reproducción del video . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
4.2.3. Implementación de la estimación en tiempo real del ancho de banda de
transmisión . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
4.2.3.1. Detalles de la implementación . . . . . . . . . . . . . . . . . . . . . . . . . . 64
4.2.3.2. Función estimación ancho de banda . . . . . . . . . . . . . . . . . . . . . 68
4.2.4. Estrategias temporales en la estimación del ancho de banda . . . . . . . 69
4.2.4.1. Implementación del uso de iteraciones . . . . . . . . . . . . . . . . . . . 70
5. Transmisor y receptor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
5.1.
Implementación del transmisor adaptativo . . . . . . . . . . . . . . . . . . . . . . . . . 72
5.1.1. Justificación uso de dos hilos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
5.1.2. Clase H264BitStream . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
5.1.3. Justificación de semáforos en la cola circular . . . . . . . . . . . . . . . . . . . . 79
5.1.4. Solución de semáforos en la aplicación . . . . . . . . . . . . . . . . . . . . . . . . 81
5.1.5. Solución de ancho de banda adaptativo . . . . . . . . . . . . . . . . . . . . . . . . . 85
5.1.6. Medidas para reducir el alto número de intercambios entre capas . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
5.2. Criterios de diseño del receptor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
5.2.1. Relación entre tiempo de reproducción y tiempo de transmisión . . . . 88
5.2.2. Estrategia de filtrado en recepción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
5.2.3. Solución de semáforos de la aplicación . . . . . . . . . . . . . . . . . . . . . . . . . 95
6. Evaluación del sistema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
6.1
Características de codificación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
6.1.1 Elección de los parámetros de cuantificación . . . . . . . . . . . . . . . . . . . . 99
6.2
Resultados al aplicar el algoritmo de filtrado . . . . . . . . . . . . . . . . . . . . . . . . 99
6.3
Perfiles de ancho de banda de transmisión . . . . . . . . . . . . . . . . . . . . . . . . 101
6.4
Puesta en escena . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
6.4.1 Prueba 1 - Ancho de banda límite de 300 Kbit/s . . . . . . . . . . . . . . . . . 107
6.4.2 Prueba 2 - Ancho de banda límite de 600 Kbit/s . . . . . . . . . . . . . . . . . 111
6.4.3 Prueba 3 - Ancho de banda límite de 1,3 Mbit/s . . . . . . . . . . . . . . . . . 115
5
Sistema de video adaptativo H264/SVC sobre TCP
6.4.4 Prueba 4 - Ancho de banda variable de 1,3 Mbit/s y 600 Kbit/s . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
6.4.5 Prueba 5 - Ancho de banda de 1,3 Mbit/s compartido . . . . . . . . . . . . 120
7. Conclusiones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
7.1
Líneas futuras . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
APÉNDICES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
A. Ficheros de configuración del codificador de JSVM utilizados en las
simulaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
B. Sintaxis H264/SVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
C. Manual de utilidades del proyecto . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
C.1.
C.2.
C.3.
Utilidades de vídeo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
Utilidades de compilación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
Utilidades desarrolladas en el proyecto . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
Bibliografía . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
Sistema de video adaptativo H264/SVC sobre TCP
6
Lista de Figuras
1.1. Esquema de codificación H264/AVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
1.2. Esquema intra-predicción de bloques 4x4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
1.3. Esquema intra-predicción de bloques 16x16 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
1.4. Esquema inter-predicción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.1. Esquema de codificación H264/SVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.2. Estructura de bipredicción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.3. Estructura diádica y no diádica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.4. Escalabilidad espacial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.5. Estructuras de dependencia de calidad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.6. Estructura del primer byte de la cabecera de las unidades NAL . . . . . . . . . . . . 30
2.7. Tipos de unidad NAL H264/AVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
2.8. Tipos de unidad NAL H264/SVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
2.9. Estructura de los tres últimos bytes de la cabecera de las unidades NAL en
H264/SVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
3.1. Estructura de la codificación, con capa base, capa de calidad mejorada y capa
de resolución superior . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
3.2. Estructura de la codificación, con capa base, capa de calidad mejorada con uso
de MGS y capa de resolución superior . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
3.3. Flujo de inicio con tamaño de GOP igual a 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
3.4. Flujo de inicio con tamaño de GOP igual a 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
3.5. Flujo de inicio con tamaño de GOP igual a 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
3.6. Flujo normal con tamaño de GOP igual a 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
3.7. Flujo normal con tamaño de GOP igual a 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
3.8. Flujo normal con tamaño de GOP igual a 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
3.9. Flujo en IDR múltiple periodo intra-predicción con tamaño de GOP igual a 2 . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
3.10. Flujo en IDR múltiple periodo intra-predicción con tamaño de GOP igual a 4 . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
3.11. Flujo en IDR múltiple periodo intra-predicción con tamaño de GOP igual a 8 . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
3.12. Flujo en IDR no múltiple periodo intra-predicción con tamaño de GOP igual a 2 .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
3.13. Flujo en IDR no múltiple periodo intra-predicción con tamaño de GOP igual a 4 .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
3.14. Flujo en IDR no múltiple periodo intra-predicción con tamaño de GOP igual a 8 .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
3.15. Flujo inicio codificación con tres capas, capa base, capa calidad mejorada y capa
de resolución superior . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
7
Sistema de video adaptativo H264/SVC sobre TCP
3.16. Flujo normal codificación con tres capas, capa base, capa calidad mejorada y
capa de resolución superior . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
3.17. Flujo en IDR múltiple periodo intra-predicción codificación con tres capas, capa
base, capa calidad mejorada y capa de resolución superior . . . . . . . . . . . . . . . . . . 51
3.18. Flujo en IDR no múltiple periodo intra-predicción codificación con tres capas,
capa base, capa calidad mejorada y capa de resolución superior . . . . . . . . . . . . . . 52
3.19. Intercambio entre capas 110 y 011 en flujo normal. Caso 1 . . . . . . . . . . . . . . . 53
3.20. Intercambio entre capas 110 y 011 en flujo normal. Caso 2 . . . . . . . . . . . . . . . 53
3.21. Intercambio entre capas 110 y 011 en flujo IDR múltiple periodo intrapredicción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
3.22. Intercambio entre capas 110 y 011 en flujo IDR no múltiple periodo intrapredicción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
4.1. Fases de establecimiento y finalización de conexión . . . . . . . . . . . . . . . . . . . . . 56
4.2. Casos de transmisión: Paquete enviado y reconocido, retransmisión y paquete
duplicado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
4.3. Ejemplo de control de flujo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
4.4. Cabecera TCP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
4.5. Fase “slow start” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
4.6. Ejemplo control de congestión . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
5.1. Ciclo de histéresis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
6.1. Algoritmo extracción hasta la capa 000 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
6.2. Algoritmo extracción hasta la capa 001 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
6.3. Algoritmo extracción hasta la capa 100 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
6.4. Algoritmo extracción hasta la capa 010 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
6.5. Algoritmo extracción hasta la capa 011 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
6.6. Algoritmo extracción hasta la capa 110 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
6.7. Perfil de ancho de banda: Capa 000 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
6.8. Perfil de ancho de banda: Capa 010 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
6.9. Perfil de ancho de banda: Capa 001 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
6.10. Perfil de ancho de banda: Capa 011 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
6.11. Perfil de ancho de banda: Capa 100 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
6.12. Perfil de ancho de banda: Capa 110 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
6.13. Escenario de red para las pruebas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
6.14. Flujo transmitido: Prueba 300 Kbit/s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
6.15. Perfil de transmisión según opciones del socket: Prueba 300 Kbit/s . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
6.16. Intercambio entre capas: Prueba 300 Kbit/s . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
6.17. Flujo transmitido: Prueba 300 Kbit/s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
6.18. Perfil de transmisión según opciones del socket: Prueba 300 Kbit/s . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
6.19. Intercambio entre capas: Prueba 300 Kbit/s . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
Sistema de video adaptativo H264/SVC sobre TCP
8
6.20. Flujo transmitido: Prueba 600 Kbit/s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
6.21. Perfil de transmisión según opciones del socket: Prueba 600 Kbit/s . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
6.22. Intercambio entre capas: Prueba 600 Kbit/s . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
6.23. Flujo transmitido: Prueba 1,3 Mbit/s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
6.24. Perfil de transmisión según opciones del socket: Prueba 1,3 Mbit/s . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
6.25. Intercambio entre capas: Prueba 1300 Kbit/s . . . . . . . . . . . . . . . . . . . . . . . . . . 117
6.26. Flujo transmitido: Prueba 1300-600-1300 Kbit/s . . . . . . . . . . . . . . . . . . . . . . . 118
6.27. Perfil de transmisión según opciones del socket: Prueba 1300-600-1300 Kbit/s .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
6.28. Intercambio entre capas: Prueba 1300-600-1300 Kbit/s . . . . . . . . . . . . . . . . . 120
6.29. Perfil de transmisión según opciones del socket: Prueba 1,3 Mbit/s compartido .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
6.30. Intercambio entre capas: 1,3 Mbit/s compartido . . . . . . . . . . . . . . . . . . . . . . . 121
9
Sistema de video adaptativo H264/SVC sobre TCP
Lista de Tablas
2.1.
3.1.
3.2.
6.1.
6.2.
6.3.
Lista de ejemplos de codificación Exp-Golomb . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Resultados algoritmo de extracción para el ejemplo 1 . . . . . . . . . . . . . . . . . . . . 41
Resultados algoritmo de extracción para el ejemplo 2 . . . . . . . . . . . . . . . . . . . . 44
Parámetros de cuantificación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
PSNR obtenidas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
Medias y desviaciones típicas del ancho de banda de transmisión . . . . . . . . . 105
Sistema de video adaptativo H264/SVC sobre TCP
10
Agradecimientos
Les doy las gracias y le dedico este proyecto a mi familia por su apoyo y comprensión
durante el largo trayecto universitario así, como el de realización del PFC.
También, le doy las gracias al director de mi proyecto, Jorge Mata Díaz por su ayuda y
tutelaje en el desarrollo del PFC, en el que gran parte de haberlo llevado a buen puerto
es gracias a él.
11
Sistema de video adaptativo H264/SVC sobre TCP
Resum
Durant els últims 20 anys, la comunitat científica ha estat estudiant la possibilitat de
desenvolupar un sistema de video escalable. Es va intentar desenvolupar als anys 90 a
l’estàndard MPEG2, però no va arribar a desenvolupar-se lo suficientment per a poder
convertir-lo en un projecte comercial.
L’any 2003, va aparèixer l’estàndard H264, amb el que es va aconseguir una millora important
en la taxa de compressió de video respecte al seu antecessor MPEG2. Es va aconseguir
mantenir la qualitat de la seqüencia de video amb taxes de compressió fins a un 50% més
grans que a l’estàndard anterior.
Amb el pas dels anys, s’han anat afegint annexos a l’estàndard H264, essent el més important
l’annex G, “Scalable Video Coding”, corresponent a l’ús de video escalable. Un flux escalable,
es defineix com aquell flux de dades, que pot ser descodificat i conformant amb l’estàndard al
filtrar fins a uns determinats atributs, eliminant part del flux de dades.
H264/SVC consta de tres atributs de dependència, els identificadors temporals, se resolució i
de qualitat. D’aquesta manera, SVC permet codificar una mateixa seqüencia de video amb
capes de millora de PSNR objectiva, i de millora de resolució. Per exemple, una seqüencia de
video codificada amb tres capes, capa base, capa de millora de qualitat i capa amb més
resolució, donarà lloc a diferents possibilitats de filtratge. És a dir, serà possible la extracció de
fluxos conformants amb resolució més alta i més baixa, diferents velocitats de reproducció, y
diferents PSNR.
L’objectiu d’aquest projecte, és el desenvolupament d’una aplicació de video escalable sota
demanda funcionant sobre el protocol de transport TCP. L’adequació al tipus de video i a les
condicions de xarxa són els paràmetres de disseny principals de l’aplicació. Concretament, el
principal objectiu ha obtenir, és que les transmissions de video siguin adaptatives a la connexió
de xarxa.
Actualment, existeixen molts sistemes de video sota demanda que utilitzen solucions
propietàries, com en el cas de “Flash Media Server”, i unes altres que utilitzen H264/SVC
(“Advanced Video Coding”), l’annex A de l’estàndard. Les dues més importants són sistemes de
video sota demanda i punt a punt a Internet, com per exemple, Youtube; i la Televisió Digital
Terrestre (TDT). Ambdós sistemes son susceptibles a l’aparició d’errors, i cadacún els combat
de forma diferent. Als sistemes de video per Internet, quan es perd un paquet utilitzant TCP, es
reenvia, en canvi, a la TDT s’utilitza OFDM per minimitzar els errors.
Els paràmetres principals de la connexió de xarxa que s’utilitzaran per a fer el sistema
adaptatiu, són l’ample de banda disponible, i el temps d’anada i tornada del paquets. El
paràmetre d’ample de banda disponible serà estimat pels “sockets” a partir de la grandària de
la finestra de congestió i el RTT de la connexió. D’aquesta manera, l’estratègia a seguir, serà
l’estimació a temps real dels amples de banda necessaris per transmetre fins una determinada
capa, i transmissions amb l’ample de banda més gran que sigui menor al disponible. Per
aconseguir-ho, es fa l’estimació de les longituds incloses a cada extracció (per a capes
Sistema de video adaptativo H264/SVC sobre TCP
12
superiors a la capa base, s’inclouran unitats NAL amb diferents atributs), i es rectifica l’ample
de banda amb la velocitat de reproducció, per a obtenir les estimacions en temps real.
Els instants d’estimació, vindran limitats per l’algoritme de filtrat adaptatiu. No serà possible
fer estimacions després de cada unitat NAL, perquè els fluxos amb canvis temporals de nivells
d’extracció, estaran limitats pel fet que cada tira B depèn de les dos tires I, P o B anteriors.
Això, fa que només es puguin elegir com a punts de tall les tires I amb DTQ igual a 000. A més,
les extraccions adaptatives seran d’alguna de les dues formes següents:
1. Canviar d’identificadors al punt de tall i filtrar les tires B següents.
2. Filtrar les tires I del canvi amb els identificadors anteriors i posteriors, incloent totes
les tires I que compleixin algun del dos requisits, i filtrar les tires B posteriors amb els
identificadors anteriors en temps, ja que depenen de les dos tires I, P o B anteriors.
L’altre paràmetre de la connexió de xarxa, és el temps de recepció. Per al cas d’un receptor en
temps real, es defineixen les següents estratègies de filtratge. Quan una unitat NAL es rebuda
més tard que l’instant de reproducció, es filtra automàticament. A més, s’ha de tornar a filtrar
al final de cadascuna de les iteracions (entre tira I amb DTQ igual a 000 i la següent amb els
mateixos atributs) amb els nous atributs límit obtinguts després de filtrar les tires que no han
arribat a temps, per a que el flux segueixi sent conformant.
En aquest projecte, s’han realitzat probes de xarxa en un entorn real, per a provar la utilitat del
sistema desenvolupat. Concretament, s’ha codificar el video BigBuckBunny amb tres capes,
capa base, capa de millora de qualitat i capa amb més resolució; i s’ha provat el sistema amb
dos routers entremitjos. Els resultat indiquen que realment es tracta d’un sistema que pot ser
l’alternativa als sistemes actual, sempre que es disposi d’una connexió de banda ampla.
13
Sistema de video adaptativo H264/SVC sobre TCP
Resumen
Durante los últimos 20 años, la comunidad científica ha estado estudiando la posibilidad de
desarrollar un sistema de video escalable. Se intentó desarrollar en los años 90 en el estándar
MPEG2, pero no llego a desarrollarse lo suficientemente para poder convertirlo en un proyecto
comercial.
En el año 2003, apareció el estándar H264, que conseguía una mejora importante en tasa de
compresión de video respecto a su antecesor MPEG2. Se consiguió mantener la calidad de la
secuencia de video con tasas de comprensión un 50% mayores al anterior estándar.
Con el paso de los años, se han ido añadiendo anexos al estándar H264, siendo el más
importante el anexo G, “Scalable Video Coding”, correspondiente al uso de video escalable. Se
define un flujo escalable, como aquel flujo de datos, que puede ser decodificable y
conformante con el estándar al filtrar hasta unos determinados atributos, eliminando parte del
flujo de datos.
H264/SVC consta de tres atributos de dependencia, los identificadores temporales, de
resolución y de calidad. De esta forma, SVC permite codificar una misma secuencia de video
con capas de mejora de PSNR objetiva, y de mejora de resolución. Por ejemplo, una secuencia
de video codificada con tres capas, capa base, capa de mejora de calidad y capa con más
resolución, dará lugar a varias posibilidades de filtrado. Es decir, será posible la extracción de
flujos conformantes con mayor y menor resolución, distintas velocidades de reproducción, y
PSNR diferentes.
El objetivo del presente proyecto, es el desarrollo de una aplicación de video escalable bajo
demanda sobre el protocolo de transporte TCP. La adecuación al tipo de video y a las
condiciones de red son los parámetros de diseño principales de la aplicación. En concreto, el
principal objetivo a alcanzar es que las transmisiones de video sean adaptativas a la conexión
de red.
Actualmente, existen muchos sistemas de video bajo demanda que utilizan soluciones
propietarias como es el caso de “Flash Media Server” de Adobe, y otras que utilizan H264/AVC
(“Advanced Video Coding”), el anexo A del estándar. Las dos más importantes son sistemas de
video bajo demanda punto a punto en Internet como Youtube; y la Televisión Digital Terrestre
(TDT). Ambos sistemas son susceptibles de la aparición de errores, y cada uno de ellos lo
combate de forma distinta. En los sistemas de video por Internet, cuando se pierde un paquete
utilizando TCP, se reenvía, mientras que en la TDT se utiliza OFDM para minimizar los errores.
Los parámetros principales de la conexión de red que se van a utilizar para hacer el sistema
adaptativo son el ancho de banda disponible, y el tiempo de ida y vuelta de los paquetes. El
parámetro de ancho de banda disponible va a ser estimado por los “sockets” a partir del
tamaño de la ventana de congestión y el RTT de la conexión. De esta forma, la estrategia a
seguir será la estimación en tiempo real de los anchos de banda necesarios para transmitir
hasta una determinada capa y transmisiones con el ancho de banda mayor que sea menor al
disponible. Para lograrlo, se hace la estimación de los tamaños incluidos en cada extracción
Sistema de video adaptativo H264/SVC sobre TCP
14
(para capas superiores a la base, se incluirán unidades NAL con diferentes atributos), y se
rectifica el ancho de banda con la velocidad de reproducción, para obtener las estimaciones en
tiempo real.
Los instantes de estimación vendrán limitados por el algoritmo de filtrado adaptativo. No será
posible hacer estimaciones detrás de cada unidad NAL, porque los flujos con cambios
temporales de niveles de extracción, vendrán limitados por el hecho de que cada tira B
depende de las dos tiras I, P o B anteriores. Esto hace que solo pueda cogerse como punto de
corte las tiras I con DTQ igual a 000. Además, las extracciones adaptativas van a ser de una de
las dos formas siguientes:
1. Cambiar de identificadores en el punto de corte y filtrar las tiras B siguientes
2. Filtrar las tiras I del cambio con los identificadores anteriores y posteriores, incluyendo
todas las tiras que cumplan uno de los dos requisitos, y filtrar las tiras B posteriores
según los identificadores anteriores en tiempo, debido a que dependen de las dos tiras
I, P o B anteriores.
El otro parámetro de la conexión de red, es el tiempo de recepción. En el caso de un receptor
para trabajar a tiempo real, se definen las siguientes estrategias de filtrado. Cuando una
unidad NAL es recibida en un instante temporal mayor al instante de reproducción, se desecha
automáticamente. Además, se debe volver a filtrar al final de cada iteración entre I con DTQ
igual a 000 y la siguiente, con los nuevos atributos limite obtenidos después de filtrar las tiras
que no han llegado a tiempo, para que el flujo resultante siga siendo conformante.
En el presente proyecto, se han realizado pruebas de red en un entorno real, para probar la
utilidad real del sistema desarrollado. En concreto, se ha codificado el video BigBuckBunny con
tres capas, capa base, capa de mejora de calidad y capa con más resolución; y se ha probado el
sistema con el uso de dos routers intermedios. Los resultados indican que realmente se trata
de una alternativa válida a los sistemas actuales, siempre que se disponga de una conexión de
ancha banda.
15
Sistema de video adaptativo H264/SVC sobre TCP
Abstract
During last 20 years, scientific community has been studying scalable video coding developing
possibility. In nineties, they try to develop it in MPEG2 standard, but it was not enough
developed in order to become a commercial project.
In year 2003, it appears H264 standard, getting a significant improvement of video
compression tax against his predecessor MPEG2. They got maintain quality video sequence
achieving 50% major video compression taxes.
During years, H264 annex has been appeared. The most important annex is G annex, “Scalable
Video Coding”, which corresponds to scalable video use. An scalable bit stream is defined as
that bit stream which could be decoded and standard confortable when it is filtered with
specific attributes, deleting part of bit stream.
H264/SVC standard has three dependency attributes, temporal, resolution and quality
identifiers. Thus, SVC allows to code the same video sequence with PSNR and resolution
improvement layers. For example, a coded video sequence of three layers, base layer,
improvement quality layer and improvement resolution layer, become in different filtering
possibilities. Therefore, it could be possible conformant extractions with different PSNR,
resolution and playing velocity.
The project objective is develop an scalable video on demand application over TCP protocol.
Principal application parameters are video type and net conditions adequacy. Specifically,
achieved principal objective is that video transmissions become network connection adaptive.
Actually, it exists a lot of video on demand systems, which use proprietary solutions such as
“Flash Media Server”, or they use H264/AVC (“Advanced Video Coding”), A annex of H264
standard. Two most important applications are point to point Internet video on demand
systems and Digital Television (TDT). Both systems are susceptible of error appearance but
each one fight differently errors. In Internet video systems, when a packet is lost using TCP, it
is forwarded, while in TDT it is used OFDM in order to minimize transmission errors.
Principal network connection parameters, which will be used in order to become and adaptive
system, are available network bandwidth and packet round trip time. Available bandwidth
parameter will be estimated by sockets from congestion window size and connection RTT.
Thus, the strategy will be real time estimation of necessary bandwidth in order to transmit up
to a certain layer, and transmit with maximum bandwidth less than available bandwidth. In
order to achieve this, extraction included sizes are estimated (for superior layers than base
layer, it will be included NAL units with different attributes), and it is rectified bandwidth with
playing velocity, in order to obtain real time estimations.
Estimation moments are limited by adaptive filter algorithm. It could not be possible to
estimate after every NAL unit, because bit streams with temporal changes, will be limited by
the fact that every B slice depends on last two I, P or B slices. Therefore, it could only catch
cutoff point in I slices with DTQ equal to 000. Furthermore, adaptive extractions will be of one
of the two following:
Sistema de video adaptativo H264/SVC sobre TCP
16
1. Change identifiers in cutoff point and filter following B slices.
2. Filter change I slices with both identifiers, previous and posterior, including all slices
which comply one of both requisites, and filter posterior B slices by previous time
identifiers, due to, they depend on last two I, P or B slices.
The other network connection parameter is receiver time. In real time applications, there are
defined the following filtering strategies. When a NAL unit is received after its playing moment,
it is filtered. Furthermore, it has to be filtered another time after every iteration between I
slice with DTQ equal 000 and following next I slice with DTQ equal 000, with new limit
attributes obtained after filtering slices which had not arrived at time, in order to obtain a
H264 conformant resultant bit stream.
In this project, there have been made network test in a real environment, in order to check
developed system real utility. Specifically, it has been coded BigBuckBunny video sequence
with three layers, base layer, PSNR quality improvement layer, and resolution improvement
layer; and it has been checked the system by the use of a network environment which contain
two intermediate routers. Obtained results indicate that it is really a valid alternative to actual
systems, if we have a broadband connection.
17
Sistema de video adaptativo H264/SVC sobre TCP
Sistema de video adaptativo H264/SVC sobre TCP
18
Capítulo 1:
Introducción:
En los últimos años se han desarrollado un gran conjunto de sistemas de video bajo
demanda en diferentes entornos, desde sistemas de televisión por pago, hasta
sistemas de videos bajo demanda en Internet, como por ejemplo “Youtube” o
“Vimeo”.
El objetivo del presente proyecto, es el desarrollo de otro sistema de video bajo
demanda, que sea adaptativo a las condiciones de red, y que tome provecho de las
diferentes características del video transmitido. Así, la principal innovación del
presente proyecto es el hecho de trabajar con H264/SVC, la extensión del estándar
H264 en su anexo G. El estándar es el documento “ITU-T H.264 Advanced video coding
for generic audiovisual services (2012).
Hasta ahora, la mayoría de sistemas bajo demanda habían sido implementados con los
protocolos RTP (“Real Time Transport Protocol”), o sus versiones con mejoras de
seguridad RTSP (“Real Time Streaming Protocol”) y RTCP. También en versiones
comerciales como el caso de Adobe con “Flash Media Server” junto con toda la
tecnología “Flash”, “ActionScript” y “Flex”, que mediante el uso de códec propietarios
(“VP6 Sorenson” en el video) permitía el desarrollo de sistemas de video bajo demanda
sobre HTTP y TCP.
El principal reto que se nos plantea en el presente proyecto, es el del desarrollo de un
sistema que sea fiable extremo a extremo independientemente de cual sea su sistema
de acceso (“Wifi”, “ADSL”, “WiMAX”, “FTTH”, …), razón por la cual se va a trabajar
sobre TCP, protocolo orientado a conexión, fiable y con control de errores extremo a
extremo. Se tendrá que tratar con todos los problemas asociados a su uso, como es el
caso que al inicio de la conexión, en la etapa de “slow start” las transmisiones no van a
ser lo suficientemente rápidas como para que se pueda recibir el contenido en tiempo
de reproducción, razón por la que se van a utilizar búferes en recepción para controlar
el flujo transmitido.
En concreto, con el uso de H264/SVC, que define los flujos de datos con diferentes
atributos de escalabilidad nos permitirá transmitir hasta una determinada capa
durante un cierto tiempo, y hasta otra determinada capa durante otro cierto tiempo.
La idea principal es la de codificar con diferentes capas con atributos de velocidad de
reproducción, resolución y PSNR diferentes, combinándolos todos en un flujo de datos
único. De esta manera será posible filtrar con unos determinados atributos de los
comentados anteriormente, para transmitir con condiciones del video cambiantes, que
se adapten a las condiciones de red existentes.
19
Sistema de video adaptativo H264/SVC sobre TCP
Así, la conexión de red vendrá principalmente caracterizada por el ancho de banda
disponible para transmisión y el tiempo de transmisión extremo a extremo,
parámetros de los que se va a sacar provecho en la búsqueda de un algoritmo de
transmisión que sea adaptativo a estas condiciones de red. En concreto, se van a
controlar los tamaños de transmisión de las diferentes capas en busca de la capa con
mayor calidad posible para ser transmitida, que cumpla la restricción que el tamaño
transmitido se pueda recibir y decodificar en tiempo real.
El proyecto constara de los capítulos siguientes:
1. Presentación de H264 y del software disponible para H264/SVC.
2. Descripción detallada de H264/SVC.
3. Descripción detallada de los algoritmos de filtrado y de filtrado adaptativo de
flujos de datos H264/SVC.
4. Descripción detallada de TCP y de la estimación del ancho de banda de
transmisión.
5. Descripción detallada de la implementación del sistema transmisor y de los
criterios de diseño del receptor en caso de buscar un sistema en tiempo real.
6. Resultados obtenidos y líneas futuras.
1.1.
JSVM y OpenSVCDecoder:
Actualmente, existen un codificador y dos decodificadores de H264/SVC. El software
correspondiente es “Join Scalable Video Model” (JSVM) y “OpenSVCDecoder”.
JSVM, es un software desarrollado por el “Joint Video Team” del ISO/IEC “Moving
Pictures Experts Group” (MPEG) y el ITU-T “Video Coding Experts Group” (VCEG), capaz
de codificar y decodificar flujos de video en el estándar H264/SVC.
“OpenSVCDecoder” es una librería desarrollada por el IETR/INSA de la ciudad de
Rennes, que implementa un decodificador de flujos H264/SVC en tiempo real.
“OpenSVCDecoder” se usa conjuntamente con el reproductor “Mplayer” y permite
visualizar flujos de datos codificados en SVC.
1.2.
Proyectos similares:
El proyecto más similar al que se presenta en este documento, es el “MPEG DASH
(Dynamic Adaptive Streaming over HTTP)”, el cual a diferencia del actual que trabaja
con SVC, trabaja con la transmisión de flujos H264/AVC.
El parámetro de diseño principal de “MPEG Dash” es que concentra flujos de
diferentes calidades (parámetro de cuantificación diferente), y los transmite
Sistema de video adaptativo H264/SVC sobre TCP
20
adaptativamente a las condiciones de red, seleccionando las unidades NAL de un flujo
o de otro en función de las condiciones de red.
El funcionamiento es inverso al proyecto actual, en este caso la estimación se hace en
recepción, donde a partir del tamaño de ocupación del buffer se hace una estimación
del ancho de banda al que se va a solicitar la recepción. Se entiende que cuando se
llena se puede pedir más velocidad de transmisión porque la velocidad de red es
mayor a la de reproducción, y que cuando se vacía se debe reducir la velocidad de
transmisión.
Los perfiles de los proyectos son muy similares, pero la diferencia principal es que en
“MPEG Dash” se transmite flujo AVC, y en el presente proyecto se transmiten flujos
SVC, con las ventajas asociadas a este estándar.
1.3.
Medidas objetivas de calidad:
Para medir objetivamente una secuencia de video utilizamos el PSNR (“Peak Signal to
Noise Ratio”) en dB. Se define como el coeficiente entre el valor máximo que puede
tener una secuencia al cuadrado y el error cuadrático medio de la secuencia.
Se considera como una medida de calidad objetiva, ya que cuantifica el error
producido en el tratamiento de la secuencia de video. En general, cuanto mayor sea la
PSNR en dB mayor será la calidad de la secuencia de video reconstruida.
1.4.
Introducción a H264:
H264 es un estándar de codificación digital de video que introduce muchas mejoras de
compresión respecto a sus predecesores MPEG2 y MPEG4 Visual, de los que hereda
muchas de sus características de codificación.
H264 está desarrollado por “Joint Video Team”, formado a su vez por los equipos del
ITU-T VCEG y el ISO/IEC MPEG. El documento estándar publicado en 2003, no define
como codificar el video, pero sí define toda la implementación del decodificador, con
lo que para codificar se puede llevar a cabo el procedimiento inverso.
21
Sistema de video adaptativo H264/SVC sobre TCP
A continuación se van a ver las principales características del proceso de codificación y
decodificación.
El proceso de codificación consta de tres etapas principales:
1. Predicción: Ya sea intra-predicción o inter-predicción, en función de si se
predice desde el propio a anteriores fotogramas.
2. Transformación y cuantificación: Se pasa la información al dominio
transformado y se cuantifica.
3. Codificación entrópica: Codificación en palabras de longitud variable del
resultado.
Figura 1.1: Esquema de codificación H264/AVC
1.4.1. Predicción:
El codificador procesa todo el contenido del fotograma en macro-bloques que van de
16x16 a 4x4 en muestras de luminancia y de 8x8 a 2x2 en muestras de crominancia,
debido al submuetreo 4:2:0 del video. Durante este proceso se realizan predicciones a
partir de los bloques ya codificados. Se conoce como Intra-predicción cuando los
macro-bloques proviene del mismo fotograma, y como Inter-predicción cuando los
macro-bloques proviene de otro fotograma previamente codificado.
La predicción será necesaria en función del error cuadrático medio, en los Intrapredecidos habrá casos en que será más eficiente enviar su información directamente.
En los casos en que sí sea necesario realizar la predicción, se obtiene el residual entre
la predicción hecha y los valores del macro-bloque actual.
La inter-predicción se conoce como estimación de los vectores de movimiento,
mientras que la compensación de movimiento es el proceso de la obtención de los
residuales a partir de la Inter-predicción.
Sistema de video adaptativo H264/SVC sobre TCP
22
La Intra-predicción utiliza bloques de 16x16 hasta 4x4 píxeles para realizar la
predicción a partir de los macro-bloques contiguos. Las formas de extrapolar para los
casos de 4x4 muestras son las siguientes:
Figura 1.2: Esquema intra-predicción de bloques 4x4
Como se puede ver en la figura 1.2, las formas de extrapolar en el caso de 4x4 muestras son de
arriba abajo, prediciendo las muestras inferiores a partir de las superiores; de izquierda a
derecha, promediando las muestras de arriba y de la izquierda; y varias combinaciones en
diagonal dando más peso a muestras de dos de los lados del macro-bloque.
Y en el caso de 16x16 muestras:
Figura 1.3: Esquema intra-predicción de bloques 16x16
Como se puede ver en la figura 1.3, las formas de extrapolar en el caso de 16x16
muestras son de arriba abajo, de izquierda a derecha, promediando las muestras de
arriba y de la izquierda y en combinaciones diagonales de las muestras de abajo a la
izquierda y arriba a la derecha.
La inter-predicción se hace con bloques de 16x16 píxeles a 4x4 píxeles, y se utiliza para
sacar provecho de las regiones similares entre diferentes fotogramas. Tal como se
puede ver en la figura 1.4 se predicen regiones del fotograma predicho a partir de
macro-bloques de los fotogramas de referencia, cogiendo tamaños variables con
bloques de 16x16 a 4x4 muestras, en función del error cuadrático medio de la
predicción.
23
Sistema de video adaptativo H264/SVC sobre TCP
Figura 1.4: Esquema inter-predicción
1.4.2. Transformación y cuantificación:
En H264, se transforma a partir de la “Transformada Discreta del Coseno” (DCT), para
obtener un conjunto de coeficientes prácticamente incorrelados y en los que la energía
se concentra en un poco número de ellos.
La DCT se basa en multiplicar por delante y por detrás por una matriz A y A transpuesta
respectivamente, a la matriz que contiene los coeficientes. Los coeficientes de la
matriz son:
Para el caso de 4x4 muestras, la matriz A es la siguiente:
A la salida de la transformación, tendremos un bloque de coeficientes transformados,
en los que la energía se va a concentrar en pocos de ellos. Una vez se ha transformado
se pasa al proceso de cuantificación, en el que a partir de un parámetro de
cuantificación (QP) se van dividiendo por el parámetro de cuantificación los
coeficientes resultantes, dando lugar a muchos ceros. De esta forma, cuando mayor
sea el parámetro de cuantificación, mayor será el número de ceros y más información
se perderá, y cuanto menor sea más información se conservará y, por lo tanto, mejor
calidad tendrá el video reconstruido.
1.4.3. Codificación entrópica:
Sistema de video adaptativo H264/SVC sobre TCP
24
El resultado de la transformación y cuantificación en forma de coeficientes
transformados o de residuales de la predicción deben ser estructurados de alguna
forma para la posterior transmisión en forma de flujo.
En H264 se utilizan dos codificaciones entrópicas con palabras de longitud variable.
Estas codificaciones son “Context Adaptive Variable Length Coding” (CAVLC) y “Context
Adaptive Binary Arithmetic Coding” (CABAC).
La diferencia principal entre las dos codificaciones es que con CABAC se consiguen
compresiones mayores aunque su complejidad algorítmica es mucho mayor que en
CAVLC, lo que se traduce en la necesidad de más recursos computacionales para poder
llevar a cabo las codificaciones.
En este proyecto, se ha elegido el uso de CAVLC, y se va a ver como realmente se
consiguen altas tasas de compresión, a pesar de ser el algoritmo con tasas de
compresión menores entre los dos a elegir.
25
Sistema de video adaptativo H264/SVC sobre TCP
Capítulo 2:
H264/SVC:
En este capítulo vamos a ver todos los conceptos necesarios sobre el anexo G del
estándar H264, para facilitar la correcta comprensión del proyecto en desarrollo.
Partiendo de la definición de flujo decodificable en H264/AVC, se generaliza en
H264/SVC el concepto de flujo de datos escalable, como el flujo tal que se pueden
extraer sub-flujos decodificables, dividiendo el flujo de datos en distintas capas.
Se muestra a continuación el esquema general de codificación del H264/SVC.
Figura 2.1: Esquema de codificación H264/SVC
2.1.
Conceptos de escalabilidad:
En H264/SVC se definen tres tipos de escalabilidad, escalabilidad temporal, ya propia
de H264/AVC, escalabilidad espacial, que consiste en diferentes capas con resolución
espacial diferente, y escalabilidad de calidad, que consiste en diferentes pasos de
cuantificación (QP), dando lugar a capas de mayor o menor PSNR.
2.1.1. Escalabilidad temporal:
Sistema de video adaptativo H264/SVC sobre TCP
26
Se define la escalabilidad temporal como la capacidad de partir en tiempo una capa en
diferentes casos de identificador de dependencia temporal (T0, …, Ti). La escalabilidad
temporal, ya es propia del estándar H264/AVC, de forma que funciona igual en AVC
que en SVC.
Se entiende por escalabilidad temporal los niveles de dependencia entre tiras B, de
forma que cada nueva capa que se añade se traduce en doblar el número de tiras B de
la estructura del orden de reproducción. Las tiras B se forman de la forma siguiente.
Figura 2.2: Estructura de bipredicción
En las tiras B se realiza un proceso de bipredicción, a partir de las listas cero y uno de
tiras I, P o B anteriores y posteriores al orden de reproducción. En el uso de
escalabilidad temporal se utilizan estructuras de predicción jerárquicas y diádicas. En
general en el caso de estructuras diádicas se obtiene un número de capas
correspondiente al logaritmo en base dos del tamaño de GOP más uno.
número de capas = log(GOP_size) + 1
Existen tres casos a contemplar, como se verá en la figura siguiente, estructura diádica,
no diádica y el caso de solo usar tiras P inter-predichas.
La estructura diádica es cuando se multiplica por dos el número de tiras B al
incrementar el número de identificadores de escalabilidad temporal. En concreto,
cuando se pone la primera B se añade una entre tiras I y P, y a partir de la primera B
con cada identificador temporal que se añade se añaden el doble de tiras I de las que
había. De esta forma se genera una estructura en la que las tiras B que se añaden se
van intercalando a derecha e izquierda de las otras tiras I, P o B anteriores en tiempo
de transmisión formando la estructura que se muestra en el caso a) de la figura 2.3.
Este caso se corresponde con una estructura diádica con un tamaño de GOP igual a
ocho, dando lugar a la capa base más tres capas de mejora.
27
Sistema de video adaptativo H264/SVC sobre TCP
El caso b) muestra la estructura de GOP no diádica para un tamaño de GOP igual a
nueve. Como se puede ver en la figura a partir de las tiras I se predicen las dos tiras P
siguientes, y a partir de las tiras I y P se hace la bi-predicción de dos tiras B
intermedias. La estructura es no diádica porque no respeta que se vayan añadiendo
tiras B multiplicando por dos e intercalándolas secuencialmente, tal como sucede en la
figura del caso a).
El caso c) muestra una estructura diádica para el caso de solo usar tiras P. En este caso,
a partir de la tira I inicial se predicen tres tiras P intermedias, y a partir de las tiras P
intermedias se predicen más tiras P posteriores en tiempo de reproducción.
Normalmente, cuando nos encontremos con una estructura de este tipo se va a tratar
de un tamaño de GOP igual a uno en el que cada tira P posterior en tiempo va a
depender de la tira I o P anterior en tiempo.
Figura 2.3: Estructura diádica y no diádica
2.1.2. Escalabilidad espacial:
La escalabilidad espacial, está basada en la capacidad de escalar en tamaño la
resolución del video de menor a mayor tamaño. Así, las capas superiores dependen de
las inferiores. En este caso aparte de las predicciones inter e intra, se añade el caso de
la predicción entre capas.
Se muestra a continuación un ejemplo con dos capas de escalabilidad espacial.
Sistema de video adaptativo H264/SVC sobre TCP
28
Figura 2.4: Escalabilidad espacial
La predicción entre capas se realiza de tal forma que se utiliza información propia de la
capa y de las capas inferiores. En concreto hay tres tipos de predicción entre capas:
1. Predicción de los vectores de movimiento (Inter-Layer Motion Prediction, M):
Consiste en sacar versiones interpoladas de los vectores de movimiento de la
capa inferior.
2. Predicción a partir del residual (Inter-Layer Residual Prediction, R): Se interpola
el residual de la capa inferior.
3. Predicción de macro-bloques intra-predecidos (Inter-Layer Intra Prediction): Se
interpola la intra-predicción realizada en la capa inferior.
La diferencia principal entre usar M y R, es que cuando se trabaja con la interpolación
de los vectores de movimiento, en la siguiente tira se sigue prediciendo desde la capa
base, mientras que cuando se trabaja con R, en las tiras siguientes se sigue trabajando
con inter-predicción en la capa superior.
2.1.3. Escalabilidad de calidad:
La escalabilidad de calidad se basa en el uso de dos o más capas con la misma
resolución pero con diferente parámetro de cuantificación a la hora de obtener el valor
de los coeficientes transformados.
En H264/SVC se utiliza “Medium-Grain Scalability Coding” (MGS), que permite predecir
desde la propia capa y desde las capas inferiores los valores de los residuales en cada
caso. Se caracteriza por el hecho de permitir partir los coeficientes transformados en
diferentes capas de mejora, asegurándose que se va a poder reconstruir usando los
coeficientes de las capas inferiores en caso de que no se disponga de todos los
coeficientes transformados en la capa superior.
La ventaja principal de usar MGS respecto a sus antecesores, es que nos permite el
intercambio entre capas en cualquier momento. En MPEG4 se utilizaba “Fine-Grain
Scalability Coding”, que a diferencia de la escalabilidad de SNR, predecía todas las
29
Sistema de video adaptativo H264/SVC sobre TCP
capas de mejora a partir de la capa base. En el otro extremo esta lo que se planteo en
MPEG2, que consistía en predecir todas las capas a partir de la de mejora. El problema
principal que apareció es que no se obtenía unas buenas tasas de codificación
comparado con el caso de transmitir varios flujos codificados con AVC, a diferencia del
caso de MGS que si se consiguió.
En MGS se utilizan fotogramas clave, que sirven para re-sincronizar la capa base con
las capas de mejora. De esta forma, se almacenan los fotogramas clave para no tener
que recodificar los fotogramas clave en las capas de mejora.
En la figura siguiente se muestran las diferentes estrategias de codificación en
escalabilidad de SNR.
Figura 2.5: Estructuras de dependencia de calidad
El caso a) es el correspondiente a FGS, b) es el extremo opuesto propuesto en MPEG2,
c) es un caso intermedio y d) es el caso de MGS.
2.1.4. Escalabilidad híbrida:
El concepto general de escalabilidad en el estándar H264/SVC, se basa en las posibles
combinaciones de los tres tipos de escalabilidad, dando lugar a flujos de datos
conformantes con diferentes combinaciones de los tres tipos de escalabilidad. Así se
podría generar secuencias de video codificadas con varias capas de escalabilidad
temporal y de SNR dentro de cada capa con una resolución diferente.
2.2.
Cabecera de las unidades NAL:
En H264 hay tres tipos de unidades NAL:
1. VCL NALU: son propiamente las unidades NAL que contienen la información
codificada de la secuencia de video.
2. Non-VCL NALU: Contienen conjuntos de parámetros de codificación,…
Sistema de video adaptativo H264/SVC sobre TCP
30
3. Cabeceras NALU del flujo de datos.
En este apartado vamos a analizar las cabeceras de las VCL NALU en H264/SVC.
En H264/AVC las cabeceras de la unidad NAL son de un byte de longitud, en cambio las
SVC contienen cuatro bytes de longitud, teniendo el primer byte el mismo contenido
que en AVC. En SVC se utilizan las unidades NAL de tipo 20, que son las unidades NAL
de tiras codificadas de extensión escalable.
Figura 2.6: Estructura del primer byte de la cabecera de las unidades NAL
F: 1 bit
forbidden_zero_bit: Se define que cuando valga uno indica un error en la
sintaxis.
NRI: 2 bits
nal_ref_idc: Un valor de 00 indica que la unidad NAL no será necesaria para
reconstruir fotogramas de referencia en predicciones futuras. Se puede descartar la
unidad NAL siempre que su valor sea de 00 pudiendo seguir decodificando sin su
existencia. Las tiras B de las que dependen otras tiras B según la estructura diádica
nunca tendrán un valor de 00, mientras que serán las tiras B de las que no depende
ninguna unidad NAL las que tendrán un valor de 00.
TYPE: 5 bits
nal_unit_type: Indica el tipo de unidad NAL en cuestión.
Los valores posibles en H264/AVC son los siguientes:
Figura 2.7: Tipos de unidad NAL H264/AVC
En SVC los valores posibles son los siguientes:
31
Sistema de video adaptativo H264/SVC sobre TCP
Figura 2.8: Tipos de unidad NAL H264/SVC
Los principales tipos de unidad NAL son las unidades NAL VCL (tipos 1, 2, 3, 4 y 5),
correspondientes en H264/AVC a la codificación parcial o total de una tira en instante
de refresco instantáneo, o sin instante de refresco instantáneo, y las non-VCL (tipos 6,
7 y 8) correspondientes al envió de información sobre la secuencia (SPS), sobre los
fotogramas (PPS), o de información suplementaria para la decodificación (SEI).
En H264/SVC, se añaden las unidades NAL correspondientes a la información
codificada para las capas superiores, llamadas de extensión de tira escalable (tipo 20),
las de información de capa a nivel de secuencia (SSPS, tipo 15) y las Prefix NAL Unit
(tipo 14), para contener información de compatibilidad con H264/AVC.
En H264/SVC además se añaden otros tres bytes que contienen la información de capa
superior para las unidades NAL de tipo 14 y 20.
Figura 2.9: Estructura de los tres últimos bytes de la cabecera de las unidades NAL en
H264/SVC
R: 1 bit
reserved_one_bit: Bit reservado para extensiones futuras.
I: 1 bit
idr_flag: Indica si se trata de una unidad NAL de IDR (vale 1), o no. Las tiras IDR,
tienen la peculiaridad que permiten resetear los errores propagados, ya que se
decodifican por si solas.
PRID: 6 bits
priority_id: Indica la prioridad de la unidad NAL. Cuanto menor es su valor, más
prioridad tiene la unidad NAL. Básicamente, los valores introducidos se ciñen a los
niveles de dependencia, de forma que una unidad NAL de una tira I en la primera capa
Sistema de video adaptativo H264/SVC sobre TCP
32
de mejora será la más prioritaria de todas y a medida que se suben capas hasta llegar a
la capa superior en las tiras B sin que otras tiras B dependan de la bi-predicción se
asignara los valores más altos.
N: 1 bit
no_inter_layer_pred_flag: Indica que se debe usar predicción entre capas para
decodificar la tira (vale 1) o no.
DID: 3 bits
dependency_id: Identifica el nivel de dependencia espacial de la unidad NAL.
Un valor de cero indica capa base, y a medida que aumenta se va pasando a las capas
superiores. Existen ocho resoluciones posibles.
QID: 4 bits
quality_id: Identifica el nivel de dependencia de calidad de las capas MGS. Para
una capa (Di, Ti, Qi) existe una capa (Di, Ti, (Qi – 1)) a partir de la que se hace
predicción entre capas. Existen diez y seis niveles de escalabilidad de calidad por nivel
de resolución.
TID: 3 bits
temporal_id: Identifica el nivel de dependencia temporal de la capa. Una capa
con un determinado identificador temporal depende siempre de los identificadores
temporales inferiores pero nunca superiores. Existen ocho niveles de dependencia
temporal por cada capa de calidad y/o resolución.
U: 1 bit
use_ref_base_pic_flag: Indica que se utilizan fotogramas base de referencia
para la inter-predicción (vale 1) o no (vale 0).
D: 1 bit
discartable_flag: Cuando vale uno indica que la unidad NAL actual no se utiliza
para decodificar otras unidades NAL con valores superiores de dependency_id, ni en
esta unidad de acceso ni en ninguna otra AU. Estas unidades NAL pueden ser
descartadas sin comprometer la integridad de las capas con identificador de
dependencia superior.
O: 1 bit
output_flag: Cuando vale uno indica que esta unidad NAL se utilizará para el
proceso de decodificación de otras tiras posteriores en tiempo de transmisión.
33
Sistema de video adaptativo H264/SVC sobre TCP
RR: 2 bits
reserved_three_2_bits: Bits reservados para extensiones futuras. Debe valer
“11”.
2.3.
Sintaxis de las unidades NAL:
En el estándar H264 se proponen varios tipos de lectura, en función de cómo están
estructurados los datos de las unidades NAL. En concreto se propone:




u(n): Leer n bits y devolver su valor como natural (unsigned).
u(v): Leer v bits que son función de otros parámetros y devolver su valor como
natural (unsigned).
ue(v): Leer un código Exp-Golomb y devolver su valor como natural (unsigned).
se(v): Leer un código Exp-Golomb y devolver su valor como entero (signed). El
signo positivo va con los números pares.
Los códigos Exp-Golomb son una codificación entrópica caracterizada por palabras de
longitud variable. Estos códigos se generan de la forma siguiente:
[sucesión de zeros][1][información]
número_ceros_sucesión = floor(log2(número_codigo + 1);
información = número_codigo + 1 – exp(2, número_ceros_sucesión);
Tabla 2.1: Lista de ejemplos de codificación Exp-Golomb
Y se decodifican de la forma siguiente:
número_ceros_sucesión = read(ceros);
información = read(número_ceros_sucesión después de uno);
Sistema de video adaptativo H264/SVC sobre TCP
34
número_codigo = información + exp(2, número_ceros_sucesión) – 1;
En H264 hay tres tipos de unidades NAL tal y como se ha comentado antes, las
unidades NAL VCL, las non-VCL y las cabeceras. Vamos a ver a continuación los
parámetros más importantes de los distintos tipos de unidad NAL.
2.3.1. Unidades NAL non-VCL:
Son las unidades NAL, que nos aportan información a nivel de secuencia o de
fotograma, para la posterior correcta decodificación. Las comunes en AVC y SVC son:



Supplemental Enhancement Information (SEI).
Sequence Parameter Set (SPS).
Picture Parameter Set (PPS).
Además en H264/SVC se añaden las siguientes:


Prefix NAL Unit.
Subset Sequence Parameter Set (SSPS).
2.3.1.1.
Supplemental Enhancement Information:
Los SEI aportan información acerca de la secuencia de video y su organización. Hay
alrededor de 40 tipos de mensaje SEI pero nos vamos a centrar en el
“Scalability_Information_SEI”, que solo se utiliza en SVC, y proporciona toda la
información de cómo está estructurada la secuencia de video.
Los elementos sintácticos más importantes que forman parte de este tipo de mensaje
SEI son:
num_layers_minus1: Indica el número de combinaciones diferentes de los
parámetros DTQ que forman la secuencia de video, es decir indica el número de capas
de la codificación.
layer_id: Asigna un identificador a cada capa. El identificador de capa es único,
y es un parámetro intercambiable por los tres siguientes.
dependency_id: Identificador de dependencia espacial de cada capa.
quality_id: Identificador de dependencia de calidad de cada capa.
temporal_id: Identificador de dependencia temporal de cada capa.
frame_height_in_mbs_minus1: Indica la altura en macro-bloques de los
fotogramas.
35
Sistema de video adaptativo H264/SVC sobre TCP
2.3.1.2.
Sequence Parameter Set:
El “Sequence Parameter Set” contiene información acerca de los parámetros de
codificación usados en origen, y se debe transmitir para que el decodificador pueda
realizar la función inversa en recepción. Solo puede haber uno en todo el flujo de datos
y se corresponde con la capa base. Para las demás capas están los “Subset Sequence
Parameter Set” que contiene el SPS.
Los elementos sintácticos más importantes en el SPS son:
seq_parameter_set_id: Un identificador para que los PPS puedan referenciar de
que SPS dependen.
pic_order_cnt_type: Un valor de cero indica que en la cabecera de la tira
tendremos su orden dentro del GOP. Los demás valores están sin definir. Siempre a
cero.
pic_width_in_mbs_minus1: Indica la anchura en macro-bloques del fotograma.
2.3.1.3.
Picture Parameter Set:
Los PPS contiene información para decodificar, principalmente sobre la capa de
cuantificación. Puede haber uno para cada capa de las que forman el flujo de datos, y
llevan asociado un SPS para la capa 000, y un SSPS para las demás.
Los elementos sintácticos más importantes en el PPS son:
pic_parameter_set_id: Un identificador del conjunto de parámetros a nivel de
fotograma para poder referenciarlo desde la cabecera de la tira.
seq_parameter_set_id: Identificador del SPS o SSPS del cual depende.
entropy_coding_mode_flag: Nos indica si la codificación de datos de la
secuencia de video se ha realizado con CAVLC (0) o CABAC (1). Ambos tipos de
codificación son codificadores entrópicos con longitud de las palabras variables, y se
aplican a los coeficientes transformados en forma de codificación.
2.3.2. Unidades NAL VCL:
Las unidades NAL VCL son las que contienen la información útil del video. En función
del tipo de unidad NAL se pueden clasificar en “Coded Slice of a non-IDR Picture”,
“Coded Slice of an IDR Picture” y las “Coded Slice Extension” propias de SVC. Por tipo
de tira se pueden clasificar en tiras I (Intra-predecidas), tiras P (inter-Predecidas) y tiras
B (Bipredecidas).
Todas las unidades NAL VCL, constan de la cabecera de la unidad NAL ya analizada en
apartados anteriores y de la cabecera de la tira, que nos dará toda la información para
Sistema de video adaptativo H264/SVC sobre TCP
36
decodificar, ya que referencia al “Picture Parameter Set” que a su vez referencia al
“Sequence Parameter Set” o “Subset Sequence Parameter Set” correspondiente.
2.3.2.1.
Coded Slice of non-IDR Picture:
Las tiras codificadas de una imagen que no son de instante de refresco instantáneo,
son aquellas que forman parte de la capa base, y que además de poder ser tiras I,
como en el caso IDR, pueden ser tiras P o B. Se caracterizan por ser iguales en
H264/AVC que en H264/SVC.
Los elementos sintácticos más importantes de la cabecera de las tiras no IDR son:
first_mb_in_slice: Indica la posición del primer macro-bloque en la tira. En
principio vale cero, pero si la tira fuera demasiado grande para caber en una unidad
NAL, se utiliza para indicar la posición relativa en número de macro-bloques.
slice_type: Indica el tipo de tira. Las tiras I son el número 2, las P el número 0 y
las B el número 1.
pic_parameter_set_id: Indica de que “Picture Parameter Set” depende.
pic_order_cnt_lsb: Nos indica cual sera el orden de decodificación, el cual va a
seguir la estructura del GOP.
direct_spatial_mv_pred_flag: Indica si esta activa (1) o desactiva (0) la
predicción directa entre capas. Un valor de cero indica que se pueden coger las tiras
anterior y posterior para la decodificación temporal.
Los elementos sintácticos más importantes de la parte de datos de las tiras son:
mb_skip_run: Se utiliza en CAVLC, e indica el número de macro-bloques no
codificados o perdidos.
mb_skip_flag: Se utiliza en CABAC, e indica si el macro-bloque presente se
reconstruye con datos de la propia tira o de otras.
2.3.2.2.
Coded Slice of an IDR Picture:
Las tiras codificadas de una imagen de refresco instantáneo de decodificación, solo
pueden ser tiras I, y nunca tendrán ningún mb_skip_flag igual a uno, ni ningún
mb_skip_run diferente de cero. Se utilizan como punto de recuperación de errores, ya
que dichas unidades NAL no dependen de ninguna otra.
Los elementos sintácticos de estas unidades NAL son los mismos de las no IDR, con lo
que la cabecera de la tira contiene los mismos campos.
2.3.2.3.
Coded Slice Extension:
37
Sistema de video adaptativo H264/SVC sobre TCP
Son las tiras propias de las capas superiores según H264/SVC. Mantienen mucha
similitud con la sintaxis de H264/AVC (la parte de datos es igual). Sin embargo, se
añaden algunos campos importantes para la caracterización de la escalabilidad.
Los elementos sintácticos más importantes que se añaden respecto a las de AVC son:
store_ref_base_pic_flag: Indica si se debe tener en cuenta la tira
inmediatamente inferior, según niveles de dependencia, en el proceso de predicción
de los vectores de movimiento de los macro-bloques de los datos de tira.
ref_layer_dq_id: Indica el valor de los parámetros DQ de la capa que se utiliza
como referencia. El parámetro DQ se establece según la expresión:
DQ_id = (dependency_id << 4) + quality_id
slice_skip_flag: Un valor de uno indica que no hay datos de tira.
num_mbs_in_slice_minus1: Indica el número de macro-bloques que se van a
predecir directamente.
Sistema de video adaptativo H264/SVC sobre TCP
38
Capítulo 3:
Filtrado adaptativo:
3.1.
Filtrado de unidades NAL:
Hasta este capítulo, se ha introducido la teoría necesaria para la correcta comprensión
de los puntos que se introducirán a continuación. En concreto, se puede considerar
como el capítulo central del proyecto, ya que es aquí donde se introducirá, la forma de
filtrar las unidades NAL, de tal forma que con el resultado obtenido pasado el filtrado
sea posible obtener una secuencia de video decodificable con los paquetes de
software JSVM y OpenSVCDecoder.
En primer lugar, vamos a definir como se entiende la palabra filtrar en este contexto.
Entendemos como filtro de unidades NAL, el filtro que es capaz de extraer sub-flujos
decodificables a partir del flujo general con distintos parámetros máximos de
“dependency_id”, “quality_id” y “temporal_id”. De esta forma se extraerán capas con
atributos menores a los máximos que serán a su vez conformantes con el estándar, y
por lo tanto decodificables y reproducibles.
En segundo lugar, cabe destacar que en el algoritmo desarrollado se ha buscado, la
máxima adaptación a todas las codificaciones posibles, pero en el transcurso del
desarrollo, he decidido acotar algunas limitaciones, contemplando aspectos como el
de implementabilidad de la lógica interna en tiempo real equiparablemente inferior al
tiempo de reproducción.
Razón, por la que se han impuesto las siguientes restricciones en el proceso de
codificación:


El nivel de dependencia entre capas siempre respecto a la inferior.
Máximo 2 capas de escalabilidad de SNR por cada capa.
Para tratar el tema con detalle, se van a tomar en consideración las distintas
implicaciones en el proceso de filtrado, teniendo en cuenta que las reglas expuestas a
continuación, van acotadas a las restricciones anteriores.
De esta forma, el planteamiento elegido es empezar de abajo a arriba añadiendo
nuevas reglas impuestas según el nivel de opciones utilizado.
3.1.1. Reglas de dependencia en el filtrado de unidades NAL:
Se empezará desde una primera versión en la que se verán las reglas impuestas por el
uso de diferentes capas con escalabilidad espacial, conjuntamente con el uso de
escalabilidad temporal. Una vez vistas las reglas de dependencia en el filtrado de
39
Sistema de video adaptativo H264/SVC sobre TCP
unidades NAL para la reproducción en este caso, se pasara a evaluar las reglas
introducidas por el uso de escalabilidad de SNR, y la introducción de “Medium Grain
Scalability”.
SINTAXIS:
Si se desea extraer (Di, Ti, Qi) se debe extraer (Dj, Tj, Qj)
Equivalente a:
(Di, Ti, Qi)  (Dj, Tj, Qj)
Si se desea extraer (Di , Ti, Qi) no se debe extraer (Dj, Tj, Qj)
Equivalente a:
(Di, Ti, Qi) -/-> (Dj, Tj, Qj)
3.1.1.1.
Reglas con escalabilidad espacial y temporal:
En general, las reglas de dependencia cumplen:
Escalabilidad temporal:
(D, T + 1, 0)  (D, T, 0)
Escalabilidad espacial:
(D + 1, T, 0)  (D, T, 0)
En particular, se deben añadir las siguientes reglas:
Reglas combinadas:
Si existe (Di, TMAX + 1, 0):
(DMAX, TMAX, QMAX) -/-> (Di, TMAX + 1, 0)
Esta regla básicamente indica que cuando existan más tiras B en alguna capa inferior
que en la capa que se va a extraer (es decir, que se utilice una velocidad de
reproducción mayor en capas inferiores), al extraer la capa superior a velocidad de
reproducción menor que la capa inferior, esas tiras B de las capas inferiores van a ser
filtradas en la extracción de la capa superior porque no habrán sido utilizadas para las
predicciones entre capas, y consecuentemente no serán necesarias para la
decodificación.
3.1.1.2.
Reglas con escalabilidad de SNR y uso de MGS:
Sistema de video adaptativo H264/SVC sobre TCP
40
En general las reglas de dependencia cumplen:
Escalabilidad de SNR y uso de MGS:
(D, T, Q + 1)  (D, T, Q)
Con el uso de MGS se añade una nueva regla general, que implica que cuando se
utilizan niveles temporales con escalabilidad de SNR que en la capa superior no
incluyen todos los coeficientes DCT de la codificación, en caso de existir alguna capa
con la misma resolución y nivel temporal inferior, se deben incluir todas las capas MGS
de esos niveles que contengan coeficientes DCT.
Si existe (DMAX , Ti, QMAX + 1)
Ti < TMAX
(DMAX, TMAX, QMAX)  (DMAX, Ti, QMAX + 1)
Reglas combinadas con escalabilidad espacial y temporal:
Para el correcto funcionamiento del algoritmo que se expondrá en el siguiente
apartado, es importante remarcar que en un video codificado con H.264 SVC, se deben
aplicar todas las reglas que se han ido desglosando en varios apartados, para obtener
un archivo SVC filtrado que sea conformante con el estándar.
3.1.2. Algoritmo de filtrado de unidades NAL:
A través de las reglas expuestas anteriormente, se ha procedido a la obtención del
algoritmo en lenguaje de programación que llevara a cabo el acometido de extraer
según los límites impuestos por dichas reglas.
Se distinguen los dos casos según se trate de un video codificado que utilice MGS, o en
ausencia de su uso.
3.1.2.1.
Algoritmo de extracción sin usar MGS:
Para una mejor comprensión del código que se muestra a continuación, vamos a ver
un ejemplo del funcionamiento del algoritmo de filtrado explicado detalladamente.
En este caso, no se contempla el uso de MGS, por lo que el ejemplo elegido, ha sido
pensado para contener los tres tipos de escalabilidad, es decir una codificación con
tres capas, la capa base, una capa de mejora de calidad, y otra con más resolución. Así,
se estaría utilizando escalabilidad de resolución y de SNR. Por esto, se elige un tamaño
de GOP igual a 2 generando así dos capas temporales por capa de resolución y calidad.
En este caso particular, dispondremos de seis capas, que según el valor de sus
identificadores DTQ, serán las capas 000, 001, 100, 010, 011 y 110. La generación del
flujo se hace según la imagen de la figura 3.1.
41
Sistema de video adaptativo H264/SVC sobre TCP
Figura 3.1: Estructura de la codificación, con capa base, capa de calidad mejorada y
capa de resolución superior
Partiendo de la capa base (000) se generan las capas superiores en niveles de
dependencia de resolución (100), de calidad (001) y temporal (010), y a partir de las
capas superiores se generan las capas temporales superiores en resolución (110) y
calidad (011). Estas últimas capas dependen a su vez de la capa base y de las capas de
mejora.
El algoritmo de filtrado, se encarga de obtener la extracción con un DTQ_th máximo,
encargándose de cumplir todos los niveles de dependencia, es decir, hacer que en
cada extracción se cumplan todas las reglas descritas en el apartado anterior.
Por ejemplo, para conseguir la extracción del flujo con máxima resolución a la máxima
velocidad de reproducción se deben incluir las unidades NAL correspondientes a las
capas 000, 010, 100 y 110, porque para cumplir las reglas, la extracción hasta 110 debe
incluir todas sus dependencias, la capa 100 según dependencia temporal y las capas
000 y 010 porque la capa base de la que se predice entre capas es esta.
Es importante darse cuenta que no depende de las capas de calidad mejorada, ya que
se parte de una codificación, en la que se debe haber utilizado como capa base de la
de resolución mayor, la capa base. En este caso también se podría añadir las capas de
mejora de calidad, pero no se obtendría el mínimo flujo de transmisión.
Para completar el ejemplo, se ve en la tabla siguiente para cada DTQ_th de extracción,
las capas que va a incluir una vez analizado según el algoritmo de extracción que se
mostrará más adelante.
DTQ_th
000
001
100
010
011
110
Capas incluidas
000
001
100
010
011
Sí
No
No
No
No
Sí
Sí
No
No
No
Sí
No
Sí
No
No
Sí
No
No
Sí
No
Sí
Sí
No
Sí
Sí
Si
No
Sí
Sí
No
Tabla 3.1: Resultados algoritmo de extracción para el ejemplo 1
110
No
No
No
No
No
Sí
Sistema de video adaptativo H264/SVC sobre TCP
42
A continuación, vemos el código correspondiente al algoritmo de filtrado para el caso
sin uso de MGS, el cual se encarga de realizar el proceso descrito en el ejemplo, y en el
que los atributos “dependency_id”, “quality_id” y “temporal_id” se corresponden con
los atributos de cada unidad NAL analizada.
//PARAMETROS LIMITE EN LA EXTRACCIÓN
int dependency_id_th, quality_id_th, temporal_id_th;
int extract = 0; //1: NALU se debe extraer
//0: No se debe extraer
//Parametros auxiliares para manejar los limites en las distintas capas
int quality_id_tmp;
…
extract = 0;
quality_id_tmp = quality_id_th;
for(int i=dependency_id_th; i>-1; i--){
for(int j=temporal_id_th; j>-1; j--){
for(int k=quality_id_tmp; k>-1; k--){
if(dependency_id == i && temporal_id == j && quality_id == k){
extract = 1;
break;
}
}
if(extract == 1)
break;
}
if(extract ==1)
break;
quality_id_tmp = 0;
}
if(extract == 1){
//ALMACENAR o TRANSMITIR
}
3.1.2.2.
Algoritmo de extracción usando MGS:
De la misma forma, que en el caso sin MGS, vamos a ver un ejemplo, que permita la
correcta comprensión del código que se añade al algoritmo de extracción para el caso
en que se va a usar MGS.
La codificación de video elegida es la misma que en el ejemplo anterior, pero usando
MGS en la capa de calidad mejorada. En concreto, se van a generar dos capas de
calidad mejorada, que contendrán cuatro de los ocho coeficientes transformados cada
43
Sistema de video adaptativo H264/SVC sobre TCP
una. De esta forma, se generan las ocho capas 000, 001, 002, 100, 010, 011, 012 y 110,
tal y como se ve en la figura 3.2.
Figura 3.2: Estructura de la codificación, con capa base, capa de calidad mejorada con
uso de MGS y capa de resolución superior
Aunque, en la imagen se muestra, la capa añadida (Q=2) como si fuera predicha a
partir de la capa de mejora (Q=1), en realidad se trata de una codificación con MGS,
por lo que se trata de la misma capa pero en este caso se parten los coeficientes
transformados en dos capas. En la práctica, se van a dividir las unidades NAL de la
misma forma que si se estuvieran utilizando varias capas de mejora.
La principal diferencia, con el algoritmo de extracción sin el uso de MGS, es que se va a
cumplir la última regla general expuesta, que consiste en incluir las capas con
identificador de calidad mayor, nivel temporal inferior y misma resolución que el de la
extracción, en los casos en que se va extraer con identificador de calidad menor e
identificador temporal más grande.
Este es el caso, que sucede cuando se quiere extraer hasta la capa 011, en que según el
algoritmo de filtrado sin MGS, cumpliendo todas las dependencias se iban a extraer las
capas 000, 001, 010 y 011. Lo que sucede, es que al usar MGS, los coeficientes
transformados quedan divididos en las capas con Q igual a uno y dos, razón por la que
si se quiere extraer hasta 011 se debe incluir la capa 002 para que se incluyan todos los
coeficientes transformados de la capa DT igual a 00.
Es importante tener en cuenta, que en el caso de haber utilizado dos capas de calidad
mejorada el algoritmo de extracción funciona correctamente sin el uso de MGS. Por
esto, ya se ha expuesto al inicio del capítulo que se limita a dos capas con diferentes
calidades por capa de resolución, y posibilidad de usar MGS en la capa de mejora.
Para completar el ejemplo, se ve en la tabla siguiente para cada DTQ_th de extracción,
las capas que va a incluir una vez analizado según el algoritmo de extracción que se
mostrará más adelante.
DTQ_th
000
001
002
Capas incluidas
100
010
011
012
110
Sistema de video adaptativo H264/SVC sobre TCP
000
001
002
100
010
011
012
110
Sí
No
No
No
No
No
No
Sí
Sí
No
No
No
No
No
Sí
Sí
Sí
No
No
No
No
Sí
No
No
Sí
No
No
No
Sí
No
No
No
Sí
No
No
Sí
Sí
Sí
No
Sí
Sí
No
Sí
Sí
Sí
No
Sí
Sí
Sí
Si
No
No
Sí
Sí
No
No
Tabla 3.2: Resultados algoritmo de extracción para el ejemplo 2
44
No
No
No
No
No
No
No
Sí
A continuación, se muestra el código correspondiente al algoritmo de filtrado para el
caso con uso de MGS. Los atributos “dependency_id”, “quality_id” y “temporal_id” se
corresponden con los atributos de cada unidad NAL analizada.
A continuación, vemos el código correspondiente al algoritmo de filtrado para el caso
sin uso de MGS, el cual se encarga de realizar el proceso descrito en el ejemplo, y en el
que los atributos “dependency_id”, “quality_id” y “temporal_id” se corresponden con
los atributos de cada unidad NAL analizada.
//PARAMETROS LIMITE EN LA EXTRACCIÓN
int dependency_id_th, quality_id_th, temporal_id_th;
int extract = 0; //1: NALU se debe extraer
//0: No se debe extraer
//Parametros auxiliares para manejar los limites en las distintas capas
int quality_id_tmp;
//Parametros que contendran las capas a las que se les da acceso
int D_array[NUM_LAYER], T_array[NUM_LAYER], Q_array[NUM_LAYER];
int pos_array = 0;
…
extract = 0;
quality_id_tmp = quality_id_th;
for(int i=dependency_id_th; i>-1; i--){
for(int j=temporal_id_th; j>-1; j--){
for(int k=quality_id_tmp; k>-1; k--){
if(dependency_id == i && temporal_id == j && quality_id == k){
extract = 1;
break;
}
}
if(extract == 1)
break;
}
if(extract ==1)
break;
45
Sistema de video adaptativo H264/SVC sobre TCP
quality_id_tmp = 0;
}
//Comprobar que en caso de (D,T,Q) almacenado con ((D < dependency_id_th ||
T < temporal_id_th)&&Q>=1)
// Se incluyan también (D,T,Qi) con Qi>Q
int i = 0;
if(quality_id > 0 && extract == 0){
while(!(D_array[i] == -1 && T_array[i] == -1 && Q_array[i] == -1) == true){
if((D_array[i] < dependency_id_th || (T_array[i] < temporal_id_th)) &&
Q_array[i] > 0){
if(dependency_id == D_array[i] && temporal_id == T_array[i] &&
quality_id > Q_array[i]){
extract = 1;
}
}
i++;
}
}
//Comprobar si existe (D, T, Q) introducido en los arrays
i = 0;
int DTQ_exists_in_array = 0;
while(!(D_array[i] == -1 && T_array[i] == -1 && Q_array[i] == -1)){
if(dependency_id == D_array[i] && quality_id == Q_array[i] && temporal_id ==
T_array[i]){
DTQ_exists_in_array = 1;
break;
}
i++;
}
//Almacenar capas a las que se les da acceso y que no han sido introducidas antes
(DTQ_exists_in_array == 0)
if(extract == 1 && DTQ_exists_in_array == 0){
D_array[pos_array] = dependency_id;
Q_array[pos_array] = quality_id;
T_array[pos_array] = temporal_id;
pos_array++;
}
if(extract == 1){
//ALMACENAR o TRANSMITIR
}
3.2.
Filtrado adaptativo:
Sistema de video adaptativo H264/SVC sobre TCP
46
Se define el filtrado adaptativo, como la capacidad de extracción de distintas capas
máximas a través del tiempo, de forma que durante un intervalo de tiempo se extraerá
a un DTQ_th y durante otro intervalo de tiempo a otro DTQ_th distinto del primero y
así, sucesivamente.
Las reglas del filtrado adaptativo, vendrán limitadas por las líneas de dependencia
entre unidades NAL propias del estándar H264. De esta manera empezaremos por ver
como se conforman los flujos de transmisión en el estándar H264/AVC, para seguir con
la conformación del estándar H264/SVC, para a posteriori poder obtener los posibles
puntos de corte en que se pueda realizar un intercambio de capa.
3.2.1. Orden de transmisión de flujo de datos H264/AVC:
Hay tres casos a contemplar, el flujo inicial en que se transmite una I seguida de una P,
porque I y P, siempre van transmitidas antes que las B que se reproducen antes de la I
o P en cuestión, contemplado como flujo en inicio; flujo normal y flujo cuando se
encuentra una unidad NAL de refresco instantáneo de decodificación (IDR).
Vamos a ver unos cuantos ejemplos con valores variables de tamaño de GOP.
Flujo de inicio:
GOP size = 2:
Figura 3.3: Flujo de inicio con tamaño de GOP igual a 2
GOP_size = 4:
Figura 3.4: Flujo de inicio con tamaño de GOP igual a 4
GOP size = 8:
47
Sistema de video adaptativo H264/SVC sobre TCP
Figura 3.5: Flujo de inicio con tamaño de GOP igual a 8
Flujo normal:
GOP size = 2:
Figura 3.6: Flujo normal con tamaño de GOP igual a 2
GOP_size = 4:
Figura 3.7: Flujo normal con tamaño de GOP igual a 4
GOP size = 8:
Figura 3.8: Flujo normal con tamaño de GOP igual a 8
Sistema de video adaptativo H264/SVC sobre TCP
48
Como se puede ver, el orden de dependencia es tal que se van añadiendo tiras B, hasta
llegar al máximo identificador de dependencia, y a partir de ahí se van repartiendo de
dos en dos formando la estructura que se puede ver en las imágenes. La diferencia
entre el flujo de origen y el normal es tal que en el origen se transmiten primero las
tiras I y P para que las B que se transmiten a posteriori sean anteriores en orden de
reproducción.
En el caso de intercambio por tira I de refresco de decodificación se deben contemplar
dos casos. En primer lugar, el caso en que el periodo de IDR es múltiple del periodo de
tiras intra-predecidas, caso en el que cuando se pone la tira IDR le toca a una tira I. Y el
segundo es el caso contrario, caso en el que debido a que el periodo IDR debe ser
múltiple del tamaño de GOP, le corresponderá la posición de una P.
Flujo en IDR:
IDR_period = M * Intra_period (M entero):
GOP size = 2:
Figura 3.9: Flujo en IDR múltiple periodo intra-predicción con
tamaño de GOP igual a 2
GOP size = 4:
Figura 3.10: Flujo en IDR múltiple periodo intra-predicción con
tamaño de GOP igual a 4
GOP size = 8:
49
Sistema de video adaptativo H264/SVC sobre TCP
Figura 3.11: Flujo en IDR múltiple periodo intra-predicción con
tamaño de GOP igual a 8
IDR_period != M * Intra_period (M entero):
GOP size = 2:
Figura 3.12: Flujo en IDR no múltiple periodo intra-predicción con
tamaño de GOP igual a 2
GOP size = 4:
Figura 3.13: Flujo en IDR no múltiple periodo intra-predicción con
tamaño de GOP igual a 4
GOP size = 8:
Sistema de video adaptativo H264/SVC sobre TCP
50
Figura 3.14: Flujo en IDR no múltiple periodo intra-predicción con
tamaño de GOP igual a 8
El detalle más importante en que hay que fijarse es el hecho que cuando aparece una
tira I de refresco instantáneo de decodificación, las tiras B siguientes no tienen dos
tiras para ser inter-predichas y consecuentemente se transforman en tiras P en las que
el segundo subíndice indica la posición relativa.
Para el filtrado adaptativo en H264/AVC tendremos combinaciones con diferentes
identificadores de dependencia temporal, como por ejemplo 010 y 020. Al tener
siempre dependencia hacía atrás en tiempo de reproducción respecto al tiempo de
transmisión será posible cortar por cualquier sitio obteniendo como resultado flujos
conformantes con el estándar, independientemente de si los intercambios son de
identificador temporal mayor a menor, o menor a mayor.
3.2.2. Orden de transmisión de flujo de datos H264/SVC:
Para el caso del estándar H264/SVC se elige una codificación que contiene los tres
tipos de escalabilidad a modo de ejemplo para detectar las características que deben
cumplir los puntos de corte para obtener flujos de datos conformantes con el
estándar.
En concreto, se elige una codificación de tres capas, capa base, capa de calidad de SNR
mejorada y capa con resolución superior a las dos capas anteriores, con un tamaño de
GOP en cada capa de dos. Se va a ver para esta codificación el orden de transmisión
del flujo de datos para cada uno de los cuatro casos. Los subíndices indican la capa
correspondiente a la que pertenecen las unidades NAL, siendo cero la capa base, 1 la
capa de escalabilidad de SNR y 2 la capa de escalabilidad de resolución.
Se muestra a continuación, los flujos generados.
Flujo de inicio:
Figura 3.15: Flujo inicio codificación con tres capas, capa base,
capa calidad mejorada y capa de resolución superior
51
Sistema de video adaptativo H264/SVC sobre TCP
Flujo normal:
Figura 3.16: Flujo normal codificación con tres capas, capa base,
capa calidad mejorada y capa de resolución superior
Flujo en IDR:
IDR_period = M * Intra_period (M entero):
Figura 3.17: Flujo en IDR múltiple periodo intra-predicción codificación con
tres capas, capa base, capa calidad mejorada y capa de resolución superior
IDR_period != M * Intra_period (M entero):
Sistema de video adaptativo H264/SVC sobre TCP
52
Figura 3.18: Flujo en IDR no múltiple periodo intra-predicción codificación con
tres capas, capa base, capa calidad mejorada y capa de resolución superior
De forma general, igual que en el caso analizado, el orden de transmisión cuando se
transmite más de una capa, sigue el orden temporal de H264/AVC, fijando el orden
entre capas correspondiente a la codificación. En este caso, se transmiten primero las
unidades NAL de la capa base, seguidas por las de escalabilidad de SNR, y finalmente
las de escalabilidad de resolución.
3.2.3. Parámetros de diseño del filtrado adaptativo:
Vamos a analizar a continuación la posibilidad de transmitir flujos filtrados
adaptativamente que puedan contener cualquier combinación entre las seis capas
generadas (000, 001, 100, 010, 011 y 110).
En primer lugar es importante darse cuenta que en los flujos resultantes se deberá
cumplir todas las restricciones de dependencia propias del estándar. Así, si se fuera a
cortar por tiras P o tiras B, ya se ve enseguida que dependerían de las tiras I anteriores,
por lo que podría dar lugar a flujos de datos no conformantes.
De esta forma, se ve la necesidad de que los puntos de corte se localicen en las tiras I
de la capa base. Entonces, teniendo en cuenta que las tiras B que siguen al punto de
corte son dependientes de las dos tiras I y/o P anteriores se llega a dos posibilidades
en el filtrado realizado en el flujo normal:
1. Cambiar de DTQ_th en la tira I con DTQ igual a 000, y filtrar las tiras B
siguientes, de forma que se consigue un flujo de datos decodificable porque las
siguientes tiras B que aparecen ya disponen de dos tiras I y/o P para poder ser
decodificadas correctamente.
2. La segunda opción, es no filtrar las tiras B que se transmiten después del punto
de corte. En este caso, estas tiras B dependerán del DTQ_th inicial porque para
53
Sistema de video adaptativo H264/SVC sobre TCP
poder ser decodificadas, deberá ser filtrado en el DTQ_th que se dispongan las
dos tiras I y/o P anteriores, y como antes del filtrado la tira I y/o P anterior será
extraída en el primer DTQ, las tiras B que siguen al punto de corte se van a
filtrar con el DTQ_th que había antes del corte. De forma similar las siguientes
tiras B que aparezcan dependerán de las dos tiras I y/o P anteriores, razón por
la cual dependerán de las tiras I siguientes al punto de corte incluidas en la
extracción. Se ve así la necesidad de extraer las tiras I siguientes al corte para
que se incluya las necesarias para decodificar las dos tiras B siguientes. Es decir,
debe incluir las tiras I según los dos DTQ_th, el anterior y el posterior al punto
de corte. Así, el funcionamiento es el siguiente, intercambio a DTQ_th2 cuando
se detecte tira I con DTQ igual a 000, cambio a DTQ_th cuando se detecte
dependencia temporal más grande que uno y intercambio a DTQ_th2 cuando
se vuelva a detectar tira con nivel de dependencia temporal igual a 0.
En el caso de intercambio de capa por un punto de corte IDR, que también cumple que
la tira del intercambio es una I con DTQ igual a 000, al ser las tiras siguientes
dependientes solamente de la unidad NAL IDR, van a poder realizar el intercambio sin
tener que filtrar ni tener en cuenta consideraciones adicionales.
Se muestra el ejemplo de un intercambio entre 110 y 011 para cada uno de los casos.
Flujo normal:
Figura 3.19: Intercambio entre capas 110 y 011 en flujo normal. Caso 1
Figura 3.20: Intercambio entre capas 110 y 011 en flujo normal. Caso 2
Flujo en intercambio IDR:
IDR_period = M * Intra_period (M entero):
Figura 3.21: Intercambio entre capas 110 y 011 en flujo IDR múltiple
Sistema de video adaptativo H264/SVC sobre TCP
periodo intra-predicción
IDR_period != M * Intra_period (M entero):
Figura 3.22: Intercambio entre capas 110 y 011 en flujo IDR no múltiple
periodo intra-predicción
54
55
Sistema de video adaptativo H264/SVC sobre TCP
Capítulo 4:
Estimación del ancho de banda de transmisión:
Una vez visto el algoritmo de filtrado de unidades NAL, el siguiente paso para
desarrollar el sistema de transmisión de video adaptativo sobre TCP, es plantearse cuál
será él, o los parámetros que nos permitirán transmitir adaptativamente a la conexión
un determinado número de capas durante un cierto tiempo y otro determinado
número de capas durante otro cierto tiempo, y así sucesivamente.
De esta forma, es en el protocolo TCP, donde vamos a buscar los parámetros
característicos de la conexión, razón por la cual en primer lugar se verá una breve
descripción de los parámetros de funcionamiento del protocolo de transporte TCP.
4.1.
Protocolo de control de Transporte:
TCP es un protocolo de transporte orientado a conexión, fiable y con control de
errores extremo a extremo. Es orientado a conexión porque antes de iniciar la
conexión se pasa por la fase de establecimiento y al finalizar la conexión se pasa por la
fase de cierre de conexión. Es fiable porque se encarga de comprobar y asegurar que
los paquetes se reciban y que sea en orden correcto, mediante el uso de control de
errores, basados en el uso de paquetes de reconocimiento de recepción por parte del
extremo receptor.
En primer lugar, cuando aparece una conexión usando TCP, se pasa por la fase de
establecimiento, que es un proceso de tres pasos, el extremo que inicia la apertura
activa envía un paquete SYN, al extremo que debe estar escuchando en un puerto de
recepción, para que cuando reciba un paquete SYN, responda con un SYN-ACK, que le
indica al extremo inicial que se va a establecer conexión, y este finalmente envía un
paquete de reconocimiento de recepción del paquete de establecimiento de conexión,
momento en que la conexión queda establecida, y ya se puede iniciar la transmisión de
paquetes de datos. La fase de cierre funciona exactamente igual, pero en este caso los
paquetes enviados son FIN, FIN-ACK y ACK. Vemos a continuación una imagen que
muestra ambas fases de conexión.
Sistema de video adaptativo H264/SVC sobre TCP
56
Figura 4.1: Fases de establecimiento y finalización de conexión
Una conexión TCP queda caracterizada por dos direcciones IP y dos puertos, los
correspondientes al origen y al destino de la conexión. De esta forma se llama
establecimiento activo a la parte que fija la dirección y el puerto de destino y transmite
desde dirección y puerto origen, y establecimiento pasivo al extremo que fija su
dirección y puerto de destino y pone un socket en escucha a la espera de que se
establezcan conexiones.
En una conexión TCP, se define el control de errores como la capacidad de detectar
cuando se produce un error en las transmisiones. De esta forma, se utilizan paquetes
ACK, de reconocimiento que se encargan de asegurar cuando se reciben en el extremo
transmisor que los paquetes enviados hasta el reconocido han sido recibidos
correctamente.
Así, existen tres posibilidades cuando se envía un paquete, primero que se reciba y se
reconozca correctamente, segundo que el paquete se pierda y tercero que haya un
reenvió del paquete debido a la pérdida del reconocimiento. Es por esta razón, que se
define el tiempo de retransmisión (RTO) antes de que se reenvíe el paquete. El valor
de este tiempo viene determinado por medidas del tiempo de transporte extremo a
extremo (“Round Trip Time”), y se utiliza con un algoritmo de backoff exponencial que
va multiplicando por 2 (RTO(n) = 2 * RTO(n – 1)), a medida que se van perdiendo
paquetes porque se asume que cuando se pierden es un indicativo de una situación de
congestión. Las tres situaciones citadas son las siguientes.
57
Sistema de video adaptativo H264/SVC sobre TCP
Figura 4.2: Casos de transmisión: Paquete enviado y reconocido,
retransmisión y paquete duplicado
Además, TCP dispone de control de flujo, en que mediante el mecanismo de ventana
deslizante se controla que el flujo en red sin haber sido procesado por parte del
extremo receptor no exceda el límite fijado por el tamaño de la ventana deslizante. El
funcionamiento es tal que cada vez que se transmite un determinado paquete de
tamaño N bytes, se reduce el tamaño de la ventana en dicho tamaño, llegando como
mínimo al tamaño de ventana igual a 0 bytes, caso en que se detendrá la transmisión a
la espera de que el nodo receptor envíe otro paquete indicando que el tamaño de la
ventana ha aumentado. Se muestra a continuación una imagen que contiene un
ejemplo de funcionamiento del control de flujo.
Sistema de video adaptativo H264/SVC sobre TCP
Figura 4.3: Ejemplo de control de flujo
4.1.1. Cabecera TCP:
La cabecera del protocolo de control de transporte es la siguiente:
Figura 4.4: Cabecera TCP
Los campos por los que está formado son los siguientes:


Puerto de origen.
Puerto de destino.
58
59
Sistema de video adaptativo H264/SVC sobre TCP







Número de secuencia: Número del paquete transmitido. Sigue orden
secuencial.
Número de ACK: Número de secuencia de reconocimiento hasta el que se
reconoce paquetes anteriores recibidos correctamente.
Tamaño de la cabecera: Se expresa en palabras de 4 bytes.
Code bits: Bits para enviar mensajes especiales.
o FIN: Finalizar conexión
o SYN: Establecer conexión.
o RTS: Resetear la conexión.
o PSH: Petición de envió de datos.
o ACK: Reconocimiento de paquetes.
o URG: Campo de puntero urgente valido.
Tamaño de la ventana deslizante.
Checksum: Función resumen obtenida a partir de las direcciones IP y otros
atributos.
Opciones: MSS, Window Scale y Timestamp.
A parte de los campos descritos en TCP también es posible añadir opciones en la
cabecera, se puede modificar el tamaño de segmento mediante la opción MSS, o el
escalado de ventana, y ponerle etiquetas temporales a los paquetes marcando los
tiempos de envío y recepción para poder por ejemplo obtener una estimación de RTO.
4.1.2. Control de congestión:
El control de congestión en TCP es el que se encarga de controlar las situaciones con
alto tráfico en red que conlleven reenvíos de paquetes. Consta de tres mecanismos,
inicio lento, evitar congestión y ser conservativo después de eventos de retransmisión.
Al iniciar la transmisión se empieza con “slow start”, se fija la ventana de congestión a
que solo se pueda transmitir un segmento, y cada vez que se recibe un ACK, se
multiplica por dos de forma exponencial el número de segmentos que se pueden
transmitir. Una vez se detecta que ha habido alguna perdida, se pasa a trabajar con
uno de los otros dos métodos.
Sistema de video adaptativo H264/SVC sobre TCP
60
Figura 4.5: Fase “slow start”
Si se detectan tres ACK duplicados, se pasa a trabajar con el mecanismo “Congestion
Avoidance”, que se basa en incremento aditivo, y decremento multiplicativo, de forma
que cuando se detectan los tres ACK duplicados se reduce la ventana de congestión a
la mitad y a partir de ese momento, con la situación de congestión detectada se pasa a
aumentar el tamaño de uno en uno. Se puede ver a continuación un ejemplo de este
mecanismo.
Figura 4.6: Ejemplo control de congestión
Por último, en el caso de que se detecte una retransmisión, se reduce el tamaño a uno
y se empieza otra vez los aumentos de forma exponencial hasta un límite fijado
normalmente en la mitad de tamaño que tenía antes de detectar la situación de
congestión.
61
4.2.
Sistema de video adaptativo H264/SVC sobre TCP
Estimación del ancho de banda de transmisión:
Una vez vistas las principales características del protocolo de transporte TCP, vamos a
pasar a evaluar con que parámetros será posible controlar a nivel de aplicación que la
transmisión sea adaptativa al protocolo TCP. Básicamente, los parámetros principales
son el ancho de banda disponible, y el tiempo de transmisión extremo a extremo.
Es importante darse cuenta que se pueden definir varias estrategias a nivel de capa de
aplicación, como por ejemplo añadir comunicación entre los extremos transmisor y
receptor, para mediante la definición de un protocolo a nivel de aplicación conseguir
evitar transmisiones en ciertas circunstancias.
En este proyecto, a diferencia del concepto anterior se ha optado por evitar definir un
protocolo a nivel de aplicación y en su lugar, se ha elegido que mediante las medidas
estimadas por parte del sistema operativo se consiga saber aproximadamente cuál es
el ancho de banda disponible, y acotar la transmisión de forma adaptativa a las
condiciones de red existentes. A nivel de socket el ancho de banda disponible podrá
ser estimado por la siguiente expresión:
BW(bits/s) = cwnd(bits) / RTT(s)
Es por esta razón que el siguiente paso lógico de la operación es tratar de obtener en
tiempo real la estimación del ancho de banda a transmitir por parte de cada una de las
posibles combinaciones de parámetros de escalabilidad del video codificado.
4.2.1. Tamaño de las capas de extracción en tiempo real:
El primer paso para poder obtener una estimación en tiempo real que nos permita
comparar el ancho de banda disponible con el ancho de banda necesario para
transmitir hasta una capa determinada, es obtener en tiempo real el tamaño de cada
unidad NAL con una determinada combinación de DTQ, para así mediante el
conocimiento de la velocidad de transmisión del video poder estimar para cada capa el
ancho de banda necesario para su transmisión.
Con un fotograma:
BW(bits/s) = L(bits/frame)*Fps(frame/s)
Con N fotogramas:
BW(bits/s) = L(bits en N frames)*Fps(frames/s)/N(frames)
Sistema de video adaptativo H264/SVC sobre TCP
62
El primer punto importante, es darse cuenta, que no basta con obtener el tamaño de
una determinada unidad NAL de la DTQ, sino que en su lugar el tamaño que se tiene
que obtener en tiempo real, es el agregado, de todas las capas incluidas que habría en
la extracción de un determinado DTQ. De esta forma, se ve la necesidad de disponer
una vez analizada cada una de las unidades NAL de una estimación del ancho de banda
a transmitir para cada una de las posibles combinaciones DTQ del video codificado.
En segundo lugar, es importante ver que será necesario aplicar el algoritmo de
extracción de unidades NAL cada vez que se analice una de dichas unidades para poder
obtener la estimación de todas y cada una de las capas.
Así, el algoritmo con el que se obtendrá el tamaño de las unidades NAL en tiempo real,
básicamente lo que realizara será un incremento del tamaño de cada una de las capas
en las que la unidad NAL deba ser incluida.
4.2.2. Velocidad de reproducción del video:
El siguiente parámetro para la estimación del ancho de banda necesario para la
transmisión, es la velocidad de reproducción del video.
La obtención de dicho parámetro es totalmente dependiente del identificador de
escalabilidad temporal, parámetro ya propio de H.264 en su versión AVC. A pesar de
tener una dependencia directa con este parámetro, es importante remarcar que el
parseado entre “dependency_id” y la velocidad de reproducción necesaria para la
estimación del ancho de banda, será dependiente del tipo de video.
En general se cumple que si se aumenta el parámetro de escalabilidad temporal se
multiplica por dos la velocidad de reproducción, pero la velocidad mínima de
reproducción es dependiente de la codificación empleada, concretamente se
determina a partir de los parámetros “Frame Rate” y “GOP_size”. Por ejemplo para un
“GOP_size” de 4 con orden de reproducción IbBbPbBbI… y un “Frame Rate” máximo
de 50 frames/s, la velocidad de transmisión con “temporal_id” de 0 es de 12,5
frames/s.
4.2.3. Implementación de la estimación en tiempo real del ancho de banda de
transmisión:
El objetivo de la implementación es conseguir que en tiempo real se vayan obteniendo
los tamaños agregados, y a partir de su velocidad de reproducción y del número de
unidades NAL incluidas con el DTQ máximo de la capa se deduzca el ancho de banda
de transmisión durante los distintos tramos del video codificado.
63
Sistema de video adaptativo H264/SVC sobre TCP
El punto más importante a tener en cuenta es la necesidad de aplicar el algoritmo de
extracción cada vez que se analiza una unidad NAL, debido a la necesidad de
incrementar el tamaño de cada una de las combinaciones que incluyen el DTQ de la
capa analizada.
De esta forma, se valoró el desarrollo del mismo algoritmo de extracción en orden
inverso, porque se adecuaría mucho mejor al hecho de comprobar de abajo arriba en
niveles de dependencia, el hecho de si se debe añadir o no el tamaño de una unidad
NAL a una capa de extracción. Sin embargo, no se logró llegar a un algoritmo cerrado
que se adaptara al máximo número de unidades NAL.
A causa, de no encontrar dicho algoritmo cerrado que evaluara en orden inverso, se
pasó a contemplar otra opción igual de valida. Básicamente, se trata que una vez
analizada una iteración en las que se presentaran todas las combinaciones de DTQ
existentes en la secuencia de video (entre una tira I con DTQ igual a 000 a otra con las
mismas características), se aplicara el algoritmo con todas las posibles combinaciones y
se almacenaran los datos dentro de un objeto de tipo “extraction_layer” que
básicamente contendrá la información de la capa que contiene, especificada como
DTQ máximo de la extracción, y un conjunto de vectores conteniendo los DTQ que
incluye la extracción.
El “struct” correspondiente a los objetos de tipo “extraction_layer” es el siguiente:
#define NUM_LAYER
N
struct extraction_layer
{
int dependency_id_th;
int quality_id_th;
int temporal_id_th;
int limitD[NUM_LAYER];
que contiene el STRUCT.
int limitQ[NUM_LAYER];
int limitT[NUM_LAYER];
int real_time_size;
última iteración.
int size_aggregated;
iteración.
int total_size;
int num_NALU_included;
size_aggregated.
int total_num_NALU;
//DTQ de la capa que contiene el STRUCT.
//Conjunto de DTQ incluidos en la extracción de la capa
//Tamaño de la capa superior aislada obtenido en la
//Tamaño agregado de todas las capas en la última
//Tamaño total.
//Número de unidades NAL con DTQ_max incluidas en
//Número total de unidades NAL incluidas.
Sistema de video adaptativo H264/SVC sobre TCP
float bandwidth;
64
//Ancho de banda estimado
};
Como, se puede observar, además de contener las capas tal como se ha descrito
anteriormente, el mismo objeto almacenará los tamaños, y el número de unidades
NAL con el DTQ máximo de la capa en tiempo real. Además, mediante la fórmula
expuesta anteriormente, se va a computar en tiempo real el ancho de banda asociado
a las medidas realizadas.
Siguiendo, con la explicación de cómo se aplicará el algoritmo, una vez almacenadas
todas las combinaciones de extracción en las demás iteraciones, solo será necesario
evaluar que este contenida en alguna de las capas almacenadas.
4.2.3.1.
Detalles de la implementación:
A continuación se muestra parte del código para llevar a cabo las iteraciones
anteriores.
En primer lugar, se especifica el código necesario para conseguir que una vez
almacenadas todas las capas superiores en el vector de objetos “extraction_layer”, se
analice en todos los casos que capas debe incluir, y se incluyan en las capas correctas
(código que sólo será necesario incluir en la primera iteración).
Este código, básicamente aplica el algoritmo de filtrado para obtener como resultado
en los vectores “limitT”, “limitQ” y “limitD” de cada objeto “extraction_layer”, todas
las capas incluidas según el algoritmo de filtrado. Para conseguirlo, se fija un DTQ_th
máximo, y se analizan todos los DTQ_th que se hayan detectado en la evaluación entre
la primera y segunda tira I con DTQ igual a 000, comprobando para cada caso si se
debe incluir la capa en el objeto “extraction_layer”. La decisión se toma aplicando el
algoritmo de filtrado, y en los casos que la extracción sea positiva, se contabiliza el
tamaño en la capa y se añade la capa a evaluar en los vectores “limitT”, “limitQ” y
“limitD”.
De esta forma, se consigue que mediante la evaluación de todas las capas para cada
uno de los DTQ_th, lo cual se traduce en el uso de dos bucles que recorrerán todas las
capas, una vez finalizada la iteración se consigue que cada objeto “extraction_layer”
tenga las capas incluidas según el algoritmo de extracción en sus vectores “limitT”,
“limitQ” y “limitD”.
for(int l=0; l<num_layer; l++){
pos_escritura = 0;
65
Sistema de video adaptativo H264/SVC sobre TCP
for(int m=0; m<num_layer; m++){
extract = 0;
quality_id_tmp = extract_layer[l].quality_id_th;
for(int i=extract_layer[l].dependency_id_th; i>-1; i--){
for(int j=extract_layer[l].temporal_id_th; j>-1; j--){
for(int k=quality_id_tmp; k>-1; k--){
if(extract_layer[m].dependency_id_th
==
i
extract_layer[m].temporal_id_th == j && extract_layer[m].quality_id_th == k){
extract = 1;
break;
}
}
if(extract == 1)
break;
}
if(extract ==1)
break;
quality_id_tmp = 0;
}
&&
//Comprobar que en caso de (D,T,Q) almacenado con ((D < dependency_id_th
|| T < dependency_id_th)&&Q>=1)
// Se incluyan también (D,T,Qi) con Qi>Q
int o = 0;
if(extract_layer[m].quality_id_th > 0 && extract == 0){
while(!(extract_layer[l].limitD[o] == -1 && extract_layer[l].limitT[o] == -1 &&
extract_layer[l].limitQ[o] == -1) == true){
if((extract_layer[l].limitD[o] < extract_layer[l].dependency_id_th ||
(extract_layer[l].limitT[o]
<
extract_layer[l].temporal_id_th))
&&
extract_layer[l].limitQ[o] > 0){
if(extract_layer[m].dependency_id_th == extract_layer[l].limitD[o] &&
extract_layer[m].temporal_id_th
==
extract_layer[l].limitT[o]
&&
extract_layer[m].quality_id_th > extract_layer[l].limitQ[o]){
extract = 1;
break;
}
}
o++;
}
}
//Introducir el tamaño de las NAL Units que se deben extraer en el tamaño
agregado.
if(extract == 1){
if(l!=m){
extract_layer[l].size_aggregated += extract_layer[m].real_time_size;
}
//Introducir los DTQ que se van a extraer en "extract_layer[l]"
Sistema de video adaptativo H264/SVC sobre TCP
66
//Obtener posición en la que se debe escribir
extract_layer[l].limitD[pos_escritura] = extract_layer[m].dependency_id_th;
extract_layer[l].limitT[pos_escritura] = extract_layer[m].temporal_id_th;
extract_layer[l].limitQ[pos_escritura] = extract_layer[m].quality_id_th;
pos_escritura++;
}
}
}
Por otra parte, una vez ya están almacenadas las capas extraídas, el algoritmo para
incluir el tamaño en todas las capas donde se introduce, así como el número de
unidades NAL que se han incluido en el “struct” de cada capa, es el que se muestra a
continuación.
Este código básicamente comprueba para cada unidad NAL si pertenece a alguno de
los DTQ incluidos en la extracción de cada DTQ_th, es decir recorre dos bucles, uno con
todos los DTQ_th (objetos “extraction_layer”) y el otro con todas las capas incluidas en
la extracción. De esta forma, si la unidad NAL analizada pertenece a la extracción, se
incrementan los tamaños agregados de la capa, ya que cada capa debe contener en
tiempo real el tamaño de todas las capas incluidas en la extracción.
A parte, se deben contabilizar el número de fotogramas incluidos en la extracción, en
este caso sólo se va a contabilizar las unidades NAL que tengan los mismos atributos
que la capa analizada. Se consigue como resultado que se vayan actualizando en
tiempo real los tamaños agregados de cada capa, así como el número de fotogramas
incluidos, parámetros necesarios para la correcta estimación.
for(int i=0; i<num_layer; i++){ //Para todas las capas.
for(int j=0; j<num_layer; j++){ //Para todas las capas que están incluidas en la
extracción.
if(dependency_id == extract_layer[i].limitD[j] && temporal_id ==
extract_layer[i].limitT[j] && quality_id == extract_layer[i].limitQ[j]){
//Incrementar número de unidades NAL almacenadas y tamaños
almacenados
if(pos_final != -1){
extract_layer[i].real_time_size = (pos_final - pos);
extract_layer[i].size_aggregated += (pos_final - pos);
extract_layer[i].total_size += (pos_final - pos);
}
else{
extract_layer[i].real_time_size = (size - pos + 3);
extract_layer[i].size_aggregated += (size - pos + 3);
67
Sistema de video adaptativo H264/SVC sobre TCP
extract_layer[i].total_size += (size - pos + 3);
}
break;
}
}
if(dependency_id == extract_layer[i].dependency_id_th && temporal_id ==
extract_layer[i].temporal_id_th && quality_id == extract_layer[i].quality_id_th){
if(NALU_type == 1 || NALU_type == 5 || NALU_type == 20){
if(dependency_id
!=
last_dependency_id
||
temporal_id
!=
last_temporal_id || quality_id != last_quality_id){
extract_layer[i].num_NALU_included++;
extract_layer[i].total_num_NALU++;
}
}
}
}
Es importante fijarse en dos puntualizaciones de la implementación. La primera de
ellas es que a veces existen tiras codificadas que ocupan más de una unidad NAL, razón
por la cual es necesario mantener en memoria el DTQ de la unidad NAL anterior
(variables “last_dependency_id”, “last_temporal_id” y “last_quality_id”). De esta
forma se comprueba que sólo se añada una unidad NAL en el cómputo del ancho de
banda estimado cuando estas son consecutivas.
En segundo lugar, en el mismo caso, el ancho de banda estimado sólo debe ser
calculado al sumarse la última unidad NAL del mismo tipo cuando aparece una tira
codificada que contiene varias unidades NAL. Para lograrlo, se pasa a obtener el ancho
de banda estimado una vez analizada la unidad NAL siguiente. El código
correspondiente se muestra a continuación:
if((dependency_id != last_dependency_id || quality_id != last_quality_id ||
temporal_id != last_temporal_id) && (NALU_type == 1 || NALU_type == 5 ||
NALU_type == 20)){
int
extract_layer_pos
=
array_position_of_DTQ_th(extract_layer,
last_dependency_id, last_temporal_id, last_quality_id, num_layer);
extract_layer[extract_layer_pos].bandwidth
=
bandwidth(extract_layer[extract_layer_pos]);
}
}
Sistema de video adaptativo H264/SVC sobre TCP
68
Este código, se encarga de que el ancho de banda estimado incluya todas las unidades
NAL que formen parte del fotograma. Se realiza una vez analizada la siguiente unidad
NAL para evitar que se trate de un fotograma formado por varias unidades NAL. Se
consigue así, que la estimación sea realizada con todo el tamaño incluido. El método
“array_position_of_DTQ_th” se encarga de devolver la posición del vector de objetos
“extraction_layer” en que se encuentran los identificadores “last_temporal_id”,
“last_quality_id” y “last_dependency_id” como DTQ_th del objeto. Así, una vez
seleccionado el objeto “extraction_layer” se pasa a utilizar el método “bandwidth”
para obtener la estimación del ancho de banda de transmisión de la capa en tiempo
real, método que se verá en el siguiente apartado.
4.2.3.2.
Función estimación ancho de banda:
Vamos a ver a continuación, el método que se encarga de calcular el ancho de banda
estimado para una capa en concreto. Se muestra a continuación el código de la función
y una breve descripción sobre su funcionamiento.
float bandwidth(extraction_layer& extract_layer){
float fps, bandwidth;
if(extract_layer.num_NALU_included == 0)
return 0;
if(extract_layer.temporal_id_th == 0){
fps = 12.5;
}
else if(extract_layer.temporal_id_th == 1){
fps = 12.5;
}
else if(extract_layer.temporal_id_th == 2){
fps = 25;
}
bandwidth
=
(float)((float)extract_layer.size_aggregated
(float)extract_layer.num_NALU_included);
//Reinicializar variables
extract_layer.real_time_size = 0;
extract_layer.size_aggregated = 0;
extract_layer.num_NALU_included = 0;
return bandwidth;
}
*
fps
/
69
Sistema de video adaptativo H264/SVC sobre TCP
Esta función se encarga de obtener el ancho de banda estimado en tiempo real, a
partir de las estimaciones de tamaño y del número de fotogramas incluidos, mediante
la rectificación según la velocidad de reproducción, para determinar que ancho de
banda será necesario para la extracción hasta cada una de las diferentes capas.
Los detalles importantes a destacar son dos, en primer lugar, al trabajar con la
acumulación de unidades NAL incluidas de la capa superior en lugar que de todas las
capas incluidas, la velocidad de reproducción en la estimación debe ser la mitad para
todos los casos que la velocidad de reproducción real.
En segundo lugar, se ha añadido el código que reinicia el algoritmo cada vez que se
obtiene el ancho de banda estimado, concretamente, reinicializando tamaños y
número de unidades NAL incluidas.
Por último, y no menos importante, se debe tener en cuenta que esta función deberá
ser redefinida para otra codificación que no cumpla una velocidad de reproducción de
12,5 frames/s con “temporal_id” igual a 0.
4.2.4. Estrategias temporales en la estimación del ancho de banda:
Una vez vista la implementación de la estimación del ancho de banda adaptativo,
vamos a ver las distintas estrategias temporales en cuanto a instantes de estimación y
obtención de ancho de banda de transmisión, para poder tratar con dicha estimación a
nivel de aplicación a través del tiempo.
Las diferentes estrategias serán o bien secuencialmente, en que se estima y se
transmite secuencialmente cada vez, provocando un retardo a nivel de aplicación
entre transmisiones, o concurrentemente, con el uso de dos hilos, cada uno de los
cuales se encarga de una de las dos tareas.
Viendo, en primer lugar que la estrategia secuencial, puede provocar retardos a nivel
de aplicación, la elección tomada es su ejecución concurrente, lo cual ya de entrada
pasa a justificar el uso de dos hilos a nivel de aplicación, tal y como se verá en el
capítulo siguiente.
Los instantes en que se va a realizar la estimación del ancho de banda necesario para
la transmisión de una determinada capa, vendrán limitados por el filtrado adaptativo.
El hecho de que sólo sea posible un intercambio entre capas cada vez que aparezca
una tira I con DTQ igual a 000, hace que realizar estimaciones después de cada
fotograma no sea interesante, porque el algoritmo de filtrado adaptativo limita los
instantes en que se puede cambiar el DTQ_th. Como se ha visto en el capítulo 3 si se
cogieran instantes arbitrarios, la extracción daría lugar a flujos no conformantes con el
estándar.
Sistema de video adaptativo H264/SVC sobre TCP
70
De esta forma, se genera el concepto de iteraciones de diferencia entre los dos hilos,
entendiendo iteración, como cada instante de estimación que se avance el primer hilo
en las estimaciones al segundo hilo. Se define, cada iteración según la limitación propia
del filtrado adaptativo, es decir cada vez que se llega a una tira I con DTQ igual a 000 se
realizará la estimación del ancho de banda, y consecuentemente se avanzará una
iteración. Es por esto que será un punto clave definir cuantas iteraciones se podrá
avanzar el primer hilo haciendo estimaciones al siguiente.
4.2.4.1.
Implementación del uso de iteraciones:
Para poder tratar con el uso de iteraciones se definen unas variables extras en la
estructura “extraction_layer”, tal y como se puede ver a continuación.
struct extraction_layer
{
…
int num_iterations;
//Número de veces que se ha recorrido desde 000-I
hasta 000-I.
float aggregated_bandwidth; //Suma de los anchos de banda de todas las
iteraciones presentes hasta el momento.
};
Las variables que han añadido son el número de iteraciones que se avanza la
estimación a la obtención del ancho de banda para transmitir, y el ancho de banda
agregado, que se define de forma que se vayan sumando los anchos de banda a
medida que se avancen iteraciones para obtener los resultados como el promediado
entre el ancho de banda agregado y el número de iteraciones.
void actualizate_bandwidth(extraction_layer& extract_layer){
extract_layer.bandwidth = bandwidth(extract_layer);
extract_layer.num_iterations++;
extract_layer.aggregated_bandwidth = extract_layer.aggregated_bandwidth +
extract_layer.bandwidth;
}
El método “actualízate_bandwidth” se encarga de obtener el ancho de banda según lo
expuesto anteriormente, con el único método dependiente del video en cuestión
(“bandwidth”), incrementa el número de iteraciones y suma el ancho de banda
71
Sistema de video adaptativo H264/SVC sobre TCP
obtenido al agregado, de forma que si es la primera iteración que se avanza el valor
agregado será exactamente el valor del ancho de banda de la iteración.
float read_bandwidth(extraction_layer& extract_layer, sem_t* s1, sem_t* s3){
float bandwidth_aux = extract_layer.aggregated_bandwidth /
extract_layer.num_iterations;
extract_layer.bandwidth = 0;
if(extract_layer.num_iterations > 1){
extract_layer.aggregated_bandwidth = extract_layer.aggregated_bandwidth *
(extract_layer.num_iterations - 1) / extract_layer.num_iterations;
}
else
extract_layer.aggregated_bandwidth = 0;
extract_layer.num_iterations--;
return bandwidth_aux;
}
En cambio, el método “read_bandwidth” hace un promediado entre el número de
iteraciones del ancho de banda agregado, de forma que se consigue, que si se deja una
sola iteración de diferencia como mucho, los valores estimados en tiempo real sean los
correctos.
Es importante darse cuenta, que el acceso a estos métodos deberá definir control de
acceso ya que se accederá por dos hilos a direcciones de memoria compartida. El
control de acceso se verá en el capítulo siguiente, y se realiza mediante el uso de
semáforos.
Además, se ha de notar que mediante este control de acceso, se va a controlar cuántas
iteraciones se puede avanzar la estimación a la obtención del ancho de banda a
transmitir.
Por otra parte, aunque se ha definido un control con promediados, también sería
posible definirlo permitiendo que el primer hilo se avance más de una iteración y que
los tamaños de ancho de banda fueran los valores obtenidos en la estimación
mediante el uso de vectores que contengan todas las estimaciones en lugar de una
variable agregada de ancho de banda. Aunque, obviamente, se iba a complicar
bastante más la implementación en código.
Sistema de video adaptativo H264/SVC sobre TCP
72
Capítulo 5:
Transmisor y receptor:
En este capítulo, vamos a ver el desarrollo del transmisor adaptativo, con cada una de
sus peculiaridades a nivel de programación de la aplicación, tales como semáforos de
control de acceso, y uso de varios hilos ejecutados concurrentemente. A parte,
también se verán los criterios de diseño del receptor, que a diferencia del transmisor
no ha sido desarrollado en el presente proyecto.
5.1.
Implementación del transmisor adaptativo:
En este capítulo, se va a tratar la solución práctica empleada para diseñar la aplicación
de transmisión de flujo de video H264/SVC de forma adaptativa sobre el protocolo de
transporte TCP.
5.1.1. Justificación uso de dos hilos:
Con el objetivo de desarrollar la aplicación capaz de adaptarse a las condiciones de red
en la transmisión del flujo de datos de video codificados en H264/SVC, se ve la
necesidad de utilizar hilos ejecutados concurrentemente en el hecho que las diferentes
interacciones deben permitir estar transmitiendo continuamente para no crear
retardos secuenciales en las transmisiones de red.
Así, las tareas a llevar a cabo por parte del ejecutable final serán:
1. La estimación del ancho de banda de transmisión de cada una de las diferentes
capas, a través de computar el número de bytes a transmitir y las capas
incluidas rectificadas por la velocidad de reproducción.
2. La transmisión de las unidades NAL correspondientes a la capa con máximo
ancho de banda de transmisión inferior al ancho de banda de red disponible en
cada momento.
De esta forma, se genera la necesidad, de utilizar dos hilos ejecutados
concurrentemente y una clase intermedia compartida con todos los atributos de
caracterización del flujo de datos, el primero de los dos se encargará de analizar el
contenido, obtener el ancho de banda estimado de la forma expuesta en el capítulo 4,
y almacenarlo en el objeto compartido por los dos hilos. En cambio, el segundo se
encargará de extraer según el algoritmo de filtrado los datos y la obtención de la
estimación de red en origen del ancho de banda disponibles, para posteriormente
transmitir las unidades NAL correspondientes por red obtenidas desde el objeto
compartido por los dos hilos.
73
Sistema de video adaptativo H264/SVC sobre TCP
5.1.2. Clase H264BitStream:
Para poder llevar a cabo el desarrollo, se ha empezado por diseñar una clase
intermedia compartida entre los diferentes hilos, la clase se ha bautizado como
H264BitStream.
Se ha decidido desarrollarla como una cola circular con muchos campos para cada una
de las posiciones de la cola, de forma que cada unidad NAL quede caracterizada por
sus atributos facilitando así el reconocimiento por parte del segundo hilo en la
extracción adaptativa.
Los atributos propios de la cola circular son:
int capacity;
//Capacidad de la cola circular
int numNALUnit;
//Número de elementos introducidos en la cola circular
(Número de unidades NAL)
int pos_set;
//Posición en la que debe ser introducido el siguiente
elemento
int pos_get;
//Posición en la que toca extraer el siguiente elemento
Se utilizan estos atributos para controlar los casos de cola llena y cola vacía que en el
acceso concurrente de los hilos implican el uso de semáforos de control de acceso,
para evitar situaciones en las que se produzcan problemas de concurrencia en la
consulta o modificación de los atributos de la cola circular, tal y como se verá en este
capítulo más adelante.
Los otros atributos propios del flujo de datos de video H264/SVC son:
char** array_NALU;
//Vector de punteros de unidades NAL
int size_H264BitStream; //Tamaño de H264BitStream almacenado en la cola
circular
int* size_NALU;
//Vector con los tamaños de cada unidad NAL
int* NALU_type;
//Vector con los valores de tipo de unidad NAL
int* dependency_id;
//Vector con los valores de escalabilidad espacial
int* quality_id;
//Vector con los valores de escalabilidad de SNR
int* temporal_id;
//Vector con los valores de escalabilidad temporal
int* slice_type;
//Vector con los valores de tipo de tira (En el caso de no
ser unidades NAL VCL tendrá valor de -1)
int max_sizeNALU;
//Tamaño máximo de todas las unidades NAL del
H264BitStream
Sistema de video adaptativo H264/SVC sobre TCP
74
Se utilizan vectores correspondientes a cada uno de los atributos que permiten
clasificar si la unidad NAL se incluye en la extracción de una capa y/u otra en función
del algoritmo de extracción. Además se inicializa un doble puntero, para convertirse en
matriz correspondiente a la variable “array_NALU”, se diseña de esta forma para
asegurar que en cada uno de los índices se va a introducir el contenido de datos de
cada unidad NAL analizada, para posteriormente tener acceso a la transmisión por red
a través de la cola circular intermedia.
Se diseñan dos constructores, uno el por defecto, que se encarga de reservar el
espacio de memoria correspondiente a los vectores y la matriz que contendrá el
contenido del flujo de datos, y otro, que inicializa el contenido de la cola circular con
un determinado número de unidades NAL que se pasan como variable buffer
directamente como atributo del constructor. Para el primer caso, se puede inicializar el
contenido de la cola circular mediante el método init().
H264BitStream::H264BitStream(const int max_capacity, const int max_NALUsize)
{
//Inicialización parámetros cola circular
pos_set = 0;
pos_get = 0;
capacity = max_capacity;
numNALUnit = 0;
size_H264BitStream = 0;
max_sizeNALU = max_NALUsize;
//Reserva del espacio de memoria necesario para almacenar el contenido de todas
las unidades NAL
array_NALU = new char* [capacity];
for(int i=0; i<capacity; i++)
array_NALU[i] = new char[max_sizeNALU];
size_NALU = new int[capacity];
NALU_type = new int[capacity];
dependency_id = new int[capacity];
quality_id = new int[capacity];
temporal_id = new int[capacity];
slice_type = new int[capacity];
}
H264BitStream::H264BitStream(const int max_capacity, const char* buffer, const int
numNALU, int* pos_inicio_NALU, const int max_NALUsize);
75
Sistema de video adaptativo H264/SVC sobre TCP
void H264BitStream::init(const char* buffer, const int numNALU, int*
pos_inicio_NALU);
En el segundo caso o en la combinación del primer y el tercer caso, se inicializa el
contenido de la cola circular intermedia, pasándole como parámetros un vector de
caracteres con el contenido de las unidades NAL a introducir en la cola circular, y un
vector de posiciones iniciales para identificar los puestos en que están situados los
inicios de cada unidad NAL.
Las posiciones de inicio de unidad NAL que se pasan como parámetro en los casos con
inicialización apuntan a la posición del byte ‘\1’, correspondiente al cuarto byte del
conjunto de bytes que indican el inicio de una unidad NAL (“\0\0\0\1”). De esta forma
la inicialización de los tamaños se hace restando dos posiciones de inicio consecutivas,
ya que identifican el inicio de dos unidades NAL consecutivas, y la segunda posición es
a su vez la posición final de la primera unidad NAL de las dos. A parte, se restan cuatro
bytes porque se contabiliza en la cola circular el tamaño de datos codificados sin incluir
la identificación del inicio de unidad NAL.
La inicialización del contenido de la unidad NAL en la cola circular, se hace copiando el
contenido del buffer que se pasa como parámetro entre las posiciones de inicio y final
de cada unidad NAL. De esta forma, se empieza a copiar en la posición inicial más uno,
para apuntar al primer byte de la unidad NAL, y se termina de copiar en la posición
inicial de la siguiente unidad NAL menos tres.
//Inicialización de los tamaños de las unidades NAL correspondientes a las unidades
NAL que se van a introducir
for(int i=0; i<capacity; i++){
if(i < numNALUnit){
size_NALU[i] = pos_inicio_NALU[i+1]-pos_inicio_NALU[i]-4;
}
else
size_NALU[i] = 0;
}
//Inicialización de la matriz que contendrá las unidades NAL
for(int i=0; i<numNALUnit; i++){
pos = pos_inicio_NALU[i]+1;
for(int j=0;j<size_NALU[i];j++){
array_NALU[i][j]=buffer[pos];
pos++;
}
pos_set = (pos_set + 1) % capacity;
}
Sistema de video adaptativo H264/SVC sobre TCP
76
A parte, de los métodos constructores de la clase, también se han diseñado métodos
para la introducción y extracción de unidades NAL en la cola circular de forma
individual, y también métodos para la obtención de los atributos correspondientes a
cada unidad NAL. Vamos a ver en primer lugar los métodos para la introducción
(“put_NALU”) y para la extracción (“get_NALU”) de unidades NAL, que como se puede
ver modifican las variables propias de la cola circular, de forma que en cada utilización
de por ejemplo, el método “get_NALU” se incrementa el “pos_get”.
En el método “put_NALU”, se introduce una unidad NAL en la cola circular. Los
parámetros que se pasan a la función son un vector de caracteres que contiene el
contenido del flujo de datos H264/SVC, y las posiciones inicial y final del vector en las
que está contenida la unidad NAL. El funcionamiento del método es tal que se inicializa
en primer lugar el contenido de la unidad NAL de la cola circular copiando el contenido
del “buffer” entre las posiciones inicial y final. Acto seguido, se inicializan los atributos
de la unidad NAL, sacando el contenido de las cabeceras de la unidad NAL y de la
cabecera de la tira.
Los métodos “obtain_lenght_exp_Golomb” y “decod_exp_Golomb” utilizados en la
obtención del tipo de tira, se encargan de tratar con palabras codificadas con el
algoritmo Exp-Golomb. El primero de los dos obtiene el tamaño de la palabra ExpGolomb y el segundo se encarga de decodificar una palabra codificada según ExpGolomb. Los atributos que se pasan a la función son: el byte dentro del vector de
caracteres y el bit inicial de la palabra Exp-Golomb dentro del byte. En este caso se
utiliza primero la obtención de la longitud para saltarse la primera palabra Exp-Golomb
de la cabecera de la tira y se obtiene la decodificación de la segunda palabra que es la
correspondiente al tipo de tira.
//Introducción de una unidad NAL en la cola circular intermedia
void H264BitStream::put_NALU(const char* buffer, const int pos_inicial, const int
pos_final)
{
int eg_length, eg_byte_inicial;
//Introducir NAL Unit en la posición "pos_set"
for(int i=0; i<(pos_final-pos_inicial); i++){
array_NALU[pos_set][i] = buffer[pos_inicial + i];
}
size_NALU[pos_set] = pos_final - pos_inicial;
size_H264BitStream += size_NALU[pos_set];
77
Sistema de video adaptativo H264/SVC sobre TCP
//Obtener NALU type, DTQ y Slice_type
NALU_type[pos_set] = (int)((array_NALU[pos_set][0])&0x1F);
if(NALU_type[pos_set] == 14 || NALU_type[pos_set] == 20){
dependency_id[pos_set] = (int)(((array_NALU[pos_set][2])&0x70)>>4);
quality_id[pos_set] = (int)((array_NALU[pos_set][2])&0x0F);
temporal_id[pos_set] = (int)(((array_NALU[pos_set][3])&0xE0)>>5);
}
else if(NALU_type[pos_set] == 1 || NALU_type[pos_set] == 2 ||
NALU_type[pos_set] == 3 || NALU_type[pos_set] == 4 || NALU_type[pos_set] == 5 ||
NALU_type[pos_set] == 6 || NALU_type[pos_set] == 7 || NALU_type[pos_set] == 8 ||
NALU_type[pos_set] == 15){
dependency_id[pos_set] = 0;
quality_id[pos_set] = 0;
temporal_id[pos_set] = 0;
}
if(NALU_type[pos_set] == 1 || NALU_type[pos_set] == 5){
eg_length = obtain_length_exp_Golomb(array_NALU[pos_set],1,0);
eg_byte_inicial = eg_length/8;
eg_byte_inicial += 1;
eg_length = eg_length % 8;
slice_type[pos_set] = decod_exp_Golomb(array_NALU[pos_set], eg_byte_inicial,
eg_length, &eg_length);
}
else
slice_type[pos_set] = -1;
numNALUnit++;
pos_set = (pos_set + 1) % capacity;
}
El método “get_NALU” extrae una unidad NAL de la cola circular. En concreto copia la
información de la posición “pos_get”, en los parámetros pasados como atributos, es
decir, copia el contenido de la unidad en el atributo “NALU” y de los atributos de
caracterización de la unidad NAL en los demás atributos de la función.
void H264BitStream::get_NALU(char* NALU, int& NALU_size, int& d_id, int& t_id,
int& q_id);
void H264BitStream::get_NALU(char* NALU, int& NALU_size, int& d_id, int& t_id,
int& q_id, int& type_slice);
void H264BitStream::get_NALU(char* NALU, int& NALU_size, int& d_id, int& t_id,
int& q_id, int& type_slice, int& type_NALU)
Sistema de video adaptativo H264/SVC sobre TCP
78
{
//Copiar el contenido de la unidad NAL en la posición "pos_get"
for(int i=0; i<size_NALU[pos_get]; i++){
NALU[i] = array_NALU[pos_get][i];
}
type_NALU = NALU_type[pos_get];
NALU_size = size_NALU[pos_get];
d_id = dependency_id[pos_get];
t_id = temporal_id[pos_get];
q_id = quality_id[pos_get];
type_slice = slice_type[pos_get];
type_NALU = NALU_type[pos_get];
numNALUnit--;
pos_get = (pos_get + 1) % capacity;
}
Vamos a ver a continuación los demás métodos utilizados en la clase H264BitStream,
usados para obtener externamente los atributos de una determinada unidad NAL, se
muestran las cabeceras de los métodos debido a la simpleza de dichos métodos.
//Obtención de atributos
//Obtener tamaño total de las unidades NAL almacenadas en la cola circular
int H264BitStream::get_size_H264BitStream();
//Obtener el número de unidades NAL almacenadas en la cola circular
int H264BitStream::get_numNALU();
//Obtener el tamaño maximo en unidades NAL para almacenar en la cola circular
int H264BitStream::get_capacity();
//Obtener el tamaño de la unidad NAL en la posición numNALU
int H264BitStream::get_sizeNALU(const int numNALU);
//Obtener "array_NALU[numNALU][pos]"
char H264BitStream::get_content(const int numNALU,const int pos);
//Obtener contenido de la unidad NAL número numNALU
void H264BitStream::get_content(char *buffer, const int numNALU);
//Obtener NALU_type en la posición numNALU
int H264BitStream::get_NALU_type(const int numNALU);
//Obtener dependency_id en la posición numNALU
79
Sistema de video adaptativo H264/SVC sobre TCP
int H264BitStream::get_dependency_id(const int numNALU);
//Obtener quality_id en la posición numNALU
int H264BitStream::get_quality_id(const int numNALU);
//Obtener temporal_id en la posición numNALU
int H264BitStream::get_temporal_id(const int numNALU);
//Obtener slice_type en la posición numNALU
int H264BitStream::get_slice_type(const int numNALU);
//Obtener tamaño maximo de unidades NAL
int H264BitStream::get_max_sizeNALU();
//Obtener la siguiente posición en la que se va a introducir una unidad NAL
int H264BitStream::get_pos_set();
//Obtener la siguiente posición de la que se va a extraer una unidad NAL
int H264BitStream::get_pos_get();
5.1.3. Justificación de semáforos en la cola circular:
Como se ha comentado antes, el uso de dos hilos con acceso concurrente a la cola
circular intermedia implica la necesidad de combatir las situaciones de contorno en la
modificación de variables compartidas. Por esta razón, aunque se hayan mostrado los
métodos sin control de acceso mediante semáforos, realmente se ha trabajado con
semáforos para solucionar los problemas.
De esta forma, se va a mostrar la solución elegida para tratar con la clase
H264BitStream. Al ser una cola circular compartida, y haber accesos por parte de dos
hilos, uno para introducir y el otro para extraer el contenido de una posición de la cola
circular, se ha tenido que definir el control de acceso en los métodos “get_NALU” y
“put_NALU”.
La solución utilizada consta de dos semáforos, uno de acceso a zona crítica y el otro de
control de las situaciones en que el hilo que accede concurrentemente debe ser
detenido, casos de cola bacía para extraer unidades NAL y cola llena para introducirlas.
La solución utilizada en el método “put_NALU” es la siguiente:
void H264BitStream::put_NALU(const char* buffer, const int pos_inicial, const int
pos_final, const int is_last_NALU)
{
Sistema de video adaptativo H264/SVC sobre TCP
80
//Coger Exclusión Mutua
sem_wait(&s1);
if(numNALUnit == capacity && pos_set == pos_get){
num_wait_s2++;
sem_post(&s1);
sem_wait(&s2);
sem_wait(&s1);
}
//Introducir unidad NAL
//Liberar exclusión mutua
if(numNALUnit == 1 && num_wait_s2 > 0){
num_wait_s2--;
sem_post(&s2);
}
sem_post(&s1);
}
Como se puede observar en el código anterior se controla el acceso a la zona crítica
controlando el caso en que no se puede introducir ninguna unidad NAL, que se
corresponde con que la cola este llena en el momento de ir a introducir una nueva
unidad NAL.
Para controlar entre los dos extremos que haya algún hilo detenido en la cola se utiliza
la variable número de hilos en espera en el segundo semáforo, que cuando tenga un
valor superior a cero, indicara o que se encuentra en caso de cola llena o de cola bacía
con hilos en espera a que cambie la situación actual.
De esta forma, en el caso del método “put_NALU” se controla al final del método si se
sale de una situación de cola bacía con hilos detenidos en el método “get_NALU”
debido a que la cola este bacía, comprobando que haya hilos detenidos en el segundo
semáforo y que el número de unidades NAL introducidas en la cola al salir sea de una,
la que se acaba de introducir, y en tal caso se pone un recurso para los hilos detenidos.
La solución utilizada en el método “get_NALU” es la siguiente:
void H264BitStream::get_NALU(char* NALU, int& NALU_size, int& d_id, int& t_id,
int& q_id, int& type_slice, int& type_NALU)
{
//Coger Exclusión Mutua
sem_wait(&s1);
if(numNALUnit == 0 && pos_set == pos_get){
81
Sistema de video adaptativo H264/SVC sobre TCP
num_wait_s2++;
sem_post(&s1);
sem_wait(&s2);
sem_wait(&s1);
}
//Obtener unidad NAL
//Liberar exclusión mutua
if(numNALUnit == (capacity-1) && num_wait_s2 > 0){
num_wait_s2--;
sem_post(&s2);
}
sem_post(&s1);
}
En el método “get_NALU”, la situación en que se tiene que detener la ejecución del
hilo concurrente es en el caso de que al ir a extraer la cola circular esta bacía. Se
implementa la misma solución que antes, se utiliza el primer semáforo para entrar en
exclusión mutua a la zona donde comprobar si se trata del caso cola bacía, y detener el
hilo en dicho caso. En la salida del método debe comprobarse que no se salga de la
situación de cola llena con algún hilo en espera para poner un recurso en el semáforo
dos en tal caso.
La solución compatibiliza el uso de dos semáforos tratando los dos casos extremos, ya
que en el segundo semáforo que es donde realmente se detienen los hilos, solo puede
encontrarse uno de los dos casos a la vez, es decir en ningún caso puede haber hilos
detenidos en cola bacía y llena a la vez. Se consigue así, el funcionamiento deseado de
la cola circular en que los accesos concurrentes al mismo recurso compartido (misma
posición en la cola circular) se controla mediante semáforos como control de acceso.
Además, en los demás métodos de acceso a atributos de la cola circular o de una
determinada unidad NAL, se implementa un control de acceso mediante el primer
semáforo de entrada y salida de la zona critica.
//Los demás métodos
sem_wait(&s1)
//Metodo
Sem_post(&s1);
5.1.4. Solución de semáforos en la aplicación:
Sistema de video adaptativo H264/SVC sobre TCP
82
Tal y como se ha comentado en el último apartado del capítulo 4, también se utilizaran
semáforos para controlar los instantes de actualización del ancho de banda estimado
de transmisión por parte del primer hilo concurrente, y en los instantes de lectura de
la estimación del ancho de banda de transmisión de cada una de las posibles capas a
transmitir.
En el capítulo 4 se han visto las diferentes estrategias que se pueden seguir en la
diferencia en el número de iteraciones entre lectura por parte del primer hilo y
transmisión por parte del segundo, pudiendo dejar un mínimo de una iteración entre
actualización y un máximo indeterminado de iteraciones de diferencia, teniendo en
cuenta que con la solución utilizada cuando hay más de una iteración de diferencia
entre los dos hilos se realizan promediados del ancho del ancho de banda de
transmisión de las diferentes capas entre el número de iteraciones avanzadas.
A pesar, de haber expuesto las diferentes estrategias, no se ha presentado la solución
con semáforos correspondiente, solución que se va a ver a continuación. Los métodos
en los que se va a utilizar semáforos son “actualizate_bandwidth” y “read_bandwidth”
de la forma que se muestra en los párrafos siguientes:
void actualizate_bandwidth(extraction_layer& extract_layer, sem_t* s1, sem_t* s3){
sem_wait(s1);
//Actualizar ancho de banda de transmisión de la capa
if(num_wait_s3 > 0){
sem_post(s3);
}
sem_post(s1);
}
float read_bandwidth(extraction_layer& extract_layer, sem_t* s1, sem_t* s3){
sem_wait(s1);
if(extract_layer.num_iterations == 0){
num_wait_s3++;
sem_post(s1);
sem_wait(s3);
sem_wait(s1);
}
//Leer ancho de banda estimado de la capa
sem_post(s1);
return bandwidth_aux;
83
Sistema de video adaptativo H264/SVC sobre TCP
}
Como se puede ver en las actualizaciones solo se coge el semáforo de exclusión mutua,
mientras que en la lectura de los valores estimados se detiene al hilo en caso que el
número de iteraciones de diferencia entre los dos hilos sea de cero debido a que
cuando este valor es cero no hay lecturas posibles del ancho de banda estimado,
situación que se corresponde cuando los dos hilos se sincronizan.
De esta forma, en el “actualízate_bandwidth”, cuando se detectan hilos en espera
(variable “num_wait_s3” más grande que cero), se ponen recursos para que los hilos
en espera sean despertados. El funcionamiento, es tal que en la actualización del
ancho de banda sólo se va a despertar hilos en la lectura, cuando la lectura se avance a
la actualización, es decir el caso en que se hayan quedado detenidos.
Para que no haya problemas de concurrencia el primer semáforo debe ser compartido
con el primero de la clase H264BitStream razón por la que se añade el siguiente
método a dicha clase.
//Obtener la dirección de memoria
sem_t* H264BitStream::get_s1_memdir()
{
sem_t* sem;
sem_wait(&s1);
sem = &s1;
sem_post(&s1);
return sem;
}
Así, el control de acceso a los métodos de actualización y lectura de la estimación del
ancho de banda de transmisión solo permite detener el caso de lectura del valor
almacenado por parte de la actualización pero no limita el número de iteraciones que
se puede avanzar el hilo de actualización. Se ha diseñado así para a posteriori controlar
a nivel de aplicación el número de iteraciones de diferencia a nivel de aplicación.
La solución final por la que se ha optado es la de dejar una sola iteración de diferencia
entre actualizaciones y lecturas, lo que se traduce en un máximo de dos iteraciones en
el análisis de unidades NAL por parte del primer hilo antes de que sean analizadas por
parte del segundo.
Es por esta razón que teniendo en cuenta la limitación propia del filtrado adaptativo en
los instantes de actualización del ancho de banda que se producen al final de una
Sistema de video adaptativo H264/SVC sobre TCP
84
iteración, entendiendo una iteración como el número de unidades NAL entre una tira I
con DTQ igual a 000 y la siguiente con las mismas características; el tamaño de la cola
circular para evitar que la aplicación se detenga debe cumplir la siguiente restricción,
debido a que al inicio de la ejecución debe haber estimado como mínimo una iteración
sin que haya comenzado a transmitir:
CAPACIDAD COLA CIRCULAR > NUMERO DE UNIDADES NAL EN UNA ITERACIÓN
Además en el caso de una iteración como máximo se debe cumplir que:
CC_CAPACITY <= NUM_NALU_IN_1_ITER * (NUM_ITER + 1)
Vamos a ver a continuación la solución de semáforos a nivel de aplicación con la
restricción de un máximo de una iteración entre actualizaciones y lecturas del ancho
de banda estimado, y a analizar si podría aparecer algún problema de concurrencia o
de detención de la aplicación debido a los posibles entrelazados.
HILO 1{
1_iter_to_circular_queue();
actualizate_BW();
while(!end_of_execution){
1_iter_to_circular_queue();
sem_wait(&s4);
actualizate_BW();
}
}
HILO 2{
while(!end_of_execution){
read_BW();
obtain_DTQ_th();
tx_1_iter_with_DTQ_th();
sem_post(&s4);
}
}
Esta solución, permite cumplir los criterios de diseño debido a que con el semáforo
que se ha añadido se asegura que la ejecución concurrente nunca se avance más de
una iteración de actualizar a leer, o dos en el análisis del contenido. Los casos críticos
serán:
85
Sistema de video adaptativo H264/SVC sobre TCP
1. La combinación de cola bacía con que se detenga el primer hilo en el semáforo
cuatro, lo cual no sucederá nunca debido a que cuando se detiene en el
semáforo el primer hilo, va con dos iteraciones de diferencia.
2. Cola llena y que se detenga en “read_BW”, que tampoco sucederá porque con
la cola llena cumpliendo la restricción antes impuesta habrá como mínimo un
recurso para leer el ancho de banda estimado.
Por otro, lado tampoco se produce ningún caso en que ambos hilos queden detenidos
a la vez, razón por la que la solución propuesta es correcta.
5.1.5. Solución de ancho de banda adaptativo:
Para conseguir que la solución final sea adaptativa al protocolo de red, se hacen
estimaciones del ancho de banda disponible para poder transmitir, ancho de banda
que vendrá limitado por el protocolo TCP, y se compara cogiendo el valor máximo
menor que el disponible con los anchos de banda de transmisión de las capas, de
forma que siempre se va a transmitir a la máxima velocidad posible.
De esta forma el método del hilo 2 “obtain_DTQ_th”, en el que se obtiene el DTQ_th
tal que el ancho de banda de transmisión sea el máximo menor que el disponible,
queda de la forma siguiente.
void obtain_DTQ_th(int d_th, int t_th, int q_th, const float* read_BW, const
extraction_layer* extract_layer)
{
int bandwidth_th = obtain_BW_th_from_socket_options();
int BW_pos = 0;
for(int i=1; i<num_layer; i++){
if(read_BW[i] < bandwidth_th && read_BW[i] > read_BW[BW_pos])
BW_pos = i;
}
d_th = extract_layer[BW_pos].dependency_id_th;
t_th = extract_layer[BW_pos].temporal_id_th;
q_th = extract_layer[BW_pos].quality_id_th;
}
Se consigue así, que en cada iteración se trabaje con la extracción de la capa de
tamaño máximo con la que el ancho de banda de red disponible permite extraer a
tiempo real.
Sistema de video adaptativo H264/SVC sobre TCP
86
En esta versión, se ha hecho que en caso que el ancho de banda no fuera suficiente
para poder transmitir la capa 000, la transmita igualmente, caso que se controlara
mediante el uso de un buffer de recepción, que se encargara de almacenar cuando no
se transmita a tiempo real. De igual forma, se podría definir un valor de menos uno de
inicio que a la postre se interpretara en caso de ser el valor elegido, como que en esta
iteración no se transmitiera.
5.1.6. Medidas para reducir el alto número de intercambios entre capas:
Durante el transcurso del desarrollo de las pruebas de red (ver capítulo 6) se ha
detectado que existe en las pruebas un gran número de intercambios entre capas
debido a la alta variabilidad del video codificado. Esto puede llegar a ser un poco
desquiciante ya que durante la reproducción del video, en caso de no indicarle una
resolución fija para el video, se va a redimensionar el video constantemente.
Por esta razón, se buscan estrategias que permitan reducir el número de intercambios
entre capas, para conseguir una reproducción más suave de la secuencia de video.
La primera estrategia que se va a utilizar es utilizar un segundo estimador de ancho de
banda que suavice los saltos que existen con el estimador a partir de las opciones del
“socket”. El estimador hará un seguimiento del tamaño transmitido hasta un
determinado momento rectificado por el tiempo de ejecución. Así, el ancho de banda
disponible vendrá determinada por la siguiente expresión:
BW(n) = a * BW_socket + (1 - a) * BW(n – 1)
donde:
BW(n – 1) = tamaño_transmitido (bit) / tiempo_ejecución (s)
Con esta estrategia, se consigue una variabilidad del ancho de banda disponible más
suave que con el primer estimador. Esto podría provocar que haya casos de congestión
en que se transmita por encima del ancho de banda disponible, pero estos posibles
errores van a ser resueltos en el buffer de entrada de los “socket”, haciendo que se
precargue el buffer sin llegar a transmitir, porque vendrá controlado por el control de
congestión de TCP.
La segunda estrategia para evitar este problema, será utilizar un ciclo de histéresis en
el intercambio entre capas. Hacer que para subir de capa necesite el ancho de banda
necesario para hacerlo más un umbral extra, y para bajar el necesario menos un
umbral extra. Se muestra en la siguiente figura un ejemplo, en el que el ancho de
banda necesario para cambiar de capa es de 700 Kbit/s, se sube con 800 Kbit/s y se
baja con 600 kbit/s.
87
Sistema de video adaptativo H264/SVC sobre TCP
Figura 5.1: Ciclo de histéresis
Finalmente, el ciclo de histéresis solo se aplicara a los casos en que se suba de capa,
porque en el caso de intercambios entre capas hacia abajo, podría provocar problemas
de transmitir más de lo disponible. En concreto, solo se va a aplicar en el caso de
cambio de resolución de inferior a mayor, porque en los demás casos no habrá cambio
de resolución del video.
Sistema de video adaptativo H264/SVC sobre TCP
5.2.
88
Criterios de diseño del receptor:
La parte del receptor a diferencia del transmisor se va a tratar con un marco de trabajo
en el que se adaptara el transmisor, en concreto se va a utilizar un receptor de TCP,
que solo se encargara de recibir el contenido transmitido sin tener en cuenta las
características del video transmitido.
Se deben diferenciar dos aplicaciones objetivo, en primer lugar la transmisión de video
con buffers de recepción, que son el caso principal, y en segundo lugar las aplicaciones
orientadas a reproducción en tiempo real. El primer caso se contempla mediante el
uso de un receptor estándar al que se le añade la peculiaridad de utilizar un buffer de
recepción en el destino, para poder almacenar parte del video antes de reproducirlo, y
como se verá en el capítulo siguiente será el caso analizado. Para el segundo caso se
van a mostrar los criterios de diseño pertinentes pero no se va a desarrollar dejándolo
como posible mejora al presente proyecto.
5.2.1. Relación entre tiempo de reproducción y tiempo de transmisión:
El parámetro más crítico en el receptor orientado a funcionar en tiempo real, serán los
tiempos de transmisión extremo a extremo. Así, en características del video esto se
traduce en la diferencia entre los tiempos de transmisión y los tiempos de
reproducción, ya que la naturaleza del estándar hace que se transmitan antes algunas
tiras que otras que se reproducen antes debido a los niveles de dependencia temporal
propios del H264.
Es por esta razón que en primer lugar se deberá hacer una conmutación entre tiempos
de transmisión y tiempos de reproducción, para a posteriori controlando el tiempo de
reproducción en el receptor poder hacer comparaciones de tiempo y en caso de que
alguna unidad NAL llegara fuera del intervalo de reproducción descartar el contenido
recibido.
Vamos a ver a continuación como relacionar los tiempos de reproducción con los de
transmisión, para así poder hacer a posteriori dichas comparaciones. Es importante
darse cuenta que las relaciones serán dependientes del parámetro “GOP_size” elegido
y de los identificadores de dependencia temporal asociados a cada tamaño de GOP.
Así, en primer lugar se va a mostrar el código para determinar los identificadores de
dependencia temporal, a partir del tamaño de GOP.
void obtain_B_structure(const int GOP_size, int* B_t_id_structure){
int num_B_t_max = 0;
int num_slice = 0;
int dist_B = 0;
89
Sistema de video adaptativo H264/SVC sobre TCP
num_t = log2(GOP_size);
for(int i=0 ; i<(GOP_size - 1); i++){
B_t_id_structure[i] = 0;
}
for(int i=0; i<num_t; i++)
B_t_id_structure[i] = i + 1;
num_slice += num_t;
for(int i=0; i<num_t; i++){
if((dist_B = obtain_dist_B(B_t_id_structure[i], num_t)) == -1){
std::cout << "Internal error while computing dist_B\n";
return;
}
if(B_t_id_structure[i] == num_t)
num_B_t_max ++;
if(dist_B == 0 && (B_t_id_structure[i] != num_t || num_B_t_max == 2)){
if(num_B_t_max == 2)
num_B_t_max = 0;
}
else if((i + dist_B + 2 < GOP_size)){
B_t_id_structure[i + dist_B + 1] = B_t_id_structure[i];
num_slice ++;
}
}
num_B_t_max = 0;
int i = 0;
while(num_slice < (GOP_size - 1)){
int aux;
while(B_t_id_structure[i] != 0){
i++;
}
i--;
aux = i;
while(B_t_id_structure[i] < num_t){
B_t_id_structure[i+1] = B_t_id_structure[i] + 1;
num_slice ++;
/*DEBUG
std::cout << "t[" << (i + 1) << "] = " << t[i + 1] << '\n';
//END DEBUG*/
i++;
}
i = aux;
Sistema de video adaptativo H264/SVC sobre TCP
90
while(B_t_id_structure[i] != 0){
if((dist_B = obtain_dist_B(B_t_id_structure[i], num_t)) == -1){
std::cout << "Internal error while computing dist_B\n";
return;
}
if(B_t_id_structure[i] == num_t)
num_B_t_max ++;
if(dist_B == 0 && (B_t_id_structure[i] != num_t || num_B_t_max == 2)){
if(num_B_t_max == 2)
num_B_t_max = 0;
}
else if((i + dist_B + 2) < GOP_size){
int j = 0;
while(B_t_id_structure[i + j + dist_B + 1] != 0 && B_t_id_structure[i] !=
B_t_id_structure[i + j + dist_B + 1]){
j++;
}
if(B_t_id_structure[i] != B_t_id_structure[i + j + dist_B + 1]){
B_t_id_structure[i + j + dist_B + 1] = B_t_id_structure[i];
num_slice ++;
if(num_slice == (GOP_size - 1))
break;
}
}
i++;
}
}
return;
}
Lo que hace este código es obtener los identificadores de dependencia temporal para
todos los casos con identificador mayor que uno y durante un tamaño de GOP. Está
basado en la estructura diádica de los GOP, y consigue pasándole como parámetro el
tamaño de GOP, devolver un vector que contiene en orden secuencial los valores de
los identificadores de dependencia temporal según su orden de transmisión.
Como se puede observar en el código se utiliza el método “obtain_dist_B”, que
básicamente lo que hace es calcular en qué posición se va a repetir el siguiente
identificador temporal, aunque a medida que avanzan las posiciones hay que añadir
rectificaciones para que cada valor se ponga en la posición correcta. El código de la
función es el siguiente:
int obtain_dist_B(const int t_id, const int num_t){
91
Sistema de video adaptativo H264/SVC sobre TCP
int dist_B = 0;
for(int i=1; i<(num_t - t_id + 1); i++){
int aux;
if((aux = exp2(2,i)) == -1)
return -1;
dist_B += aux;
}
return dist_B;
}
Como se puede apreciar, las distancias entre la repetición de los mismos
identificadores temporales vienen determinados por la suma de las exponenciales de
dos elevado a cada valor entre uno y el número de identificadores temporales menos
el valor del identificador temporal. De forma que se generan distancias de 2, 6, 14, …
Por ejemplo para el caso de un tamaño de GOP igual a 8, en el que los identificadores
temporales según su orden de transmisión es: 1, 2, 3, 3, 2, 3, 3; para el caso con
identificador temporal igual a dos se obtiene una distancia 2, lo que colocaría el
segundo dos en la cuarta posición.
El el código general, la estructura obtenida se genera llenando las posiciones y cuando
se detecta que una posición relativa está ocupada se desplaza la posición a la derecha.
En este caso como se habría generado la estructura 1, 2, 3, 3, al obtener la distancia de
2 se pondría en la quinta posición. La estructura se genera analizando en primer lugar
los identificadores temporales menores y subiendo hasta los mayores, de forma que
las rectificaciones van saliendo en orden correcto para que el resultado sea el
esperado.
Una vez visto cómo obtener el orden de identificadores de dependencia temporal,
vamos a pasar a ver el código que permite obtener la relación buscada entre instantes
de transmisión, los que tenemos actualmente, e instantes de reproducción.
Para esto vamos a distinguir de igual forma que antes los valores con identificador
temporal superior a cero, para obtener la relación directa entre unos y otros. Es
importante darse cuenta que los valores que se buscan son el de las B, por lo que
siempre serán valores negativos respecto al valor de una I o una P anteriores en
tiempo de transmisión.
Vamos a ver a continuación, el código correspondiente a la obtención de los retardos
de reproducción respecto al orden de transmisión.
void obtain_num_frames_in_tr(int* n_frames, cons tint* temporal_id, cons tint
GOP_size)
Sistema de video adaptativo H264/SVC sobre TCP
92
{
Int* array_pos = new int[2];
Int adding_size;
n_frames[0] = -GOP_size / 2;
for(int i=1; i<GOP_size; i++){
//Buscar las siguientes dos posiciones con mismo temporal_id
search_next_2_positions(temporal_id, array_pos, i);
adding_size = obtain_adding_size(GOP_size, temporal_id[i]);
n_frames[array_pos[0]] = n_frames[i-1] – adding_size;
n_frames[array_pos[1]] = n_frames[i-1] + adding_size;
}
return;
}
Este código, se encarga de encontrar la relación entre identificadores temporales e
instantes de reproducción. Para ello se inicializa la primera posición correspondiente a
“temporal_id” igual a uno a la mitad del tamaño de GOP. Esto, será siempre así, según
la estructura diádica. A partir de la primera posición, lo que sucede es que para cada
repetición del identificador temporal, se obtiene una posición relativa que se suma y
se resta respecto a la posición anterior en tiempo para obtener su posición de orden
de reproducción.
Para realizar estas dos funcionalidades, se utilizan los métodos
“search_next_2_positions”, que se encarga de encontrar las dos posiciones siguientes
con el mismo identificador temporal; y “obtain_adding_size”, para obtener la posición
relativa que se debe sumar y restar en las dos nuevas posiciones obtenidas. El código
de estos dos métodos se muestra a continuación:
void search_next_2_positions(const int* temporal_id, int* array_pos, cons tint
pos_inicial)
{
int tmp = pos_inicial + 1;
array_pos[0] = pos_inicial;
array_pos[1] = 0;
while(array_pos[1] == 0){
if(temporal_id[tmp] == temporal_id[pos_inicial]){
array_pos[1] = tmp;
}
tmp ++;
}
return;
93
Sistema de video adaptativo H264/SVC sobre TCP
}
El método “obtain_adding_size” devuelve la diferencia relativa de la posición de la tira
en orden de reproducción respecto a la tira anterior, y está basada en la estructura
diádica. En concreto se obtiene la exponencial de dos elevado al número de
identificadores temporales menos el identificador temporal, dando lugar a resultados,
para por ejemplo un tamaño de GOP igual a 8, de 2 y de 1 para los identificadores
temporales de 2 y de 3.
Su funcionamiento es tal que teniendo como parámetro de entrada los identificadores
temporales: 1, 2, 3, 3, 2, 3, 3; las posiciones con “temporal_id” igual a 2 obtendrán
unas diferencias relativas de +/- 2, que respecto a la posición -4 del “temporal_id”
igual a 1, darán lugar a las posiciones -2 y -6. Lo mismo sucede con los “temporal_id”
igual a 3, que dan lugar a +/-1. Finalmente se obtiene un orden de reproducción: -4, -2,
-1, -3, -6, -5, -7.
Int obtain_adding_size(cons tint GOP_size, const int t_id)
{
Int dif = log2(GOP_size) – t_id;
return (exp(2, dif));
}
El concepto sobre el que se ha trabajado es la correlación existente entre los
diferentes retardos relativos, que se basa en que a medida que se incrementa el
identificador temporal se va dividiendo por dos el tamaño que hay que añadir entre
retardos relativos.
Finalmente, el paso de número de tiras relativas a retardo relativo se obtiene
mediante la velocidad de reproducción.
Tiempo de reproducción = Número de fotogramas / fps
5.2.2. Estrategia de filtrado en recepción:
Una vez visto cómo obtener el vector de diferencias relativas entre tiempo de
reproducción y tiempo de transmisión se debe comprobar si el instante de recepción
de una unidad NAL es anterior o posterior al instante de entrega para reproducción,
para que en caso de que sea posterior dicha unidad NAL sea filtrada en recepción.
Sistema de video adaptativo H264/SVC sobre TCP
94
De esta forma, debido al comportamiento del filtrado de unidades NAL, el hecho de
filtrar en función de los tiempos de recepción podría provocar la conformación de
flujos de datos que no fueran decodificables.
Por esta razón, se van a usar dos hilos, el primero de los cuales se encargara de
comprobar los instantes de tiempo de recepción y en caso de que alguna unidad NAL
llegara fuera de tiempo, de redefinir el DTQ máximo de la extracción en función de que
capa se descarte en una determinada iteración. Así, el segundo hilo, se encargara de
aplicar el algoritmo de filtrado al flujo resultante de la extracción hecha por el primer
hilo en la cola circular intermedia, fijando como DTQ máximo el obtenido en dicha
iteración por parte del primer hilo, para que el flujo resultante sea conformante con el
estándar H264/SVC.
Así, en primer lugar se muestra, como se va a tratar por parte del primer hilo el
descartar las unidades NAL en función de los tiempos de recepción, partiendo de que
se conoce previamente el vector de diferencias relativas “n_frames” y el vector de
identificadores temporales “t_id”.
HILO 1{
while(receive_NALU()){
if(temporal_id == 0){
num_frames[DQ] += GOP_size;
num_frame = num_frames[DQ];
position = 0;
}
else if(temporal_id > 0){
position = search_next_temporal_id_position(temporal_id, t_id, position,
GOP_size);
num_frame = num_frames[DQ] + n_frames[position];
}
If((num_frame / fps) < tiempo_recepcion){
discart();
obtain_new_DTQ_th(dependency_id, temporal_id, quality_id,
dependency_id_th, temporal_id_th, quality_id_th);
}
else
NAL_UNIT_to_cc();
}
}
En el filtrado se distingue entre identificadores temporales iguales a cero y mayores
que cero. Esto se hace porque para el caso de iguales a cero, se va a añadir
95
Sistema de video adaptativo H264/SVC sobre TCP
exactamente un tamaño de GOP al número de fotogramas, mientras que en el caso de
identificadores temporales mayores que cero, se va a obtener la posición en orden de
reproducción a partir del vector que contiene las diferencias relativas en orden de
reproducción. Funciona de forma, que en primer lugar se obtiene la siguiente posición
con ese identificador temporal (método “search_next_temporal_id_position”), para
localizar la posición en que está situada la diferencia relativa, para posteriormente
sumarla al número de fotograma absoluto.
A continuación, se muestra el método “search_next_temporal_id_position”:
El funcionamiento, es tal que todas las unidades NAL en que el tiempo de recepción
sea mayor que el tiempo de reproducciónvan a ser filtradas. Para conseguirlo se usa el
método “search_next_temporal_id_position” que se muestra a continuación.
Int search_next_temporal_id_position(cons tint temporal_id, cons tint* t_id, cons tint
initial_position, cons tint GOP_size)
{
for(int i=initial_position; i<GOP_size; i++){
if(t_id[i] == temporal_id)
return i;
}
}
Así, una vez obtenida la posición absoluta en orden de reproducción, todas las
unidades NAL en que su tiempo de recepción sea mayor que el tiempo de
reproducción van a ser filtradas. En cambio, siempre que se llegue a tiempo para la
correcta reproducción las unidades NAL son almacenadas en la cola circular intermedia
(objeto de la clase H264BitStream).
En el caso, en que se filtra además de descartar la unidad NAL, se va a redefinir la capa
máxima a la que se podrá filtrar para que el segundo hilo, usando este dato pueda
filtrar el flujo entero de una iteración según el DTQ_th resultante de dicha iteración.
5.2.3. Solución de semáforos de la aplicación:
Finalmente, la aplicación constara de dos hilos, tal y como se ha descrito
anteriormente. De esta forma las variables compartidas serán el objeto de la clase
H264BitStream y el valor máximo de la extracción. El pseudocódigo correspondiente a
cada uno de los dos hilos en los que se deberá definir una solución de control de
acceso mediante semáforos es el siguiente.
HILO 1{
Sistema de video adaptativo H264/SVC sobre TCP
96
while(!end_of_execution){
receive_1_iter_filter_and_modify_DTQ_th();
modify_DTQ_th2(dependency_id_th, temporal_id_th, quality_id_th);
}
}
HILO2{
while(!end_of_execution){
obtain_DTQ_th2(dependency_id_th, temporal_id_th, quality_id_th);
filter_1_iter_and_send_to_play();
}
}
Como se había comentado antes, el primer hilo se encarga de llevar a cabo el filtrado
de unidades NAL según los tiempos de recepción y la actualización en cada iteración
del DTQ_th. El segundo hilo, se encarga de filtrar al DTQ_th obtenido por el primer hilo
y enviar a reproducir el video.
En esta solución se implementa de forma que cada hilo tiene su valor de DTQ_th, y la
aplicación comparte las variables globales DTQ_th2. En los accesos a los métodos de
actualización y modificación de dicha variable, se define control de acceso mediante
semáforos, para evitar situaciones conflictivas en tiempo de ejecución.
En cada uno de los métodos se accede en primer lugar mediante el semáforo principal
de la aplicación que es el correspondiente a la cola circular intermedia, de igual forma
que se hacía en el transmisor. Una vez introducido el control de acceso, los métodos
quedan de la forma siguiente.
void_modify_DTQ_th2(const int dependency_id_th, const int temporal_id_th, const
int quality_id_th, sem_t* s1, sem_t* s3)
{
sem_wait(s1);
if(actualized){
nw_sem3 ++;
sem_post(s1);
sem_wait(s3);
sem_wait(s1);
}
actualized = true;
dependency_id_th2 = dependency_id_th;
temporal_id_th2 = temporal_id_th;
quality_id_th2 = quality_id_th;
if(nw_sem3 > 0)
97
Sistema de video adaptativo H264/SVC sobre TCP
sem_post(s3);
sem_post(s1);
}
void obtain_DTQ_th2(int dependency_id_th, int temporal_id_th, int quality_id_th)
{
sem_wait(s1);
if(!actualized){
nw_sem3 ++;
sem_post(s1);
sem_wait(s3);
sem_wait(s1);
}
actualized = false;
dependency_id_th = dependency_id_th2;
temporal_id_th = temporal_id_th2;
quality_id_th = quality_id_th2;
if(nw_sem3 > 0)
sem_post(s3);
sem_post(s1);
}
La solución propuesta, usa la variable “actualized” como método de control de acceso,
variable que sólo se modifica dentro de los métodos y siempre en exclusión mutua. La
variable indica si se ha actualizado el DTQ_th. De esta forma, se quedara detenido en
el segundo hilo cuando su valor sea falso, porque indicara que no ha sido actualizado, y
en primer hilo cuando sea cierto. Así, en el primer hilo lo actualiza a cierto y en el
segundo lo actualiza a falso. El funcionamiento de los semáforos es el mismo, se entra
a zona crítica y en caso que deba detenerse lo hace en el segundo semáforo. Al salir de
los métodos se da recursos para el semáforo detenido, en caso que haya algún hilo
detenido y en espera.
Esta solución permite que la ejecución sea concurrente entre los dos hilos con un
máximo de una iteración de diferencia entre actualizaciones de DTQ_th2 y con un
máximo de dos iteraciones entre los dos hilos, aunque el primero quedándose
detenido en el semáforo de espera. Además, no hay ninguna interacción que haga que
los dos hilos se queden parados y entre ellos se van abriendo la puerta en los casos de
detención de uno de ellos con lo que se considera una buena solución.
Sistema de video adaptativo H264/SVC sobre TCP
98
Capítulo 6:
Evaluación del sistema:
Para la evaluación del sistema se ha elegido la secuencia de video BigBuckBunny con
una duración de 9 minutos y 56 segundos. En concreto se va a hacer una codificación
de tres capas con resoluciones de 640x360 en la capa superior y su versión diezmada
de 360x180 en la capa base y en la capa de mejora de calidad, con una velocidad de
reproducción de 24 fotogramas por segundo cada una de ellas.
Se verán a continuación la elección de las principales características de codificación.
6.1.
Características de la codificación:
En JSVM se utilizan unos ficheros de codificación en los que se especifica diferentes
atributos de codificación. En concreto, se eligen el número de capas, el tamaño de
GOP, el periodo de intra-predicción, que indica cada cuantos fotogramas aparece una
tira I, el periodo IDR, que indica cada cuantos fotogramas aparece una tira de IDR, la
capa base a partir de la que se predice entre capas, …
Sin embargo, el parámetro más importante que se elige es el parámetro de
cuantificación, que será el principal determinante de la PSNR obtenida. Se puede
demostrar que una PSNR de 40 dB proporciona una secuencia decodificable
visualmente aceptable para el ojo humano.
En primer lugar vamos a centrarnos en la elección de la estructura diádica. Se elige un
tamaño de GOP igual a 2 y un periodo de intra-predicción igual a 4, para cada una de
las tres capas. La elección ha sido tomada porque cuanto mayor es el tamaño de GOP,
cuando hay cambios repentinos de escena, se va a bi-predecir de fotogramas que no se
van a parecer en nada. Es por esto que se eligen valores pequeños que permitan
obtener una secuencia reconstruida con mejor PSNR. Esta combinación da lugar a la
secuencia de tiras en orden de reproducción siguiente:
IBPBIBP…
En cuanto a la elección del periodo de tiras de instante de refresco instantáneo, se ha
optado por un periodo de 16 tiras, de forma que cada cuatro tiras I una de ellas sea de
decodificación instantánea. La elección ha sido tomada para que los errores
propagados, sean reseteados cada un número razonable de tiras.
De esta forma la codificación da lugar a una secuencia de video codificado con seis
capas de extracción posible, dos capas de escalabilidad temporal por cada una de las
tres capas principales, de forma que habrán seis resultados posibles al aplicar el
algoritmo de filtrado.
99
Sistema de video adaptativo H264/SVC sobre TCP
En cuanto a la capa de la que predicen, se ha optado por hacer predecir tanto la capa
de resolución superior como la de mejora de la capa base. La elección de la capa base
en el caso de la capa de mejora de resolución, ha sido tomada porque con el algoritmo
de filtrado se consigue una mejor relación PSNR a ancho de banda de transmisión, ya
que se filtrara la capa de mejora de calidad al filtrar hasta la capa superior.
6.1.1. Elección de los parámetros de cuantificación:
Para la elección de los parámetros de cuantificación se ha tenido en cuenta la PSNR de
la secuencia reconstruida. De esta forma buscando unas PSNR similares a 40 dB se han
obtenido los siguientes parámetros de cuantificación:
D
Q
T
QP
0
0
0
32
0
0
1
33
0
1
0
25
0
1
1
26
1
0
0
27
1
0
1
28
Tabla 6.1: Parámetros de cuantificación
Como se puede observar, se han elegido los parámetros de cuantificación de 32, 25 y
27 para cada una de las tres capas. En cuanto a las capas temporales superiores se ha
utilizado el mismo parámetro de cuantificación más uno.
Por último, en las componentes de crominancia, se les ha aplicado una rectificación de
más dos en el parámetro de cuantificación debido a la naturaleza del ojo humano a
reconocer con más precisión la componente de luminancia.
Se considera una buena elección de los parámetros de cuantificación porque se
obtienen las siguientes PSNR en la secuencia reconstruida:
CAPA
0
1
2
PSNR (Y)
PSNR (Cr)
36.2303 dB 42.9990 dB
41.0125 dB 45.2626 dB
41.2202 dB 45.8067 dB
Tabla 6.2: PSNR obtenidas
PSNR (Cv)
41.7011 dB
44.4091 dB
45.1039 dB
Como se puede ver se consiguen PSNR superiores a los 40 dB en todos los casos
menos en la capa base que es de 36 dB. Se considera aceptable, por el hecho de que
existe una capa de mejora de PSNR para esta capa.
6.2.
Resultados al aplicar el algoritmo de filtrado:
Sistema de video adaptativo H264/SVC sobre TCP
100
A continuación, se muestran los flujos de datos resultantes una vez aplicado el
algoritmo de filtrado, donde se pueden observar las capas incluidas en cada extracción,
tal y como se ha explicado en el ejemplo del capítulo 3:
Hasta capa 000:
Figura 6.1: Algoritmo extracción hasta la capa 000
Hasta 001:
Figura 6.2: Algoritmo extracción hasta la capa 001
Hasta 100:
Figura 6.3: Algoritmo extracción hasta la capa 100
Hasta 010:
101
Sistema de video adaptativo H264/SVC sobre TCP
Figura 6.4: Algoritmo extracción hasta la capa 010
Hasta 011:
Figura 6.5: Algoritmo extracción hasta la capa 011
Hasta 110:
Figura 6.6: Algoritmo extracción hasta la capa 110
6.3.
Perfiles de ancho de banda de transmisión:
A continuación, se verán los perfiles de ancho de banda de transmisión de las
diferentes extracciones posibles, es decir con cada una de las diferentes
combinaciones de identificadores de dependencia.
Lo que se muestra en las figuras es el ancho de banda necesario para transmitir hasta
una determinada capa a través del tiempo. El resultado ha sido obtenido a través de la
estimación de ancho de banda en tiempo real. Por lo tanto, se verá para cada capa cual
sería la velocidad de transmisión necesaria para transmitir hasta esa capa en cada
instante temporal de la duración del video.
Hasta capa 000:
Sistema de video adaptativo H264/SVC sobre TCP
Figura 6.7: Perfil de ancho de banda: Capa 000
Hasta capa 010:
Figura 6.8: Perfil de ancho de banda: Capa 010
Hasta capa 001:
102
103
Sistema de video adaptativo H264/SVC sobre TCP
Figura 6.9: Perfil de ancho de banda: Capa 001
Hasta capa 011:
Figura 6.10: Perfil de ancho de banda: Capa 011
Hasta capa 100:
Sistema de video adaptativo H264/SVC sobre TCP
104
Figura 6.11: Perfil de ancho de banda: Capa 100
Hasta capa 110:
Figura 6.12: Perfil de ancho de banda: Capa 110
Como era de esperar, las capas superiores necesitan un ancho de banda mayor que las
inferiores. Vamos a ver a continuación los anchos de banda de transmisión medios, así
como sus desviaciones típicas para poder valorar objetivamente la variación del video
a través del tiempo, aunque ya podemos ver en las gráficas que se trata de una
secuencia de video que contiene escenas con mucho y con poco movimiento porque
las desviaciones típicas serán de un valor considerablemente grande.
Capa
Ancho de banda medio
Desviación típica (Kbit/s)
105
Sistema de video adaptativo H264/SVC sobre TCP
(Kbit/s)
000
202,87
100,13
010
298,86
184,88
001
533,16
237,12
011
576,51
278,39
100
1195,90
743,28
110
1294,00
846,80
Tabla 6.3: Medias y desviaciones típicas del ancho de banda de transmisión
Como se puede ver en la tabla 6.3, se obtienen unas desviaciones típicas desde el 45
por ciento al 66 por ciento. Esto indica que la variabilidad del video es grande, es decir,
que existen escenas con poco y con mucho movimiento, lo que provoca que el tamaño
del video codificado sea tan variante.
A parte, las medias obtenidas de aproximadamente 300 Kbit/s, 600 Kbit/s y 1,3 Mbit/s
para cada una de las tres capas principales, se consideran un buen ejemplo de las
capacidades del estándar H264/SVC, ya que para el objetivo del presente proyecto que
es la transmisión de la secuencia de video, permiten una estrategia que divida las
capas de forma clara y concisa.
6.4.
Puesta en escena:
El último apartado del capítulo 6, será la puesta en escena del sistema de
comunicaciones diseñado en un escenario real. Se va a emular una red con un
transmisor (“sender”), dos routers intermedios (“routerA” y “routerB”) y un
destinatario (“sink”) usando la herramienta de emulación “Simtools”. A parte, el
dispositivo “host” tendrá acceso a las tres interfaces de red generadas. El esquema de
red es el siguiente:
Figura 6.13: Escenario de red para las pruebas
Sistema de video adaptativo H264/SVC sobre TCP
106
En el primer router se configura el ancho de banda máximo que puede aceptar la
transmisión, así como su RTT. En cambio, en el segundo router se configura el tamaño
máximo de la cola de espera y su retardo de transmisión, obteniendo el ancho de
banda disponible como el producto del tamaño de la cola por dos veces el retardo
introducido, que se corresponde con tamaño de la cola por RTT.
Las pruebas de red que se van a realizar son las cinco siguientes:
1. Transmisión de la secuencia BigBuckBunny con una limitación de ancho de
banda que permita extraer hasta la capa base, es decir un ancho de banda
disponible de 300 Kbit/s.
2. Transmisión de la secuencia BigBuckBunny con una limitación de ancho de
banda que permita extraer hasta la capa de mejora de calidad, es decir un
ancho de banda disponible de 600 Kbit/s.
3. Transmisión de la secuencia BigBuckBunny con una limitación de ancho de
banda que permita extraer hasta la capa de mejora de resolución, es decir un
ancho de banda disponible de 1,3 Mbit/s.
4. Transmisión de la secuencia BigBuckBunny con una limitación de ancho de
banda variable. La elección tomada es de 1,3 Mbit/s durante los primeros 200
segundos, 600 Kbit/s durante los siguientes 200 segundos y 1,3 Mbit/s hasta el
final.
5. Transmisión simultánea de dos flujos de datos, por un lado la secuencia
BigBuckBunny, y por otro lado una secuencia de video codificada según
H264/SVC. Se va a utilizar una limitación de ancho de banda de 1,3 Mbit/s, y el
objetivo de esta prueba será observar cómo se adapta la transmisión en un
entorno en el que se comparte el ancho de banda.
Para poder realizar las pruebas, se debe configurar en primer lugar el dispositivo
“host” para recepción de flujo en la tercera interfaz, ya que las transmisiones van a ser
realizadas por parte del dispositivo “sender” y recibidas por parte del “host” en dicha
interfaz. Se muestra a continuación, los comandos de configuración que se ejecutan en
el “host”:
host$ifconfig tap0 0
host$ifconfig tap2 172.16.5.2/24
host$route add -net 192.168.1.0/24 gw 172.16.5.1
De esta forma, queda configurado el dispositivo “host” con una dirección IP de la
tercera interfaz de red, y como pasarela para llegar a la primera interfaz se utiliza el
“routerB”.
107
Sistema de video adaptativo H264/SVC sobre TCP
Para la prueba cinco, se va a transmitir simultáneamente hacia el “host” (secuencia
BigBuckBunny), y hacia el “sink” (secuencia H264/AVC).
6.4.1. Prueba 1 - Ancho de banda límite de 300 Kbit/s:
Se configura el primer router con un ancho de banda límite de 300 Kbit/s para obtener
un perfil de transmisión que se adecue a la transmisión de la capa base. Viendo el
perfil de las capas 000 y 010 ya se puede observar que la variabilidad en tamaño del
video puede que provoque que no haya suficiente ancho de banda para poder
transmitir en la capa base durante todo el tiempo.
A continuación se muestra el flujo transmitido capturado con la herramienta de red
“Wireshark”:
Figura 6.14: Flujo transmitido: Prueba 300 Kbit/s
Como se puede observar la transmisión se detiene a los 220 segundos. Esto se debe al
hecho que no puede asumir en tiempo real la transmisión del flujo de datos, lo que
provoca que “mplayer” se congele y no se consiga el objetivo de poder reproducir la
secuencia en tiempo real.
A continuación, vemos el perfil generado de transmisión a partir de los valores
estimados de ancho de banda por parte del “socket” y la figura correspondiente al
intercambio entre capas realizado durante los 220 segundos de transmisión.
Sistema de video adaptativo H264/SVC sobre TCP
Figura 6.15: Perfil de transmisión según opciones del socket: Prueba 300 Kbit/s
Leyenda
Valor Capa
1
000
2
010
3
001
4
011
5
100
6
110
108
109
Sistema de video adaptativo H264/SVC sobre TCP
Figura 6.16: Intercambio entre capas: Prueba 300 Kbit/s
La diferencia de duración entre la simulación y las otras dos figuras se debe a los
instantes temporales en que se transmite con una capa con identificador temporal
menor al máximo, ya que en estos casos se reduce la duración del video. Esta
diferencia podría deberse al hecho que siempre se transmite con un ancho de banda
menor al disponible y por lo tanto las transmisiones se avanzan al instante de
reproducción. Sin embargo, este no es el caso, porque si se debiera a esta segunda
razón el video no se detendría.
Como puede verse en la figura 6.16, la mayor parte del tiempo se transmite hasta las
capas 000 y 010, por lo que se obtiene el resultado esperado para la prueba realizada.
Sin embargo, como no puede llegar a transmitir todo el flujo, se llega a la conclusión
que será necesario introducir un buffer de entrada en recepción que cargue parte del
video antes de empezar a reproducir, porque en caso contrario la reproducción se
detiene.
Se ha repetido la prueba introduciendo el uso del buffer, y se ha obtenido el flujo de
transmisión siguiente:
Sistema de video adaptativo H264/SVC sobre TCP
110
Figura 6.17: Flujo transmitido: Prueba 300 Kbit/s
Como puede esperarse se obtiene un flujo aproximado de 300 Kbit/s durante toda la
transmisión. La duración de 515 segundos queda justificada porque como se verá
durante gran parte de la transmisión se extrae hasta la capa 000, razón por la que se
reduce la duración del video.
El buffer intermedio que se ha elegido en este caso es de 3 Mbyte, de forma que antes
de empezar a transmitir se ponen 3 Mbyte en el buffer, haciendo que se inicie
aproximadamente un minuto después de empezar a transmitir. Esto nos indica que la
duración del video es de 465 segundos, por lo que se deduce, que aproximadamente el
25 % del tiempo se transmite con identificador temporal menor al máximo.
A continuación, se muestran las figuras correspondientes al perfil generado por las
estimaciones del “socket” y el intercambio entre capas realizado en la transmisión.
111
Sistema de video adaptativo H264/SVC sobre TCP
Figura 6.18: Perfil de transmisión según opciones del socket: Prueba 300 Kbit/s
Figura 6.19: Intercambio entre capas: Prueba 300 Kbit/s
Como puede observarse la mayor parte del tiempo se transmite hasta las capas 000 y
010.
6.4.2. Prueba 2 - Ancho de banda límite de 600 Kbit/s:
La segunda prueba realizada, está orientada a la reproducción de la secuencia de video
hasta la capa de mejora de PSNR, razón por la que se limita la transmisión a 600 Kbit/s.
En esta, y en las siguientes pruebas se ha decidido poner otra limitación al ancho de
banda para quede limitado por la velocidad de reproducción del video, aparte de por
Sistema de video adaptativo H264/SVC sobre TCP
112
el propio ancho de banda disponible. Para conseguirlo, se ha utilizado la opción “nocache” en el reproductor multimedia, para que no utilice un buffer interno de
almacenamiento. La razón de esta elección, es para evitar que la duración de la
transmisión sea mucho más reducida que la duración del video.
Se considera una buena estrategia, porque existe suficiente ancho de banda disponible
para poder reproducir como mínimo la capa base en tiempo real y se evita así que se
avance demasiado la transmisión. Esta estrategia se convierte en una limitación
porque la cola de espera hasta nivel de aplicación será la ventana de control de flujo
de TCP, y habrá instantes en que esta quedara bacía, y por lo tanto limitara las
transmisiones.
A continuación, se muestra el flujo transmitido de la segunda prueba capturado con
“Wireshark”:
113
Sistema de video adaptativo H264/SVC sobre TCP
Figura 6.20: Flujo transmitido: Prueba 600 Kbit/s
Como puede observarse se consigue un flujo de duración de 530 segundos. La razón
por la que termina antes es los instantes temporales en que se transmite con
identificador temporal menor al máximo. Además, como puede observarse, se obtiene
un flujo que en la mayor parte del tiempo está cerca de los 600 Kbit/s tal y como se
esperaba. Las razones por las que hay instantes de tiempo con menor ancho de banda
son el hecho de no utilizar buffer interno en el reproductor o situaciones de
congestión.
A continuación, se muestran las figuras correspondientes al perfil generado de flujo
máximo que se puede transmitir según las estimaciones obtenidas del “socket” y el
intercambio entre capas realizado en la transmisión:
Sistema de video adaptativo H264/SVC sobre TCP
114
Figura 6.21: Perfil de transmisión según opciones del socket: Prueba 600 Kbit/s
Figura 6.22: Intercambio entre capas: Prueba
Como puede observarse en el perfil el ancho de banda medio disponible es
aproximadamente de 600 Kbit/s, tal y como se esperaba. Los casos en que este
disminuye significativamente son casos de perdida de paquetes, razón por la que se
activa el control de congestión. Como se ha podido ver en la reproducción de la
secuencia el sistema a 600 Kbit/s se adapta correctamente a las fases de inicio y de
control de congestión.
115
Sistema de video adaptativo H264/SVC sobre TCP
A parte, como puede observarse en la figura 6.22, la mayor parte del tiempo se
transmite hasta las capas 000, 010, 001 y 011, lo cual se corresponde con al ancho de
banda necesario para transmitir dichas capas.
6.4.3. Prueba 3 - Ancho de banda límite de 1,3 Mbit/s:
La tercera prueba tiene como objetivo la transmisión del flujo a la máxima resolución
durante la mayor parte del tiempo, ya que como se ha visto en los perfiles de
transmisión de las capas la variabilidad en los tamaños hace que no pueda ser
transmitido a la máxima capa durante todo el tiempo.
A continuación, se muestra el flujo transmitido en esta prueba (capturado con
“Wireshark”):
Sistema de video adaptativo H264/SVC sobre TCP
116
Figura 6.23: Flujo transmitido: Prueba 1,3 Mbit/s
Como puede observarse se consigue un flujo de duración de 560 segundos. La razón
por la que termina antes es la misma que en la segunda prueba, ya que no se utiliza
buffer en el reproductor. Además, como puede observarse, se obtiene un flujo que en
la mayor parte del tiempo está cerca de los 1,3 Mbit/s tal y como se esperaba. Se
detectan casos con pérdida de paquetes como a los 460 segundos, pero al seguir
reproduciendo a tiempo real se observa que el sistema se adapta bien a los errores
debido al hecho que siempre transmite por debajo del ancho de banda disponible.
A continuación, se muestran las figuras correspondientes al perfil generado de flujo
máximo que se puede transmitir según las estimaciones obtenidas del “socket” y el
intercambio entre capas realizado en la transmisión:
117
Sistema de video adaptativo H264/SVC sobre TCP
Figura 6.24: Perfil de transmisión según opciones del socket: Prueba 1,3 Mbit/s
Figura 6.25: Intercambio entre capas: Prueba 1300 Kbit/s
En la figura 6.25, se observan varias situaciones con pérdida de paquetes, pero como
puede observarse el sistema reacciona a gran velocidad a la bajada de ancho de banda
disponible. Sin embargo, es importante darse cuenta que se deben a pérdidas de la
propia transmisión, razón por la que se recupera con gran velocidad, y en ninguno de
los tres casos analizados hasta ahora ha habido ancho de banda compartido con otras
transmisiones, caso que se verá en la prueba cinco.
A parte, como puede observarse en la figura 6.25, la transmisión ha estado
principalmente concentrada en las capas 100 y 110, tal y como se esperaba.
6.4.4. Prueba 4 - Ancho de banda variable de 1,3 Mbit/s y 600 Kbit/s:
Sistema de video adaptativo H264/SVC sobre TCP
118
Esta prueba, será evaluado con ancho de banda variable, los primeros 200 segundos se
dispondrá de 1,3 Mbit/s, los siguientes 200 segundos de 600 Kbit/s y hasta el final de la
secuencia 1,3 Mbit/s.
A continuación, se puede ver la figura correspondiente al flujo transmitido capturada
con “Wireshark”:
119
Sistema de video adaptativo H264/SVC sobre TCP
Figura 6.26: Flujo transmitido: Prueba 1300-600-1300 Kbit/s
Como se puede observar, se obtiene el perfil deseado de 1,3 Mbit/s, 600 Kbit/s y 1,3
Mbit/s con intercambios de flujo en los instantes indicados. Se obtiene una duración
de 540 segundos, como en los anteriores casos debido al acortamiento del video al
filtrar con identificadores temporales menores que el máximo.
A continuación, se muestran las figuras correspondientes al perfil de transmisión según
las estimaciones realizadas por el “socket” y el intercambio entre capas realizado en la
transmisión:
Figura 6.27: Perfil de transmisión según opciones del socket: Prueba 1300-600-1300
Kbit/s
Sistema de video adaptativo H264/SVC sobre TCP
120
Figura 6.28: Intercambio entre capas: Prueba 1300-600-1300 Kbit/s
Como puede observarse en la figura 6.28, se extrae mayormente a las capas 100 y 110
cuando el ancho de banda disponible es de 1,3 Mbit/s, y a las capas 000, 010, 001 y
011 cuando el ancho de banda disponible es de 600 Kbit/s.
6.4.5. Prueba 5 - Ancho de banda de 1,3 Mbit/s compartido:
En esta prueba, se han realizado dos transmisiones simultáneas desde el dispositivo
“sender”, una dirigida al dispositivo “host” con la secuencia codificada según
H264/SVC, y la otra dirigida al dispositivo “sink” con una secuencia codificada según
H264/AVC. El objetivo de esta prueba es observar cómo se reparte el ancho de banda
disponible (1,3 Mbit/s) entre las dos transmisión. Es una prueba más similar a los
entornos reales en que simultáneamente se comparte el ancho de banda con otras
aplicaciones.
En esta prueba, se ha prescindido de mostrar el flujo capturado con “Wireshark”
porque es el agregado por las dos transmisiones y se va a trabajar con el perfil de
transmisión obtenido a través de las estimaciones por parte del “socket”. A
continuación, se muestran las figuras correspondientes al perfil de transmisión y al
intercambio entre capas de esta prueba:
121
Sistema de video adaptativo H264/SVC sobre TCP
Figura 6.29: Perfil de transmisión según opciones del socket: Prueba 1,3 Mbit/s
compartido
Figura 6.30: Intercambio entre capas: 1,3 Mbit/s compartido
Como puede observase en la figura 6.29, se obtiene un ancho de banda disponible de
entre 300 y 900 Kbit/s, lo que nos indica que ambos flujos luchan por el ancho de
banda disponible durante todo el tiempo repartiéndoselo entre ambos.
Es importante darse cuenta de que existen situaciones con pérdidas en la transmisión
como se puede observar, y el sistema es capaz de restablecerse incluso en el caso de
flujo compartido con otras transmisiones, lo que indica una cierta robustez a las
situaciones de “congestion avoidance” por parte del sistema desarrollado. Sin,
embargo, es igual de importante percatarse que habrán situaciones de congestión
límite para todos los caos que harán que la transmisión se detenga debido a las
colisiones.
Sistema de video adaptativo H264/SVC sobre TCP
122
Por último, debido al flujo disponible, principalmente se extrae a las capas 000, 010,
001 y 011.
123
Sistema de video adaptativo H264/SVC sobre TCP
Capítulo 7:
Conclusiones:
Después de analizar la evaluación del sistema se llega a las conclusiones siguientes:
1. El algoritmo de filtrado desarrollado da lugar a flujos de datos conformantes
con el estándar H264/SVC.
2. Los resultados de aplicar las estrategias de filtrado adaptativo planteadas
aunque no dan lugar a flujos de datos conformantes estrictamente hablando,
son reproducibles por parte de “OpenSVCDecoder”, con cambios de resolución,
calidad y velocidad apreciables a simple vista. Por lo que se puede considerar
los flujos resultantes como conformantes con H264/SVC.
3. Las pruebas de red sin compartir el ancho de banda disponible reaccionan
correctamente a las pérdidas de paquetes permitiendo reproducir la secuencia
de video en tiempo real, siempre que se disponga del ancho de banda
necesario para transmitir como mínimo hasta la capa base.
4. En los casos en que no se dispone del ancho de banda necesario para transmitir
hasta la capa base, el uso de un buffer que almacene parte del flujo antes de
reproducir garantiza la correcta reproducción del video, con el retardo
introducido por el buffer. Cuanto menor sea el ancho de banda disponible, más
retardo se deberá introducir.
5. Las pruebas de red compartiendo el ancho de banda disponible reaccionan
correctamente a las pérdidas de paquetes permitiendo reproducir la secuencia
de video en tiempo real, siempre que se disponga de “n” veces” el ancho de
banda necesario para transmitir como mínimo hasta la capa base, donde “n” es
el número de transmisiones simultáneas, ya que tienden a repartirse el ancho
de banda a partes iguales, a menos que se definan los anchos de banda limite
por aplicación.
6. Obviamente, con situaciones de alta congestión, las transmisiones a tiempo
real no serán posible debido a las colisiones.
7. El sistema desarrollado es una alternativa real a los sistemas de video bajo
demanda existentes siempre que se disponga de una conexión de banda ancha.
7.1.
Líneas futuras:
Existen muchas mejoras que se podrían llevar a cabo para mejorar el sistema
desarrollado. A continuación, se muestran tanto posibles mejoras para el sistema
como proyectos futuros continuación del presente proyecto:
Sistema de video adaptativo H264/SVC sobre TCP
124
1. Desarrollar el receptor orientado a aplicaciones a tiempo real, diseñado en el
apartado 2 del capítulo 5.
2. Desarrollar un codificador H264/SVC a tiempo real, lo cual sería condición
necesaria para poder desarrollar sistemas de videoconferencia que trabajaran
con el estándar H264/SVC, ya que actualmente con “JSVM” las codificaciones
no son a tiempo real.
3. Modificar “OpenSVCDecoder” para que detecte cuando se transmite con
identificador temporal menor que el máximo, y conseguir que adapte la
velocidad de reproducción.
4. Desarrollar “plugins” para los principales navegadores web que permitan
incorporar el códec H264/SVC para poder reproducir las secuencias H264/SVC
en el navegador web.
5. Incorporar el sistema de comunicaciones trabajando sobre HTTP, ya sea en
forma de aplicación programada con PHP, o con “servlets” de JAVA, o
incluyéndolo de forma nativa en el estándar HTML5.
125
Sistema de video adaptativo H264/SVC sobre TCP
APÉNDICES
Sistema de video adaptativo H264/SVC sobre TCP
126
Apéndice A:
Ficheros de configuración del codificador de JSVM
utilizados en las simulaciones:
Los siguientes ficheros han sido utilizados para la configuración de la codificación
hecha en la secuencia de video “BigBuckBunny”. Concretamente, se han codificado dos
capas de escalabilidad temporal para cada una de las capas, siendo las capas: capa
base, capa de calidad mejorada (ambas con resolución 320x180) y capa de resolución
superior a 640x320.
El archivo principal, “confSVC.cfg” es el siguiente:
# JSVM Main Configuration File
#========================GENERAL================================
OutputFile stream.264
# Bitstream file
FrameRate 24.0
# Maximum frame rate [Hz]
FramesToBeEncoded 14000
# Number of frames (at input
frame rate)
NonRequiredEnable 0
# NonRequiredSEI enable
(0:disable, 1:enable)
CgsSnrRefinement 1
# SNR refinement as 1: MGS; 0:
CGS
EncodeKeyPictures 1
# Key pics at T=0 (0:none,
1:MGS, 2:all)
MGSControl 1
# ME/MC for non-key pictures in
MGS layers
# (0:std, 1:ME with EL, 2:ME+MC
with EL)
#===================== CODING STRUCTURE ========================
GOPSize 2
# GOP Size (at maximum frame
rate)
IntraPeriod 4
# Intra Period
NumberReferenceFrames 1
# Number of reference pictures
BaseLayerMode 0
#Base layer mode (0,1: AVC
compatible, 2: AVC w subseq SEI)
ConstrainedIntraUps 0
# constrained intra upsampling
#======================= MOTION SEARCH =========================
SearchMode 4
# Search mode (0:BlockSearch,
4:FastSearch)
SearchFuncFullPel 3
# Search function full pel
# (0:SAD, 1:SSE, 2:HADAMARD,
3:SAD-YUV)
SearchFuncSubPel 2
# Search function sub pel
# (0:SAD, 1:SSE, 2:HADAMARD)
SearchRange 32
# Search range (Full Pel)
ELSearchRange 4
# Enh. layer search range
FastBiSearch 1
# Fast bi-directional search
(0:off, 1:on)
127
Sistema de video adaptativo H264/SVC sobre TCP
BiPredIter 4
# Max iterations for bi-pred
search
IterSearchRange 8
# Search range for iterations
(0: normal)
#========?================ LOOP FILTER =========================
LoopFilterDisable 0
# Loop filter idc (0: on, 1:
off, 2: on except for slice boundarieS, 3: Se aplica 2 etapas de
filtrado (limite bloques y limite tiras)
# 4: Luma on but Chroma off in
enh. layer # (w.r.t. idc=0)
# 5: Luma on except on slice
boundaries but Chroma off in enh. layer # (w.r.t. idc=2)
# 6: Como 3 en las muestras
luma y sin filtrado croma
# Loop filter idc (0: on,
1: off, 2:
# on except for slice
boundaries,
# 3: Luma on but Chroma off in
enh. layer # (w.r.t. idc=0)
# 4: Luma on except on slice
boundaries.
# but Chroma off in enh. layer
# (w.r.t. idc=2)
LoopFilterAlphaC0Offset 0
# AlphaOffset(-6..+6): valid
range
LoopFilterBetaOffset 0
# BetaOffset (-6..+6): valid
range
InterLayerLoopFilterDisable 0
# filter idc for inter-layer
deblocking
InterLayerLoopFilterBetaOffset 0 # BetaOffset for inter-layer
deblocking
#======================= LAYER DEFINITION ======================
NumLayers 3
# Number of layers
LayerCfg confSVC_layer0.cfg
# Layer configuration file
LayerCfg confSVC_layer1.cfg
# Layer configuration file
LayerCfg confSVC_layer2.cfg
# Layer configuration file
#====================== WEIGHTED PREDICTION ====================
WeightedPrediction 0
# Weighting IP Slice
(0:disable, 1:enable)
WeightedBiprediction 1
# Weighting B Slice (0:disable,
1:explicit,
# 2:implicit)
#===================== LOSS-AWARE RDO ==========================
LARDO 0
# Loss-aware RDO (0:disable,
1:enable)
#========================= HRD =================================
EnableVclHRD 0
# Type I HRD (default 0:Off,
1:on)
EnableNalHRD 0
# Type II HRD (default 0:Off,
1:on)
#======================= RATE CONTROL ==========================
RateControlEnable 0
# Enable base-layer rate
control (0=off, 1=on)
#====================== FRAME-COMPATIBLE =======================
MuxMethod 0
# Enable 3D mux method (0:
none, 1: SbS, 2: TaB)
Sistema de video adaptativo H264/SVC sobre TCP
MuxFilter 15
#
#
#
#
#
#
#
#
#
#
#
#
#
128
# 3D Muxing/DOwnsampling Filter
0: decimate,
1: average
2: [-1 2 6 2 -1]/8
3: [-1 2 -1]
4: [-1 4 26 4 -1]/32
5: [ 1 -2 5 56 5 -2 1]/64
6: HF1
7: HF0
8: SVC
9: CDF9
10: CDF7
11: "1024"•
12: low-pass (fractional-pixel
offset)
# 13: JVT-R006 (fractional-pixel
offset)
# 14: JVT-R070 (fractional-pixel
offset)
# 15: SVC (fractional-pixel offset)
MuxOffset0 1
(view 0)
MuxOffset1 1
Layer1;
# 16: HF0 (fractional-pixel offset)
# offset for input to layer 0
# is not zero; offset for
Los archivos de configuración de las tres capas son los siguientes. A continuación se
muestra “confSVC_layer0.cfg”:
# JSVM Layer Configuration File
#=========================== INPUT ============================
SourceWidth 320
# Input frame width
SourceHeight 180
# Input frame height
FrameRateIn 24
# Input frame rate [Hz]
FrameRateOut 24
# Output frame rate [Hz]
InputFile BigBuckBunny_320x180@24_000-000s.yuv
# Input file
SymbolMode 0
# 0=CAVLC, 1=CABAC
IDRPeriod 16
# IDR period (should be (GOP
size)*N)
IntraPeriod 4
# Intra period (should be (GOP
size)*N)
#=========================== CODING ===========================
ProfileIdc 77
# value of profile_idc (or 0
for auto detection)
MinLevelIdc 10
# minimum level (level_idc * 10
)
CbQPIndexOffset 2
# QP index offset for the Cb
component
CrQPIndexOffset 2
# QP index offset for the Cr
129
Sistema de video adaptativo H264/SVC sobre TCP
component
MaxDeltaQP 1
# Max. absolute delta QP
QP 32.0
# Quantization parameters
#========================= CONTROL ============================
InterLayerPred 0
# Inter-layer Pred. (0:no,
1:yes, 2:adap.)
ILModePred 0
# Inter-layer mode pred. (0:no,
1:yes, 2:adap.)
ILMotionPred 0
# Inter-layer motion pred.
(0:no, 1:yes, 2:adap.)
ILResidualPred 0
# Inter-layer residual pred.
(0:no, 1:yes, 2:adap.)
#================ EXTENDED SPATIAL SCALABILITY ================
UseESS 0
# ESS mode
#============================= MGS ============================
MGSVectorMode 0
# MGS vector usage selection
#====================== QP Cascading ==========================
ExplicitQPCascading 1
# QP Cascading (0:auto,
1:explicit)
DQP4TLevel0 0
# Delta QP for temporal level 0
DQP4TLevel1 1
# Delta QP for temporal level 1
#=================== SVC TO AVC REWRITE =======================
AvcRewriteFlag 0
# Enable SVC to AVC rewrite (0:
no, 1: yes)
El archivo “confSVC_layer1.cfg” es el siguiente:
# JSVM Layer Configuration File
#==================== INPUT / OUTPUT ==========================
SourceWidth 320
# Input frame width
SourceHeight 180
# Input frame height
FrameRateIn 24
# Input frame rate [Hz]
FrameRateOut 24
# Output frame rate [Hz]
InputFile BigBuckBunny_320x180@24_000-000s.yuv
# Input file
SymbolMode 0
# 0=CAVLC, 1=CABAC
IDRPeriod 16
# IDR period (should be (GOP
size)*N)
IntraPeriod 4
# Intra period (should be (GOP
size)*N)
#======================== CODING ==============================
ProfileIdc 86
# value of profile_idc (or 0
for auto detection)
MinLevelIdc 10
# minimum level (level_idc * 10
)
CbQPIndexOffset 2
# QP index offset for the Cb
component
CrQPIndexOffset 2
# QP index offset for the Cr
component
MaxDeltaQP 1
# Max. absolute delta QP
QP 25.0
# Quantization parameters
Sistema de video adaptativo H264/SVC sobre TCP
130
BaseLayerId 0
# Layerd ID for the base layer
#======================== CONTROL =============================
InterLayerPred 2
# Inter-layer Pred. (0:no,
1:yes, 2:adap.)
ILModePred 2
# Inter-layer mode pred. (0:no,
1:yes, 2:adap.)
ILMotionPred 2
# Inter-layer motion pred.
(0:no, 1:yes, 2:adap.)
ILResidualPred 2
# Inter-layer residual pred.
(0:no, 1:yes, 2:adap.)
#================ EXTENDED SPATIAL SCALABILITY ================
UseESS 1
# ESS mode
ESSCropWidth 320
# base layer upsampled frame
width
ESSCropHeight 180
# base layer upsampled frame
height
ESSOriginX 0
# base layer upsampled frame xpos
ESSOriginY 0
# base layer upsampled frame ypos
#=========================== MGS ==============================
MGSVectorMode 0
# MGS vector usage selection
#====================== QP Cascading ==========================
ExplicitQPCascading 1
# QP Cascading (0:auto,
1:explicit)
DQP4TLevel0 0
# Delta QP for temporal level 0
DQP4TLevel1 1
# Delta QP for temporal level 1
#=================== SVC TO AVC REWRITE =======================
AvcRewriteFlag 0
# Enable SVC to AVC rewrite (0:
no, 1: yes)
El archivo “confSVC_layer2.cfg” es el siguiente:
# JSVM Layer Configuration File
#===================== INPUT / OUTPUT =========================
SourceWidth 640
# Input frame width
SourceHeight 360
# Input frame height
FrameRateIn 24
# Input frame rate [Hz]
FrameRateOut 24
# Output frame rate [Hz]
InputFile [email protected]
# Input file
SymbolMode 0
# 0=CAVLC, 1=CABAC
IDRPeriod 16
# IDR period (should be (GOP
size)*N)
IntraPeriod 4
# Intra period (should be (GOP
size)*N)
#========================= CODING =============================
ProfileIdc 86
# value of profile_idc (or 0
for auto detection)
MinLevelIdc 10
# minimum level (level_idc * 10
)
131
Sistema de video adaptativo H264/SVC sobre TCP
CbQPIndexOffset 2
# QP index offset for the Cb
component
CrQPIndexOffset 2
# QP index offset for the Cr
component
MaxDeltaQP 1
# Max. absolute delta QP
QP 27.0
# Quantization parameters
BaseLayerId 0
# Layerd ID for the base layer
#======================= CONTROL ==============================
InterLayerPred 2
# Inter-layer Pred. (0:no,
1:yes, 2:adap.)
ILModePred 2
# Inter-layer mode pred. (0:no,
1:yes, 2:adap.)
ILMotionPred 2
# Inter-layer motion pred.
(0:no, 1:yes, 2:adap.)
ILResidualPred 2
# Inter-layer residual pred.
(0:no, 1:yes, 2:adap.)
#=============== EXTENDED SPATIAL SCALABILITY =================
UseESS 1
# ESS mode
ESSCropWidth 640
# base layer upsampled frame
width
ESSCropHeight 360
# base layer upsampled frame
height
ESSOriginX 0
# base layer upsampled frame xpos
ESSOriginY 0
# base layer upsampled frame ypos
#========================== MGS ===============================
MGSVectorMode 0
# MGS vector usage selection
#===================== QP Cascading ===========================
ExplicitQPCascading 1
# QP Cascading (0:auto,
1:explicit)
DQP4TLevel0 0
# Delta QP for temporal level 0
DQP4TLevel1 1
# Delta QP for temporal level 1
#================= SVC TO AVC REWRITE =========================
AvcRewriteFlag 0
# Enable SVC to AVC rewrite (0:
no, 1: yes)
Sistema de video adaptativo H264/SVC sobre TCP
Apéndice B:
Sintaxis H264/SVC:
132
133
Sistema de video adaptativo H264/SVC sobre TCP
Sistema de video adaptativo H264/SVC sobre TCP
134
135
Sistema de video adaptativo H264/SVC sobre TCP
Sistema de video adaptativo H264/SVC sobre TCP
136
137
Sistema de video adaptativo H264/SVC sobre TCP
Sistema de video adaptativo H264/SVC sobre TCP
138
139
0
Sistema de video adaptativo H264/SVC sobre TCP
Sistema de video adaptativo H264/SVC sobre TCP
140
141
Sistema de video adaptativo H264/SVC sobre TCP
Sistema de video adaptativo H264/SVC sobre TCP
142
143
Sistema de video adaptativo H264/SVC sobre TCP
Sistema de video adaptativo H264/SVC sobre TCP
144
Apéndice C:
Manual de utilidades del proyecto:
C.1. Utilidades de video:
Reproducción de una secuencia YUV en Mplayer:
Una secuencia YUV, es aquella secuencia de video que está representado por las tres
componentes de representación de imagen YUV, es decir, una secuencia de video
decodificada.
La forma de indicarle a Mplayer que se va a reproducir una secuencia YUV es la
siguiente:
mplayer -demuxer rawvideo -rawvideo fps=FPS_IN:w=W_IN:h=H_IN in.yuv
En primer lugar se le indica que el formato de la secuencia de video no está codificado
(“rawvideo”), acto seguido para que Mplayer pueda reproducirlo se le indican la
velocidad de reproducción y su resolución. Mplayer con estos atributos es capaz de
detectar las diferentes combinaciones en número de bits para la representación de
todas sus componentes.
Reproducción de una secuencia codificada con H264:
Mplayer detecta automáticamente cuando se inicia la reproducción de una secuencia
de video codificada con H264, aunque para conseguir una respuesta más rápida por
parte de Mplayer es útil utilizar la extensión “.264”. El único parámetro que se le debe
indicar es la velocidad de reproducción.
Vemos a continuación el comando a ejecutar para reproducir una secuencia H264:
mplayer –fps FPS_IN in.264
Para la reproducción de un archivo codificado con SVC se utiliza exactamente el mismo
comando, y Mplayer ya se encarga de detectar que esta codificado con SVC. Para que
Mplayer detecte las codificaciones de SVC se debe compilar configurando el código
para que utilice este decodificador. Para más información sobre como realizar la
compilación, ver [4].
Descomprimir un fichero codificado:
Vamos a ver a continuación, el comando para obtener un fichero descomprimido en
formato YUV a partir de un fichero de entrada que use una de las siguientes
145
Sistema de video adaptativo H264/SVC sobre TCP
codificaciones o multiplexores de video y audio: AVI, MP4, H264; MPEG2, MPEG4. La
utilidad utilizada es “ffmpeg” y el comado correspondiente es el siguiente:
ffmpeg -i in.avi -v FPS_IN -s W_INxH_IN –pix-fmt yuv420p out.yuv
Los parámetros que se le indican son el fichero de entrada (“in.avi”), la velocidad de
reproducción de la secuencia de entrada, su resolución (se indica con un carácter “x”
en el medio) y el formato de codificación del archivo no comprimido de la salida. Se
elige por defecto “yuv420p”.
Obtención de versiones sub-muestreadas y sobre-muestreadas de una secuencia
YUV:
Para la obtención de versiones sub-muestreadas y sobre-muestreadas de una
secuencia YUV utilizaremos la utilidad “DownConvertStatic” del paquete de software
JSVM. El comando a utilizar es el siguiente:
DownConvertStatic W_IN H_IN in.yuv W_OUT H_OUT out.yuv NUM_METHOD
En los parámetros se indica las secuencias de entrada y de salida, y sus resoluciones. Es
decir, se indica la resolución del archivo de entrada, y la resolución deseada para el
archivo de salida. Además, se indica el o los filtros que se utilizaran para el submuestreo o el sobre-muestreo, mediante el parámetro “NUM_METHOD. Existen otros
parámetros, para aprender a utilizarlos o ver los distintos tipos de filtrado se
recomienda la lectura de [3]. El resultado de ejecutar esta utilidad será la versión sub o
sobre-muestreada de la entrada utilizando el método indicado.
Codificación de una secuencia H264/SVC:
El siguiente paso lógico, en las funcionalidades sobre utilidades de video, es la
codificación de una secuencia utilizando el estándar H264/SVC. Para codificar con AVC
se cogerá el caso particular de la siguiente explicación, en que solo se incluye una capa.
El proceso de codificación se realiza con la siguiente instrucción:
H264AVCEncoderLibTestStatic –pf confSVC.cfg
Existen muchos parámetros adicionales que se le pueden indicar, pero estos serán
equivalentes a los parámetros que se indicaran en el fichero de configuración. De esta
forma el único parámetro que se pasa es el archivo de configuración, donde se
inicializan todas las variables necesarias para la codificación.
Vemos a continuación las principales variables de codificación. No se van a presentar
todas las posibilidades del codificador “H264AVCEncoderLibTestStatic”. Para obtener
más información se recomienda la lectura de [3].
Sistema de video adaptativo H264/SVC sobre TCP
146
La codificación consta de varios ficheros de configuración, el principal (“confSVC.cfg”) y
uno por cada capa de las que conste la codificación (“confSVC_layer*i+”). Empezamos
presentando las opciones de configuración más importantes del archivo principal. En
ellas veremos la identificación del flujo de salida, su estructura de codificación, los
métodos utilizados en la búsqueda de muestras realizada en intra e inter-predicción y
la identificación de los ficheros correspondientes a las distintas capas que forman
parte de la codificación.
Empezamos, viendo la identificación del fichero de salida. Los parámetros que deberán
especificarse son los siguientes:
#============================ GENERAL ================================
OutputFile path/stream.264
# Bitstream file
FrameRate 24.0
# Maximum frame rate [Hz]
FramesToBeEncoded 14000
# Number of frames (at input frame rate)
Especificamos el nombre del fichero de salida, su velocidad de reproducción, y el
número de fotogramas de la secuencia de entrada que van a ser codificados. Como
punto importante, remarcar que para que no haya errores en la codificación el número
de fotogramas a codificar debe ser múltiplo del tamaño de GOP especificado en los
atributos que veremos a continuación.
En segundo lugar, se especifica la estructura de codificación, para conseguirlo
debemos fijar el tamaño de GOP de la secuencia y el periodo entre fotogramas intrapredecidos. La estructura en SVC se genera siguiendo los principios de funcionamiento
de la estructura diádica, de forma que con el tamaño de GOP determinaremos el
número de tiras B que habrá entre las tiras I y P.
#======================== CODING STRUCTURE ===========================
GOPSize 2
# GOP Size (at maximum frame rate)
IntraPeriod 4
# Intra Period
Seguimos en tercer lugar viendo las principales opciones en cuanto a los algoritmos de
búsqueda de muestras y el tamaño máximo sobre el que se van a realizar las
búsquedas. Es importante darse cuenta, que la velocidad de la codificación dependerá
bastante de la elección de estos parámetros.
#========================== MOTION SEARCH ============================
147
SearchMode 4
SearchFuncFullPel 3
SearchFuncSubPel 2
SearchRange 32
ELSearchRange 4
FastBiSearch 1
BiPredIter 4
IterSearchRange 8
Sistema de video adaptativo H264/SVC sobre TCP
# Search mode (0:BlockSearch, 4:FastSearch)
# Search function full pel
# (0:SAD, 1:SSE, 2:HADAMARD, 3:SAD-YUV)
# Search function sub pel
# (0:SAD, 1:SSE, 2:HADAMARD)
# Search range (Full Pel)
# Enh. layer search range
# Fast bi-directional search (0:off, 1:on)
# Max iterations for bi-pred search
# Search range for iterations (0: normal)
Con estos atributos, decidimos si utilizamos búsqueda rápida o por bloques, el tipo de
algoritmo utilizado para búsqueda a nivel de muestra o de sub-muestra, el tamaño
máximo de distancias en las búsquedas, así, como otros atributos más.
Por último, en el archivo de configuración principal, tenemos unos atributos que nos
permiten identificar donde encontrar los archivos de configuración de cada una de las
capas. Habrá una variable por cada capa de las que conste la codificación.
#========================== LAYER DEFINITION ===========================
NumLayers 3
# Number of layers
LayerCfg confSVC_layer0.cfg
# Layer configuration file
LayerCfg confSVC_layer1.cfg
# Layer configuration file
LayerCfg confSVC_layer2.cfg
# Layer configuration file
Pasamos a ver a continuación los principales atributos que se deben definir en los
archivos de configuración de cada una de las capas. En concreto veremos la
identificación de la secuencia de entrada en formato YUV, las características de la
estructura, las características de la codificación, si se utiliza predicción entre capas y si
se utiliza escalabilidad de resolución.
En primer lugar vamos a ver, la identificación de la secuencia YUV de entrada, su
resolución y su velocidad de reproducción de entrada. Además podemos fijar el valor
de la velocidad de reproducción de salida, con lo que en caso de que sean valores
distintos aumentaría o disminuiría el número de fotogramas codificados. Esta opción
nos permite por ejemplo fijar una secuencia de entrada a 50 fotogramas por segundo,
y en la capa base solo codificar la mitad de estos fotogramas fijando la velocidad de
salida a 25 fotogramas por segundo.
#==================== INPUT / OUTPUT ==========================
Sistema de video adaptativo H264/SVC sobre TCP
148
SourceWidth 320
# Input frame width
SourceHeight 180
# Input frame height
FrameRateIn 24
# Input frame rate [Hz]
FrameRateOut 24
# Output frame rate [Hz]
InputFile BigBuckBunny_320x180@24_000-000s.yuv
# Input file
Se verá a continuación, los parámetros correspondientes el periodo de tiras intrapredecidas, que indica para cada capa la periodicidad de las tiras I; y el periodo de tiras
IDR, que nos indicara la periodicidad en instantes de refresco, que seran tiras
decodificables por sí mismas, y como consecuencia instantes en los que se dejaran de
propagar errores.
#======================== CODING STRUCTURE ===========================
IDRPeriod 16
IntraPeriod 4
# IDR period (should be (GOP size)*N)
# Intra period (should be (GOP size)*N)
En tercer lugar, se verán los atributos que fijaran si se utilizara predicción entre capas
en la capa actual, y en caso que sea así, a partir de que capa se va a predecir.
#======================== CODING ==============================
BaseLayerId 0
# Layerd ID for the base layer
#======================== CONTROL =============================
InterLayerPred 2
# Inter-layer Pred. (0:no,
1:yes, 2:adap.)
ILModePred 2
# Inter-layer mode pred. (0:no,
1:yes, 2:adap.)
ILMotionPred 2
# Inter-layer motion pred.
(0:no, 1:yes, 2:adap.)
ILResidualPred 2
# Inter-layer residual pred.
(0:no, 1:yes, 2:adap.)
En este caso, decidimos para cada capa de mejora la capa sobre la que se realizaran las
predicciones, normalmente la inferior; aunque existen casos como cuando se utiliza
una capa intermedia con calidad mejorada, en que la capa de resolución superior se
hace predecir sobre la capa base por temas de eficiencia entre tamaños de extracción
utilizando el algoritmo de filtrado y calidad visual obtenida. En el caso de la capa base
este atributo no se utiliza ya que no va a predecir de ninguna capa.
Además, se especifica el tipo de predicciones entre capas que se va a utilizar, pudiendo
elegir un tipo para todas las predicciones entre capas (primer atributo), o un tipo para
149
Sistema de video adaptativo H264/SVC sobre TCP
cada uno de los tres tipos de predicción entre capas. En las capas superiores se deberá
especificar un valor de 1 o de 2, mientras que en la capa base se elegirá el valor de 0,
ya que no existe predicción entre capas.
Pasamos a ver, los atributos correspondientes al parámetro de cuantificación que
vamos a utilizar. En primer lugar veremos la forma de fijar el parámetro de
cuantificación que vamos a utilizar. Además vamos a ver como fijar parámetros de
cuantificación diferentes en las componentes de crominancia, y en las distintas capas
temporales que se generan.
#======================== CODING ==============================
MaxDeltaQP 1
# Max. absolute delta QP
QP 25.0
# Quantization parameters
Con estos dos parámetros fijamos el parámetro de cuantificación para la capa, y la
máxima desviación absoluta que se permitirá respecto al valor fijado, en este caso el
parámetro de cuantificación quedaría entre 24 y 26.
#======================== CODING ==============================
CbQPIndexOffset 2
# QP index offset for the Cb component
CrQPIndexOffset 2
# QP index offset for the Cr component
Con estos dos parámetros fijamos la diferencia relativa de cada una de las dos
componentes de crominancia respecto al valor de la capa. Normalmente se utilizara
estos atributos con diferencias positivas ya que el ojo humano es más sensible a la
componente de luminancia, y consecuentemente nos podremos permitir
normalmente el hecho de que no se obtengan unas PSNR tan altas en las componentes
de crominancia.
Para conseguir, diferentes parámetros de cuantificación en las distintas capas
temporales generadas dentro de cada capa utilizamos “QPCascading”, en el que
definimos de la misma forma que antes las diferencias relativas respecto al valor de la
capa, para cada una de las capas de escalabilidad temporal. Es necesario especificar un
valor para cada capa en caso de especificarse su uso.
#======================= QP Cascading =========================
ExplicitQPCascading 1
# QP Cascading (0:auto, 1:explicit)
DQP4TLevel0 0
# Delta QP for temporal level 0
DQP4TLevel1 1
# Delta QP for temporal level 1
Sistema de video adaptativo H264/SVC sobre TCP
150
En quinto lugar, veremos como determinar si vamos a utilizar escalabilidad espacial.
Tendremos un atributo que nos permitirá activar su uso, y deberemos indicar la
resolución de la capa en la que estamos trabajando. Este atributo se deberá activar
tanto cuando estemos utilizando una capa con resolución superior, como cuando
estemos generando una capa de calidad mejorada con el uso de MGS. Se muestran a
continuación estos atributos:
#================ EXTENDED SPATIAL SCALABILITY ================
UseESS 1
# ESS mode
ESSCropWidth 320
# base layer upsampled frame width
ESSCropHeight 180
# base layer upsampled frame height
ESSOriginX 0
# base layer upsampled frame x-pos
ESSOriginY 0
# base layer upsampled frame y-pos
En penúltimo lugar se va a explicar cómo se debe hacer para realizar una codificación
usando MGS y generando varias capas de mejora con partición de los coeficientes.
Para ello, disponemos de un atributo que se encarga de permitir activar el uso de MGS
con partición de coeficiente, y posteriormente asignaremos valores para cada capa de
mejora, la suma de los cuales debe ser 8, correspondientes al número de coeficientes
disponibles. Se muestran a continuación estos atributos:
#=========================== MGS ==============================
MGSVectorMode 1
# MGS vector usage selection
MGSVector0 4
# Specifies 0th position of the vector
MGSVector1 2
# Specifies 1st position of the vector
MGSVector2 2
# Specifies 2nd position of the vector
Decodificación de una secuencia H264/SVC:
La utilidad para decodificar una secuencia H264, tanto AVC como SVC, es
“H264AVCDecoderLibTestStatic”. Esta utilidad convierte una secuencia codificada
según H264 en una secuencia de video no comprimida en formato YUV. A continuación
se muestra el comando para decodificar, donde sus atributos son la secuencia H264 de
entrada, y el fichero en el que almacenar el flujo decodificado:
H264AVCDecoderLibTestStatic in.264 out.yuv
C.2. Utilidades de compilación:
151
Sistema de video adaptativo H264/SVC sobre TCP
Compilación con make:
Para realizar la compilación del código que se haya desarrollado utilizaremos el
compilador de GNU: GCC. Veremos a continuación la plantilla de un Makefile que
utilizara este compilador. En concreto, el ejemplo que se propone trabaja con la
utilidad c++, que se corresponde con el compilador del lenguaje de programación c++
del conjunto de compiladores GCC.
Para compilar vamos a utilizar el siguiente comando. Este debe ejecutarse en el
directorio raíz en que se encuentran los archivo de código fuente.
cd project_dir
make
Vemos a continuación el conjunto de instrucciones que forman parte del Makefile:
EXEC := application_name
DIRSRC := src/
DIROBJ := obj/
DIRHDR := include/
CXXFLAGS := -I $(DIRHDR)
OBJS := $(subst $(DIRSRC),
$(wildcard $(DIRSRC)*.cpp)))
$(DIROBJ),$(patsubst
%.cpp,
%.o,
.PHONY: all clean
all: info $EXEC
$(EXEC): $(OBJS)
$(CXX) -o $@ $^
$(DIROBJ) %.o: $(DIRSRC) %.cpp
$(CXX) $(CXXFLAGS) -c $< -o $@
clean:
rm -f *.log $(EXEC) *~ $(DIROBJ)* $(DIRSRC)*~ $(DIRHEA)*~
El Makefile anterior se encarga de realizar la compilación del fichero por etapas. En
primer lugar a partir los ficheros de código fuente obtiene los ficheros objeto
resultantes y los almacena en el directorio “obs/”. Acto seguido, se realiza el proceso
de enlazado para obtener el ejecutable resultante.
Además hemos definido el comportamiento cuando se ejecute “make clean”, para que
elimine todos los ficheros temporales.
Sistema de video adaptativo H264/SVC sobre TCP
152
El siguiente comando realiza la misma funcionalidad. En él se deben especificar todas
las cabeceras y ficheros de código fuente necesarios para la compilación.
c++ -o application_name hdr1.h … hdrN.h src1.cpp … srcN.cpp
Compilación con KDevelop4:
En el programa KDevelop4, se trabaja con Makefiles que van a ser compilados
utilizando CMake. Para compilar en KDevelop solo es necesario incluir todos los
ficheros en el proyecto y sus nombres, tanto de cabecera como de código fuente en el
archivo “CMakeLists.txt”. Así, es el propio programa el que se encarga de generar los
ficheros de compilación.
En concreto deben ponerse utilizando la siguiente línea de texto:
add_executable(application_name hdr1.h … hdrN.h src1.cpp … srcN.cpp)
C.3. Utilidades desarrolladas en el proyecto:
Obtener los atributos de una secuencia H264/SVC:
La primera utilidad desarrollad, se encarga de mostrar por pantalla los atributos de
cada una de sus unidades NAL. En concreto muestra tipo de unidad NAL, capa a la que
pertenece y en caso de ser una tira codificada, tipo de tira (I, P o B). Además, en todos
los casos muestra el número de unidad NAL, y su tamaño en bytes.
El comando correspondiente es el siguiente:
obtain_NALU_parameters in.264
El único parámetro que tiene es el flujo de entrada.
Filtrado hasta una capa máxima:
La segunda utilidad desarrollada en el proyecto se encarga de obtener una versión
filtrada de la secuencia de video H264/SVC de entrada. De esta forma, eligiendo en la
línea de comandos el DTQ máximo de la extracción obtenemos a la salida otra
secuencia H264/SVC, que es a su vez conformante con el estándar, es decir, la
secuencia resultante será decodificable y reproducible.
El comando correspondiente para esta utilidad es el siguiente:
extract_DTQ in.264 out.264 D_th T_th Q_th
Como se puede observar se fijan los atributos máximos de la extracción, el archivo de
entrada, y el archivo de salida en que será almacenada la versión filtrada.
153
Sistema de video adaptativo H264/SVC sobre TCP
Extracción con ancho de banda fijo:
Esta utilidad, se encarga de extraer según el algoritmo de filtrado siempre hasta la
capa con ancho de banda necesario para transmitir hasta esa capa máximo pero
menor al disponible, que en este caso será fijo y será uno de los atributos que se le
pasaran al ejecutable.
El comando correspondiente es el siguiente:
fixedBW_extraction in.264 out.264 max_BW(KB/s)
Como se puede observar los atributos que se le van a pasar son el archivo de entrada,
el de salida y el ancho de banda disponible. Este ancho de banda limite será
comparado con las estimaciones del ancho de banda necesario para transmitir hasta
cada una de las posibles capas, y servirá para limitar la extracción. Se ve así, que
cuanto mayor sea el ancho de banda disponible, más calidad tendrá la secuencia
extraída.
Extracción con ancho de banda variable:
Este caso, será igual que el anterior pero utilizando intercambios de ancho de banda
disponible a través del tiempo. Para conseguirlo se ha utilizado un fichero auxiliar en el
que se indicaran los diferentes anchos de banda y se pasa como atributo el periodo de
actualización entre cambios de ancho de banda máximo (se indica en segundos).
El comando correspondiente es el siguiente:
variableBW_extraction in.264 out.264 BW.txt time(s)
Sus atributos son la secuencia de entrada, el fichero donde almacenar la secuencia de
salida, el fichero auxiliar en el que se almacena un valor de ancho de banda (KB/s) por
línea y el intervalo de actualización.
Este ejecutable funciona de tal forma que cuando transcurre el tiempo indicado, se
actualiza el ancho de banda disponible. Conseguimos así, emular el funcionamiento de
situaciones en que el ancho de banda disponible es variante.
Extracción por red:
Finalmente, se va a explicar el funcionamiento del sistema de transmisión diseñado.
Esta vez al trabajar a través de redes, ha sido necesario definir dos utilidades distintas,
el transmisor se encargara de enviar el flujo de dato filtrado según el ancho de banda
disponible y el receptor de enviarlo al reproductor.
El comando correspondiente a la transmisión del flujo de datos es el siguiente:
network_extraction in.264 @dst_IP dst_PORT
Sistema de video adaptativo H264/SVC sobre TCP
154
Los parámetros son los correspondientes al fichero de entrada y la identificación del
servidor formada por su dirección IP y su puerto. De esta forma fijamos el destino de la
transmisión y vamos extrayendo hasta la capa con mayor ancho de banda inferior al
disponible, que obtenemos con la estimación de TCP, es decir, tamaño de la ventana
de congestión dividido por el RTT, o con la estimación de tamaños enviados dividido
por el tiempo de ejecución o una combinación entre los dos casos.
Una vez realizadas las pruebas en la puesta en escena del proyecto se ha visto que el
estimador reaccionaba de forma muy agresiva debido a la detección de pérdidas. Por
esta razón se ha desarrollado una última versión en la que se puede elegir el peso de
cada uno de los estimadores. El comando correspondiente es el siguiente:
network_extractor in.264 @dst_IP dst_PORT TCP_est_height(%)
En este caso se indica además el peso que tendrá el estimador de TCP en tanto por
ciento.
La otra utilidad necesaria para el funcionamiento del sistema es un receptor TCP
estándar, que se encargue de almacenar el contenido recibido, o de enviarlo al
reproductor. Es importante darse cuenta que el receptor se deberá ejecutar siempre
antes que el transmisor ya que funcionara como servidor, y en caso de hacerlo en
orden inverso, el transmisor no encontraría el socket escuchando en el puerto y
dirección IP correspondientes.
El comando correspondiente al receptor es el siguiente:
tcp_server @src_IP src_PORT
Se le indica la dirección IP y el puerto en la que realizar la escucha y se envía a la salida
estándar el contenido de video recibido.
Para terminar vamos a ver la utilización de estas comandas y otra adicional (bfr), para
la realización de las pruebas que se han detallado en el capítulo 6.
En primer lugar creamos un fichero FIFO, que utilizaremos como punto intermedio
entre el receptor y el buffer que se encargara de cargar parte del fichero antes de
empezar a reproducirse.
mkfifo fifo_name
En segundo lugar utilizamos el comando bfr para disponer del buffer, que nos va a
permitir precargar parte de la secuencia antes de empezar a reproducir y redirigimos
su salida estándar para ser reproducida con Mplayer.
bfr fifo_name -v -pk1m -m 10% -i 99% --throttle 90% --speedcap 8000K
155
Sistema de video adaptativo H264/SVC sobre TCP
--buffersize BUFFER_SIZE -o - | mplayer -nocache - 1>/dev/null
En tercer lugar ponemos el receptor en escucha:
tcp_server @src_IP src_PORT
Para finalizar ejecutamos
“network_extraction”:
en
el
origen
de
la
transmisión
el
comando
network_extraction in.264 @dst_IP dst_PORT
Lo que conseguimos con estas instrucciones es que empiece la transmisión y que se
vaya cargando el video en el buffer intermedio. Entonces cuando ha terminado de
cargar el buffer que le hemos indicado, empezara la reproducción de la secuencia de
video en Mplayer.
Sistema de video adaptativo H264/SVC sobre TCP
156
Bibliografía:
[1] ITU-T, “H264, advanced video coding for generic audiovisual services”,
2012
[2+ Marc Torrent Vernetta, “Diseño de un sistema de transmisión de video
escalable sobre un sistema de redes P2P”, 2010
[3] ITU-T, “JSVM software manual”, 2011
*4+ Médéric Blestel y Mickaël Raulet, “Open SVC Decoder: a flexible SVC
library”, 2010
[5] Universidad Politécnica de Catalunya. Departamento de telemática.
Jorge Mata *et al.+, “Multimedia communications. TCP Flows Practice”,
2014
Descargar