Sie sind auf Seite 1von 82

PROYECTO FINAL DE CARRERA

COMPRESIÓN DE IMÁGENES Y VIDEO


(formato MPEG2)

Fernando Martín Pap


Director: Mg. Silvia Mabel Castro

UNIVERSIDAD NACIONAL DEL SUR – BAHIA BLANCA –


ARGENTINA

Departamento de Ciencias e Ingeniería de la Computación


Ingeniería en Sistemas de Computación
x de abril de 2005
Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

AGRADECIMIENTOS

A mis padres y hermanos, que siempre confiaron en mi, me han apoyado en


todo momento y me dieron fuerzas para poder cumplir mi meta.
A mi directora, por todo el tiempo que me dedicó, por sus recomendaciones y
por haber confiado en mi.
A todos aquellos que hicieron que mis años de estudio hayan sido realmente
maravillosos.

2 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

ÍNDICE

Introducción 6
Percepción 6
El sistema visual 7
El ojo 7
La retina 7
Los conos 8
Los bastones 9
Psicofísica visual 9
El sistema auditivo 11
El oído 12
La membrana basilar 12
Psicofísica auditiva 13
Bandas críticas 13
Enmascaramiento frecuencial 14
Enmascaramiento temporal 15
Compresión 16
Codificación de Huffman 16
Codificación aritmética 19
Compresión de imágenes 20
Compresión de imágenes con pérdida 21
Submuestreo (subsampling) 21
Formatos de muestreo de YCbCr 23
Transformada discreta del coseno (DCT) 24
Wavelet 28
Formato de imagen JPEG 30
Esquema secuencial (baseline) 32
Cuantificación 33
Recorrido en zigzag 35
Codificación RLC 35

3 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

Codificación DPCM 36
Codificación entrópica 37
Codificación de los coeficientes DC Diferenciales 37
Codificación de los coeficientes AC 38
Caso de estudio: COMPRESSLIB 40
Librería de compresión de imágenes 41
Muestreo 43
Discretización en bloques 45
Transformación DCT 45
Cuantificación 48
Codificación DPCM 49
Recorrido en zigzag y codificación RLC 50
Codificación de Huffman 54
Compress demo 56
Image viewer 57
Compresión de video 59
Codificación temporal 60
Compensación de movimiento 60
Compresión de audio 61
Replicación de banda espectral (SBR) 61
Formato de video MPEG2 62
Perfiles y niveles 63
Capas 63
Codificación de video 64
Cuadros I, P, B, D 64
Compensación de movimiento 65
Codificación de audio 66
Modelo psicoacústico 67
Multiplexado y sincronización de audio y video 69

4 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

Trenes de programa y de transporte 69


Tren de programa 69
Tren de transporte 70
Unidades de presentación y de acceso 70
Trenes elementales empaquetados (PES) 71
Multiplexado del tren de programa 72
Multiplexado del tren de transporte 72
Encabezado del paquete de transporte 73
Información específica de programa (PSI) 73
Buffers del codificador y del decodificador 74
Estampillas de tiempo y referencias de reloj 75
Estampilla de tiempo de presentación (PTS) 77
Estampilla de tiempo de decodificación (DTS) 77
Asignación de estampillas de tiempo 78
Librerías de reproducción de video MPEG 78
Librería SMPEG 79
Bibliografía 82

5 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

INTRODUCCIÓN
Históricamente la representación de la información ha sido una de las áreas
que ha generado mucho interés. En los comienzos de la computación, las
limitaciones en los medios de almacenamiento convirtieron en una tarea crucial la
representación óptima de la información. Técnicas de compresión como la
codificación de Lempel-Ziv, de Huffman, o la aritmética, permitieron representar la
información con mucho menor cantidad de datos.
En las tres técnicas anteriormente mencionadas se procesan los datos de
modo tal de evitar almacenar información redundante. Si la información
recuperada luego del proceso de descompresión es exactamente igual a la
original, decimos que es un proceso de compresión sin pérdida, en caso contrario
se dice que es un proceso de compresión con pérdida.
La primera de las alternativas se basa en la redundancia estadística (entropía)
de los datos y es de un uso muy general, ya que no pierde información. La
segunda puede lograr relaciones de compresión mucho mejores, pero lo hace
mediante la eliminación de información. Cuanto más información se elimine, mayor
será la relación de compresión, pero la calidad de la información recuperada será
menor. Debido a esto entra en juego la noción de calidad —que es inversamente
proporcional a la relación de compresión.
La compresión con pérdida sin embargo, sólo puede utilizarse para datos con
forma específica, pues en algunos casos los datos son intolerantes a la pérdida de
información. La compresión de imágenes, sonido y video son áreas de gran interés
que, basándose en la percepción humana, descartan información irrelevante para
poder lograr su cometido.
Afortunadamente la tecnología de almacenamiento ha evolucionado de un
modo considerable, no obstante el problema persiste. Áreas como la televisión
satelital, teleconferencias, telefonía visual, la industria cinematográfica, grandes
bases de datos multimedia, etc., no podrían existir —incluso aprovechando la
actual tecnología de almacenamiento disponible— si no fuera por la posibilidad de
compresión de datos.

PERCEPCIÓN
El ser humano posee muy buenos sensores que le permiten obtener una
representación del mundo exterior. Esto lo logra a través del sentido de la vista, del
oído, del tacto, del olfato y del gusto. Al tratarse de una investigación sobre
compresión de imágenes y de video, nosotros sólo nos concentraremos en el
sentido de la vista y del oído. Tanto el ojo como el oído tienen sus características
especiales y sus limitaciones. El estudio detallado de éstas ha hecho posible el
desarrollo de técnicas de compresión —tanto de sonido como de imágenes y
video— que permiten ponderar la información, de manera tal de priorizar los datos
de mayor relevancia para nuestros órganos. Primero analizaremos brevemente la
visión humana, luego la audición.

6 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

El sistema visual
La vista es uno de los cinco sentidos corporales, por el que se percibe la luz y
que da a conocer el color, la forma, la distancia, el tamaño y el movimiento de los
cuerpos.
La visión contribuye a informarnos de nuestra posición y mantiene conexiones
con los centros que rigen el equilibrio postural. Es el resultado de una serie de
fenómenos sucesivos que se producen de modo coordinado: 1) formación de la
imagen en la retina; 2) estimulación de las células receptoras de la retina; 3)
conducción al cerebro del impulso elaborado por dichas células; 4) formación de la
imagen en el cerebro.

El ojo
El ojo le transmite la información al cerebro a través del nervio óptico. Esta
información se propaga por impulsos de naturaleza electroquímica, cuya velocidad
está comprendida entre diez y cien metros por segundo.
Cuando los ojos están abiertos, la luz entra por la pupila, que es una abertura
del iris. El diámetro de la pupila puede modificarse: se agranda cuando desciende
la luminosidad y se contrae a plena luz, y ello de modo automático, obedeciendo a
un reflejo nervioso.
Detrás de la pupila se encuentra el cristalino, que concentra la luz sobre el
fondo del ojo. El cristalino es regulable, permitiendo así ver con claridad tanto los
objetos próximos como los lejanos.
En el fondo del ojo se halla situada la retina. La retina esta formada por capas
de células nerviosas sensibles a la luz.
La córnea esta situada en la parte anterior del ojo y es, al igual que el cristalino,
una superficie que contribuye a concentrar los rayos luminosos sobre la retina. El
cristalino —y, en cierta medida, también la córnea— desvía los rayos de tal forma
que la imagen se proyecta invertida sobre la retina.

La retina
La retina está compuesta por fotorreceptores que convierten la intensidad y el
color de la luz en señales nerviosas que son procesadas por el cerebro. La retina
contiene dos clases de fotorreceptores, bastones y conos. Los bastones son más
numerosos —alrededor de 120 millones— y son más sensitivos a la luz que los
conos. Sin embargo, los bastones no son sensibles al color. Los conos —entre 6 y
7 millones— son quienes proveen al ojo de sensitividad al color, y están
mayormente concentrados en la mácula. En el centro de esta región se encuentra
la fóvea —un área de 0.3 mm de diámetro—, donde no existen bastones y la
concentración de conos es muy grande.

7 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

Los conos
Las experiencias empíricas sugieren que dentro del conjunto de los conos
existen tres clases distintas de receptores de color, y se han establecido las curvas
de respuesta para cada tipo de cono (figura 1) [CRRE]. Basándose en estas
curvas de respuesta se pudieron clasificar los conos en "rojos" (64%), "verdes"
(32%) y "azules" (2%) [NAVE2005]. Los conos verdes y rojos están concentrados
en la fóvea, mientras que la sensitividad de los conos azules se encuentra
mayormente fuera de esta zona.
Los conos azules merecen un estudio particular debido a que constituyen tan
sólo un 2% del total y se encuentran fuera de la fóvea. Se los identifica en la curva
de respuesta a la luz en un pico aproximadamente a los 445 nm. Si bien son
mucho más sensitivos a la luz que los conos verdes y rojos, no es suficiente para
contrarrestar su poco porcentaje en cantidad. Sin embargo, la sensitividad al color
azul en nuestra percepción visual final es comparable a la de los colores verde y
rojo. Esto sugiere que nuestro cerebro posee un "amplificador azul".
La percepción visual de los objetos intensamente azules es menos precisa que
la percepción de objetos rojos o verdes. Esta reducción de agudeza visual se
atribuye a dos efectos. Primero, los conos azules se encuentran fuera de la fóvea,
donde los conos dispuestos muy cerca unos de otros pueden brindar la mayor
resolución. Segundo, el índice de refracción para la luz azul es lo suficientemente
diferente del índice de refracción de la luz roja y verde como para que cuando el
rojo y el verde estén en foco, el azul se vaya ligeramente de foco.
Los conos son los responsables de la visión de alta definición. El ojo se mueve
continuamente para que la luz reflejada por el objeto en interés se concentre en la
fóvea, donde reside la mayor cantidad de conos.

Figura 1: Curvas de respuesta de los conos.

8 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

Los bastones
Si bien anteriormente mencionamos que la presencia de bastones es nula
dentro de la fóvea, éstos se encuentran concentrados en todo el resto de la
superficie de la retina. Son los encargados de la visión nocturna, de la detección
de los movimientos y de la visión periférica.
Los bastones son fotorreceptores increíblemente eficientes —mas de mil veces
más sensitivos que los conos. Tal es así que, bajo condiciones óptimas, pueden
activarse tan sólo por fotones individuales. La visión adaptada a la oscuridad se
alcanza en su totalidad luego de un período de oscuridad considerable (alrededor
de 30 minutos). Esto se debe a que el proceso de adaptación de los bastones es
mucho más lento que el de los conos.
Mientras que la agudeza o resolución visual es mucho mejor con los conos, los
bastones son mejores sensores de movimiento. Debido a que los bastones
predominan en la visión periférica, esta visión es más sensitiva a la luz, y por lo
tanto podemos ver objetos menos brillantes con nuestra visión periférica. Por
ejemplo, si vemos una estrella no muy brillante con nuestra visión periférica, al
intentar mirarla directamente desaparecerá. Esto es debido a que estamos
moviendo la imagen dentro de la región de la fóvea, la cual es rica en conos y
pobre en bastones, y por lo tanto menos sensitiva a la luz. Por la misma razón es
que se pueden detectar mejor los movimientos con la visión periférica.

Psicofísica visual
Una de las áreas en donde comenzó la psicología es en el campo de la
psicofísica. La psicofísica intenta encontrar la "física del cuerpo humano". Consiste
en aplicarle un estímulo a una persona, y luego obtener de esta persona la
respuesta de la experiencia psicológica asociada al estímulo físico.
Uno de los descubrimientos es la noción de threshold o umbral. Un umbral es
un límite psicológico de la percepción. El umbral absoluto es la mínima cantidad de
estimulación sensorial que se puede detectar el 50 % de las veces (el motivo por el
cual el límite se fijó en el 50 % es la variabilidad de la capacidad humana). El
umbral relativo es el menor incremento o decremento de un estímulo físico que
puede detectarse el 50 % de las veces. La noción de umbral no es exclusiva del
sentido de la vista, sino que se puede aplicar a cualquiera de los órganos
sensoriales. Un ejemplo de umbral relativo aplicado al sentido de la vista podría
ser decidir cuál de dos luces es más brillante.
La relación entre la intensidad de la luz que entra al ojo y el brillo percibido no
es una función lineal. Esto significa que a medida que la intensidad de una fuente
luminosa cambia, el observador no percibirá un cambio igual en el brillo. La
respuesta de la intensidad real del ojo es muy parecida a una respuesta
logarítmica. De hecho, se ha mostrado experimentalmente que la intensidad de
una fuente luminosa debe ser cercana al doble antes de que el ojo pueda detectar

9 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

que ésta ha cambiado. Por lo tanto, los cambios ligeros en la intensidad en


regiones oscuras de una imagen tienden a ser más perceptibles que los cambios
iguales en regiones brillantes. Esta relación que hay entre la intensidad de la
iluminación y el brillo percibido se conoce como Ley de Weber.
Existen varios fenómenos que muestran que la iluminación percibida no es una
función simple de la intensidad. Entre ellos se encuentra el contraste simultáneo,
que es una ilusión por la cual el brillo percibido de una región depende de la
intensidad del área circundante. En la figura 2 se observan cinco cuadrados
dispuestos horizontalmente, cada uno de ellos sucesivamente más claro. Dentro
de cada cuadrado se encuentra un círculo exactamente igual, sin embargo cuanto
más claro es el cuadrado que lo contiene, más oscuro parece verse.

Figura 2: Contraste simultáneo.

Otro fenómeno a tener en cuenta es el de las bandas de Mach, que es una


ilusión por la cual el sistema visual acentúa los cambios importantes de intensidad.
El sistema visual tiende a sobrevalorar o infravalorar la intensidad en las
proximidades de los límites de dos regiones con intensidades diferentes. De este
modo, el ojo incrementa el realce en los contornos de las transiciones de
intensidad, y gracias a esto se puede obtener una agudeza visual muy buena. Si
se observa la figura 3 de izquierda a derecha, cada banda pareciera hacerse más
oscura justo antes de la transición. Si la figura 3 se observa de derecha a
izquierda, cada banda pareciera hacerse más clara justo antes de la transición.
Esto provoca la ilusión de que la transición sea de mayor amplitud de lo que es en
realidad.

Figura 3: Bandas de Mach.

El sistema visual también tiene problemas en cuanto a la respuesta en

10 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

frecuencia. El ojo tiene problemas para resolver detalles finos, o transiciones de


intensidad. Generalmente, la respuesta en frecuencia del ojo disminuye a medida
que las transiciones de intensidad se vuelven cada vez más finas. El contraste es
otro factor a tener en cuenta. Cuanto más alto es el contraste, más fino es el
detalle que el ojo puede resolver. Por lo tanto, cuando las transiciones son
demasiado finas o el contraste es demasiado bajo, el ojo ya no puede resolverlos
satisfactoriamente. En estos casos el ojo sólo puede percibir un promedio del nivel
de gris del área en cuestión. En la figura 4 se puede apreciar un patrón que
incrementa la frecuencia de izquierda a derecha y disminuye el contraste de abajo
hacia arriba [MS].

Figura 4: Patrón de frecuencia y contraste.

El sistema auditivo
Este es el sistema mediante el cual podemos percibir los sonidos. Las
cualidades del sonido percibidas por el oído son el tono, la intensidad y el timbre.
El tono depende de la frecuencia de las vibraciones: una frecuencia elevada
provoca tonos agudos y una frecuencia baja tonos graves. La frecuencia se mide
en Hertz —Hz.— y se refiere a la cantidad de ciclos por segundo de una onda
periódica. La intensidad con que se percibe un sonido depende de la amplitud de
la vibración y del tono. Psicológicamente se lo percibe como volumen y se mide en
decibeles —dB. El timbre permite distinguir sonidos de la misma intensidad y
frecuencia, pero con distintas armónicas de la frecuencia del tono fundamental; es
decir, con distinta forma de onda —por este motivo es que podemos diferenciar
una misma nota en distintos instrumentos musicales.
El sonido puede ser medido con gran exactitud, sin embargo entender cómo se
recibe y se transforma en pensamientos dentro del cerebro no es nada trivial. La
audición es el resultado de una serie de procesos acústicos, mecánicos, nerviosos

11 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

y mentales que nos da la impresión de sonido.

El oído
En la estructura física del oído se pueden distinguir tres zonas: el oído externo,
el oído medio y el oído interno.
El oído externo comprende el pabellón de la oreja, en forma de embudo, y el
conducto auditivo externo, obturado en su extremo por el tímpano.
El oído medio se halla constituido por la caja del tímpano, cavidad que contiene
la cadena de huesecillos: martillo, yunque y estribo. Estos huesecillos transmiten
las vibraciones desde el tímpano hasta la ventana oval.
El oído interno está constituido por una serie de cavidades alojadas en el hueso
temporal, y consta de tres partes: el vestíbulo, la cóclea y los conductos
semicirculares. En el vestíbulo se encuentra la ventana oval, por la que el oído
interno comunica con el medio. Al vestíbulo le sigue la cóclea, un tubo diminuto
que se enrolla dos veces y media sobre sí mismo. El interior de la cóclea está
dividido en tres conductos mediante dos membranas que lo recorren
longitudinalmente. Sobre una de ellas se encuentra el órgano de Corti, que es el
órgano de la audición propiamente dicho y que está formado por unas 25.000
células sensitivas.
Las vibraciones sonoras transmitidas por las partículas del aire son canalizadas
por el pabellón de la oreja hacia el conducto auditivo externo, hasta llegar al
tímpano. Por medio de la cadena de huesecillos el tímpano comunica las
vibraciones a la ventana oval y a la cóclea. La presión originada en la cóclea por
las vibraciones sonoras hace vibrar a la membrana basilar. Durante el paso de la
onda, el órgano de Corti también oscila, friccionando la membrana tectorial y
excitando las células sensoriales, que estimulan el cerebro.

La membrana basilar
La membrana basilar se encuentra dentro de la cóclea y la recorre en toda su
extensión. Esta membrana varía en masa y rigidez a lo largo de su longitud. Sobre
el extremo más próximo a la ventana oval la membrana es rígida y liviana, y
debido a esto su frecuencia de resonancia es alta. Sobre el extremo más lejano la
membrana es blanda y pesada, y es por esto que su frecuencia de resonancia es
baja. El rango de las frecuencias de resonancia disponibles en la membrana
determina el rango de frecuencias de la audición humana. El oído humano puede
distinguir entre 16 y 20.000 vibraciones por segundo (entre 16 Hz. y 20 kHz.), pero
la mayoría de las personas sólo puede distinguir sonidos que se encuentran dentro
del rango de los 20 Hz. hasta los 15 kHz. La membrana basilar transforma cada
frecuencia en impulsos nerviosos en una región distinta, de manera que la
percepción del tono depende del oído y no del sistema nervioso central. Además,
esta membrana posee pequeños músculos que actúan como si fuera un sistema
de realimentación positiva que mejora el factor Q de resonancia [TEKTRONIX97].

12 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

Psicofísica auditiva
La psicofísica auditiva o psicoacústica es el estudio de la percepción subjetiva
de los sonidos en los seres humanos. En otras palabras, es el estudio de la
psicología de la percepción acústica.
Ya mencionamos en la sección de psicofísica visual que la noción de umbral no
es exclusiva de ningún sentido. Para el oído, el umbral relativo del tono sobre el
rango medio de audición es aproximadamente de 2 Hz. Es decir que se pueden
percibir cambios de tono no menores a 2 Hz. No obstante, bajo ciertas
condiciones, se puede llegar a percibir variaciones menores [WIKIPEDIA2005].
El límite inferior para el umbral absoluto de la intensidad de cualquier sonido
audible está a 0 dB. El límite superior no está tan claramente definido. Se podría
definir como la intensidad máxima sin que dañe físicamente al oído. Pero este no
es un límite fijo, pues depende del tiempo de exposición. Por ejemplo,
exposiciones de cortos períodos de sonidos de 120 dB. podrían ser inofensivas
para el oído, sin embargo largas exposiciones de sonidos de 80 dB. podrían
dañarlo.
Un estudio más riguroso de los límites inferiores de audibilidad determina que
el umbral mínimo para el cual se puede oír un sonido es dependiente de la
frecuencia del mismo. Por medio de mediciones de tonos de la menor intensidad
audible y a distintas frecuencias, se puede establecer una curva de respuesta de
umbral absoluto de audición (figura 5) [TEKTRONIX97]. El oído posee un pico de
sensitividad (un mínimo en la curva) dentro del rango de 1 kHz. hasta 5 kHz., y
cabe destacar que la voz humana cae dentro de este mismo rango.

Figura 5: Curva del umbral en silencio.

Bandas críticas
Los sonidos con distintas frecuencias causan que vibren áreas diferentes de la
membrana basilar, excitando a unas u otras células sensitivas. Las señales de los

13 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

sonidos son contínuas, y por lo tanto existen sonidos de infinitas frecuencias


diferentes. Por supuesto que no puede existir una relación biunívoca entre cada
frecuencia posible con un área distinta de la membrana basilar, por lo tanto habrán
sonidos de frecuencias similares que excitarán a las mismas células nerviosas.
Debido a esto, si dos sonidos con el mismo volumen que se encuentran dentro de
la misma banda crítica suenan simultáneamente, el sonido no será percibido el
doble de fuerte, sino que levemente más fuerte que cualquiera de ellos por
separado. Para que dos sonidos se encuentren dentro de la misma banda crítica,
es necesario que sus frecuencias sean similares. Si los sonidos hubieran sido de
frecuencias lo suficientemente distintas como para estar dentro de distintas
bandas críticas, el sonido percibido hubiera sido considerablemente mas fuerte.
Esto se debe a que no se solapan las células sensitivas excitadas en la membrana
basilar. En las frecuencias audibles más bajas, el ancho de las bandas críticas es
de aproximadamente 100 Hz. A medida que se incrementa la frecuencia, el ancho
de las bandas críticas se hace más grande, superando los 3 kHz. en las
frecuencias más altas.

Enmascaramiento frecuencial
Bajo determinadas condiciones, un sonido que es claramente audible puede
ser enmascarado por otro sonido. Por ejemplo, se complicaría mucho mantener
una conversación si hay mucho ruido en el ambiente. A este fenómeno se lo llama
enmascaramiento frecuencial. Un sonido débil es enmascarado si se hace
inaudible con la presencia de otro más fuerte. Si un sonido se encuentra cercano
en frecuencia al sonido fuerte será más fácilmente enmascarado que si se
encuentra apartado de su frecuencia. En la figura 6 se puede apreciar cómo un
único tono afecta al umbral [TEKTRONIX97]. El umbral se incrementa tanto hacia
las frecuencias bajas como hacia las altas, pero el incremento hacia las
frecuencias altas es un poco más acentuado. En presencia de un espectro
complejo, como el de la música, el umbral se incrementaría en la mayoría del
rango. Es por esto que el zumbido de un cassette analógico sólo se puede oír
durante los espacios en blanco.

14 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

Figura 6: Enmascaramiento frecuencial.

Enmascaramiento temporal
El comportamiento resonante de la membrana basilar es análogo al
comportamiento de un analizador de transformadas. De acuerdo a la teoría de las
transformadas, cuanto más exacto se conoce el dominio de la frecuencia de una
señal, menos exactitud se dispondrá en el dominio del tiempo —y viceversa. Es
decir que cuanto más pueda distinguir una transformada entre dos frecuencias,
menor será su capacidad para discriminar entre dos eventos. En el oído humano
se observa un compromiso de modo de equilibrar la incerteza en ambos dominios,
y por lo tanto no es perfecto en ninguno de ellos. La imperfección al discriminar
entre frecuencias es lo que produce el mencionado enmascaramiento frecuencial.
La imperfección en la discriminación del tiempo se debe a la respuesta
resonante del oído. El factor Q es tal que un determinado sonido debe estar
presente por al menos un milisegundo para que pueda ser audible. Debido a esta
lenta respuesta, el enmascaramiento puede producirse aún cuando las señales
involucradas no son simultáneas. El preenmascaramiento y postenmascaramiento
se producen cuando el sonido enmascarante continúa enmascarando sonidos más
débiles antes y después de la duración real del sonido enmascarante (figura 7)
[TEKTRONIX97].

15 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

Figura 7: Enmascaramiento temporal.

COMPRESIÓN
La compresión de datos reduce la cantidad de bytes necesarios para
representar la información. Es decir, reduce la cantidad de memoria necesaria
para almacenar la información. Del mismo modo, también reduce la cantidad de
tiempo requerido para transmitir información a una tasa de transmisión dada.
Como ya mencionamos, podemos clasificar los métodos de compresión en:
 Compresión sin pérdida.

 Compresión con pérdida.

Como los métodos de compresión con pérdida son muy dependientes del área
en cuestión —audio, imágenes, video, etc.—, en esta sección solamente nos
ocuparemos de la compresión sin pérdida.
Hay una gran cantidad de aplicaciones en las que no es posible realizar una
compresión con pérdida debido a que la mínima pérdida de la información original
sería intolerable —archivos de texto, ejecutables, etc. En estos casos la única
alternativa es la compresión sin pérdida. Pero de todos modos, en los casos en
que sí se puede aplicar compresión con pérdida, la mayoría de las veces también
se realiza (como último paso) una compresión sin pérdida. El hecho de aplicar una
compresión sin pérdida luego de haber realizado toda la compresión con pérdida
comprime aún mas los datos, sin mas efectos adversos que un incremento en el
tiempo de los procesos de compresión-descompresión.
Existen muchas técnicas de compresión sin pérdida, entre las más importantes
se encuentran la codificación de Huffman y la codificación aritmética. Estas
técnicas se basan en la codificación entrópica. La entropía es la cantidad de
información presente en los datos, y un codificador de entropía codifica un
conjunto de símbolos con la menor cantidad de bits necesarios para
representarlos.

Codificación de Huffman
La codificación de Huffman es un método de codificación entrópica de longitud
variable que asocia un valor específico con un único código. La codificación de

16 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

Huffman se conoce como una codificación de prefijo debido a que ningún código
es prefijo de otro más largo. Esta propiedad hace que un código Huffman sea
decodificable unívocamente.
La codificación de Huffman es general, es por esto que la compresión debe
pensarse sobre símbolos abstractos, siendo por ejemplo las letras del alfabeto un
caso particular. En un archivo de texto simple, cada caracter está representado por
ocho bits. Esta representación no es óptima si tenemos en cuenta que
estadísticamente algunos caracteres están presentes mucho más frecuentemente
que otros. La codificación de Huffman ordena los símbolos más frecuentes en
secuencias cortas de bits, y por lo tanto los símbolos menos frecuentes estarán
representados por secuencias más largas.
Las frecuencias relativas de todos los símbolos pueden ser conocidas —por
medio de estudios estadísticos— o pueden calcularse en cada caso en particular.
Por ejemplo, existen tablas que indican los valores probabilísticos de ocurrencia de
cada letra en un texto —cada idioma posee su propia tabla. Entonces, para
comprimir un texto se puede utilizar una codificación de Huffman siguiendo la tabla
correspondiente —que no necesariamente será cien por cien exacta— o calcular la
probabilidad real de cada símbolo que se encuentra en ese texto en particular.
Cada alternativa tiene sus ventajas y sus desventajas. El hecho de utilizar una
tabla facilita mucho la implementación del compresor —el descompresor utiliza la
misma tabla para llevar a cabo la tarea de descompresión—, pues de lo contrario
habría que contar las apariciones de cada caracter dentro del texto. Por esta
misma razón también puede ser —si el texto es extenso— que el compresor
resulte más eficiente. Por otro lado, si se calcula la probabilidad exacta de
aparición de cada símbolo, intuitivamente podríamos pensar que el texto acabaría
ocupando menos datos debido a que la representación de la información
terminaría siendo la óptima. Si bien esto es cierto, no debemos olvidarnos que
junto al texto comprimido debe estar también la tabla con la cual se llevó a cabo la
compresión, de lo contrario el proceso no sería reversible. Por lo tanto veremos
una ganancia al calcular las probabilidades reales sólo en aquellos textos tal que
su tamaño sea considerable respecto de lo que ocupa su tabla correspondiente
—a menos que la tabla estándar se ajuste muy bien al texto.
Generalmente las tablas no indican los valores probabilísticos, sino que
directamente muestran el código correspondiente. En el caso en que sólo se
disponga de las probabilidades —ya sea porque es la única información que brinda
la tabla o porque se desea utilizar una tabla ad hoc— habrá que construir una tabla
que indique el código que representa a cada símbolo. A continuación veremos un
ejemplo de cómo calcular las probabilidades reales de un texto y otro de cómo
construir una tabla de símbolos con sus respectivos códigos.
Supongamos el siguiente texto: "este es un texto de ejemplo". Primero
determinaremos el alfabeto, luego contaremos la cantidad de apariciones dentro
del texto. La longitud de nuestro texto es de 27 caracteres, por lo tanto la
probabilidad de cada símbolo será la cantidad de apariciones dividido 27.

17 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

Símbolo Apariciones Probabilidad


1
’d’ 1 27
7
’e’ 7 27
1
’j’ 1 27
1
’l’ 1 27
1
’m’ 1 27
1
’n’ 1 27
2
’o’ 2 27
1
’p’ 1 27
2
’s’ 2 27
3
’t’ 3 27
1
’u’ 1 27
1
’x’ 1 27
5
’ ’ (espacio) 5 27

Tabla 1: Cálculo de probabilidades.

Ahora veremos cómo construir una tabla de símbolos con sus respectivos
códigos, teniendo como dato sus probabilidades. Supongamos la siguiente tabla
[LIOU2001]:
Símbolo Probabilidad
a0 0.4
a1 0.3
a2 0.2
a3 0.04
a4 0.04
a5 0.02
Tabla 2: Probabilidades para construir una tabla de códigos Huffman.

El procedimiento es el siguiente:

Repetir mientras haya mas de una probabilidad


Ordenar las probabilidades en orden descendiente.
Combinar las dos probabilidades más pequeñas.
Asignarle "0" al miembro superior y "1" al miembro inferior de cada par (o viceversa).

18 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

Seguir el camino de cada símbolo hasta llegar al final (probabilidad 1) registrando los unos y
ceros.
Asignarle a cada símbolo la secuencia registrada, de derecha a izquierda.

Gráficamente (figura 8):

Figura 8: Codificación de Huffman.

Finalmente la tabla es la siguiente:


Símbolo Código (Codeword) Longitud
a0 1 1
a1 00 2
a2 010 3
a3 0111 4
a4 01100 5
a5 01101 5
Tabla 3: Tabla de símbolos con sus respectivos códigos Huffman.

Codificación aritmética
La codificación aritmética se basa en secuencias de símbolos. En vez de
asignarle un código único a cada símbolo, esta técnica genera una serie de
valores que corresponden con una única secuencia de datos. Para producir la
codificación se utiliza la probabilidad de ocurrencia de los símbolos individuales.
Esta técnica representa cada símbolo como un segmento de la recta real entre
0 y 1. La codificación de una secuencia de símbolos se logra seleccionando un
segmento de reales y transmitiendo un número específico dentro de ese
segmento.
Veamos un ejemplo para poder comprender mejor el método [LIOU2001].
Consideremos los siguientes símbolos con sus respectivas probabilidades de
ocurrencia:

19 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

Símbolo Probabilidad
A 0.50
C 0.30
G 0.15
T 0.5
Tabla 4: Probabilidades de codificación aritmética.

Gráficamente (figura 9) se explica cómo codificar la secuencia de símbolos


"CAT".

Figura 9: Codificación aritmética.

Cualquier número en el rango de 0.6425 a 0.65 representa la cadena "CAT".


La codificación aritmética puede comprimir desde un 5% hasta un 10% mas
que la codificación de Huffman. Lamentablemente no sólo es más compleja de
comprender y de implementar, sino que además está sujeta a patentes
pertenecientes a IBM, AT&T y Mitsubishi.

COMPRESIÓN DE IMÁGENES
La mayoría de las imágenes poseen una característica en común: los pixeles
cercanos están correlacionados, y por lo tanto contienen información redundante.
Entonces es primordial encontrar la representación menos correlacionada de la
imagen. En las imágenes tenemos dos tipos de redundancia:
 Redundancia espacial (o correlación entre pixeles cercanos).

 Redundancia espectral (o correlación entre los distintos planos de

color o bandas espectrales).


Las investigaciones en compresión de imágenes buscan reducir el número de
bits necesarios para representar una imagen por medio de la reducción de la
redundancia espacial y espectral tanto como sea posible. Además de reducir la

20 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

redundancia, en una imagen también es muy útil reducir la irrelevancia. Con esto
último nos referimos a omitir información que de todos modos ninguna persona
podrá distinguir (percepción).

Compresión de imágenes con pérdida


Todos los métodos de compresión de imágenes con pérdidas involucran la
eliminación de información de la imagen original. La gran ventaja de estos
esquemas es que pueden comprimir una imagen con un factor de compresión
mucho más alto que los esquemas de compresión sin pérdidas. Este factor de
compresión puede ser de 10:1 sin degradaciones visuales notables, pero si se
toleran algunas degradaciones visuales se pueden lograr factores de compresión
de hasta 100:1.
Existen en la actualidad muchos métodos de compresión de imágenes con
pérdidas. A continuación analizaremos los más utilizados.

Submuestreo (subsampling)
La forma más sencilla de reducir la cantidad de datos que ocupa una imagen
es directamente descartando pixeles. Si por ejemplo, eliminamos con regularidad
un pixel y el siguiente no, estaríamos comprimiendo la imagen a la mitad. Un
posible proceso de descompresión podría ser simplemente mediante replicación
de pixeles. Otra técnica más refinada podría ser realizar una interpolación de los
pixeles disponibles para obtener aquellos que habían sido descartados. Es muy
común encontrar en las imágenes que los pixeles adyacentes estén
correlacionados. Si este fuera el caso, la imagen reconstruida no será muy
diferente a la original.
Si bien la técnica anteriormente mencionada es válida, es un tanto agresiva y
puede producir degradaciones visuales intolerables para determinadas
aplicaciones. Es sabido que el ojo humano es más sensible a la luminancia (brillo)
que a la crominancia (color) —debido a que el ojo humano posee muchos mas
bastones que conos. Es por esto que los cambios graduales de color se ven como
un único color, y esto se puede utilizar para nuestro propósito.
Generalmente a las imágenes se las representa con el espacio de color RGB,
que es una tripla que define el color de cada pixel por medio de la combinación de
los tres colores primarios —rojo, verde y azul. En lugar de representar a una
imagen por medio de la adición de los colores primarios, podemos realizar una
conversión de espacios de color para poder representarla por medio de los
siguientes tres canales:
 Y: Luminancia (brillo).

 Cb: Crominancia (azul).

 Cr: Crominancia (roja).

En las figuras 10, 11 y 12 se puede ver una imagen en color junto con sus
respectivos canales RGB y YCbCr.

21 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

Figura 10: Imagen en color.

Figura 11: Canales RGB.

Figura 12: Canales YCbCr.

Dada una imagen representada con el espacio de color RGB, podemos


convertirlo al espacio de color YCbCr mediante las siguientes expresiones:
Y  0. 299R  0. 587G  0. 114B [1.1]
Cb  −0. 1687R − 0. 3313G  0. 5B [1.2]
Cr  0. 5R − 0. 4187G − 0. 0813B [1.3]
Cabe destacar que esta conversión es levemente diferente a la utilizada para la
codificación de video [JACK2001]. Además hay que tener en cuenta que los
cálculos se realizarán utilizando una precisión determinada. Debido a esto se
incurrirá en pequeños errores de redondeo que llevarán a una transformación con
pérdida, independientemente del método de muestreo que se utilice.
Una vez que hemos realizado la conversión al espacio de color YCbCr

22 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

podemos comprimir la imagen llevando a cabo un submuestreo de los canales Cb


y Cr, dejando intacto el canal Y —debido a que el ojo humano es menos sensible a
los canales cromáticos que al del brillo. Casi ningún ojo humano es capaz de
detectar esto, y el tamaño del archivo se verá reducido en un porcentaje muy alto
—dependiendo del modo en que se realice el muestreo. Existen estándares que
aconsejan sobre el modo de realizar el muestreo [JACK2001].
Este paso produce que sucesivas compresiones se vean cada vez un poco
peor, pues este paso no es reversible. Además, las fotos naturales son más
propensas a contener cambios graduales de color que las imágenes producidas
por los humanos. Es por esto que no se recomienda utilizar esta técnica sobre
imágenes que puedan incluir textos o bloques grandes de un único color.

Formatos de muestreo de YCbCr


La figura 13 ilustra la posición de las muestras de YCbCr para el formato 4:4:4.
Cada muestra posee un valor de Y, de Cb y de Cr. Cada componente de la
muestra es generalmente de 8 bits, por lo tanto cada muestra será de 24 bits.
La figura 14 ilustra la posición de las muestras de YCbCr para el formato 4:2:2.
Por cada dos muestras horizontales de la componente Y se toma una de Cb y de
Cr. Cada componente de la muestra es generalmente de 8 bits, por lo tanto cada
muestra será de 16 bits.
La figura 15 ilustra la posición de las muestras de YCbCr para el formato 4:1:1
(también conocido como YUV12). Por cada cuatro muestras horizontales de la
componente Y se toma una de Cb y de Cr. Cada componente de la muestra es
generalmente de 8 bits, por lo tanto cada muestra será de 12 bits.
En lugar de la única reducción horizontal de 2:1 de las componentes Cb y Cr
utilizada en el formato 4:2:2, el formato 4:2:0 implementa una reducción de 2:1 en
las componentes Cb y Cr tanto horizontalmente como verticalmente. Existen cinco
formatos de muestreo 4:2:0 distintos; en la figura 16 se ilustran dos de ellos.
Para mostrar datos que se encuentren en el formato 4:2:2 o 4:1:1 o 4:2:0,
primero es necesario realizar una conversión al formato 4:4:4, utilizando
interpolación para generar las muestras faltantes de Cb y Cr.

Figura 13: Formato 4:4:4. Figura 14: Formato 4:2:2. Figura 15: Formato 4:1:1.

23 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

Figura 16: Formatos 4:2:0.

Transformada discreta del coseno (DCT)


Existen muchas transformaciones matemáticas que transforman un conjunto de
datos de un sistema de medición a otro. En algunos casos la representación de los
datos en el nuevo sistema posee propiedades que facilitan la compresión de los
mismos. La transformada discreta del coseno (Discrete Cosine Transform - DCT
de aquí en mas) es una de las transformaciones más importantes en el área de la
compresión de imágenes digitales.
La DCT transforma un bloque de datos en un nuevo conjunto de valores. La
DCT inversa invierte este proceso, recuperando los valores originales de los datos.
En la teoría, en el proceso de transformación y antitransformación no se pierde
nada de información. Sin embargo, en la práctica, existe una pequeña pérdida de
información debido a los dos siguientes factores:
 Los valores del coseno no se pueden calcular exactos.

 Los resultados finales de los cálculos se ven afectados por los errores

de redondeo debido a la limitada precisión en la representación de los


datos.
Las diferencias entre los datos recuperados y los originales son generalmente
pequeñas, pero depende del método utilizado para calcular la DCT.
La DCT se puede aplicar a bloques de datos de cualquier tamaño, pero lo más
usual es utilizar bloques de 8  8. Esto se debe a que, desde el punto de vista de la
implementación, un bloque de 8  8 no demanda grandes requisitos de memoria.
Además, la complejidad algorítmica para tales bloques es asequible en la mayoría
de las plataformas. Por otro lado, desde el punto de vista del factor de compresión,
si utilizamos bloques mayores no obtendremos grandes mejoras.
La definición de la DCT está dada por:
m−1 n−1
2x  1u 2y  1v
DCTu, v  2 CuCv
nm
∑∑ pixelx, y cos 2n
cos
2m
[2.1]
y0 x0

La definición de la DCT inversa está dada por:


m−1 n−1
2x  1u 2y  1v
pixelx, y  2
nm
∑∑ CuCvDCTu, v cos 2n
cos
2m
[2.2]
y0 x0

Donde, para ambos casos:

24 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

u  0, . . . , n
v  0, . . . , m
1
, 0
C  2

1, ≠0
La DCT puede implementarse siguiendo su definición, pero existen métodos
incrementales más veloces [RY1990], [GHANBARI2003].
Puede no resultar intuitivo de su definición, pero cada valor calculado en el
proceso de transformación involucra una matriz de transformación (función base)
distinta —de n  m componentes. Para el caso más común de bloques de 8  8, se
cuenta con 64 matrices de transformación, cada una de 8  8.
Cada función base representa una combinación de frecuencias de la forma de
onda del coseno en dos dimensiones. La idea es determinar cuánto de cada
patrón de frecuencia hay en el bloque de datos a transformar. Esto se logra
realizando el producto interno de la entrada y su función base correspondiente. Es
decir, cada término de una función base específica se multiplica por su término
correspondiente en el bloque de datos. Luego, todos estos productos se suman
para formar un único valor. Este único valor representa la cantidad de la frecuencia
contenida en el bloque de datos. Básicamente, la DCT cambia los valores
originales que representan intensidades de color en valores que representan
frecuencias del coseno. En la figura 17 se observan las funciones base canónicas
y base DCT para un bloque de datos de 8  8.

Figura 17: Funciones base canónicas y base DCT.

Algunos ejemplos nos ayudarán a entender estos conceptos. En los siguientes


ejemplos se transformarán bloques de datos de 8  8 utilizando una
implementación sencilla —la utilizada en el caso de estudio COMPRESSLIB— de

25 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

la DCT. Los valores de los datos originales representan intensidades de color en el


rango de 0 a 255. Cabe destacar que la DCT produce mejores valores para la
compresión si los datos originales están centrados en 0, por lo tanto, previo a la
transformación propiamente dicha se le resta 128 a cada componente —para
obtener valores en el rango de -128 a 127. Asimismo, luego de realizar la
antitransformación se debe sumar 128 a cada componente para recuperar los
valores originales.
Primero consideremos un bloque de datos que representa una región toda del
mismo color y su respectiva transformada (figura 18). En el bloque de datos no hay
frecuencias —pues es todo del mismo color—, y consecuentemente todos los
términos de la transformada excepto el superior izquierdo (DCT 0,0 ), son cero. Si
observamos la matriz superior izquierda de las funciones base DCT en la figura 17,
veremos que es una superficie uniforme (todos sus valores son iguales). Esta
función base es especial debido a que representa el caso particular de frecuencia
cero. Al término DCT 0,0 se lo denomina coeficiente DC. El nombre DC (Direct
Current) proviene del área de la electricidad y significa corriente continua —la
corriente continua no varía en el tiempo, por lo tanto no tiene frecuencia. Al resto
de los términos se los denomina coeficientes AC (Alternating Current) y significa
corriente alterna. A los datos transformados de la figura 18 se los puede comprimir
almacenando solamente el coeficiente DC y algún código especial para indicar que
el resto de los términos son cero.

Figura 18: Transformación de un bloque uniforme.

Consideremos ahora otro ejemplo. En la figura 19 se puede observar un bloque


de datos que representa una superficie donde el color cambia suavemente. Nótese
que todos los valores no nulos resultantes de la transformación se encuentran en
la esquina superior izquierda (y a lo largo de la primera fila y la primera columna).
Estos términos no nulos corresponden a las frecuencias bajas de los datos
originales. Estos datos pueden comprimirse —mediante algún recorrido específico
de la matriz— intentando almacenar solamente los términos no nulos, de modo
análogo al ejemplo anterior.

26 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

Figura 19: Transformación de un bloque en degrade.

Analizaremos un último ejemplo. Los datos originales de la figura 20 son


aleatorios, esto lleva a que en los datos transformados no haya casi ningún valor
nulo, y parecieran no estar mejorados para poder comprimirlos. La clave es que ha
cambiado la importancia de cada valor. Examinemos nuevamente las funciones
base DCT de la figura 17: las funciones base que se encuentran en la esquina
superior izquierda capturan frecuencias bajas, mientras que las que se encuentran
en la esquina inferior derecha capturan frecuencias más altas. Las frecuencias
más altas capturan el "ruido" y el detalle fino dentro de un bloque de datos,
mientras que las frecuencias más bajas capturan la "esencia" del bloque de datos
—debido a la respuesta logarítmica del ojo; la percepción humana del ruido en las
imágenes depende de la frecuencia espacial. En algunos casos, el ruido contenido
en un bloque de datos puede ser eliminado completamente sin degradaciones
visuales. La cantidad de ruido que eliminemos al comprimir un bloque de datos
determinará la calidad de la imagen. Más específicamente, el conjunto de
coeficientes obtenido debe ser cuantificado. Es decir, cada coeficiente es dividido
por un valor almacenado en una tabla —tabla de cuantificación— de modo tal de
reducir su valor numérico. Estos nuevos valores se deben redondear —o
truncar—, y en el caso de obtener un cero, sencillamente se estaría descartando
esa información. Si el nuevo valor no resultara ser cero, de todos modos
estaríamos obteniendo una mejora, ya que cuanto menor sea el valor, menor será
la cantidad de bits que serán necesarios para representarlo. El factor de
compresión obtenido utilizando este método depende de los valores de los
elementos de la tabla de cuantificación. Cuantos mas elementos en la tabla
posean valores grandes, mayor será la cantidad de coeficientes que quedarán
nulos, y por lo tanto mayor será el factor de compresión. Por supuesto que esto
incrementará la pérdida de información, y por lo tanto la calidad de la imagen será
menor. Para reconstruir la imagen se debe revertir todo el proceso.

27 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

Figura 20: Transformación de un bloque aleatorio.

Wavelet
Como ya mencionamos, las variaciones suaves en el color se corresponden
con variaciones de baja frecuencia y las variaciones fuertes de color se
corresponden con variaciones de alta frecuencia. La transformación del espacio de
intensidades de color al espacio frecuencial se puede llevar a cabo de muchos
modos. Uno de los posibles es la anteriormente presentada DCT. Otra de las
posibles técnicas es la descomposición de una imagen por medio de la
Transformada Discreta Wavelet o Discrete Wavelet Transform (DWT), la cual
analizaremos brevemente a continuación.
La forma general de una transformada wavelet unidimensional (1-D) se puede
apreciar en la figura 21. Aquí una señal pasa a través de un filtro pasa bajos y de
otro pasa altos, l y h (de lowpass y highpass, en inglés) respectivamente, y luego
se submuestrea en un factor de dos —esto causa un proceso con pérdida—,
logrando una transformada de un nivel. Se pueden realizar múltiples niveles
repitiendo los procesos de filtrado y eliminación (submuestreo), únicamente sobre
la rama del filtro pasa bajos. Este proceso se lleva a cabo para un número K finito
de niveles, obteniendo los coeficientes wavelet: d i1 n, i ∈ 1, . . . , K y d K0 n.
Cuando no se necesita tener conocimiento de la escala o de la frecuencia, el
conjunto entero de coeficientes wavelet se expresa como wn.

Figura 21: Descomposición de una wavelet de 1-D, de K niveles.

La transformada wavelet de 1-D puede extenderse a una transformada wavelet


bidimensional (2-D) utilizando filtros wavelet separables. Con los filtros separables,
la transformada 2-D puede calcularse aplicando una transformada 1-D a cada fila

28 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

de los datos de entrada, y luego aplicándola a cada columna de los datos de


entrada. Utilizando la imagen original de la figura 22 [USEVITCH2001], la figura 23
muestra un ejemplo de transformada wavelet 2-D de un nivel (K1), con su
correspondiente esquema de descomposición en la figura 24. El mismo ejemplo,
pero para un nivel de 3, se ve en las figuras 25 y 26.

Figura 22: Imagen original.

Figura 23: Wavelet de un nivel. Figura 24: Descomposición de 1 nivel.

29 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

Figura 25: wavelet de 3 niveles. Figura 26: Descomposición de 3 niveles.

Así como la transformada wavelet se utiliza para separar una imagen en varias
clases de importancia, la antitransformada se utiliza para reensamblar las distintas
clases de datos, y de este modo poder reconstruir la imagen. Aquí también se
utiliza un filtro pasa bajos y otro pasa altos, pero el filtrado se realiza en forma
opuesta. Es decir, se comienza desde el nivel más alto, aplicando primero los
filtros por columna y luego por fila, hasta llegar al primer nivel.
La codificación basada en wavelet ha mejorado considerablemente durante los
últimos años. Un gran progreso fue la introducción de la codificación EZW
(embedded zero-tree), de Shapiro. Este algoritmo es capaz de aprovechar las
propiedades de multiresolución de la transformada wavelet y es muy eficiente.

Formato de imagen JPEG


En la actualidad existe una cantidad muy grande de formatos de imagen. Cada
uno con sus respectivos puntos fuertes y débiles, según sea la aplicación para la
cual fueron diseñados —calidad, razón de compresión, eficiencia, costos
(patentes, licencias, etc.), estándares, etc.
A mediados de 1980, miembros de la ITU —International Telecommunication
Union (Unión Internacional de Telecomunicaciones)— y de la ISO —International
Standards Organisation (Organización Internacional de Estándares)— se
asociaron para llevar a cabo un estándar para la compresión de imágenes en
escala de grises y en colores. Este estándar se llamó JPEG: Joint Photographic
Experts Group (Grupo de Expertos Fotográficos Asociados).
Unos años más tarde, el comité de JPEG decide desarrollar otro estándar para
la compresión de imágenes, llamado JPEG2000. Esto fue en respuesta a las
demandas cada vez mayores de multimedia, internet y una gran variedad de
aplicaciones de imágenes digitales. Sin embargo, en términos de la metodología
de compresión, estos dos estándares son muy distintos —mientras que el JPEG
original está basado en la DCT, el JPEG2000 está basado en la DWT.

30 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

Las imágenes JPEG pueden ser de cualquier resolución y espacio de color,


tanto con algoritmos con pérdida como sin pérdida. El estándar JPEG es de
propósito general, y posee muchas características y posibilidades. Por ejemplo,
por medio del ajuste de parámetros, se puede tomar una decisión de compromiso
entre la calidad de la imagen y su factor de compresión. El rango de compresión
es muy amplio: desde aproximadamente 100:1 —con degradaciones visuales
importantes— hasta aproximadamente 3:1 —indistinguible de la imagen original.
Generalmente, el umbral del factor de compresión para percibir diferencias entre la
imagen original y la reconstruida, se encuentra dentro del rango de 10:1 a 20:1
—dependiendo de la imagen original.
Si bien el formato JPEG se desarrolló con la intención de comprimir imágenes,
ha resultado satisfactorio para la compresión de video, principalmente si se trata
de video en tiempo real —pues es más eficiente en términos computacionales que
otras soluciones, como el formato MPEG. También resultó útil en la tarea de
edición. Sin embargo, el factor de compresión que logra no es muy alto, ya que no
aprovecha la redundancia temporal entre cuadros. Una vez que ha finalizado el
proceso de edición, el video puede convertirse a un formato más apropiado para
obtener una compresión mayor.
El formato JPEG define cuatro modos de operación distintos: sin pérdida,
secuencial, progresivo y jerárquico. La codificación sin pérdida se basa en un
algoritmo espacial, en el dominio de los pixeles. Se lleva a cabo una predicción del
valor de una muestra, teniendo en cuenta hasta tres muestras vecinas. Luego, al
valor real se le resta el valor de la predicción y la diferencia se codifica sin pérdida
utilizando codificación de Huffman o aritmética. La compresión sin pérdida logra un
factor de compresión de aproximadamente 2:1.
Los otros tres modos de compresión se basan en la DCT. El esquema
secuencial puede utilizar tanto codificación de Huffman (la opción por defecto de
JPEG - baseline sequential scheme) como codificación aritmética. Cuando la
imagen se reconstruye, cada fila (bloques de 8  8 pixeles) se decodifica —de
izquierda a derecha y de arriba hacia abajo— y se presenta secuencialmente con
toda su exactitud y resolución.
El esquema progresivo presenta la imagen en múltiples pasos. Cuando la
imagen se decodifica, inmediatamente se obtiene una mera aproximación de la
imagen completa. Progresivamente se va mejorando la calidad, hasta lograr su
exactitud total. Esto es ideal para aplicaciones de búsqueda en bases de datos de
imágenes o exploración de sitios web. Se puede utilizar selección espectral,
aproximación sucesiva, o ambas. La selección espectral codifica los coeficientes
de baja frecuencia de la DCT al principio (para obtener la imagen rápidamente),
seguido de los coeficientes de alta frecuencia (para añadir los detalles). La
aproximación sucesiva codifica los bits más significativos de los coeficientes de la
DCT, seguido de los bits menos significativos.
Por último, el modo jerárquico representa a una imagen en múltiples
resoluciones. Por ejemplo, supongamos que existen tres versiones de una imagen:
512  521, 1024  1024 y 2048  2048. Las imágenes con mejor resolución se

31 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

codifican como diferencias de la siguiente imagen más chica, requiriendo menos


bits de los que necesitaría si se almacenara individualmente. Por supuesto, el
número total de bits es mayor al requerido para almacenar solamente la imagen de
mayor resolución. Cabe destacar que las imágenes individuales en una secuencia
jerárquica pueden ser codificadas progresivamente.

Esquema secuencial (baseline)


Aquí estudiaremos las distintas etapas del pipeline de
compresión-descompresión del esquema secuencial. Primero comentaremos
brevemente cada uno de los pasos, y luego se profundizará en aquellos que lo
requieran. Las técnicas que ya hayan sido analizadas con anterioridad serán
mencionadas superficialmente. En la figura 27 se puede apreciar un diagrama
esquemático de un compresor.

Figura 27: Diagrama esquemático de un compresor (secuencial) JPEG.

Si la imagen que se desea comprimir es en colores, entonces el primer paso es


convertir esta imagen al espacio de colores YCbCr —el estándar JPEG no define
un espacio de color específico para la imagen de entrada. Luego, es posible
realizar algún submuestreo de los canales Cb y Cr. El estándar JPEG permite
cualquiera de los formatos de muestreo de YCbCr; para la correcta
descompresión, en el encabezado se almacena información del factor de muestreo
vertical y horizontal. Luego, cada plano del espacio de color se discretiza en

32 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

bloques de 8  8 pixeles —en caso de tratarse de una imagen en escala de grises,


esta imagen se discretiza sin ningún preprocesamiento.
El siguiente paso es realizar un corrimiento de los valores de las componentes
de cada bloque, pues la DCT produce mejores valores para la compresión si los
datos originales están centrados en 0. Como el rango original es de 0 a 255, al
restarle 128 el nuevo rango será de -128 a 127.
A continuación, a cada bloque se le aplica la DCT. Luego, cada bloque se
cuantifica teniendo en cuenta una tabla de cuantificación. Una vez cuantificado, se
recorre el bloque en zigzag, de modo tal de acumular la mayor cantidad posible de
ceros al final del recorrido. Después, los coeficientes DC de los bloques se
codifican mediante DPCM; los coeficientes AC se codifican mediante RLC. Luego
de esta primer codificación, cada conjunto se codifica independientemente por
segunda vez, en este caso mediante un codificador entrópico —codificación de
Huffman, pues es la única posibilidad en el esquema secuencial baseline. Una vez
terminados estos procesos, se cuenta con toda la información comprimida, lista
para almacenar o transmitir.
Para descomprimir una imagen, simplemente se invierte todo el proceso. Se
utilizan decodificadores entrópicos, un decodificador RLC, un decodificador DPCM,
se reconstruyen los bloques, se descuantifican, se antitransforman y finalmente se
obtiene la imagen recuperada.

Cuantificación
En este proceso se reduce la precisión de los coeficientes, consecuentemente
el número de bits necesarios para representarlos será menor. Esto se lleva a cabo
dividiendo cada valor en el bloque por un único divisor (entre 1 y 256) que está
almacenado en una tabla —tabla de cuantificación. Debido a la percepción
humana, generalmente las frecuencias más altas se dividen por factores mayores,
por lo tanto muchos coeficientes finalizan siendo cero. Matemáticamente la
cuantificación es una operación de división, sin embargo si los factores de
cuantificación se restringen a potencias de dos, esto se puede realizar muy
eficientemente realizando corrimientos.
La cantidad de precisión que se puede reducir sin involucrar pérdidas visuales
considerables es dependiente de los datos. Es por esto que el estándar JPEG no
impone ninguna tabla de cuantificación, sino que lo deja abierto para que cada
aplicación defina la más conveniente para sus propósitos. No obstante, existen
tablas de propósito general. Es usual que haya una tabla para la luminancia y otra
—con coeficientes mayores— para las crominancias. Además, al comprimir
utilizando estas tablas estándar, se puede almacenar en el encabezado un
parámetro de escalamiento. Esto le brinda flexibilidad a las tablas, pues
dependiendo del factor de escalamiento se podrá incrementar o disminuir la
calidad de la imagen —inversamente proporcional al factor de compresión. En la
figura 28 se muestra una tabla de cuantificación para luminancia y en la 29 una
para crominancias, ambas de propósito general [GHANBARI2003].

33 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

El proceso de decodificación restaura las magnitudes de los términos, pero por


supuesto que no la precisión original. Esto se lleva a cabo invirtiendo la operación,
es decir multiplicando por el mismo número que anteriormente se había dividido.
Por lo tanto, un conjunto de datos sólo podrá ser decodificado satisfactoriamente si
el codificador y el decodificador utilizan las mismas tablas. Las tablas pueden estar
incluidas en el conjunto de datos comprimidos —tablas ad hoc, almacenadas en el
encabezado— o pueden ser tablas predefinidas —almacenadas tanto en el
compresor como en el descompresor. El análisis de cuál de las dos alternativas es
más conveniente es análogo al realizado con las tablas de probabilidad en la
codificación de Huffman. Es posible que al utilizar tablas específicas se logre un
mejor desempeño, pero hay que tener en cuenta que estas tablas deberán formar
parte de la imagen comprimida. Si la imagen es muy grande con respecto al costo
asociado de almacenar las tablas, probablemente convenga utilizar esta opción.
Por otro lado, si la imagen a comprimir es muy pequeña, es posible que el hecho
de almacenar las tablas en la misma imagen comprimida represente un porcentaje
considerable del tamaño total, con lo cual sería conveniente utilizar las tablas
estándar. Otros factores que afectan son los de la eficiencia y complejidad de
implementación. Es muy probable que el factor de más relevancia a la hora de
decidir cuál decisión tomar sea el de la eficiencia. Es cierto que el objetivo
primordial de la compresión de imágenes es reducir la cantidad de datos que las
representan, pero en muy pocas ocasiones el hecho de guardar las tablas de
cuantificación representará un costo importante. Observemos que una tabla de
cuantificación es una matriz de 8  8 componentes, y en la mayoría de las
aplicaciones se trabaja con imágenes de varios órdenes de magnitud mayor a 8  8
pixeles.

Figura 28: Tabla de cuantificación para Y.

34 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

Figura 29: Tabla de cuantificación para Cb y Cr.

Recorrido en zigzag
Luego de la cuantificación, es muy probable que muchos términos que se
encuentran en la esquina inferior derecha se redondeen —o trunquen— a cero.
Será más eficiente almacenar la cantidad de ceros que almacenarlos
individualmente. Mas aún, cuando sólo queden elementos nulos por codificar, se
podrá almacenar un símbolo que indique esta situación.
El recorrido en zigzag es una técnica que reagrupa los términos de los bloques
en un arreglo lineal, de modo tal de incrementar la probabilidad de que los
elementos no nulos se encuentren al principio, agrupando los ceros al final. Esto
se logra recorriendo los bloques en zigzag a 45 grados, comenzando por el
extremo superior derecho y finalizando en el extremo inferior izquierdo, como se
muestra en la figura 30.

Figura 30: Recorrido en zigzag.

Codificación RLC
Una vez que se dispone del arreglo resultante del recorrido en zigzag, se lo
codifica con RLC (Run Length Coding - codificación de longitud de cadenas), en
series de pares (longitud, valor). La componente longitud indica la cantidad de
coeficientes nulos y la componente valor indica el siguiente coeficiente no nulo en

35 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

el arreglo. Cabe destacar que la componente longitud utilizará sólo cuatro bits, por
lo tanto su rango será de 0 a 15. Por lo tanto, si nos encontráramos con una
secuencia de, por ejemplo, 20 ceros y a continuación un 8, esta cadena se
representaría como: (15,0),(4,8). Es decir, el primer par indica que hay 15 ceros y
a continuación un cero —en total 16 ceros—; el primer término del segundo par
debe completar los 20 ceros, por lo tanto es 4, y finalmente le sigue el 8. Cuando
se detecta que el bloque lo termina una cadena de ceros, se codifica como (0,0).
Como muchas veces los arreglos quedan con largas cadenas de ceros
consecutivos, esta codificación elimina mucha redundancia.
Veamos un ejemplo completo, considerando el siguiente bloque:
Recorrido en zigzag:
-800 -73 0 -7 0 -2 0 -1
-800,-73,-73,0,0,0,-7,0,0,-7,0,0,0,
-73 0 0 0 0 0 0 0
0,0,-2,0,0,0,0,-2,0,0,0,0,0,0,0,-1,
0 0 0 0 0 0 0 0
0,0,0,0,0,0,-1,0,0,0,0,0,0,0,0,0,0,
-7 0 0 0 0 0 0 0
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
0 0 0 0 0 0 0 0
-2 0 0 0 0 0 0 0
RLC:
0 0 0 0 0 0 0 0
(0,-800),(0,-73),(0,-73),(3,-7),(2,-7),
-1 0 0 0 0 0 0 0
(5,-2),(4,-2),(7,-1),(6,-1),(0,0)

Codificación DPCM
La codificación DPCM (Differential Pulse Code Molulation - codificación
modulada de pulsos diferenciales) es un caso particular de la codificación
predictiva. Se basa en la información ya disponible para predecir valores futuros, y
lo que se codifica es la diferencia entre el valor real y el de la predicción.
La idea es restarle al coeficiente DC actual el coeficiente DC anterior, y
almacenar ese valor —excepto que se trate del primer coeficiente DC de la
imagen, en cuyo caso se almacena el coeficiente DC original. A este valor lo
llamaremos DC Diferencial, o simplemente Dif. Este tratamiento por separado de
los coeficientes AC se realiza para explotar la correlación entre los valores DC de
los bloques adyacentes.
Por ejemplo, supongamos que los cuatro primeros bloques —ya
cuantificados— poseen los siguientes coeficientes DC: 733, 708, 737 y 677. La
codificación DPCM se observa en la figura 31.

36 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

Figura 31: Codificación DPCM.

Para decodificar una serie de coeficientes se realiza lo siguiente. Al coeficiente


codificado se le suma el coeficiente que se ha decodificado anteriormente —a
menos que sea el primer coeficiente por decodificar, en cuyo caso no se le suma
nada. En la figura 31 se observa la decodificación DPCM del ejemplo anterior.

Figura 32: Decodificación DPCM.

Codificación entrópica
Para reducir la cantidad de bits necesarios para representar los bloques
cuantificados, tanto los coeficientes Dif. como los AC se codifican entrópicamente.
Para esto se utilizan dos esquemas básicos: el VLC (Variable Length Coding -
codificación de longitud variable) y el VLI (Variable Length Integer - entero de
longitud variable). El VLC codifica la cantidad de bits utilizados por cada
coeficiente, mientras que el VLI codifica los enteros signados.
Aquí se utilizarán tablas de códigos Huffman predefinidas, sin embargo
recordemos que el estándar JPEG permite especificar sus propios códigos en el
encabezado.

Codificación de los coeficientes DC Diferenciales


La codificación de los coeficientes Dif. se lleva cabo mediante tres pasos
[BOUMAN2001].
1. Determinar la cantidad m de bits necesarios para representar Dif k sin
signo. Por ejemplo, la representación binaria no signada del número −3
es 11, por lo tanto m  2 bits.

37 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

2. Utilizar la tabla 5 para codificar m. A esto se lo conoce como


codificación VLC.
3. Si Dif k  0, entonces tomar los m menos significativos bits. Si
Dif k  0, entonces tomar el complemento a dos de la representación de
Dif k − 1 y tomar los m menos significativos bits. A este paso se lo conoce
como codificación VLI. Se lleva a cabo para representar eficientemente
los coeficientes, pues |Dif k |  2 m − 1.
Por ejemplo, si m  2, Dif k debe pertenecer al conjunto −3, −2, 2, 3.
Como los valores −1, 0, 1 no son posibles, para no desperdiciar bits
podemos remapear los valores enteros al rango 0, 1, 2, 3.
Consideremos el caso cuando Dif k  −3. En este caso m  2. Como
Dif k  0, hay que tomar el complemento a dos de la representación de
Dif k − 1, el cual es 11111100. Tomando los m menos significativos bits
nos queda 00.
Ahora si Dif k  3, entonces la representación de Dif k en
complemento a dos es 00000011, y tomando los m menos significativos
bits nos queda 11.
En la práctica, se debe utilizar aritmética de 16 bits para el
complemento a dos, para poder trabajar con los doce bits de los valores
signados de Dif k .
El resultado de esta codificación se presenta como una cadena de bits que
contiene primero la parte VLC y luego la VLI.
Rango de los valores de DC Dif k Cantidad de bits (m) Código Huffman
0 0 00
-1,1 1 010
-3,-2,2,3 2 011
-7...-4,4...7 3 100
-15...-8,8...15 4 101
-31...-16,16...31 5 110
-63...-32,32...63 6 1110
-127...-64,64...127 7 11110
-255...-128,128...255 8 111110
-511...-256,256...511 9 1111110
-1023...-512,512...1023 10 11111110
-2047...-1024,1024...2047 11 111111110
Tabla 5: Códigos Huffman para la representación de cada valor posible de m de los
coeficientes Dif k .

Codificación de los coeficientes AC

38 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

Los coeficientes AC se codifican de modo similar a los coeficientes Dif k , pero


teniendo en cuenta que los coeficientes AC estarán representados por pares
(longitud, valor).
1. Teniendo en cuenta el par (longitud, valor), determinar el par
(longitud, m), donde longitud es la cantidad de ceros que precede al valor
no nulo y m es la cantidad de bits necesarios para representar la
componente valor del primer par. A m se lo determina del mismo modo
que en el paso 1 de la codificación de los coeficientes Dif. Entonces, por
ejemplo el par (longitud, valor)  (3,-3) deberá representarse como
(longitud, m)  (3,2).
Al par (15,0) se lo representa con el símbolo ZRL. Al par (0,0) se lo
representa con el símbolo EOB.
2. Mapear la componente valor en una secuencia de m bits, del mismo
modo que en el paso 3 de la codificación de los coeficientes Dif. A este
paso se lo denomina codificación VLI ac .
3. Utilizar una tabla de códigos Huffman para coeficientes AC
[BOUMAN2001], [GHANBARI2003] para mapear el par (longitud, m) en
un código Huffman, denominado VLC ac .
4. Concatenar los códigos VLC ac ,VLI ac para formar una cadena de bits
que representa la codificación del par original (longitud, valor).
Veamos un ejemplo que ilustre el procedimiento completo [BOUMAN2001].
Supongamos que el bloque a codificar es el primero de la imagen y que posee los
siguientes valores:
3 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 Los pares que resultan del recorrido
en zigzag son los siguientes:
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 (0,3),(15,0),(15,0),(15,0)(2,9),(0,0)
0 0 0 0 0 9 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0

La cadena de bits que representa la codificación entrópica se construye a


continuación.

39 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

011  VLC de m  2 del coeficiente DC del par (0,3)


11  VLI del coeficiente DC 3
11111111001  VLC ac de ZRL —par (15,0)
11111111001  VLC ac de ZRL —par (15,0)
11111111001  VLC ac de ZRL —par (15,0)
111111110100  VLC ac de (2,4) —del par original (2,9)
1001  VLI ac del valor 9 —del par original (2,9)
1010  VLC ac de EOB —par (0,0)

Al concatenar estos códigos obtenemos la siguiente cadena de bits:


’011”11”111 11111001’ ’11111111 001”11111 111001”11 11111101 00”1001”10 10”??????
7F F9 FF 3F E7 FD 26 ??
Las llaves denotan los límites de los bytes, y las comillas simples denotan
grupos de bits asociados a los códigos. Es claro que la cadena de bits no siempre
finalizará al final de un byte. Si el bloque actual no es el último de la imagen,
entonces la cadena de bits que producirá la codificación del próximo bloque
deberá concatenarse al final de la codificación del bloque actual. Si el bloque
actual sí es el último de la imagen, entonces lo que se realiza es completar —si
fuera necesario— el último byte con ceros, para asegurar un número entero de
bytes. A esto se lo denomina padding de ceros.
La segunda línea representa el valor hexadecimal del byte asociado. En la
secuencia se ve el valor 0xFF, pero este valor está reservado para el encabezado
JPEG. Entonces, lo que se realiza para evitar problemas es, ante la ocurrencia de
un valor 0xFF, añadir a continuación un byte con el valor 0x00. A esto se lo llama
byte stuffing. Teniendo en cuenta estos detalles, la secuencia correcta debería ser:
7F F9 FF 00 3F E7 FD 26 ??. El verdadero valor del último byte será determinado
al codificar el próximo bloque.

Caso de estudio: COMPRESSLIB


El propósito de este caso de estudio es ilustrar las diferentes etapas del
pipeline de compresión-descompresión del esquema secuencial baseline del
formato de imagen JPEG. Cabe aclarar que la intención de este caso de estudio
no es realizar una implementación de un compresor-descompresor de imágenes
JPEG. La idea es mostrar, mediante el desarrollo de un formato propio —formato
BCI (Basic Compressed Image)—, cómo se pueden llevar a la práctica los distintos
conceptos teóricos. Por este motivo es que se le ha dado mayor prioridad a la
facilidad de comprensión de la implementación que a la eficiencia.
Este desarrollo consiste de lo siguiente:
 Una librería de compresión de imágenes (COMPRESSLIB),

modularizada para poder acceder independientemente a cada una de las


etapas de compresión-descompresión.

40 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

 Una aplicación que ilustra el funcionamiento interno de cada una de


las etapas de compresión-descompresión —Compress demo.
 Una aplicación de compresión y visualización de imágenes —Image

viewer.

Librería de compresión de imágenes


Aquí describiremos el funcionamiento general de la librería, analizando en
detalle los temas que lo requieran. La librería COMPRESSLIB fue desarrollada en
C y compilada a un archivo compressor.lib, que deberá ser incluido por
cualquier aplicación que desee utilizarla. Esta librería utiliza otra librería, DevIL
(Developer’s Image Library), que es una librería de imágenes Open Source basada
en la licencia LGPL. Si bien la librería DevIL soporta muchos formatos de
imágenes, sólo se la utiliza para cargar imágenes que luego serán comprimidas
por COMPRESSLIB, o para almacenar imágenes en algún formato estándar. Por
esta razón, las aplicaciones que utilicen la librería COMPRESSLIB, tendrán que
incluir también (sólo en el caso que la aplicación requiera cargar o almacenar
imágenes con formatos estándar) el archivo devil.dll.
A continuación describiremos las capacidades y limitaciones del formato BCI.
Este formato permite almacenar dos tipos de imágenes distintas: Imágenes en
escala de grises —8 bits por pixel— e imágenes en color —24 bits por pixel—.
Para las imágenes en color, se emplea el formato de muestreo 4:2:2. Utiliza tablas
de cuantificación fijas —una para el canal Y y otra para los canales Cb y Cr—,
almacenadas en un archivo de texto (quantization.tbl), que deberá residir en
el mismo directorio que la aplicación. Estas tablas pueden modificarse
simplemente editando el archivo y cambiando los valores de los coeficientes de las
matrices. Además, en el encabezado se guarda un parámetro que indica el factor
de calidad de la imagen, que determina el escalado de estas tablas. Para la
codificación entrópica se adoptó la codificación de Huffman, y se utiliza una tabla
de códigos sugerida por [BOUMAN2001] y [GHANBARI2003], almacenada en un
archivo de texto (huffman.tbl) que debe hallarse en el mismo directorio que la
aplicación. Al igual que con las tablas de cuantificación, los códigos podrían
modificarse editando el archivo.
En la figura 33 puede observarse un diagrama del encabezado del formato.
Posee 6 campos:
 Id (Identificador) - Es el identificador del formato. Este campo es fijo, y

siempre debe contener los caracteres ’b’, ’c’, ’i’ y ’ ’(espacio) —4 datos
de tipo char (en total 4 bytes).
 L (Largo) - Este campo almacena el largo (o ancho) de la imagen,

medido en pixeles. El tipo de datos que almacena es unsigned int


—entero de 32 bits (o 4 bytes) no signado.
 A (Alto) - Este campo almacena la altura de la imagen, medida en

pixeles. El tipo de datos que almacena es unsigned int —entero de


32 bits (o 4 bytes) no signado.

41 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

 BPP (Bits Por Pixel) - Este campo almacena la cantidad de bits que

son necesarios para representar un pixel de la imagen. Sólo puede ser 8


(escala de grises) o 24 (color). Su tipo de datos es unsigned char
—entero de 8 bits (o 1 byte) no signado.
 C (Calidad) - Este campo almacena un número real entre 0 y 1, y se

utiliza para definir el escalado de las tablas de cuantificación. Controla la


calidad de la imagen, siendo 0 la peor calidad (factor de compresión más
alto), 0.66 una calidad buena (sin escalado) y 1 la mejor calidad (factor
de compresión más bajo). Su tipo de datos es float —real de 32 bits (o
4 bytes).
 T (Tamaño) - Este campo almacena la cantidad de bytes que ocupan

los datos comprimidos propiamente dichos. Es el último campo del


encabezado. El tipo de datos que emplea es unsigned int —entero
de 32 bits (o 4 bytes) no signado.

Figura 33: Encabezado del formato BCI.

Ahora estudiaremos las distintas etapas del pipeline de


compresión-descompresión. El diagrama esquemático de este pipeline puede
observarse en la figura 34. Si bien el formato no especifica una implementación
determinada, nosotros explicaremos cómo lo hace COMPRESSLIB. No
explicaremos en detalle cada una de las clases, ya que esto superaría los
alcances de este trabajo, no obstante sí se analizarán los extractos de código que
sean relevantes. Para acceder a la documentación de COMPRESSLIB, referirse al
archivo annotated.html, en la ruta
programacion\proyectofinal.cvs\compressor\docs\compresslib.
Dado que el funcionamiento general es análogo al del esquema secuencial del
formato JPEG, comenzaremos inmediatamente a analizar cada una de las etapas.

42 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

Figura 34: Diagrama esquemático de un compresor BCI.

Muestreo
En esta etapa, para la compresión, se realiza un submuestreo de los canales
YCbCr con el formato 4:2:2.
A cada canal se lo representa como si fuera una imagen individual. Los datos
están almacenados en un arreglo, por filas, de izquierda a derecha y de arriba
hacia abajo. Entonces, luego de hacer la conversión de espacio de color a YCbCr
4:4:4, tendremos una imagen que representa al canal Y, otra que representa al
canal Cb y otra que representa al canal Cr; cada una de 8 bits por pixel y del
mismo largo y alto que la original. Resta realizar el submuestreo de los canales Cb
y Cr. Para esto, a cada canal hay que aplicarle el siguiente algoritmo:

for ( UInt32 i  0; i  size; i )


{
alias[0]  dataChrominancePtr[0];
alias;
dataChrominancePtr  2;
};

ancho original
 es alto original 
size 2
(la mitad de la cantidad de pixeles
del canal Y).
 dataChrominancePtr[] es un puntero (original) a una estructura que

contiene los datos originales del canal Cb o Cr.


 alias[] es un puntero (nuevo) a una estructura donde se almacenarán

los datos del canal submuestreado.

43 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

Entonces, lo que se realiza es: 1) se copia el valor de un pixel del puntero


original en el nuevo; 2) se adelanta una posición el puntero nuevo; 3) se adelanta
dos posiciones el puntero original; 4) se repite el proceso hasta llegar al final del
puntero original (size veces).

Para la descompresión es necesario convertir del formato 4:2:2 a 4:4:4,


realizando una interpolación. Es necesario seguir el siguiente algoritmo para los
canales Cb y Cr.

alias[0]  dataChrominancePtr[0];
dataChrominancePtr;
for ( UInt32 i  0; i  ( size - 2 ); i  2 )
{
alias[2]  dataChrominancePtr[0];
temporalValue  floor ( ( ( alias[0]  alias[2] ) / 2 )  0.5 );
if ( temporalValue  255 )
temporalValue  255;
else if ( temporalValue  0 )
temporalValue  0;
alias[1]  temporalValue;
alias  2;
dataChrominancePtr;
};

 alias[] es un puntero (nuevo) a una estructura donde se almacenarán

los datos del canal Cb o Cr con las muestras faltantes reconstruidas.


 dataChrominancePtr[] es un puntero (original) a una estructura donde se

encuentran los datos originales del canal Cb o Cr submuestreado.


 size es alto Cb o Cr  ancho Cb o Cr  2 (la cantidad de pixeles del

canal Y).
Entonces el procedimiento es: 1) antes de comenzar el ciclo, se copia en la
primer componente del puntero nuevo, la primer componente del puntero original;
2) se copia en la tercer componente del puntero nuevo, la segunda componente
del puntero original; 3) se almacena en la segunda componente del puntero nuevo,
un promedio de la primer y tercer componente; 4) se avanza en dos el puntero
nuevo y en uno el puntero original; 5) se repiten los pasos 2), 3) y 4) hasta
terminar el proceso.

Aquí se ha presentado sólo un esquema general de la implementación. La


implementación propiamente dicha se puede encontrar en el código fuente, en los
archivos colorspacemanager.h y colorspacemanager.cpp, bajo la ruta
programacion\proyectofinal.cvs\compressor\src\compressor\utils

44 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

Discretización en bloques
Hasta ahora, siempre se dijo que se deben discretizar las imágenes en bloques
de 8  8, pero esto no siempre es posible. Si la imagen no tiene un largo o alto
múltiplo de 8, entonces será imposible dividir a esta imagen en bloques de sólo
8  8. No existe una única manera de afrontar este problema. Una posible solución
es "agrandar" la imagen hasta alcanzar el múltiplo de 8 más cercano —en la
dimensión que sea necesario—, y en el proceso de descompresión volver la
imagen a su tamaño original. En el presente caso de estudio se adoptó otra
solución, permitiendo bloques menores a 8  8. Supongamos que se dispone de
una imagen de 50  35, entonces tendremos 24 bloques de 8  8, 4 de 2  8, 4 de
8  3 y 1 de 2  3 (figura 35). Esta solución complica un poco la implementación de
la transformada DCT, ya que no alcanza con realizar el caso particular de 8  8,
sino que se debe llevar a cabo de modo general.

Figura 35: Discretización en bloques no uniformes.

Transformación DCT
Dado que la DCT ya se ha analizado con suficiente rigurosidad, ahora sólo nos
limitaremos a explicar cómo se ha implementado en este caso de estudio. A
continuación se presenta la implementación del constructor de una matriz de
transformación de rows  columns elementos.

Real c, d;
for ( UInt8 u  0; u  rows; u )
{
if ( u  0 )
c  1/sqrt( Real(2.0) );
else c  1;
for ( UInt8 v  0; v  columns; v )
{
if ( v  0 )
d  1/sqrt( Real(2.0) );
else d  1;
for ( UInt8 i  0; i  rows; i )

45 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

for ( UInt8 j  0; j  columns; j )


{
Real first  ( 2*c*d / sqrt( Real( rows * columns ) ) );
Real cos1  cos( ( 2*i  1 ) * u*PI / ( 2 * rows ) );
Real cos2  cos( ( 2*j  1 ) * v*PI / ( 2 * columns ) );
this-setComponent ( v  rows*u, j  columns*i, first * cos1 * cos2 );
};
};
};

Dado un bloque de datos de rows  columns componentes y una matriz de


transformación conforme —de
columns − 1  rows ∗ rows − 1  1  columns − 1  columns ∗ rows − 1  1
elementos—, el siguiente algoritmo realiza la transformación DCT.

IMatrixReal* auxMatrix  new IMatrixReal (rows, columns);


for ( UInt8 u  0; u  rows; u )
for ( UInt8 v  0; v  columns; v )
for ( UInt8 i  0; i  rows; i )
for ( UInt8 j  0; j  columns; j )
{
Real uvAux  auxMatrix-getComponent (u, v);
Int16 ijAux  ( input-getComponent (i, j) - 128 );
Real transfAux  transfMatrix-getComponent (v  rows*u, j  columns*i);
auxMatrix-setComponent ( u, v, uvAux  (ijAux * transfAux) );
};
for ( UInt8 u  0; u  rows; u )
for ( UInt8 v  0; v  columns; v )
result-setComponent (u, v, floor ( auxMatrix-getComponent (u, v)  0.5) );

 auxMatrix es una matriz auxiliar de números reales, de rows  columns

componentes, inicializada toda con ceros.


 input es una matriz de rows  columns componentes, que contiene el

bloque de datos a transformar.


 transfMatrix es la matriz de transformación de input.

En el proceso de descompresión se debe llevar a cabo una antitransformación


de los datos. A continuación se lista el algoritmo para el constructor de una matriz
de antitransformación de rows  columns elementos.

Real c, d;
for ( UInt8 u  0; u  rows; u )
for ( UInt8 v  0; v  columns; v )
for ( UInt8 i  0; i  rows; i )

46 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

{
if ( i  0 )
c  1/sqrt( Real(2.0) );
else c  1;
for ( UInt8 j  0; j  columns; j )
{
if ( j  0 )
d  1/sqrt( Real(2.0) );
else d  1;
Real first  ( 2*c*d / sqrt( Real( rows*columns ) ) );
Real cos1  cos( (2*u  1) * i*PI/( 2*rows ) );
Real cos2  cos( (2*v  1) * j*PI/( 2*columns ) );
this-setComponent (v  rows*u, j  columns*i, first * cos1 * cos2 );
};
};

Dado un bloque de rows  columns coeficientes DCT y una matriz de


antitransformación conforme —de
columns − 1  rows ∗ rows − 1  1  columns − 1  columns ∗ rows − 1  1
elementos—, el siguiente algoritmo realiza la antitransformación DCT.

IMatrixReal* auxMatrix  new IMatrixReal (rows, columns);


for ( UInt8 u  0; u  rows; u )
for ( UInt8 v  0; v  columns; v )
for ( UInt8 i  0; i  rows; i )
for ( UInt8 j  0; j  columns; j )
{
Real uvAux  auxMatrix-getComponent (u, v);
Int16 ijAux  input-getComponent (i, j);
Real transfAux  transfMatrix-getComponent (v  rows*u, j  columns*i);
auxMatrix-setComponent ( u, v, uvAux  ijAux * transfAux );
};
for ( UInt8 u  0; u  rows; u )
for ( UInt8 v  0; v  columns; v )
result-setComponent (u, v, floor ( auxMatrix-getComponent (u, v)  0.5)  128 );

 es una matriz auxiliar de números reales, de rows  columns


auxMatrix
componentes, inicializada toda con ceros.
 input es una matriz de rows  columns componentes, que contiene el

bloque de coeficientes DCT a antitransformar.


 transfMatrix es la matriz de antitransformación de input.

Para un análisis exhaustivo de los constructores de las matrices de


transformación y antitransformación, referirse al código fuente de los archivos

47 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

transformationmatrix.h y transformationmatrix.cpp, situados en el


directorio
programacion\proyectofinal.cvs\compressor\src\compressor\common
Si se desea profundizar en la implementación de la transformación DCT,
recurrir a los archivos dcttransformer.h y dcttransformer.cpp. Para la
antitransformación, a los archivos idcttransformer.h y
idcttransformer.cpp. Todos estos archivos se encuentran en
programacion\proyectofinal.cvs\compressor\src\compressor\codecs

Cuantificación
Para la cuantificación, se utiliza una tabla para la luminancia (canal Y) y otra
para las crominancias (canales Cb y Cr). Por defecto, estas tablas son las
sugeridas por [GHANBARI2003] —figuras 28 y 29—, pero al estar almacenadas
en un archivo de texto (quantization.tbl) son fácilmente editables. Vale la
pena aclarar que una imagen debe ser descomprimida con las mismas tablas que
fue comprimida, por esta razón se recomienda tener especial cuidado al editarlas.
Tanto para la cuantificación como para la descuantificación, se utiliza un
parámetro C (Calidad) de escalado, que determina la calidad de la imagen. Este
parámetro es un número real entre 0 y 1, siendo 0 la peor calidad (factor de
compresión más alto), 0.66 una calidad buena (sin escalado) y 1 la mejor calidad
(factor de compresión más bajo). Previo al escalamiento propiamente dicho, a este
parámetro C se le realiza un preproceso. Notaremos como C original y C preprocesado al
parámetro C antes y después del preproceso respectivamente. El parámetro
C preprocesado también será un número real, pero su rango es de 0.25 a 16. El
preproceso es el siguiente:
C preprocesado  2 1−C original 6−2

Esto mapea el mínimo de C original al máximo de C preprocesado , y el máximo de


C original al mínimo de C preprocesado .
Luego se cargan en memoria las tablas ya escaladas. El escalado es muy
simple, consiste de multiplicar cada componente de cada una de las dos tablas
originales por el factor de escalado C preprocesado .
Para la cuantificación, se divide el elemento (i,j) del bloque de coeficientes DC
por el elemento (i,j) de la tabla de cuantificación escalada. Para la
descuantificación, se multiplica el elemento (i,j) del bloque de coeficientes DC
cuantificados por el elemento (i,j) de la tabla de cuantificación escalada.
Para mayores detalles referirse al código fuente de los archivos
quantization.h y quantization.cpp, situados en
programacion\proyectofinal.cvs\compressor\src\compressor\common

48 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

Codificación DPCM
La implementación de la codificación y decodificación DPCM es la traducción
directa del método explicado en el esquema secuencial baseline de JPEG. Es
decir, para la codificación, al coeficiente DC del bloque a codificar se le debe restar
el coeficiente DC del bloque codificado previamente. Al resultado de esta resta lo
llamaremos Dif. Se construye un nuevo bloque, al coeficiente DC se le asigna Dif,
y al resto de los coeficientes AC se les asigna los mismos valores que los
contenidos en el bloque original. Luego, se debe almacenar el valor DC del bloque
original, para poder realizar la codificación del próximo bloque. El código que
implementa esto es el siguiente:

BlockMatrix* result  new BlockMatrix ( input.getRows (), input.getColumns () );


for ( UInt8 row  0; row  input.getRows (); row )
for ( UInt8 column  0; column  input.getColumns (); column )
result-setComponent ( row, column, input.getComponent ( row, column ) );

result-setComponent (0, 0, input.getComponent (0, 0) - this-previousEncodingDCValue);


this-previousEncodingDCValue  input.getComponent (0, 0);
return result;

 es una matriz inicializada toda con ceros, donde se almacenará


result
el bloque de coeficientes DCT codificado con DPCM.
 input es el bloque de coeficientes DCT a codificar con DPCM.

 previousEncodingDCValue es el valor DC del bloque codificado previamente.

Si fuera el primer bloque a codificar, previousEncodingDCValue es igual a cero.

Para la decodificación, al coeficiente codificado se le suma el coeficiente que


se ha decodificado anteriormente. Se construye un nuevo bloque y al coeficiente
DC se le asigna este valor. Además, este valor se almacena para la correcta
decodificación del próximo bloque. Al resto de los coeficientes AC del bloque
recién creado se les asigna los valores contenidos en el bloque original. La
implementación es la siguiente:

BlockMatrix* result  new BlockMatrix ( input.getRows (), input.getColumns () );


for ( UInt8 row  0; row  input.getRows (); row )
for ( UInt8 column  0; column  input.getColumns (); column )
result-setComponent ( row, column, input.getComponent ( row, column ) );

result-setComponent (0, 0, input.getComponent (0, 0)  this-previousDecodingDCValue);


this-previousDecodingDCValue  result-getComponent (0, 0);
return result;

 result es una matriz inicializada toda con ceros, donde se almacenará

49 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

el bloque de coeficientes DCT decodificado con DPCM.


 input es el bloque de coeficientes DCT a decodificar con DPCM.

 previousDecodingDCValue es el valor DC del bloque decodificado

previamente. Si fuera el primer bloque a decodificar, previousDecodingDCValue


es igual a cero.

Para explorar el código fuente original, los archivos que se deben observar son:
dctdpcm.h y dctdpcm.cpp, ubicados en
programacion\proyectofinal.cvs\compressor\src\compressor\encoding

Recorrido en zigzag y codificación RLC


Dado que COMPRESSLIB implementa el recorrido en zigzag en las mismas
clases que implementa la codificación y decodificación RLC, aquí también
estudiaremos todo en conjunto. Primero analizaremos la forma en que se realizan
los recorridos de matrices. Recordemos que COMPRESSLIB utiliza bloques de
m  n elementos, siendo m y n  8. Debido a esto, no alcanza con definir un único
recorrido para el bloque más común de 8  8, sino que es necesario definir un
recorrido para cada bloque posible —en total son 64 recorridos distintos. A
continuación se ofrece el código que implementa la construcción de un vector de
pares (i,j), que define el recorrido de un bloque de rows  columns componentes.
Cada par que contiene el vector, indica las componentes (i,j) que deben visitarse a
medida que se va avanzando. Así, por ejemplo, si tenemos en cuenta el recorrido
de la figura 30 (para un bloque de 8  8 elementos), los pares del vector que define
el recorrido en zigzag serán:
[(0,0),(0,1),(1,0),(2,0),(1,1),(0,2),(0,3),(1,2),(2,1),(3,0),(4,0)...(7,7)]

PathVector* path  new PathVector ();

UInt8 row  0;
UInt8 column  0;

while ( (row  (rows - 1)) || (column  (columns - 1)) )


{
path-push_back( Tuple2UInt8,UInt8 (row, column) );
if ( column  (columns - 1) )
column;
else row;

// Tests if the last component was reached.


if ( (row  (rows - 1)) && (column  (columns - 1)) )
{
path-push_back( Tuple2UInt8,UInt8 (row, column) );

50 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

break;
};

while ( (column ! 0) && (row  (rows - 1)) )


{
path-push_back( Tuple2UInt8,UInt8 (row, column) );
column–;
row;
};

path-push_back( Tuple2UInt8,UInt8 (row, column) );


if ( row  (rows - 1) )
row;
else column;

// Tests if the last component was reached.


if ( (row  (rows - 1)) && (column  (columns - 1)) )
{
path-push_back( Tuple2UInt8,UInt8 (row, column) );
break;
};

while ( (row ! 0) && (column  (columns - 1)) )


{
path-push_back( Tuple2UInt8,UInt8 (row, column) );
column;
row–;
};
};

// This is only true when rows is equal to 1 and columns is equal to 1.


if ( path-size()  0 )
path-push_back( Tuple2UInt8,UInt8 (0, 0) );

return path;

es el vector donde se almacena el recorrido de la matriz.


 path
Si se desea acceder al código fuente, referirse a los archivos
dctrlccoder.cpp o dctrlcdecoder.cpp, en
programacion\proyectofinal.cvs\compressor\src\compressor\encoding

Para la codificación RLC se construye un vector de pares (longitud, valor). La


componente longitud indica la cantidad de coeficientes nulos y la componente

51 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

valor indica el siguiente coeficiente no nulo en el recorrido. Al igual que en el caso


de JPEG, aquí también se destinaron cuatro bits para la representación de la
componente longitud, por lo tanto su rango será de 0 a 15. A continuación se
presenta la primer parte del código que construye este vector.

while ( ! isStreamOver () )
{
element  nextStreamElement ();
// If the element is equal to our skip element
if ( element  skipElement )
{
// then if it is less than the maximum
if ( skipElementCount  maxRunLength )
// add it to the count
skipElementCount;
else
{
// put it in the result
rlcResult.push_back ( Tuple2_TQuantity,_TDataType (skipElementCount,element) );
skipElementCount  0;
};
}
else
{
// Put the tuple in the result
rlcResult.push_back ( Tuple2_TQuantity,_TDataType (skipElementCount,element) );
skipElementCount  0;
};
};

 isStreamOver (), basándose en el recorrido zigzag para la matriz actual,

retorna un valor booleano que indica si ya se han visitado todas las


componentes.
 nextStreamElement (), basándose en el recorrido zigzag para la matriz

actual, retorna el próximo elemento de la matriz.


 skipElement representa al elemento sobre el cual se realizará la

codificación RLC, en nuestro caso es el número 0. La razón de ser de


esta variable es para brindar flexibilidad al algoritmo.
 skipElementCount lleva la cuenta de cuántos ceros se han encontrado en

el recorrido.
 maxRunLength representa la cantidad máxima de ceros consecutivos que

se pueden encontrar. En nuestro caso es 15. Este valor se almacena en


una variable para brindar flexibilidad al algoritmo.
 rlcResult es el vector en el que se almacena la codificación RLC.

En esta primer parte se ha recorrido todo el bloque de coeficientes DCT,

52 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

llenando el vector de pares (longitud, valor) con los valores encontrados. Resta
postprocesar este vector, principalmente porque COMPRESSLIB termina cada
codificación RLC con el par (0,0), independientemente de cuáles sean los últimos
valores del bloque. Pero además, por ejemplo, si los últimos 50 elementos del
recorrido son nulos, el código anterior terminaría la codificación con estos pares:
[...(15,0),(15,0),(15,0),(2,0)]. Esto se puede codificar de un modo mucho más
eficiente: [...(0,0)]. Esto es lo que realiza la última parte del código.

Int32 rlcResultSize  rlcResult.size ();


rlcResultSize–;
if ( rlcResultSize  0 )
{
while ( rlcResult[rlcResultSize].getSecond ()  0 )
{
if ( rlcResultSize  0 )
rlcResultSize–;
else break;
};

rlcResult.resize ( rlcResultSize  1 );
};

// Add end of block


rlcResult.push_back ( Tuple2_TQuantity,_TDataType (0,0) );

 rlcResultSize almacena la cantidad de pares que contiene el vector de

codificación rlcResult.
Si se desea profundizar más en el tema, el código fuente se encuentra en los
archivos rlccoder.h, rlccoder.cpp, dctrlccoder.h y dctrlccoder.cpp.
Todos los archivos pueden encontrarse en
programacion\proyectofinal.cvs\compressor\src\compressor\encoding

Para la decodificación RLC, el proceso se invierte: dado un vector de pares


(longitud, valor), se debe construir un bloque de coeficientes DCT. A continuación
puede apreciarse el código que lo implementa.

tuple  *input;
input;
Tuple2_TQuantity,_TDataType nullTuple (0, skipElement);
while ( !( tuple  nullTuple ) )
{
for ( UInt8 i  0; i  tuple.getFirst (); i )
storeInNextOutputPosition ( skipElement );

53 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

storeInNextOutputPosition ( tuple.getSecond () );

tuple  *input;

input;
};
while ( !(isDataContainerFull ()) )
storeInNextOutputPosition ( skipElement );

es un iterador para acceder al vector con la codificación RLC.


input
 storeInNextOutputPosition ( element ), basándose en el recorrido zigzag para la

matriz correspondiente, almacena el valor element en la componente


correspondiente, en el bloque de coeficientes DCT que se genera en la
decodificación.
 isDataContainerFull () retorna un valor booleano que indica si el bloque de

coeficientes DCT que se genera en la decodificación ya está completo.


Para un análisis exhaustivo, el código completo puede encontrarse en los
archivos rlcdecoder.h, rlcdecoder.cpp, dctrlcdecoder.h y
dctrlcdecoder.cpp. La ruta de acceso es
programacion\proyectofinal.cvs\compressor\src\compressor\encoding

Codificación de Huffman
La codificación de Huffman que se ha implementado es casi la misma que la
presentada en el esquema secuencial baseline de JPEG. La única diferencia es
que, por una cuestión de simplicidad, los coeficientes DC se codifican utilizando la
tabla de códigos Huffman de coeficientes AC —por defecto es la misma que
proponen [BOUMAN2001] y [GHANBARI2003]. Comencemos con la primer parte
de la implementación.

Tuple2 _TQuantity , _TDataType  tuple;


std::vectorBool output;
for (std::vector Tuple2 _TQuantity , _TDataType  ::iterator iter  input.begin(); iter  input.end();
iter)
{
// Dereference iter to obtain values.
tuple  *iter;
encodeTuple ( output, tuple );
};

 iteres un iterador para acceder a las tuplas codificadas con RLC.


 output es un vector binario, es donde se almacenará la codificación.
 encodeTuple ( output, tuple ) realiza la codificación Huffman de tuple y la

54 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

añade al final del vector output.


La codificación termina una vez que se ejecuta encodeTuple ( output, tuple ) tantas
veces como tuplas haya para codificar. Veamos ahora cómo está implementado
encodeTuple ( output, tuple ).

Tuple2 _TQuantity , _TDataType  preprocessedTuple;


preprocess ( output, preprocessedTuple, tuple );
lookup ( output, preprocessedTuple );
postprocess ( output, preprocessedTuple, tuple );

 preprocess ( output, preprocessedTuple, tuple ) le asigna a la primer componente

de preprocessedTuple la primer componente de tuple, y a la segunda


componente de preprocessedTuple le asigna la cantidad de bits necesarios
para representar a la segunda componente de tuple.
 lookup ( output, preprocessedTuple ) busca en la tabla de códigos Huffman el

par que contiene preprocessedTuple. El código obtenido se añade al final del


vector binario output.
 postprocess ( output, preprocessedTuple, tuple ) añade al final de output la

representación en binario de la segunda componente de tuple.


Si se desea profundizar en los detalles de implementación de los distintos
métodos, referirse a los archivos huffmancoder.h, huffmancoder.cpp,
dcthuffmancoder.h y dcthuffmancoder.cpp. Los cuatro archivos pueden
accederse desde
programacion\proyectofinal.cvs\compressor\src\compressor\encoding

Por otro lado, en el proceso de decodificación, lo que se debe hacer es: dado
un vector binario, devolver un vector de pares que representen la codificación
RLC.

Tuple2 _TQuantity , _TDataType  tuple;


std::vector Tuple2 _TQuantity , _TDataType   output;
UInt32 vectorSize  input.size ();
while ( this-usedBits  vectorSize )
{
tuple  lookup ( input );
postprocess ( output, tuple, input );
};
return output;

 es una tupla de dos elementos.


tuple
 output es un vector que contiene tuplas de dos elementos. Al finalizar el

proceso de decodificación, este vector tendrá todos los pares que


representan la codificación RLC.
 input es un vector binario que contiene la información codificada.

55 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

 representa la posición de búsqueda actual dentro de input.


usedBits
 lookup ( input ) retorna un par (longitud, m): longitud indica la cantidad de

ceros que hay antes de un valor no nulo y m es la cantidad de bits que


utiliza ese valor no nulo.
 postprocess ( output, tuple, input ) postprocesa el par tuple de modo tal de

poder asignarle a output el par (longitud, valor). Lo único que cambia es la


segunda componente, postprocess ( output, tuple, input ) utiliza los m siguientes
bits de input para obtener valor.
Si se desea obtener más información acerca de esta implementación, acceder
a los archivos huffmandecoder.h, huffmandecoder.cpp,
dcthuffmandecoder.h y dcthuffmandecoder.cpp. Estos archivos se
encuentran en
programacion\proyectofinal.cvs\compressor\src\compressor\encoding

Si lo que se desea es obtener información acerca de cómo se implementó el


árbol de códigos Huffman, acceder al archivo huffmantree.h ubicado en
programacion\proyectofinal.cvs\compressor\src\compressor\utils

Compress demo
Esta aplicación ilustra el funcionamiento interno de cada una de las etapas del
pipeline de compresión-descompresión (figura 36). La aplicación permite definir los
valores de un bloque de datos de 8  8 elementos. Según en el modo en que se
esté trabajando, el rango de los valores de las componentes será de 0 a 255
(Image mode) o de -99 a 999 (Numeric mode). Avanzando hacia la derecha del
bloque de datos, la aplicación presenta los distintos estados de la compresión: un
bloque con los coeficientes DCT, un bloque con los coeficientes DCT
cuantificados, la codificación RLC y la codificación Huffman. Avanzando hacia la
izquierda de la codificación Huffman, la aplicación presenta los distintos estados
de la descompresión: codificación RLC, un bloque con los coeficientes DCT
cuantificados, un bloque con los coeficientes DCT, y finalmente un bloque con los
datos recuperados.
A la izquierda de los bloques de datos se encuentra dispuesta verticalmente
una barra de desplazamiento. Al desplazar esta barra hacia arriba, se incrementa
la calidad; al hacerlo hacia abajo, se decrementa.
La tabla de cuantificación que se utiliza es la definida para la luminancia. Esta
tabla, escalada según sea la posición de la barra de desplazamiento, se presenta
debajo del bloque que contiene los datos recuperados.
Si se está trabajando en Image mode, a la izquierda de la barra de
desplazamiento, se presentan dos cuadros, dispuestos verticalmente. El cuadro
superior representa gráficamente al bloque de datos. El cuadro inferior representa
gráficamente al bloque de datos recuperados. Ambos cuadros están en escala de
grises y amplificados para poder observar detalladamente la representación de
cada pixel. Entre medio de los dos cuadros se puede apreciar el factor de

56 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

compresión. Esto se calcula realizando el cociente entre la cantidad de bits


requeridos para almacenar el bloque de datos original —64 pixeles  1 byte  64
bytes  512 bits— y la cantidad de bits requeridos para almacenar la codificación
Huffman.
Para definir los valores del bloque de datos hay varias posibilidades. Llenar
manualmente cada una de las componentes, llenar todo el bloque de modo
aleatorio (Fill | Random generate) o llenarlo con patrones predefinidos (Fill | Fixed
generation). Hay cinco patrones predefinidos: bloque negro (Fill | Fixed generation | Black
square), bloque blanco (Fill | Fixed generation | White square), triangular superior (Fill |
Fixed generation | Upper triangular) —blanco arriba de la diagonal—, triangular inferior
(Fill | Fixed generation | Lower triangular) —blanco debajo de la diagonal— y grilla (Fill |
Fixed generation | Checker) —pixeles blancos y negros alternados.

Figura 36: Compress demo.

Image viewer
Esta aplicación (figura 37) demuestra la utilidad práctica real de la librería
COMPRESSLIB. Permite visualizar y comprimir imágenes en formato BCI.
Además, también puede visualizar imágenes en formato BMP y convertirlas a BCI.
En el extremo superior izquierdo se encuentra un menú principal con dos ítems:
File y View. El primero de ellos se utiliza para: abrir un archivo (File | Open...), cerrar
un archivo (File | Close), guardar un archivo (File | Save), guardar un archivo con otro
nombre (File | Save as...) o para salir de la aplicación (File | Exit). El ítem View sólo se
habilita cuando se abre una imagen en color. Se utiliza para elegir visualizar: la
imagen original, la imagen comprimida y la imagen de error (View | Images); los tres
canales RGB de la imagen original (View | Channels | RGB | Original image); los tres
canales RGB de la imagen comprimida (View | Channels | RGB | Compressed image); el
canal de luminancia y los dos de crominancia de la imagen original (View | Channels |
YUV | Original image); o el canal de luminancia y los dos de crominancia de la imagen
comprimida (View | Channels | YUV | Compressed image).

57 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

Cuando abrimos un archivo —ya sea .bci o .bmp—, se visualizan por defecto
la imagen original, la comprimida y la de error. Además, también se habilita una
barra de desplazamiento horizontal y un botón. Esta barra nos permite cambiar el
factor de compresión —de 0 a 100—, y el botón nos permite aplicar los cambios.
Cuando presionemos el botón, la imagen original se comprimirá con el factor de
compresión elegido, y se actualizará la imagen comprimida. También se
actualizará la imagen de error, que es la diferencia entre la imagen original y la
comprimida. Si la imagen cargada es en color, para la representación de la imagen
de error sólo se utilizará el canal Y. Esto se hace de este modo debido a que este
canal es predominante sobre los otros dos. La diferencia se realiza de esta
manera: PixelError(i,j)  PixelOriginal(i,j) - PixelComprimido(i,j)  128; limitando el
resultado en 0 como mínimo y en 255 como máximo.

Figura 37: Image viewer.

Por debajo del menú principal se encuentra una barra de estados con siete
campos. Cada uno de ellos, de izquierda a derecha, indica:
 Width (ancho): ancho de la imagen, medido en pixeles.

 Height (alto): alto de la imagen, medido en pixeles.

 bpp (bits per pixel - bits por pixel): cantidad de bits necesarios para

representar un pixel de la imagen. Será 8 si la imagen es en escala de


grises y 24 si es en colores.
 Format (formato): formato de la imagen. Sólo puede ser bci o bmp.

 Compression ratio (factor de compresión): factor de compresión de

58 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

la imagen comprimida respecto de lo que ocuparía la imagen sin


comprimir.
 PSNR (Peak Signal to Noise Ratio - relación de la señal de pico

respecto del ruido): una métrica de error. Un valor de PSNR alto es


bueno porque indica que la relación de la señal respecto del ruido es
alta. Aquí, la señal es la imagen original, y el ruido es el error en la
imagen reconstruida. Se calcula del siguiente modo:

PSNR  20  log 10 255 [3.1]


MSE

n−1m−1
∑ ∑ fi, j − Fi, j 2
i0 j0
MSE  nm [3.2]
Donde: fi, j y Fi, j, con 0 ≤ i  n y 0 ≤ j  m, representan una
imagen de n  m pixeles, original y reconstruida respectivamente.
Los valores de la métrica PSNR generalmente varían entre 20 y 40. El
valor en sí mismo no es significativo, sino que se utiliza para comparar la
calidad de distintas imágenes reconstruidas.
 Status (estado): Indica cuál tarea se está llevando a cabo. Existen 4

posibilidades: Idle (estado ocioso), Opening file... (abriendo un archivo),


Saving file... (guardando un archivo) y Updating image... (actualizando las
imágenes).

COMPRESIÓN DE VIDEO
Desde los comienzos de la industria de la animación, lo que los espectadores
percibieron como un flujo continuo de movimiento, fueron en realidad sólo
secuencias de imágenes. El requisito para que esta técnica funcione
correctamente, es que las imágenes cambien lo suficientemente rápido como para
lograr la ilusión de movimiento real.
Hasta hace algunos años, el video digital estaba reservado sólo para
aplicaciones profesionales, la mayoría de los equipos estaban diseñados
principalmente para video analógico. El problema era que las señales analógicas
poseen algunos inconvenientes. Dentro de un ancho de banda dado para una
señal analógica, cualquier forma de onda es válida. Por este motivo, los ruidos
eléctricos —variaciones de tensión, distorsiones, etc.— que puedan interferir en
una señal, no podrán ser detectados. En determinadas ocasiones, se puede inferir
la presencia de ruido en una señal analógica, pero no se puede determinar con
exactitud qué parte de la señal recibida corresponde al ruido y cuál a la señal
original.
Con el transcurso del tiempo, la tecnología comenzó a ser más económica, y
las técnicas digitales en audio y video crecieron rápidamente. La información
digital es más robusta y puede codificarse para eliminar los errores, tanto en los

59 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

procesos de grabación como en los de transmisión. Las técnicas de grabación,


edición y transmisión digital permiten manipulaciones de los datos que son
imposibles en señales analógicas. Una vez que el audio o el video están
digitalizados, se convierten en datos. Estos datos no se pueden diferenciar de
cualquier otra clase de datos, por lo tanto el audio y el video digital se convierten
en un área de estudio muy importante dentro de la computación.
Las imágenes se comprimen para poder transmitirlas más rápido o
almacenarlas más eficientemente. Puesto que el video es una secuencia de
imágenes, la necesidad de compresión es aún mayor. La técnica más básica de
compresión de video podría ser simplemente una secuencia de imágenes
comprimidas. Sin embargo, el factor de compresión que se logra mediante esta
técnica no es muy alto, ya que no aprovecha la redundancia temporal entre
cuadros.

Codificación temporal
Es común encontrar secuencias de video donde las diferencias entre las
imágenes o cuadros (frames) sucesivos son pequeñas. En estos casos, la
correlación entre cuadros es muy grande, y sería redundante almacenar (de aquí
en mas, léase como almacenar o transmitir) cada uno de ellos. Una codificación
predictiva puede reducir gran parte de la redundancia. Lo que se hace entonces,
es almacenar sólo las diferencias. La primer imagen de un video sólo se codifica
utilizando alguna técnica de compresión de imágenes. Para codificar el siguiente
cuadro, se calculan las diferencias y se construye una nueva imagen con esos
datos. A esta nueva imagen se la comprime del mismo modo que a la primera, y
luego recién se la almacena. A las imágenes codificadas mediante predicción se
las denomina inter, mientras que a las codificadas sin predicción se las denomina
intra. El proceso de predicción puede llevarse a cabo con varios cuadros
consecutivos, sin embargo, cada n cuadros inter debe haber un cuadro intra.
Existen varios motivos para esta restricción. El peor de los casos es que, por algún
motivo, se introduzcan errores. Estos errores se propagarán hasta la próxima
imagen intra, por lo tanto el parámetro n no debe ser demasiado grande. Otro
motivo es que en una secuencia de video puede ocurrir un cambio de escena, con
lo cual los cuadros ya no estarán fuertemente correlacionados y la predicción no
brindará beneficios. Otra de las razones se hace evidente a la hora de la
reproducción o edición. En una reproducción, si se desea adelantar o retroceder
rápidamente, el nuevo punto de comienzo será una imagen intra, por lo tanto el
parámetro n dará la granularidad. En la edición, será necesario realizar
decodificaciones y recodificaciones en cascada. Cuanto más grande sea n, mayor
será el tiempo de proceso.

Compensación de movimiento
Cuando en una secuencia de video existen objetos en movimiento o se

60 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

desplaza la pantalla, los valores de algunos pixeles entre un cuadro y el siguiente,


se verán trasladados horizontalmente, verticalmente o en ambas direcciones. La
idea de la compensación o estimación de movimiento es encontrar ese traslado de
posición para poder minimizar las diferencias entre los pixeles de ambos cuadros.
Aplicar esta técnica para cada pixel individual no mejorará la compresión, ya
que deberíamos almacenar cada traslado y cada diferencia, lo cual es muy
ineficiente. Sin embargo, si esta técnica se lleva a cabo para un grupo de pixeles,
se pueden obtener resultados muy favorables. Al desplazar un grupo de pixeles
dentro de un cuadro, de tal modo que las diferencias entre pixeles se vean
minimizadas, se podrán alcanzar factores de compresión muy grandes. Este
desplazamiento deberá ser almacenado junto con los datos comprimidos, pero es
despreciable frente al beneficio obtenido. A este desplazamiento se lo denomina
vector de movimiento, y generalmente se lo representa mediante un par de
números enteros que especifican el corrimiento horizontal y vertical.

Compresión de audio
Generalmente, el audio representa un papel muy importante dentro del video,
tanto semánticamente como físicamente. Por lo tanto, la compresión de audio, si
bien es un área en si misma, está muy relacionada con la compresión de video. La
mayoría de las técnicas de compresión de audio están basadas en la eliminación
de información que es perceptualmente irrelevante. Si bien existen muchos
métodos de compresión sin pérdida [WHITTLE2003], su aplicación es limitada
debido a sus bajos factores de compresión.
La mayoría de las técnicas de compresión de audio con pérdidas utilizan
transformadas —DCT modificada (MDCT), transformada de Fourier, etc.— para
convertir las formas de onda muestreadas en un dominio frecuencial. Una vez
realizada la transformación, las componentes de frecuencia son ponderadas
mediante el cálculo de un umbral de enmascaramiento. Si la energía de la
componente está por debajo de este umbral, se considera que la componente es
irrelevante y no se la codifica. El umbral de enmascaramiento se calcula teniendo
en cuenta el umbral absoluto de audibilidad y los principios de enmascaramiento
frecuencial y temporal. Si la señal a codificar posee múltiples canales, se puede
realizar una compresión entrópica, ya que los distintos canales generalmente
están correlacionados.

Replicación de banda espectral (SBR)


La replicación de banda espectral (en inglés, Spectral Band Replication) es una
nueva herramienta de codificación que mejora la ganancia de los codificadores
perceptuales. La SBR es una técnica de extensión de ancho de banda, donde una
porción importante del ancho de banda de la señal se reconstruye a partir de la
banda baja recibida. A esta técnica la desarrolló una compañía internacional,
Coding Technologies.

61 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

La SBR no es un codificador de audio autocontenido, sino que es un


complemento de los codificadores de audio tradicionales (de aquí en más
codificadores núcleo). La SBR actúa como un preproceso del codificador núcleo y
como un postproceso del decodificador núcleo. En el codificador, la SBR extrae
información importante (datos SBR) para poder asegurar un desempeño óptimo en
el decodificador. Esta información es muy pequeña comparada con la información
total. El codificador núcleo se debe encargar de codificar la banda baja de la señal,
hasta una cierta frecuencia de corte. Todas las frecuencias mayores a la
frecuencia de corte serán reconstruidas por la SBR, mediante los datos SBR y la
banda baja ya decodificada. La combinación de la banda baja —decodificada por
el decodificador núcleo— y la banda alta —reconstruida por la SBR— resulta en
una señal de audio de ancho de banda completo.
El fundamento de la SBR es la existencia de una fuerte correlación entre las
características de la banda alta y la banda baja de una señal. Una señal con series
armónicas fuertes que llegan a la frecuencia de corte, generalmente consistirá de
las mismas series de armónicas en la banda alta, aunque tal vez no tan
pronunciadas como en la banda baja. Del mismo modo, se asume que una señal
ruidosa en la banda baja tendrá el mismo aspecto en la banda ancha. Hay señales
que se desvían de este modelo, pero la SBR posee métodos para manejar estas
situaciones —filtrado inverso, adición adaptativa de ruido, regeneración sinusoidal.
Si se desea estudiar más profundamente esta técnica, referirse a
[EKSTRAND2002].
Los datos SBR se almacenan como datos adjuntos dentro de los datos
generados por el codificador núcleo. Esto permite que los decodificadores núcleo
que no dispongan de SBR puedan seguir siendo capaces de decodificar la señal
—sólo la banda baja.

Formato de video MPEG-2


MPEG (Moving Picture Experts Group) es un grupo de trabajo de ISO/IEC
(International Standards Organisation / International Electrotechnical Commission),
establecido en el año 1988 para desarrollar estándares para los formatos de audio
y video digital. Existen en la actualidad cinco estándares MPEG, algunos en uso y
otros en desarrollo. Cada estándar de compresión fue diseñado teniendo en
cuenta una aplicación y una velocidad de transferencia (bit rate) específico.
El formato MPEG-2 fue diseñado para un bit rate dentro del rango de 1.5
Mbit/seg. a 15 Mbit/seg. Es el estándar en el cual están basados la televisión
digital y la compresión DVD (Digital Video Disk). MPEG-2 es una extensión del
primer estándar MPEG-1, pero está diseñado para la compresión y transmisión de
televisión digital masiva. MPEG-1 es un estándar que consiste de tres partes: 1)
definición de los métodos para la compresión de video; 2) definición de los
métodos para la compresión de audio; 3) definición de un sistema para el
multiplexado del audio y el video, para poder reproducirlos simultáneamente.
MPEG-2 escala bien para la resolución y bit rate requerido para la televisión digital

62 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

de alta calidad (HDTV - High Definition TeleVision).


El formato MPEG-2 se desarrolló con la intención de que sea genérico en el
sentido que sea utilizable por un amplio rango de aplicaciones, bit rates,
resoluciones, calidades y servicios. Durante el desarrollo, se consideraron varios
requerimientos para aplicaciones típicas, y todos ellos fueron integrados en una
misma sintaxis. De todos modos, generalmente no resulta práctico ni económico
implementar hardware capaz de tratar con la totalidad de los requerimientos. Por
esta razón se estipularon los llamados perfiles y niveles, que definen varios
subconjuntos de la sintaxis total.
Comenzaremos realizando una descripción de los distintos perfiles y niveles,
luego estudiaremos las técnicas que utiliza MPEG-2 para comprimir video,
posteriormente el audio y finalmente el multiplexado y sincronización de ambos.

Perfiles y niveles
Los perfiles especifican el tipo de compresión, formato de muestreo, tipos de
cuadros, etc. Dentro de los límites de la sintaxis impuesta por un determinado
perfil, aún es posible definir varias combinaciones que determinarán el desempeño
y complejidad de los codificadores y decodificadores. Para lograr una
especificación concreta, dentro de cada perfil se definen varios niveles. Un nivel
especifica el alto y ancho de la imagen, la cantidad de cuadros por segundo y el bit
rate. Tanto los perfiles como los niveles poseen una estructura jerárquica, y cada
perfil (nivel) deberá soportar en su totalidad a su perfil (nivel) inferior.
[GHANBARI2003] describe mediante tablas los distintos perfiles que define
MPEG-2 y los niveles definidos para cada perfil.

Capas
Anteriormente mencionamos que un perfil y un nivel especifican una
determinada calidad de video. Sin embargo, dentro del bitstream pueden existir
varias capas (tanto de audio como de video). La primera se conoce como capa
base, y puede ser decodificada independientemente. Las otras capas se utilizan
sucesivamente para mejorar la calidad del audio o del video. De este modo, un
decodificador relativamente económico podría reconstruir un video o audio
utilizando sólo la capa base. Cuanto más complejo sea el decodificador, más
capas podrá decodificar y consecuentemente podrá brindar una mayor calidad de
reproducción.
Si los datos están codificados en una única capa, se dice que el bitstream es
no escalable. En caso contrario, se dice que el bitstream posee una jerarquía
escalable. La escalabilidad también puede utilizarse para aumentar la robustez en
la transmisión: se eligen los canales más seguros para la transmisión de las capas
base, y los canales de menor calidad para las capas de menor jerarquía.

63 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

Codificación de video
La organización básica de los datos que conforman un video (bitstream)
consiste de secuencias de video. A su vez, las secuencias de video están
compuestas de bloques de pixeles, macrobloques (MB), rebanadas (slices),
imágenes o cuadros (pictures o frames) y grupos de imágenes (Group Of Pictures
- GOP). El menor elemento, un bloque, consiste de 8 líneas de 8 pixeles cada una.
Los bloques se agrupan en macrobloques, de acuerdo a alguno de los perfiles
predefinidos. Por ejemplo, el macrobloque con formato 4:2:0 posee 4 bloques para
la luminancia, 1 bloque para la componente Cb y un bloque para la componente
Cr. Los macrobloques se agrupan horizontalmente en rebanadas que representan
una porción de una fila de una imagen. Las rebanadas pueden ser tan largas como
una línea completa o tan sólo un único macrobloque. Los cuadros y los GOP
merecen especial atención y serán estudiados a continuación.
Si se desea profundizar en los detalles, [JACK2001] ofrece una descripción
completa del bitstream.

Cuadros I, P, B y D
En el estándar MPEG-1 hay cuatro modos de codificar los cuadros. Los
cuadros I (intra) se codifican como imágenes independientes, similar a una imagen
JPEG. Estos cuadros permiten el acceso aleatorio dentro de un video. Por esta
razón, los cuadros I deberían ocurrir alrededor de dos veces por segundo. Estos
cuadros también deberían utilizarse cuando ocurren cambios de escena.
Los cuadros P (predicted o de predicción) se codifican respecto del cuadro
próximo anterior, que puede ser un cuadro I u otro cuadro P. El resultado es una
codificación predictiva (diferencial) hacia adelante (figura 38). Por este motivo los
cuadros P proveen más compresión que los cuadros I, utilizan compensación de
movimiento y se utilizan como referencia para los cuadros P y B.
Los cuadros B (bidireccionales) utilizan los dos cuadros (I o P) adyacentes
como referencia, logrando una predicción bidireccional (figura 38). Estos cuadros
proveen la mayor compresión y reducen el ruido promediando dos cuadros.
Generalmente hay dos cuadros B separando cuadros I o P.
Los cuadros D (DC) se codifican como imágenes independientes, pero sólo
utilizan las componentes DC de los coeficientes de la DCT. Estos cuadros son
raramente utilizados.
Un grupo de imágenes (GOP - Group Of Pictures) es una serie de uno o mas
cuadros codificados. Un GOP siempre comienza con un cuadro I y termina justo
antes de la aparición del próximo cuadro I. La cantidad de cuadros que componen
un GOP se puede configurar en el proceso de codificación. Cuanto más chico es el
número de cuadros, mejor será la calidad —pues los frames I estarán más cerca
unos de otros—, pero el factor de compresión será menor.
Debido a que los cuadros B necesitan información del pasado y del futuro, el
orden de presentación de los cuadros no será el mismo que el de transmisión. Es

64 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

decir, para poder codificar o decodificar un cuadro B, es necesaria la imagen (I o


P) que le precede y la que le sigue. De este modo, tanto el codificador como el
decodificador dispondrán de la información necesaria para poder tratar a los
cuadros B (figura 38).

Figura 38: Cuadros I, P y B.

Compensación de movimiento
La compensación de movimiento mejora la compresión de los cuadros P y B
por medio de la eliminación de las redundancias que existen entre dos cuadros.
Funciona a nivel de macrobloques. La técnica de compensación de movimiento se
basa en el hecho de que dentro de una secuencia corta de video, la mayoría de los
objetos permanecerán en la misma posición, mientras que otros sólo se moverán
en una distancia corta. El movimiento se describe como un vector bidimensional.
Este vector especifica de qué lugar de un cuadro previamente decodificado,
recuperar un macrobloque para poder predecir los valores de las muestras del
macrobloque actual.
Luego de que un macrobloque se comprima utilizando compensación de
movimiento, contendrá una diferencia espacial (el vector de movimiento) y
diferencias de contenido (términos de error), respecto del macrobloque de
referencia.
Cabe destacar que existen casos donde cierta información en una escena no
puede predecirse de un cuadro anterior. Esto se produce cuando un objeto en
movimiento descubre algo que estaba tapando —una puerta que se abre— o al
introducirse un objeto nuevo en la escena —un conejo que sale de su madriguera.
En estos casos, cuando un macrobloque en un cuadro P no se puede representar
mediante compensación de movimiento, se codifica del mismo modo que se
codificaría en un cuadro I. Es decir, simplemente se almacena esa porción de la

65 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

imagen, comprimida sin utilizar codificación temporal.


Los macrobloques de los cuadros B se pueden codificar utilizando como
referencia al cuadro previo o al siguiente, lo cual lleva a cuatro modos distintos de
codificación:
 Codificación intra sin compensación de movimiento.

 Predicción hacia adelante, con el cuadro (I o P) anterior como

referencia.
 Predicción hacia atrás, con el cuadro (I o P) siguiente como

referencia.
 Predicción bidireccional, utilizando dos cuadros (I o P) como

referencia: el anterior y el siguiente.


La predicción hacia atrás se utiliza en los casos que se introduce un nuevo
objeto en la escena o cuando algún objeto en movimiento deja al descubierto un
área nueva.

Codificación de audio
MPEG-1 utiliza una familia de tres esquemas de codificación de audio,
llamados capa 1, capa 2 y capa 3, incrementándose la complejidad y la calidad en
cada una. Estas son capas jerárquicas escalables; la capa 1 es la capa base y las
otras dos se utilizan para mejorar la calidad. Todas las capas soportan audio digital
de 16 bits, utilizando muestreos de 32, 44.1 o 48 kHz. La capa 1 es una versión
simplificada de la capa 2 y posee un bit rate dentro del rango de 32 a 448 kbps. La
capa 2 tiene un bit rate dentro del rango de 8 a 384 kbps y fue diseñada para
balancear la calidad del sonido con la complejidad del codificador. La capa 3
—también conocida como MP3, de MPeg capa 3— posee un bit rate de 8 a 320
kbps. Esta capa especifica un conjunto de características avanzadas que
persiguen un mismo objetivo: preservar tanto como sea posible la calidad del
sonido, incluso a bit rates relativamente bajos.
MPEG-1 soporta hasta dos canales de audio y cuatro modos de operación en
total:
1. Modo monofónico para un único canal de audio.
2. Modo monofónico dual para dos canales de audio independientes
—funcionalmente igual al modo estéreo.
3. Modo estéreo normal. En este modo, un canal lleva la señal de audio
izquierda y el otro canal lleva la señal de audio derecha. Cada canal se
codifica de manera independiente.
4. Modo joint-estéreo. Este modo aprovecha la correlación entre los
dos canales, la irrelevancia de la diferencia de fase, o ambas. Posee dos
modos de codificación: intensity y ms. Para el primer modo —soportado
por todas las capas—, las frecuencias altas (por encima de 2 kHz.) se
combinan. Para el segundo modo —sólo soportado por la capa 3—, un
canal transporta la suma de las señales (izquierda  derecha) y el otro la
diferencia (izquierda - derecha).

66 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

El estándar MPEG-2 extiende al estándar MPEG-1 del siguiente modo:


 Soporte para audio multicanal: Se dispone de cinco canales de alta

fidelidad, mas un canal extra que mejora la calidad en las frecuencias


bajas (también conocido como 5.1 canales), de este modo permite la
compresión del audio de la televisión de alta definición (HDTV) o
películas digitales.
 Soporte para audio multilenguaje: Soporte para siete canales

adicionales para comentarios. Los canales de comentarios poseen un


muestreo igual a la mitad de los muestreos de los canales de alta
fidelidad.
 Bit rates de compresión más bajos: Soporta bit rates adicionales de

tan sólo 8 kbits/seg.


 Muestreos de audio más bajos: Incluye nuevos muestreos de audio de

16, 22.05 y 24 kHz.

En el proceso de codificación, la entrada de audio pasa a través de un banco


de filtros que separan la señal en múltiples subbandas de frecuencia.
Simultáneamente, la entrada de audio pasa a través de un modelo psicoacústico
que determina el factor de energía de la señal respecto del umbral de
enmascaramiento de cada subbanda. El coeficiente de señal respecto del
enmascaramiento se utiliza para determinar la cantidad de bits que se utilizarán en
la cuantificación de las señales en las subbandas. Finalmente, se toma la
representación de las muestras de las subbandas cuantificadas y se las codifica.
La clave de la compresión de audio MPEG es el banco de filtros. Este banco de
filtros divide la señal de audio en 32 subbandas con el mismo ancho. Los filtros
son relativamente simples y proveen una buena resolución de tiempo con una
resolución de frecuencia razonable. El diseño posee tres puntos débiles que vale
la pena mencionar:
 Primero, el hecho de que las subbandas sean del mismo ancho, no

refleja exactamente el comportamiento dependiente de la frecuencia del


sistema auditivo humano. El ancho de una banda crítica en función de la
frecuencia es un buen indicador de este comportamiento. En las
frecuencias bajas, una sola subbanda cubre varias bandas críticas. Bajo
estas circunstancias, el número de bits de cuantificación debe ser
especificado por la banda que posea el menor enmascaramiento de
ruido.
 Segundo, el banco de filtros y sus inversas no son transformaciones

sin pérdida. Incluso sin realizar ninguna cuantificación, es imposible


recuperar perfectamente la señal original. Sin embargo, el error
introducido por el banco de filtros es pequeño e inaudible.
 Tercero, las bandas de filtros adyacentes presentan un solapamiento

importante de frecuencias. Por lo tanto, una señal con una única


frecuencia podría afectar la salida de dos filtros adyacentes.

Modelo psicoacústico

67 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

El modelo psicoacústico analiza la señal de audio y computa la cantidad de


enmascaramiento de ruido disponible como una función de la frecuencia. El
codificador utiliza esta información para decidir como representar la señal de
entrada con una cantidad limitada de bits. El estándar MPEG provee dos
implementaciones de modelos psicoacústicos a modo de ejemplo. El modelo 1 es
más sencillo y toma varias decisiones de compromiso para simplificar los cálculos.
Cualquiera de los dos modelos sirve para la compresión de todas las capas. Sin
embargo, sólo el modelo 2 incluye modificaciones específicas para poder lograr un
buen desempeño en la capa 3.
A continuación se destacan los principales pasos involucrados en los cálculos
psicoacústicos.
 Alineación temporal de los datos de audio: Los datos enviados al

modelo psicoacústico deben ser concurrentes con los datos procesados


por el banco de filtros.
 Conversión de la representación del audio a un dominio frecuencial:

El modelo psicoacústico necesita utilizar una representación frecuencial


distinta a la utilizada por el banco de frecuencias. Esto se debe a que
necesita una mayor precisión frecuencial para poder calcular los
umbrales de enmascaramiento de un modo más exacto. Ambos modelos
psicoacústicos utilizan la transformada de Fourier.
 Procesamiento de los valores espectrales, agrupados de acuerdo al

ancho de las bandas críticas: Para simplificar los cálculos


psicoacústicos, ambos modelos procesan los valores frecuenciales
discretizados en cantidades perceptuales.
 Separar los valores espectrales en componentes tonales y no tonales:

Ambos modelos identifican y separan las componentes tonales de las


ruidosas, porque el enmascaramiento de las dos clases de señales es
diferente.
 Aplicar una función de distribución: El enmascaramiento para una

señal dada se distribuye sobre alrededor de la banda crítica. El modelo 1


determina el umbral de enmascaramiento de ruido aplicando primero un
enmascaramiento determinado empíricamente. El modelo 2 lo hace
aplicando una función de distribución a las componentes de la señal.
 Especificar un límite inferior para los valores de umbral: Ambos

modelos incluyen un umbral de enmascaramiento absoluto (en silencio)


determinado empíricamente. Este umbral es el límite inferior para la
audibilidad del sonido.
 Encontrar el umbral de enmascaramiento para cada subbanda:

Ambos modelos calculan los umbrales de enmascaramiento con una


resolución frecuencial mayor que la utilizada por el banco de filtros. Para
varias frecuencias dentro de una subbanda se calculan muchos
umbrales de enmascaramiento. De todos ellos se elige uno como el
valor de umbral de la subbanda. El modelo 1 elige el menor de los
valores. El modelo 2 tiene en cuenta el ancho relativo de la banda
respecto de la banda crítica.
 Calcular el coeficiente de la señal respecto del enmascaramiento: Los

modelos calculan este coeficiente como el valor de la energía de la señal


dentro de la subbanda (para la capa 3, dentro de un grupo de

68 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

subbandas) dividido por el mínimo umbral de enmascaramiento para esa


subbanda.

Si se desea profundizar en los modelos psicoacústicos, en el banco de filtros, o


en detalles más específicos de la codificación de audio, referirse a [PAN1996].

Multiplexado y sincronización de audio y video


Una vez que se dispone de la información comprimida, antes de almacenarla o
transmitirla, se debe multiplexar el audio, el video y la información del sistema. A la
salida de un codificador de audio o video MPEG, se la llama tren elemental
(elementary stream). Una señal de televisión tradicional, generalmente está
compuesta por tres trenes elementales: uno que transporta video codificado, otro
que transporta audio estéreo codificado y otro que transporta datos de teletexto
(información acerca del programa que se esté emitiendo). Dentro del contexto de
los medios de comunicación, un programa es generalmente una de las distintas
unidades temáticas de una emisión de radio o televisión —por ejemplo, un
noticiero o una novela. Sin embargo, MPEG utiliza la palabra programa para
identificar una única emisora o canal.
A continuación analizaremos distintos aspectos necesarios para poder
comprender cómo se realiza el multiplexado y la sincronización del audio y del
video. Si se desea un estudio más detallado, consultar [JACK2001],
[TEKTRONIX97] y [SARGINSON1996].

Trenes de programa y de transporte


MPEG-2 define dos alternativas para el multiplexado. Una de ellas se llama
tren de transporte, a la otra se la denomina tren de programa. Cada una está
optimizada para determinadas clases de aplicaciones.
Un tren elemental empaquetado (Packetised Elementary Stream - PES) es una
estructura de datos básica común a la organización de los trenes de programa y
de transporte. Un paquete PES se genera empaquetando los trenes continuos de
audio y video comprimido.

Tren de programa
Este multiplexado se basa en el único definido por MPEG-1 y sólo puede estar
compuesto por un único programa. La definición de MPEG-2 utiliza una sintaxis
modificada que permite nuevas funcionalidades como, por ejemplo la
escalabilidad. El propósito de este multiplexado es el almacenamiento y
recuperación de video en medios digitales.
Un tren de programa debe utilizarse en ambientes libres de error, pues es
bastante susceptible a los errores. Uno de los motivos es que los trenes de

69 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

programa están compuestos de una sucesión de paquetes relativamente largos.


Cada paquete comienza con un encabezado. Si se produce un error en el
encabezado, posiblemente cause la pérdida del paquete completo. Como los
paquetes de un tren de programa pueden contener varios kilobytes de datos (hasta
un máximo de 64), la pérdida de un único paquete podría representar un grave
problema. El otro motivo es que los paquetes pueden ser de longitud variable, lo
cual le impide a los decodificadores la predicción de las finalizaciones y comienzos
de éstos. Por lo tanto, los decodificadores deberán obtener esta información del
encabezado de cada paquete. Si se corrompe el campo que almacena la
información de la longitud del paquete, se perderá el sincronismo, y la información
de al menos un paquete.
Los decodificadores de MPEG-2 pueden reproducir todos los trenes MPEG-1.
Sin embargo, MPEG-2 incluye varias características no soportadas por MPEG-1.
Algunas de ellas son la encriptación (scrambling) de los datos, la asignación de
prioridades a los paquetes, información de copyright, etc.

Tren de transporte
Un único tren de transporte puede contener varios programas independientes.
Por lo tanto, este modo de multiplexado está dirigido para aplicaciones que
necesiten soporte para múltiples programas, tales como la transmisión de
televisión.
Los trenes de transporte están compuestos de una sucesión de paquetes de
longitud fija de 188 bytes, llamados paquetes de transporte. La utilización de
paquetes cortos y de longitud fija indica que los trenes de transporte no son tan
sensibles a los errores como lo son los trenes de programa. Esto hace que los
trenes de transporte sean aptos para la utilización en ambientes propensos a
errores, como transmisión de televisión —tanto satelital como por cable—,
transmisión por redes, etc.
Podría parecer que los trenes de transporte son una mejor opción que los
trenes de programa, pues son capaces de transmitir múltiples programas y son
menos susceptibles a los posibles errores. Sin embargo, el multiplexado de los
trenes de transporte es mucho más complicado que el multiplexado de los trenes
de programa, y del mismo modo es más difícil crearlos y demultiplexarlos.

Unidades de presentación y de acceso


Se le llama unidad de presentación (presentation unit) a cada imagen o bloque
de sonido decodificado, según se trate de video o audio respectivamente. Los
codificadores comprimen cada unidad de presentación generando las llamadas
unidades de acceso (access unit). Cabe destacar que las unidades de acceso de
video no son de un tamaño fijo, sino que depende de qué clase son —I, P, B o D—
y del contenido de la imagen. Cada unidad de acceso de audio contiene
generalmente algunas decenas de milisegundos de audio comprimido.

70 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

El resultado de una codificación MPEG de una secuencia de video es una


sucesión de unidades de acceso de video. A esta sucesión se la denomina tren
elemental de video (video elementary stream).
Análogamente, el resultado de codificar audio mediante MPEG, es una
sucesión de unidades de acceso de audio. A esta sucesión se la llama tren
elemental de audio (audio elementary stream).

Trenes elementales empaquetados (PES)


En la creación de cualquiera de las dos clases de multiplexado de MPEG-2,
cada tren elemental debe convertirse en un tren elemental empaquetado (PES).
Un PES está compuesto estrictamente de una sucesión de paquetes PES.
Un paquete PES está compuesto de un encabezado y a continuación un
bloque de datos (payload). El payload consiste simplemente de bytes de datos
tomados secuencialmente del tren elemental original. No existe ningún
requerimiento en la alineación del comienzo de una unidad de acceso con el
comienzo del payload de un paquete PES. De este modo, una nueva unidad de
acceso puede comenzar en cualquier punto del payload de un paquete PES.
También es posible que un paquete PES contenga varias unidades de acceso
pequeñas.
Los paquetes PES pueden ser de longitud variable hasta un máximo de 64
kilobytes —una excepción a esto es un paquete PES de video en un tren de
transporte, que no posee longitud máxima. El diseñador de un multiplexor MPEG-2
tiene la libertad de elegir la longitud de los paquetes.
El encabezado de un paquete PES posee una gran cantidad de campos. A
continuación describiremos los más importantes.
 Packet start code prefix (código prefijo de comienzo de paquete):

Este campo de 24 bits posee un valor fijo de 000001H y, en conjunto con


el campo stream ID, indica el comienzo de un paquete.
 stream ID (identificador de tren): Este campo de 8 bits distingue los

paquetes PES pertenecientes a distintos trenes elementales.


 Flags (banderas): Las banderas son bits que se utilizan para indicar la

presencia o ausencia de varios campos opcionales que puede incluir un


paquete PES. Estos campos opcionales pueden contener información de
copyright, prioridad relativa, encriptación de datos, etc. Hay una bandera
que consiste de dos bits e indica la presencia o ausencia de estampillas
de tiempo. Un valor de 10 indica la presencia de un campo que contiene
una estampilla de tiempo de presentación (Presentation Time Stamp -
PTS) dentro del encabezado. Un valor de 11 indica la presencia de un
campo PTS y de un campo que contiene una estampilla de tiempo de
decodificación (Decoding Time Stamp - DTS). Un valor de 00 indica la
ausencia de ambos campos. Las estampillas de tiempo conforman el
mecanismo que asegura el sincronismo entre los trenes elementales
relacionados.
 PES header data length (longitud de los datos del encabezado PES):

Este campo de 8 bits indica la cantidad de bytes utilizados en campos

71 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

opcionales del encabezado PES.

Multiplexado del tren de programa


En un tren de programa, los paquetes PES obtenidos de los distintos trenes
elementales se agrupan en packs. Un pack está compuesto de un encabezado
pack (pack header), un encabezado de sistema (system header) opcional y un
número arbitrario de paquetes PES, tomados secuencialmente de cualquiera de
los trenes elementales, en cualquier orden. No existe ninguna restricción en la
longitud de un pack, excepto que debe ocurrir un encabezado pack al menos cada
0.7 segundos. Esto se debe a que los encabezados de sistema contienen
información acerca del tren de programa —máxima velocidad de transferencia,
cantidad de trenes elementales de audio y de video, información de temporización,
etc. Un decodificador puede utilizar esta información para determinar si es capaz
de decodificar el tren de programa o no.

Multiplexado del tren de transporte


Un tren de transporte puede contener muchos programas diferentes, y cada
uno puede utilizar un factor de compresión y un bit rate que pueden variar
dinámicamente, siempre y cuando el bit rate total se mantenga constante. A esto
se lo denomina multiplexado estadístico, y permite que un programa difícil de
comprimir ocupe ancho de banda de otro que esté manipulando información más
fácil de comprimir. Algunos programas pueden estar protegidos de modo tal que
sólo puedan ser vistos por aquellos clientes que hayan pagado alguna tarifa
adicional. Para llevar a cabo esto, el tren de transporte puede contener información
de acceso condicional (Conditional Access - CA) dentro de la información
específica de programa (Program Specific Information - PSI).
El multiplexado del tren de transporte consiste estrictamente de paquetes de
transporte de longitud fija y corta —188 bytes. Un paquete de transporte está
constituido por un encabezado de 4 bytes, seguido de un campo de adaptación, un
payload o ambos. En un tren de transporte, los paquetes PES provenientes de los
distintos trenes elementales se dividen entre los payload de varios paquetes de
transporte. Esta división está sujeta a dos restricciones: 1) el primer byte de cada
paquete PES debe comenzar en el primer byte del payload de un paquete de
transporte; 2) Un paquete de transporte puede llevar datos de sólo un paquete
PES. En realidad, cada una de estas restricciones implica a la otra, pero se
especifican las dos para una mejor comprensión.
Es muy difícil que un paquete PES pueda dividirse exactamente en un número
entero de paquetes de transporte. Generalmente, el último paquete de transporte
no podrá completar su payload de 184 bytes. Para respetar las dos restricciones
anteriores y teniendo en cuenta que los paquetes de transporte son de longitud
fija, el espacio que sobra simplemente se descarta mediante el campo de
adaptación de una longitud acorde.

72 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

Todos los PES que deben ser multiplexados juntos se convierten en paquetes
de transporte de este modo. Un tren de transporte se genera tomando
secuencialmente los paquetes de transporte resultantes. Dentro del tren de
transporte también pueden haber paquetes de transporte con información de
servicio y paquetes nulos. No existe ninguna restricción en cuanto al orden en que
se agrupan los paquetes de transporte dentro del multiplexado, excepto que se
respete el orden cronológico de los paquetes pertenecientes al mismo tren
elemental.

Encabezado del paquete de transporte


Cada paquete de transporte comienza con un encabezado de 4 bytes. De
todos los campos que posee, analizaremos los más importantes.
 Sync Byte (byte de sincronización): Es el primer byte del encabezado

del paquete y siempre contiene el valor 47H (01000111 en binario). Si


bien este valor puede repetirse dentro de un paquete de transporte, el
hecho de que se repetirá cada 188 bytes le permite a los decodificadores
ajustarse a esta frecuencia para poder identificar los comienzos de cada
nuevo paquete de transporte.
 PID (Packet IDentifier - identificador de paquete): Este campo de 13

bits se utiliza para distinguir los paquetes de transporte que contienen


datos de un tren elemental de aquellos que contienen datos de otros
trenes elementales. De los 2 13  8192 valores posibles, 17 están
reservados. De este modo, son 8175 los valores que se le pueden
asignar a los distintos trenes elementales, y por lo tanto esta es la
cantidad máxima de trenes elementales distintos que pueden componer
un tren de transporte.
 Payload Unit Start Indicator (indicador de unidad de comienzo): El

significado de este bit es dependiente del payload. Para datos de un


paquete PES, un 1 indica que el primer byte del payload es también el
primer byte del paquete PES. Para datos PSI, un 1 indica que el bloque
de datos del paquete contiene el primer byte de una sección PSI.
 Continuity Count (contador de continuidad): Este campo de 4 bits se

incrementa con la ocurrencia de paquetes pertenecientes al mismo tren


elemental (paquetes con el mismo PID). Esto le permite a los
decodificadores, detectar la pérdida de los paquetes de transporte y
eventualmente corregir —u ocultar— los errores. Cuando se llega al
máximo, la cuenta vuelve a cero.

Información específica de programa (PSI)


Dentro de un tren de transporte, cada paquete de transporte posee un PID que
indica el origen de los datos de su payload. Pueden haber muchos trenes
elementales que conformen varios programas distintos. Para poder discernir cuál
tren elemental pertenece a cuál programa, se incluye información adicional dentro
del tren de transporte, para hacer explícita la relación entre los programas

73 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

disponibles y los PID de los trenes elementales que los componen. Esa
información adicional se denomina PSI y debe estar presente en cada tren de
transporte.
La PSI especificada por MPEG-2 está compuesta por cuatro tablas.
1. PMT (Program Map Table - tabla de mapeo de programa): Cada
programa posee una PMT asociada. Esta tabla brinda detalles acerca de
los trenes elementales que lo comprenden. Además, la PMT puede
contener descriptores que ofrecen información adicional, como por
ejemplo parámetros de codificación de audio y de video, identificación de
lenguaje, detalles de acceso condicional, información de copyright, etc.
2. PAT (Program Association Table - tabla de asociación de programa):
Esta tabla contiene una lista de todos los programas disponibles en el
tren de transporte. Esta tabla siempre se encuentra en los paquetes de
transporte que poseen el PID igual a cero. Por cada programa listado, se
informa el PID de la PMT que le corresponde.
3. NIT (Network Information Table - tabla de información de red): El
programa número cero posee un significado especial dentro de la PAT.
Se utiliza para apuntar a la NIT. Esta tabla es opcional y su contenido es
privado —definido por el usuario, no por MPEG. Cuando esta tabla está
presente, brinda información física acerca de las redes que transportan el
tren de transporte —frecuencias de los canales, características de
modulación, etc.
4. CAT (Conditional Access Table - tabla de acceso condicional): Si
algún tren elemental dentro del tren de transporte está encriptado,
entonces esta tabla debe estar presente. Brinda detalles acerca del
sistema de scrambling utilizado y provee los PID de los paquetes de
transporte que contienen acceso condicional.

Buffers del codificador y del decodificador


Anteriormente hemos mencionado que no todas las unidades de acceso de
video son del mismo tamaño. Esto depende de la clase de cuadro que representan
—I, P, B o D— y del contenido de la imagen. Por lo tanto, un codificador de video
genera un número de bits variable por imagen. Este bit rate variable generalmente
se suaviza por medio de un buffer que actúa como una cola —buffer First In First
Out.
Se puede pensar que la disposición de las celdas está ordenada alrededor de
la circunferencia de un reloj de agujas —cola circular. Una de las agujas
representará al puntero de escritura y la otra al puntero de lectura. El puntero de
escritura no se mueve alrededor del reloj a una velocidad constante, sino que
avanza sobre el reloj a pasos de tamaño variable, pues cada paso representa la
escritura de una unidad de acceso completa. El puntero de lectura gira siguiendo
al de escritura, pero a una velocidad constante, de modo tal de leer los datos del
buffer a un bit rate constante. En el codificador hay una realimentación que
asegura que el puntero de escritura esté siempre por delante del de lectura, pero

74 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

no tanto como para que se produzca un overflow.


Entonces, la función del buffer del codificador es suavizar la salida de video
para producir un bit rate constante. Este nuevo tren elemental de video de bit rate
constante se transmite a través de un multiplexado de tren de transporte MPEG-2
hacia un decodificador de video. El decodificador de video también posee un buffer
que actúa como una cola. Teóricamente, el buffer del codificador y el del
decodificador son del mismo tamaño. En el buffer del decodificador, es el puntero
de escritura quien gira a velocidad constante, a medida que escribe los datos que
llegan con un bit rate constante. Detrás de éste, gira el puntero de lectura, que se
mueve alrededor de la cola circular de un modo irregular, dependiendo del tamaño
de las unidades de acceso. Realiza un movimiento por cada período de imagen,
de este modo se elimina una imagen del buffer, se decodifica y se presenta al
usuario.
Es fundamental que el decodificador elimine las unidades de acceso del buffer
precisamente en el momento adecuado. Si el decodificador lee unidades de
acceso del buffer demasiado temprano, se producirá un underflow en el buffer; si
lo hace demasiado tarde, se producirá un overflow.
En la práctica, MPEG-2 define un sistema de estampillas de tiempo y
referencias de reloj, que le permiten al decodificador determinar el momento
preciso en el cual debe eliminar una unidad de acceso del buffer. Un decodificador
que utilice las estampillas de tiempo de un modo adecuado podrá presentar las
imágenes decodificadas en sincronismo con el audio decodificado sin sufrir
overflow o underflow en el buffer.

Estampillas de tiempo y referencias de reloj


En la figura 39 [SARGINSON1996] se puede observar un decodificador de
MPEG sencillo capaz de extraer y reproducir video y audio, ya sea desde un tren
de programa o desde un tren de transporte. Los interruptores están controlados de
modo de identificar los paquetes —de transporte dentro de un tren de transporte o
los paquetes PES dentro de un tren de programa— que contienen los datos de
video o audio de los trenes elementales deseados. Un interruptor sólo permite
almacenar dentro del buffer aquellos bytes de datos que provengan de los trenes
elementales correctos. Cuando se le solicita, el decodificador de video toma una
unidad de acceso de video del buffer, la decodifica y la muestra en pantalla.
Análogamente, el decodificador de audio puede decodificar cada unidad de acceso
de audio y reproducir algunos milisegundos de audio.

75 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

Figura 39: Decodificador de MPEG.

Un decodificador podrá decodificar cada unidad de acceso de acuerdo a


estampillas de tiempo. Éstas determinan el momento exacto en el cual una unidad
de acceso debe ser eliminada del buffer y decodificada. Un decodificador que hace
un uso correcto de las estampillas de tiempo, podrá decodificar las unidades de
acceso manteniendo el sincronismo con los demás trenes elementales que
componen el programa.
Una estampilla de tiempo es, básicamente un valor que representa un tiempo.
Una función del multiplexor es asignarle estampillas de tiempo a las unidades de
acceso que produce un codificador. Para realizar esto, un codificador debe tener
un reloj de referencia. El tiempo actual se mantiene gracias a un reloj preciso
dentro del multiplexor. Cada vez que se genera una nueva unidad de acceso, se le
asigna una estampilla de tiempo basada en el tiempo actual.
Para poder interpretar las estampillas de tiempo, el decodificador debe tener su
propio reloj. De este modo, el decodificador podrá determinar exactamente en qué
momento decodificar una unidad de acceso en particular. Es fundamental que el
reloj del decodificador esté en exacto sincronismo con el reloj del codificador. Esto
se logra incluyendo muestras regulares del tiempo actual del reloj del multiplexor.
El decodificador utiliza estas muestras para chequear y corregir su reloj.
Los relojes utilizados tanto en los codificadores como en los decodificadores,
no miden el tiempo en horas, minutos y segundos, sino que en unidades de 27
MHz. Una estampilla de tiempo es un número de 33 bits que es una muestra de un
contador con una frecuencia de 90 kHz. Esta frecuencia se obtiene dividiendo el
reloj de 27 MHz. por 300.
En un tren de programa, al reloj del multiplexor se lo denomina reloj de sistema
(system clock). A las unidades de acceso en todos los trenes elementales del

76 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

programa se les asignan estampillas de tiempo basadas en este reloj de sistema.


Dentro del tren de programa se introduce regularmente —en el encabezado de los
paquetes PES— muestras del reloj de sistema, y se utilizan para que el reloj del
decodificador pueda mantenerse sincronizado. A estas muestras se las llama
referencias del reloj de sistema (System Clock Reference - SCR) y deben ocurrir
dentro del tren de programa al menos una vez cada 0.7 segundos.
La otra alternativa de multiplexado de MPEG-2, el tren de transporte, puede
contener muchos programas independientes. Cada programa posee su propio reloj
independiente, denominado reloj de programa, y no es necesario que esté
sincronizado con los relojes de los demás programas. A las unidades de acceso
que componen un programa se les asignan estampillas de tiempo basadas en el
reloj de programa correspondiente. A las muestras de cada reloj de programa se
las denomina referencias del reloj de programa (Program Clock Reference - PCR),
y se transmiten en el tren de transporte. Estas muestras le permiten al
decodificador sincronizar su reloj con el reloj del programa a decodificar. MPEG
requiere que se envíe una PCR al menos 10 veces por segundo. Para determinar
exactamente cuáles paquetes transportan una PCR para un programa en
particular, debe consultarse la PMT de ese programa.

Estampilla de tiempo de presentación (PTS)


En realidad, existen dos clases de estampillas de tiempo. La primera y más
importante es la estampilla de tiempo de presentación (Presentation Time Stamp -
PTS). Especifica el momento en el cual una unidad de acceso debe eliminarse del
buffer del decodificador, decodificarse y presentarse al usuario. MPEG asume que
este proceso puede llevarse a cabo instantáneamente, sin embargo en la práctica,
la transferencia de los datos y la decodificación consumen tiempo, y es
responsabilidad del diseñador del decodificador tener en cuenta estos detalles.
Para muchas clases de trenes elementales, las PTS son las únicas estampillas
de tiempo que se necesitan. Sin embargo, para el caso de los trenes elementales
que transportan video, puede necesitarse otro tipo de estampilla de tiempo llamada
estampilla de tiempo de decodificación (Decoding Time Stamp - DTS).

Estampilla de tiempo de decodificación (DTS)


Una DTS especifica el tiempo en el cual una unidad de acceso —una imagen—
debe eliminarse del buffer del decodificador y decodificarse, pero no presentada al
usuario. La imagen decodificada se almacena temporariamente en un buffer
secundario para presentarla en un tiempo posterior. Este tratamiento es necesario
sólo para las imágenes de tipo I y P, cuando están separadas por imágenes de
tipo B.
Una DTS nunca ocurre de modo aislado, sino que siempre acompañada de una
PTS. Aquí, la PTS indica cuándo la imagen decodificada debe ser eliminada del
buffer secundario y presentada al usuario. Por lo tanto, la PTS siempre debe ser

77 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

mayor que la DTS, pues la presentación de la imagen siempre ocurrirá luego de la


decodificación.

Asignación de estampillas de tiempo


No es necesario que cada una de las unidades de acceso tenga una estampilla
de tiempo asociada. Un decodificador generalmente sabrá por adelantado la
frecuencia con que las unidades de acceso deben ser decodificadas. Por lo tanto,
alcanza con asignarle una estampilla de tiempo a las unidades de acceso sólo
ocasionalmente, simplemente para asegurar que el proceso de decodificación
mantenga el sincronismo de largo plazo. La restricción que impone MPEG es que,
en un PES de audio o de video, debe ocurrir una estampilla de tiempo al menos
cada 0.7 segundos.
Tanto en el tren de programa como en el tren de transporte, las estampillas de
tiempo se transmiten dentro de campos opcionales de los encabezados de los
paquetes PES. Si una unidad de acceso posee una estampilla de tiempo asociada,
entonces esta estampilla de tiempo se codifica en el encabezado del paquete PES
que contiene el principio de la unidad de acceso.

Librerías de reproducción de video MPEG


Aquí hablaremos acerca de las librerías de reproducción de video MPEG. Si
bien este formato es un estándar muy conocido y utilizado, no resulta sencillo
encontrar en la Internet librerías libres de licencia. Además, de las pocas que se
pueden encontrar, no se dispone de una buena documentación. Algunas, como la
librería mpeglib (mpeglib.sourceforge.net), están desarrolladas para un sistema
operativo en particular —Linux—, lo cual reduce el campo de utilización. La librería
SMPEG (www.lokigames.com) es multiplataforma, pero no todas las
funcionalidades están implementadas para cada una de las plataformas
soportadas —el modo fullscreen sólo está implementado para el driver de video de
X11. Más grave aún, la librería libmpeg2 (libmpeg2.sourceforge.net) sólo
implementa la decodificación de video, sin tener en cuenta el audio.
Más allá de los problemas mencionados, una librería nos ahorra mucho tiempo
en el desarrollo de un reproductor de video. No sería viable llevar a cabo un
desarrollo desde cero ("from scratch"), si es que se desea terminar el proyecto en
un tiempo moderado. Para esta clase de desarrollos se necesita mucho tiempo,
muchos recursos humanos, mucho equipamiento y sobre todo un profundo
conocimiento del formato.
Si se opta por la utilización de una librería, los requerimientos para llevar
adelante el proyecto se reducen notablemente. En cuanto a los conocimientos, no
sería necesario un manejo de los detalles de bajo nivel del formato, ya que la
librería se encarga de eso.
A continuación estudiaremos la librería SMPEG y analizaremos brevemente su
funcionamiento mediante un reproductor de videos.

78 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

Librería SMPEG
La librería SMPEG (SDL MPEG), de Loki Software, es el resultado de un
proyecto Open Source y se ofrece bajo la licencia pública LGPL. Está basada en el
software de decodificación de video MPEG mpeg_play v2.2 —de UC Berkeley— y
en el decodificador de audio MPEG SPLAY —creado por Woo-jae Jung.
SMPEG es capaz de reproducir video y audio MPEG en sistemas Pentium II o
superiores, pues en sistemas más lentos no se logra un desempeño satisfactorio.
A la fecha del último release —versión 0.4.4, 28 de septiembre de 2000— sólo se
había testeado en el sistema operativo Linux. La única documentación de la que
se dispone se encuentra en el archivo smpeg.h para la interfase en C y en los
archivos MPEG*.h para la interfase en C. Todos estos archivos pueden
encontrarse en el directorio librerias de
mpeg\www.lokigames.com\smpeg-0.4.4. Cabe destacar que la última versión
de esta librería requiere la versión 1.2.0 o posterior de la librería SDL (Simple
DirectMedia Layer - www.libsdl.org) para poder compilar.
SDL brinda una API que provee facilidades para la programación multimedia
—teclado, mouse, joystick, audio, hardware 3D via OpenGL, etc. Está escrita en C,
pero posee bindings para otros lenguajes —C#, Java, Perl, etc. Además, la
versión actual soporta varios sistemas operativos tales como Windows, Linux,
Solaris, QNX y otros. La documentación puede encontrarse en los archivos *.h,
situados en el directorio librerias de
mpeg\www.lokigames.com\SDL\SDL-1.2.8\include, o en formato html
mediante el archivo index.html, situado en el directorio librerias de
mpeg\www.lokigames.com\SDL\SDL-1.2.8\docs.
Veamos ahora cómo utilizar las funcionalidades más importantes de SMPEG
mediante la implementación de un reproductor de videos. Este programa, MPEG
player, corre sobre sistemas Windows y posee una interfase gráfica que permite
un control intuitivo (figura 40). En el extremo superior izquierdo se encuentra un
menú principal con dos ítems: File y About. El primero de ellos se utiliza para: abrir
un archivo (File | Open...) o para salir de la aplicación (File | Quit). El segundo,
simplemente presenta una ventana con información acerca del programa. En
principio, los botones Play, Pause, Stop y Go to new position se encuentran
deshabilitados. Una vez que se abre un archivo, se habilita el botón Play. Al
presionar este botón, comienza la reproducción del archivo y se habilitan todos los
demás botones. Si se presiona nuevamente este botón durante una reproducción
en curso, ésta comenzará nuevamente desde el principio. Si se presiona el botón
Stop, se detiene la reproducción y queda habilitado sólo el botón Play (el sistema
queda en el mismo estado que luego de abrir un archivo). El botón Pause se utiliza
para detener temporariamente la reproducción, de modo que si luego se presiona
nuevamente el botón Pause —o el botón Play— se reanuda la reproducción en
curso. El botón Go to new position se utiliza en conjunto con la barra de

79 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

desplazamiento New position, que está situada arriba de él. La barra de progreso
Current position indica la posición actual dentro del stream (cuánto se ha reproducido
hasta ese momento). Al presionar el botón Go to new position, se desplaza la
posición actual dentro del stream según el valor del indicador de la barra de
desplazamiento New position, y la reproducción continúa desde ese punto. A modo
de ejemplo, si en una reproducción en curso se sitúa el indicador de la barra de
desplazamiento New position en el centro y luego se presiona el botón Go to new
position, la reproducción seguirá desde la mitad. A la derecha del botón Stop se
encuentra otra barra de desplazamiento (Volume), pero ésta se utiliza para
disminuir —hacia la izquierda— o incrementar —hacia la derecha— el volumen.
Más a la derecha se encuentra una casilla de verificación (Loop stream) que se
utiliza para configurar el modo continuo, lo cual indica si luego de finalizar una
reproducción comenzará de nuevo automáticamente. En el extremo derecho se
pueden apreciar varios datos internos del stream:
 Total time: indica la duración total de reproducción, en segundos.

 Current time: indica cuánto se ha reproducido hasta el momento, en

segundos.
 Has video: indica si el stream contiene información de video.

 Has audio: indica si el stream contiene información de audio.

 Video width: indica el ancho original del video.

 Video height: indica el alto original del video.

 Current FPS: indica la cantidad actual de cuadros por segundo (Frames

Per Second).
Una vez que se ha comenzado con una reproducción de video, puede
modificarse el tamaño de la ventana que lo muestra de dos formas. Una es por
medio del botón de maximizar/restaurar, que es el botón central de los tres que se
encuentran en el extremo superior derecho. La otra es llevando el puntero hacia
uno de los límites de la ventana y manteniendo presionado el botón principal del
mouse arrastrar hasta obtener el tamaño deseado.

Figura 40: MPEG player.

Cabe destacar que este programa también es capaz de reproducir archivos de


audio en formato MP3. Sin embargo, la librería tiene algunos pequeños problemas.

80 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

Si se abre un archivo de audio MP3 codificado con bitrate variable (vbr), la


información del tiempo total de duración que se obtiene no es el correcto. Por otro
lado, si el archivo de audio MP3 que se abre fue codificado con bitrate fijo, es
posible que el audio se perciba saturado. Para poder minimizar este último
problema, se recomienda bajar el volumen del reproductor y aumentar el volumen
externo (del equipo de audio).
A continuación se muestran las líneas de código más importantes de este
programa.

// Initialize SDL
this-InitializeSDL();

// Create an MPEG stream


this-mpeg  SMPEG_new((char*) this-getFilename().c_str(), &this-info, (int) this-getUseAudio());

// Set up video display


this-SetupVideo();

// Play
SMPEG_play(this-mpeg);

La primer línea llama a un método que se encarga de la inicialización de audio


y video de la librería SDL.
La segunda línea invoca a una función que crea el stream MPEG. El primer
parámetro de esta función representa el nombre del archivo que se desea
reproducir y el segundo es un parámetro de salida en el que se almacenará
información relacionada con el stream —ancho y alto del video, tiempo de
reproducción total y transcurrido, cuadros por segundo, etc.
La tercer línea llama a un método que, utilizando información obtenida por
medio de SDL, prepara a la librería SMPEG para poder llevar a cabo una
reproducción de audio, video o ambos, según sea el caso.
Por último, la cuarta línea es la más importante, pues esta llamada es la que
efectivamente se encarga de la reproducción. Internamente, mediante la función
SDL_CreateThread de la librería SDL, se crean dos threads: uno para la decodificación
del audio y otro para la de video. La sincronización de estos dos threads es una
tarea que lleva a cabo internamente la librería SMPEG.
Si se desea examinar el código completo, éste se encuentra en el directorio
programacion\mpeg\smpeg\Borland.

81 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación


Compresión de imágenes y video (formato MPEG2) Fernando Martín Pap

BIBLIOGRAFÍA

[BOUMAN2001] Prof. Charles A. Bouman. "Achromatic Baseline JPEG


Encoding Lab", abril de 2001. Purdue University: Digital Image Processing
Laboratories.
[BS1995] C. Wayne Brown, Barry J. Shepherd. "Graphics File Formats:
Reference and Guide", 1995. Prentice Hall.
[CRRE] Fredy Fabian Cuello Rojas, Juan Carlos Rueda Erazo. "Compresión
de Video Digital Bajo Los Estándares MPEG".
http://www.fuac.edu.co/autonoma/pregrado/ingenieria/ingelec/proyectosgrado
[EKSTRAND2002] Per Ekstrand. "BANDWIDTH EXTENSION OF AUDIO
SIGNALS BY SPECTRAL BAND REPLICATION", 2002. Coding
Technologies.
[GHANBARI2003] Mohammed Ghanbari. "Standard Codecs: Image
Compression to Advanced Video Coding", 2003. Institution of Electrical
Engineers.
[JACK2001] Keith Jack. "Video Demystified (A Handbook for the Digital
Engineer)", 2001. LLH Technology Publishing.
[LIOU2001] Dr. Der-Ming Liou. "Entropy Coding", 2001. Institute of Health
Informatics, National Yang-Ming University.
[MS] Marcus Magnor, Philipp Slusallek. "The Human Visual System".
[NAVE2005] Carl Rod Nave. "HyperPhysics", 2005. Georgia State University.
http://hyperphysics.phy-astr.gsu.edu/hbase
[PAN1996] Davis Pan. "A Tutorial on MPEG/Audio Compression", 1996.
Motorola Inc.
[RY1990] K. R. Rao, P. Yip. "Discrete Cosine Transform: Algorithms,
Advantages, and Applications", 1990. Academic Press.
[SARGINSON1996] P.A. Sarginson. "MPEG-2: Overview of the systems
layer", 1996. British Broadcasting Corporation.
[TEKTRONIX97] "A GUIDE TO MPEG FUNDAMENTALS & PROTOCOL
ANALYSIS (Including DVB and ATSC", 1997. Tektronix.
[USEVITCH2001] Bryan E. Usevitch. "A Tutorial on Modern Lossy Wavelet
Image Compression: Foundations of JPEG 2000", septiembre de 2001.
IEEE SIGNAL PROCESSING MAGAZINE, pág. 22.
[WHITTLE2003] Robin Whittle. "Lossless Compression of Audio", 2003.
http://www.firstpr.com.au/audiocomp/lossless
[WIKIPEDIA2005] "Psychoacoustics". Wikipedia, 2005.
http://en.wikipedia.org/wiki/Psychoacoustics

82 U. N. S. – Depto. de Cs. e Ing. de la Computación – Ing. en Sistemas de Computación

Das könnte Ihnen auch gefallen