7 DESARROLLO DEL DECODIFICADOR

Desarrollo del decodificador Decodificador vídeo MPEG-2 7 DESARROLLO DEL DECODIFICADOR 7.1 Funcionalidad Como hemos dicho en ocasiones anteriores, e

0 downloads 157 Views 87KB Size

Recommend Stories


D PARA 3 DIGITOS DECODIFICADOR BCD A 7 SEGMENTOS
CA3162 CONVERSOR A/D PARA 3 DIGITOS CA3161 DECODIFICADOR BCD A 7 SEGMENTOS "CIRCUITOS INTEGRADOS" FICHAS COLECCIONABLES Todos los meses, las fic

DECODIFICADOR PRO LOGIC
Cat. No. 15-1964 MANUAL DEL PROPIETARIO Favor de leer este instructivo antes de usar el aparato. AMPLIFICADOR/DECODIFICADOR PRO LOGIC 2 INTRODUC

Objetivo 7 : Garantizar la sostenibilidad del. del medio ambiente. Metas 7.A y 7.B : Desarrollo sostenible
Objetivo 7 : Garantizar la sostenibilidad del medio ambiente Metas 7.A y 7.B : Desarrollo sostenible 7.A : Incorporar los principios del desarrollo s

1. Creando componentes 2. conectando con tarjeta externa. 3. Decodificador de BCD a 7 segmentos
Practica 2. FCHE12022015 1. Creando componentes 2. conectando con tarjeta externa. 3. Decodificador de BCD a 7 segmentos Ejemplo 1. Crear o abrir un

Decodificador Digital Terrestre Manual del usuario - Caja multiroom
Decodificador Digital Terrestre Manual del usuario - Caja multiroom Instrucciones generales de seguridad Aviso Siga siempre estas instrucciones para

Story Transcript

Desarrollo del decodificador

Decodificador vídeo MPEG-2

7 DESARROLLO DEL DECODIFICADOR 7.1 Funcionalidad Como hemos dicho en ocasiones anteriores, el trabajo técnico realizado en este proyecto consiste en una aplicación en MATLAB que decodifica el vídeo comprimido con formato MPEG-2. La mayoría de los codificadores MPEG dan la opción al comprimir de crear la información de audio y vídeo de manera independiente o en un único fichero. Por esta razón, la aplicación creada consta de dos bloques principales. En primer lugar se ha desarrollado un demultiplexor, encargado de separar la información correspondiente al vídeo en el caso de trabajar con un fichero que contenga tanto la información de audio como la de vídeo. En segundo lugar, y como núcleo fundamental de la aplicación, se encuentra el decodificador, encargado de leer la secuencia binaria con la información de vídeo, demultiplexar las distintas capas extrayendo la información de las cabeceras. Es en esta parte donde se interpretará la información de cada imagen decodificándola para obtener las tramas de luminancia y crominancia de las que consta la imagen final. Por último, estas imágenes se ordenarán en el orden de display correspondiente, formando una única estructura. Aunque el código empleado para desarrollar estas aplicaciones se encuentra recogido como anexo, a continuación considero necesario incluir una explicación de las tareas que realizan las funciones de las dos aplicaciones.

7.1.1 Demultiplexor El demultiplexor consta de una única función, denominada demux_video(). Para poder realizar el demultiplexado basta con conocer la jerarquía de las distintas estructuras existentes en la Capa de Sistema. Como dijimos en el capítulo cuatro, existen dos formas de encapsulado que generan dos tipos diferentes de flujos de datos, el Flujo de Transporte y el Flujo de Programa. Ambos se basan en la multiplexación de unidades básicas, los PES packets, que contienen un determinado tipo de información. El problema que encontramos en el Flujo de Transporte es que divide los PES packets para formar

95

Desarrollo del decodificador

Decodificador vídeo MPEG-2

unidades menores, dejando inaccesibles las cabeceras de los PES packets. Por esto, vamos a trabajar con encapsulados mediante Flujo de Programa. Por lo tanto bastará con identificar los PES packets que porten la información de vídeo. Como el resto de estructuras o capas, los PES packets comienzan con una cabecera de cuatro bytes con la cadena formada por veintitrés ceros seguidos de un uno (‘0000 0000 0000 0000 0000 0001’) y a continuación, un byte que sirve como identificación (Stream_id). En el caso de PES packets con información de vídeo la cabecera tiene la siguiente forma: 0000 0000

0000 0000

0000 0001

110x xxxx

Por lo tanto, los valores del Stream_id están comprendidos entre los decimales 224 y 239. En la figura 7.1 se muestra el diagrama de flujo de la función que se ha definido.

Figura 7.1 Diagrama de flujo del demultiplexor

7.1.2 Decodificador Esta parte de la aplicación es considerablemente más compleja. Está formada por un total de veintisiete funciones propias (además de otras de la librería de MATLAB) y diecisiete tablas. Una gran parte de estas funciones son llamadas desde la función

96

Desarrollo del decodificador

Decodificador vídeo MPEG-2

principal, video_sequence(), y el resto son invocadas desde otras funciones de forma anidada. Resumiendo, la tarea de un decodificador consiste en extraer los parámetros de las distintas cabeceras y extensiones y almacenarlos hasta que vayan a ser usados. Una vez que conocemos estos parámetros, deberá acceder a las capas donde se almacena la información de vídeo propiamente dicha e interpretarla, en función del proceso de decodificación expuesto en la recomendación y los parámetros almacenados de las cabeceras y por último crear estructuras y multiplexarlas hasta generar el vídeo descomprimido. La recomendación ISO/IEC 13818-2, donde viene especificada la sintaxis de un bitstream legal, también indica los tipos de datos que son utilizados. Describe cuatro tipos de datos diferentes y se nombran con unos nemónicos que se enumeran a continuación: •

bslbf: Cadena de bits, bit izquierdo primero.



uimsbf: Entero sin signo, bit más significativo primero.



simsbf: Entero con signo, en formato de complemento de dos, bit más significativo (signo) primero.



vlclbf: Código de longitud variable.

A continuación daremos una breve explicación de la estructura básica de cada función, de las tareas que realiza y los parámetros que intercambia. Para comprender el funcionamiento global de la aplicación será necesario analizar los códigos incluidos como anexo, sirviendo lo que a continuación se incluye como diccionario de variables y relaciones básicas. video_sequence() Es la función principal del decodificador. En primer lugar pregunta al usuario si su archivo contiene información de audio y vídeo, o solamente de vídeo. En cualquiera de los casos se encarga de abrir este archivo y mediante la función de la librería de MATLAB fread() crea un vector con los bytes que lo forman. En este momento ya puede ir accediendo a todas las capas que forman el vídeo. Para ello va llamando sucesivamente a otras funciones en el orden esperado de un bitstream que cumpla la recomendación de MPEG-2.

97

Desarrollo del decodificador

Decodificador vídeo MPEG-2

Aunque ya se expuso el algoritmo que debía verificar la información de vídeo en el capítulo seis, se repite en este punto por comodidad y para proporcionar una mejor comprensión de los siguientes apartados. Este algoritmo indica el orden en el que aparecen las distintas cabeceras y extensiones, los bucles existentes y las condiciones que se deben cumplir para seguir dentro de éstos o continuar con las siguientes sentencias. Como se puede ver en el código de la función diseñada (adjunta en Anexo) lo que aquí se representa es una versión muy simple de las tareas a desempeñar por esta función.

video_sequence() { next_start_code() sequence_header() if (nextbits() = = extensión_start_code) { sequence_extension() do { extension_and_user_data(0) do { if (nextbits() = = group_start_code() group _of_pictures_header() extension_and_user_data(1) } picture_heade() picture_coding_extension() extension_and_user_data(2) picture_data() } while ((nextbits() = = picture_start_code) || (nextbits() = = group_start_code)) if (nextbits() != sequence_end_code) { sequence_header() sequence_extension() } } while (nextbits() != sequence_ende_code) } else { /* ISO/IEC 11172-2 */ } sequence_end_code }

En el código propuesto, a lo largo de toda la función se mantienen dos índices. El primero de ellos, indice_actual, indica la posición por la que vamos leyendo, el segundo, indice_siguiente, nos da la posición del siguiente código de comienzo, y por lo tanto, de la siguiente capa. De esta forma, a cada una de las funciones no le pasamos el vector completo con toda la información, si no la que corresponde a la capa en cuestión.

98

Desarrollo del decodificador

Decodificador vídeo MPEG-2

Debido a que MATLAB no contempla la posibilidad de las sentencias do-while, en los puntos en los que aparece esta sentencia se ha debido incluir una primera realización correspondiente al do, y a continuación una sentencia while. Como excepción a la sintaxis propuesta en la recomendación, en la función diseñada, en lugar de hacer una llamada a la función picture_data(), se ha incluido su código directamente, ya que suponía más esfuerzo el crear una función nueva que hacerlo directamente en la función superior. De esta forma, en nuestra función video_sequence, se hacen las llamadas a los distintos slices. Se debe llamar a la función slice() mientras que la cabecera que encontremos contenga un código de comienzo perteneciente a esta capa. A medida que se van formando las imágenes decodificadas, se transforman al espacio de color RGB mediante la función colorspace(). A continuación se van representando y añadiendo a una estructura superior en el orden correspondiente para la formación final del vídeo decodificado. Además, es necesario almacenar las imágenes que pueden servir de

predicción,

para

emplearse

de

parámetro

de

entrada

en

las

funciones

correspondientes. En esta función se definen variables que servirán como parámetro de entrada a otras funciones. Además al llamar a la función macroblock() sucesivas veces se crean variables con los parámetros de salida que se emplean en video_sequence(). Las variables más importantes son: •

a: vector con elementos enteros de 1 byte. Su longitud dependerá del tamaño del vídeo.



indice_acutal: Elemento entero de 4 bytes, con la posición actual.



idice_sigiente: Elemento entero de 4 bytes, con la posición del siguiente código de comienzo



flag_gop: Bandera que indica que ha aparecido una segunda cabecera de GOP y que se pone a cero el contador de temporal_reference, cuyo significado se explicará más adelante



primera_P: Bandera que indica que ya ha sido decodificada otra imagen P, por lo que la predicción de las siguiente P se realizarán por medio de este tipo de tramas.

99

Desarrollo del decodificador



Decodificador vídeo MPEG-2

horizontal_size: Entero sin signo de 2 bytes, que representa la resolución horizontal en píxeles de la imagen (anchura).



mb_width: Entero sin signo de 2 bytes que indica el número de macrobloques existentes en una fila.



vertical_size: Entero sin signo de 2 bytes, que representa la resolución vertical en píxeles de la imagen (altura)



mb_height: Entero sin signo de 2 bytes que indica el número de macrobloques existentes en una columna.



num_GOP: Contador que indica el número de GOPs decodificados. Sirve para la reordenación de tramas.



num_frame_in_GOP: Contador que indica el número de cada imagen dentro de un mismo GOP. Se obtiene a partir de temporal_reference.



slice_luma: Se recibe como parámetro de la función slice() por lo que se definirá más adelante.



slice_chroma_b: Ocurre lo mismo que en el caso anterior.



slice_chroma_r: Ocurre lo mismo que en el caso anterior.



mb_column: Ocurre lo mismo que en el caso anterior.



mb_row: Ocurre lo mismo que en el caso anterior.



pos_y: Entero sin signo de 2 bytes que indica la posición del primer píxel de cada macrobloque en cada una de los slices. Se obtiene a partir de la variable anterior.



pict_luma: Matriz de enteros sin signo de 2 bytes que contiene la componente de luminancia, se obtiene multiplexando las sucesivas slice_luma. Una vez completada, sus dimensiones serán de horizontal_size por vertical_size píxeles.



pict_chroma_b: Matriz de enteros sin signo de 2 bytes que contiene la componente de crominancia azul, se obtiene multiplexando las sucesivas slice_chroma_b. Una vez completada, sus dimensiones serán de horizontal_size por vertical_size píxeles.



pict_chroma_r: Matriz de enteros sin signo de 2 bytes que contiene la componente de crominancia roja, se obtiene multiplexando las sucesivas

100

Desarrollo del decodificador

Decodificador vídeo MPEG-2

slice_chroma_r. Una vez completada, sus dimensiones serán de horizontal_size por vertical_size píxeles. •

YCbCr: Matriz de enteros sin signo de 2 byte que contiene las tres componentes anteriores con las mismas dimentsiones.



RGB: Matriz de elementos de 4 bytes (doubles) que contiene las tres componentes de color tras la transformación



frame_pred_I: Matriz de enteros sin signo de 2 bytes que almacena la última imagen I decodificada.



frame_pred_P: Matriz de enteros sin signo de 2 bytes que almacena la última imagen I decodificada.



im_referencia: Matriz de enteros sin signo de 2 bytes que almacena la última imagen I o P decodificadas en el caso de estar decodificando una trama P y las dos últimas tramas I o P y P decodificadas para el caso de decodificar una trama B.



M: Estructura que contiene el vídeo de tramas que se van decodificando.

sequence_header() Esta

función

es

la

encargada

de

interpretar

la

cabecera

de

secuencia

(sequence_header), en donde se detallan parámetros básicos para la decodificación. Recibe como parámetro de entrada un vector auxiliar con los bytes pertenecientes a esta cabecera. Debido a que los parámetros que contiene poseen longitud de bits, se debe obtener su cadena binaria. Una vez hecho esto se comienza con la extracción de parámetros. Aunque la función está diseñada para extraer todos los parámetros de esta capa, sólo se devuelven como parámetros de salida los que se emplearán en otras capas. Los parámetros que devuelve esta función se enumeran a continuación y su explicación y longitud se detallaron en el capítulo seis. •

horizontal_size_value. Entero sin signo de 2 bytes (aunque solo necesita 12 bits). Junto con horizontal_size_extension forman el parámetro horizontal_size.



vertical_size_value. Entero sin signo de 2 bytes (aunque solo necesita 12 bits). Junto con vertical_size_extension forman el parámetro vertical_size.

101

Desarrollo del decodificador



Decodificador vídeo MPEG-2

frame_rate. Entero sin signo de 1 byte. Este parámetro se obtiene a partir de frame_rate_code en función de una tabla de la recomendación. Servirá para reproducir el vídeo de salida decodificado.



intra_quantiser_matrix. Matriz de 8x8 elementos de 1 byte sin signo que se usa en el proceso de decodificación para cuantificar los macrobloques intra. Puede haber sido obtenida del bitstream o definida por defecto.



non_intra_quantiser_matrix. Matriz de 8x8 elementos de 1 byte sin signo que se usa en el proceso de decodificación para cuantificar los macrobloques no-intra. Puede haber sido obtenida del bitstream o definida por defecto.

sequence_extension() Esta función es la encargada de interpretar la información de la extensión de secuencia (sequence_extension), en donde se detallan parámetros básicos para la decodificación. Recibe como parámetro de entrada un vector auxiliar con los bytes pertenecientes a esta extensión. Debido a que los parámetros que contiene poseen longitud de bits, se debe obtener su cadena binaria. Una vez hecho esto se comienza con la extracción de parámetros. Aunque la función está diseñada para extraer todos los parámetros de esta capa, sólo se devuelven como parámetros de salida los que se emplearán en otras capas. Los parámetros que devuelve esta función se enumeran a continuación y su explicación y longitud se detallaron en el capítulo seis. •

progressive_sequence. Entero sin signo de un byte (aunque solo se necesita 1 bit).



chroma_format. Entero sin signo de 1 byte (aunque sólo se necesitan 2 bits). Tomará el valor 1 para el formato 4:2:0, el valor 2 para 4:2:2 y el valor 3 para el formato 4:4:4.



horizontal_size_extension. Entero sin signo de 1 byte (aunque sólo se necesitan 2 bits)



vertical_size_extension Entero sin signo de 1 byte (aunque sólo se necesitan 2 bits).

102

Desarrollo del decodificador

Decodificador vídeo MPEG-2

extension_and_user_data() Es la función principal desde la que se invocan las distintas extensiones y los datos de usuario (excepto sequence_extension() y picture_coding_extension(), que deben ir tras sequence_header() y picture_header(), respectivamente, para formar un bitstream legal. Recibe como parámetros el valor de un índice (i) para distinguir desde qué punto de la estructura es llamada. En este caso recibe la cadena de bytes completa y el índice_actual, ya que a priori se desconoce el número de extensiones que puede contener. Como parámetro de salida se ha incluido únicamente el indice_siquiente por el que debe seguir la función principal, ya que para el proceso de decodificación no se necesita ninguno en los casos estudiados. Cuando el índice de entrada i tiene el valor 0 ó 2, puede invocar tanto a la función extension_data() como a la función user_data(). En el caso en que i valga 1 (después de de group_of_pictures_header()), sólo podrá llamar a la segunda. extension_data() Esta función recibe como parámetro el índice i desde la función anterior. Como hemos dicho este índice nos sirve para saber desde qué punto de la secuencia ha sido invocada y qué tipo de extensión podremos tener. Cada vez que se llame a extension_data() contendrá un único tipo de extensión. Puede ser llamada tantas veces como extensiones haya desde la función anterior. Vemos los distintos casos: •

i=0. Extensión a continuación de sequence_extension). Podremos tener una de estas dos extensiones: sequence_display_extension() sequence_scalable_extension()



i=1. En este caso no existe extension_data()



i=2. Extensión a continuación de picture_coding_extension. Podemos tener cinco tipos de extensiones: quant_matriz_extension () copyright_extension() picture_display_extension()

103

Desarrollo del decodificador

Decodificador vídeo MPEG-2

picture_spatial_scalable_extension() picture_temporal_scalable_extension() Estas funciones se han definido tal y como aparecen en la recomendación, aunque no se emplean sus parámetros en el proceso de decodificación. group_of_pictures_header() Esta función es la encargada de interpretar la cabecera de cada grupo de imágenes (group_of_pictures_header). El número de grupos de imágenes es variable, y cada vez que aparece esta cabecera se resetea el valor de la variable temporal_reference, explicada a continuación. Recibe como parámetro de entrada un vector auxiliar con los bytes pertenecientes a esta cabecera. Debido a que los parámetros que contiene poseen longitud de bits, se debe obtener su cadena binaria. Una vez hecho esto se comienza con la extracción de parámetros. Aunque la función está diseñada para extraer todos los parámetros de esta capa, no se devuelve como parámetro de salida ninguno de ellos. picture_header() Esta función es la encargada de interpretar la cabecera de cada imagen (picture_header). El número de imágenes es variable, dependerá de la duración del vídeo y de la tasa de muestreo. Será llamada hasta que se deje de cumplir cierta condición. Recibe como parámetro de entrada un vector auxiliar con los bytes pertenecientes a esta cabecera. Debido a que los parámetros que contiene poseen longitud de bits, se debe obtener su cadena binaria. Una vez hecho esto se comienza con la extracción de parámetros. Aunque la función está diseñada para extraer todos los parámetros de esta capa, solo se devuelven como parámetros de salida aquellos que se necesiten posteriormente en el proceso de decodificación. •

temporal_reference: Entero sin signo de 2 bytes (aunque sólo se necesitan 10 bits). Indica la posición de la imagen que está siendo decodificada en el GOP al que pertenece. Este valor será utilizado para mostrar las imágenes en el orden adecuado.



picture_coding_type: Entero sin signo de 1 byte (aunque sólo se necesitan 3 bits). Tomará el valor 1 para las imágenes I, el valor 2 para las P y el valor 3 para las imágenes tipo B.

104

Desarrollo del decodificador

Decodificador vídeo MPEG-2

picture_coding_extension() Esta función es la encargada de interpretar la extensión de codificación de cada imagen (picture_coding_extension). Contiene la mayoría de los parámetros necesarios en el proceso de decodificación de la información de vídeo. Recibe como parámetro de entrada un vector auxiliar con los bytes pertenecientes a esta extensión. Debido a que los parámetros que contiene poseen longitud de bits, se debe obtener su cadena binaria. Una vez hecho esto se comienza con la extracción de parámetros. Aunque la función está diseñada para extraer todos los parámetros de esta capa, solo se devuelven como parámetros de salida aquellos que se necesiten posteriormente en el proceso de decodificación. •

picture_structure: Entero sin signo de 1 byte (aunque solo necesita 2 bits). Identifica la esturcutra del cuadro, si es de trama o de campo, en este caso, qué campo es.



frame_pred_frame_dct: Entero sin singo de 1 byte (aunque solo necesita 1 bit). Indica que solo se puede hacer predicción por cuadros completos e influye en el proceso de decodificación.



concealment_motion_vectors: Entero sin signo de 1 byte (aunque solo necesita 1 bit). Indica si los macrobloque intra incorporan vectores de movimiento para la corrección de errores.



f_code: Matriz de 2x2 elementos de 1 byte sin signo que guarda información sobre el rango de desplazamiento de los vectores de movimiento.



precision: Entero de 1 byte sin signo que se define a partir del parámetro intra_dc_precision y se utilizará en el proceso de decodificación.



alternate_scan: Entero sin signo de 1 byte (aunque solo necesita 1 bit) que sirve para seleccionar cuál de las dos tablas de ordenación de coeficientes se usará.



q_scale_type: Entero sin signo de 1 byte (aunque solo necesita 1 bit) que sirve para determinar cómo se leerá el factor de escala.



intra_vlc_format: Entero sin singo de 1 byte (aunque solo necesita 1 bit) que sirve para determinar qué tabla se emplea para la decodificación de los coeficientes de la DCT.

105

Desarrollo del decodificador

Decodificador vídeo MPEG-2

slice() Esta función es la encargada de decodificar cada slice. Es llamada tantas veces como slices haya. Desde esta función es desde donde se invoca a la función macrolblock(), por lo que recibe como parámetros, además de un vector auxiliar con los bytes pertenecientes al slice en cuestión, otros muchos parámetros que serán usados por las siguientes funciones en el proceso de decodificación. Las llamadas a la función macroblock() se realizan en un bucle, hasta que deje de cumplirse la condición (fin_slice=1). Debido a que los parámetros que contiene poseen longitud de bits, se debe obtener la cadena binaria del vector de entrada. Una vez hecho esto se comienza con la extracción de parámetros y el resto de la función. Según se especifica en la recomendación, al principio de cada slice se deben resetear los predictores PMV(r,s,t) y dc_dct_pred, cuyo contenido se explicará a más adelante, ya que la función encargada de modificarlos no es esta. Esta función define variables que servirán como parámetros de salida o de entrada para otras funciones a partir de esta, o usadas dentro de la propia función, las más importantes se describen a continuación. Además al llamar a la función macroblock() sucesivas veces se crean variables con los parámetros de salida de esta función. Algunas de estas variables se crean simplemente para servir de pasarela entre las sucesivas veces que se invoca a la función macroblock(), ya que se necesitarán los valores del anterior macroblock. El resto se emplearán en la función slice. •

slice_vertical_position: Entero sin signo de 1 byte. Indica la fila (en unidades de macrobloque) del slice que se está codificando. Esta variable se obtiene del cuarto byte del código de comienzo del slice.



mb_row: Entero sin signo de 1 byte, con el mismo significado que la anterior. Es un parámetro de salida.



quantiser_scale_code: Entero sin signo de 1 byte (aunque sólo necesita 5 bits). Se obtiene del bitstream e indica el factor de escala para cuantificar los coeficientes DCT.



half_flag: Esta variable será definida más adelante. En esta función simplemente se inicializa a cero y sirve de pasarela entre las sucesivas llamadas a la función macroblock(), que es la encargada de modificarla.



int_vec: Ocurre lo mismo que en el caso anterior.

106

Desarrollo del decodificador



Decodificador vídeo MPEG-2

macroblock_motion_forward: Ocurre lo mismo que en el caso anterior pero no se inicializa, solo sirve de pasarela.



macroblock_motion_backward: Ocurre lo mismo que en el caso anterior.



PMV: Ocurre lo mismo que en el caso anterior.



dc_dct_pred: Ocurre lo mismo que en el caso anterior.



macro_luma: Se recibe como parámetro de la función macrolblock() por lo que se definirá más adelante.



macro_chroma_b: Ocurre lo mismo que en el caso anterior



macro_chroma_r: Ocurre lo mismo que en el caso anterior



mb_column: Es parámetro de salida pero lo recibe de la función macroblock(), por lo que su significado se explicará más adelante.



pos_x: Entero sin signo de 2 bytes que indica la posición del primer píxel de cada macrobloque en cada una de las columnas. Se obtiene a partir de la variable anterior.



tam: Valor que indica la longitud en píxeles de cada slice ya que su tamaño puede ser variable.



slice_luma: Matriz de elementos enteros de 2 bytes con la componente de luminaria, se obtiene multiplexando los sucesivos macro_luma. Su anchura viene determinada por la variable anterior (tam) y su altura siempre es dieciséis. Es parámetro de salida.



slice_chroma_b: Matriz de elementos enteros de 2 bytes con la componente de crominancia azul, se obtiene multiplexando los sucesivos macro_chroma_b. Su anchura viene determinada por la variable anterior (tam) y su altura siempre es dieciséis. Es parámetro de salida.



slice_chroma_r: Matriz de elementos enteros de 2 bytes con la componente de crominancia roja, se obtiene multiplexando los sucesivos macro_chroma_r. Su anchura viene determinada por la variable anterior (tam) y su altura siempre es dieciséis. Es parámetro de salida.

107

Desarrollo del decodificador



Decodificador vídeo MPEG-2

previous_macroblock_address: Valor que indica la posición en unidades de macrobloque del último macrobloque decodificado. En esta función se debe inicializar con el valor ‘-1’.



macroblock_address: Se emplea para actualizar la variable anterior, pero se define en la función macroblock() por lo que su significado se definirá más adelante.



fin_slice: Bandera que indica que se ha finalizado el slice.

macroblock() Esta es sin lugar a dudas la función más compleja e importante de toda la aplicación. Es la encargada de decodificar los macrobloques. Para esto, debe conocer el tipo de imagen que se está decodificando, para saber si se tiene que hacer predicción y de qué tipo. Además dependiendo de los casos llamará a otras funciones importantes como son block(), macroblock_skipped(), motion_vetors() y coded_block_pattern(). En este caso, la información a decodificar la recibe como cadena de bits, que tendrá una longitud variable, ya que a medida que se van decodificando macrobloques, se actualiza la cadena, eliminando los bits ya decodificados. El resto de parámetros de entrada en su mayoría son los que se han descrito anteriormente como parámetros de salida de otras funciones. Hay que destacar el parámetro de entrada im_referencia, matriz a partir de la cual se hacen las predicciones en el caso de imágenes P o B. Además hay cuatro parámetros que se deben pasar la siguiente vez que se llame a la función macroblock() para poder decodificar los macroblock skipped en el caso de que los hubiere. Estos son half_flag, int_vec, macroblock_motion_forward,

macroblock_motion_backward,

cuyos

significados

se

explicarán más adelante. Según se especifica en la recomendación, bajo determinadas circunstancias se deben resetear los predictores PMV(r,s,t) y dc_dct_pred, y los vectores de movimiento calculados, cuyo contenido se explicará a más adelante, ya que la función encargada de modificarlos no es esta. Una vez se hayan decodificado todos los vectores se deben actualizar el resto, como se indica en la recomendación. En esta función se definen una serie de variables que servirán como parámetros de entrada a las funciones siguientes, parámetros de salida o para el funcionamiento de la propia función. Además al llamar a otras funciones sucesivas veces se crean variables

108

Desarrollo del decodificador

Decodificador vídeo MPEG-2

con los parámetros de salida que se emplean en macroblock(). Se describen a continuación los más importantes: •

macroblock_address_increment: Entero sin signo de 1 byte. Se obtiene mediante la table_b1 y la decodificación de códigos de longitud variable. Indica el incremento de la dirección en unidades de macrobloque.



macroblock_address: Entero con signo de 2 bytes. Indica la posición actual del macrobloque a decodificar.



mb_column: Entero con signo de 2 bytes obtenido que indica la columna en la que está el macrobloque.



num_macroblock_skipped: Valor que indica el número de macrobloques no incluidos en el bitstream y que deben ser decodificados a partir de los anteriores macrobloques.



block_count: Entero sin signo de 1 byte que indica el número de bloques que forman el macrobloque en función del formato de croma (chroma_format).



num_mb: Indice que se emplea para poder decodifcar los macrobloque skipped.



macroblock_quant: Parámetro de salida de la función macroblock_modes() que se definirá más adelante. Se usa en el proceso de decodificación.



macroblock_motion_forward:

Parámetro

de

salida

de

la

función

macroblock_modes() que se definirá más adelante. Se usa en el proceso de decodificación. •

macroblock_motion_backward:

Parámetro

de

salida

de

la

función

macroblock_modes() que se definirá más adelante. Se usa en el proceso de decodificación. •

macroblock_pattern: Parámetro de salida de la función macroblock_modes() que se definirá más adelante. Se usa en el proceso de decodificación.



macroblock_intra: Parámetro de salida de la función macroblock_modes() que se definirá más adelante. Se usa en el proceso de decodificación.



frame_motion_type: Parámetro de salida de la función macroblock_modes() que se definirá más adelante. Se usa en el proceso de decodificación.

109

Desarrollo del decodificador



Decodificador vídeo MPEG-2

motion_vector_count: Parámetro de salida de la función macroblock_modes() que se definirá más adelante. Se usa en el proceso de decodificación.



mv_format: Parámetro de salida de la función macroblock_modes() que se definirá más adelante. Se usa en el proceso de decodificación.



dmv: Parámetro de salida de la función macroblock_modes() que se definirá más adelante. Se usa en el proceso de decodificación.



quantiser_scale_code: Entero sin signo de 1 byte (aunque sólo necesita 5 bits). Se obtiene del bitstream e indica el factor de escala para cuantificar los coeficientes DCT.



s: Indice que indica el tipo de vector de movimiento que se va a decodificar. En la recomendación toma dos valores, 0 ó 1. Nosotros, por razones de indexado de los vectores le damos los valores 1, para predicciones forward, y 2, para predicciones backward.



vector_Y: Parámetro de salida de la función moton_vectors() que se definirá más adelante. Se usa para realizar las predicciones.



vector_Cb: Parámetro de salida de la función moton_vectors() que se definirá más adelante. Se usa para realizar las predicciones.



vector_Cr: Parámetro de salida de la función moton_vectors() que se definirá más adelante. Se usa para realizar las predicciones.



PMV: Parámetro de salida de la función moton_vectors() que se definirá más adelante. Se usa para realizar las predicciones.



half_flag(r,s,t,cc): Vector se banderas con dimensiones 2x2x2x3. El índice r indica el campo desde el que se forman las predicciones, en el caso de predicciones de campo. El índice s indica el tipo de predicción, forward o bakcward. El índice t indica la componente del vector, horizontal o vertical. El índice n, indica la componente, luminancia, croma b o croma r. sirve para indicar si se toman semimuestras.



int_vec(r,s,t,cc): Vector de enteros con las mismas dimensiones que la variable anterior. Se forma a partir de la división entera de los vectores de movimiento entre dos.

110

Desarrollo del decodificador



Decodificador vídeo MPEG-2

cbp: Parámetro de salida de la función coded_block_pattern() que se definirá más adelante. Se usa para determinar qué bloques están codificados en el bitstream.



pattern_code(i): Vector de banderas con longitud igual a block_count. Si la bandera está a uno, el bloque en esa posición habrá que decodificarlo. En el caso de que macroblock_intra valga uno, todos los bloques están codificados.



f(y,x): Parámetro de salida de la función block() que se definirá más adelante.



dc_dct_pred: Parámetro de salida de la función block() que sirve de pasarela para las sucesivas llamadas a esta función.



p(y,x): Matriz de 8x8 enteros de 2 bytes. Contendrá los valores formados por las predicciones. En el caso de existir predicción backward y forward se hará la interpolación de estas dos.



y_ref: Indice para determinar la posición a partir de la cual se ha de tomar la predicción.



x_ref: Indice para determinar la posición a partir de la cual se ha de tomar la predicción.



pel_ref(y,x,cc): Matriz de enteros de 2 bytes que contiene para cada bloque la imagen o imágenes de referencia, en el caso de tratarse de imágenes P o B, respectivamente.



pel_pred_forward: Matriz de 8x8 enteros de 2 bytes que contiene la predicción forward.



pel_pred_backward: Matriz de 8x8 enteros de 2 bytes que contiene la predicción backward.



d: Matriz de 8x8 enteros de 2 bytes que contiene la suma de los coeficientes DCT decodificados más las predicciones.



macros_luma(y,x,num_mb): matriz de enteros de 2 bytes de dimensiones 16x16 con la componente de luminancia.



macros_chroma_b(y,x,num_mb): matriz de enteros de 2 bytes de dimensiones 16x16 con la componente de crominancia azul.



macros_chroma_r(y,x,num_mb): matriz de enteros de 2 bytes de dimensiones 16x16 con la componente de crominancia roja.

111

Desarrollo del decodificador



macro_luma:

Decodificador vídeo MPEG-2

matriz

de

enteros

de

2

bytes

de

dimensiones

16x16x(num_macroblock_skipped+1) con la componente de luminancia, que se obtienen por multiplexación de macros_luma. •

macro_chroma_b:

matriz

de

enteros

de

2

bytes

de

dimensiones

16x16x(num_macroblock_skipped+1) con la componente de crominancia azul, que se obtienen por multiplexación de macros_chroma_b. •

macro_chroma_r:

matriz

de

enteros

de

2

bytes

de

dimensiones

16x16x(num_macroblock_skipped+1) con la componente de crominancia roja, que se obtienen por multiplexación de macros_chroma_r. macroblock_modes() Esta función se encarga de determinar el tipo de macrobloque que se está decodificando. Esto se hace por medio de las tablas table_b2, table_b3 y table_b4 y decodificación de códigos de longitud variable. La elección de las tablas anteriores depende del tipo de imagen que se esté decodificando. Los parámetros que se obtienen en esta función servirán en todo el proceso de decodificación. Los más importantes son: •

macroblock_quant: Bandera que indica que quant_scale_code está presente en el bitstream perteneciente al macrobloque.



macroblock_motion_forward: Bandera que indica que hay predicción forward.



macroblock_motion_backward:

Bandera

queindica

que

hay

predicción

backward. •

macroblock_pattern: Bandera que indica que se llamará a la función coded_block_pattern().



macroblock_intra: Bandera que indica que el tipo de macrobloque es intra.



frame_motion_type: Indica el tipo de predicción de movimiento y define otros parámetros.

block() Esta función es invocada desde macroblock() tantas veces como bloques haya (indicado por block_count). Es la que realiza el proceso de decodificación de los datos de vídeo a partir de los cuales se podrán formar futuras predicciones.

112

Desarrollo del decodificador

Decodificador vídeo MPEG-2

En este caso, la información a decodificar la recibe como cadena de bits, que tendrá una longitud variable, ya que a medida que se van decodificando bloques, se actualiza la cadena, eliminando los bits ya decodificados. La mayoría de parámetros de entrada que recibe se usan para decidir sobre el proceso de decodificación. Para identificar el bloque de que tipo de componente estamos decodificando se hace mediante el índice de entrada i. Recibe además un de las anteriores llamadas a esta función, que se debe ir actualizando con el valor que corresponda. En esta función se definen una serie de variables que servirán como parámetros de salida o para el funcionamiento de la propia función. Las más importantes son: •

W_0: Matriz se 8x8 enteros sin signo de 1 byte que se emplea para cuantificar los coeficientes de macrobloques intra.



W_1: Matriz se 8x8 enteros sin signo de 1 byte que se emplea para cuantificar los coeficientes de macrobloques no intra.



dct_dc_size_luminace: Entero sin signo de 1 byte que se obtiene a partir de table_b12 y decodificación de códigos de longitud variable. El valor decodificado indica la longitud en bits que siguen a continuación que pertenecen al parámetro dct_dc_differential en el caso de la luminancia.



dct_dc_size_chrominance: Entero sin signo de 1 byte que se obtiene a partir de table_b13 y decodificación de códigos de longitud variable. El valor decodificado indica la longitud en bits que siguen a continuación que pertenecen al parámetro dct_dc_differential en el caso de las dos componentes de crominancia.



dct_dc_differential: Entero sin signo de 2 bytes que indica el valor diferencial de la luminancia o crominancia dependiendo del valor de i.



dct_diff: Entero sin signo de 2 bytes intermedio para calcular el valor del coeficiente DC.



dc_dct_pred(cc): Es un vector con 3 predictores, uno para cada componente, luminancia, crominancia azul y crominancia roja.



QFS(n): Vector de 64 elementos enteros de 2 bytes que contiene todos los coeficientes decodificados.

113

Desarrollo del decodificador



Decodificador vídeo MPEG-2

run: Entero sin signo de 1 byte que se obtiene a partir de las tables table_b14, table_b14bis o table_b15 y decodificación de longitud variable. Indica el número de ceros que hay que añadir en el vector QFS antes del siguiente coeficiente.



level: Entero sin signo de 1 byte que se obtiene a partir de las tablas table_b14, table_b14bis o table_b15 y decodificación de longitud variable. Indica el valor del coeficiente decodificado.



end_of_block: cadena de 2 o 4 bits para identificar el final del bloque.



eob_not_read: bandera que indica que ha finalizado el bloque.



QF(v,u): Matriz de 8x8 elementos enteros de 2 bytes. Se obtiene a partir del vector QF y mediante escaneo en zig-zag u otros.



intra_dc_mult: Valor de cuantificación para los coeficientes dc.



quantiser_scale: Valor de cuantificación para el resto de coeficientes.



F(v,u): Matriz de 8x8 elementos obtenida a partir de la matriz QF y la cuantificación y saturación de sus elementos.



f: Matriz de 8x8 elementos enteros que contiene los valores decodificados del bloque en cuestión.

macroblock_skipped() Esta función es similar a macroblock(), pero en el caso de que haya macroblock skipped. Sólo puede ser llamada si estamos decodificando imágenes P o B. Debe ser llamada desde macroblock() ya que es en esa función donde se conoce el número de macrobloques que no han sido codificados, pero necesita los parámetros para formar predicciones del macrobloque anterior. motion_vectors() Función encargada de devolver los vectores de movimiento. Desde esta función se invoca a la función motion_vector() que es la encargada de calcularlos. En esta función se determina si habrá 2 vectores de movimiento (predicción de campo) o sólo uno (predicción de trama). Para esto se define el índice que identifica estos vectores. •

r: Indice que indica el tipo de vector de movimiento que se va a decodificar. En la recomendación toma dos valores, 0 ó 1. Nosotros, por razones de indexado de los vectores le damos los valores 1, para el primer vector de campo o en el caso del

114

Desarrollo del decodificador

Decodificador vídeo MPEG-2

único de trama, y 2, para el segundo vector de campo. En el caso de predicciones de trama, este segundo vector es puesto a cero. •

Vector_prima: Este valor es definido en la función motion_vector().



PMV: Este valor es definido en la función motion_vector():



vector_Y: Vector de movimiento con dimensiones 2x2x2 para la luminancia.



vector_Cb: Vector de movimiento con dimensiones 2x2x2 para la crominancia azul.



vector_Cr: Vector de movimiento con dimensiones 2x2x2 para la crominancia roja.

motion_vector() Esta función es la encargada de calcular los vectores de movimiento. Calcula las dos componentes del vector, horizontal y vertical para un caso concreto. Para determinar el caso en el que nos encontramos, recibe como parámetros el valor de los índices r y s, que identifican de manera unívoca el vector al que nos referimos. Para el cálculo de los vectores define algunas variables intermedias que definimos a continuación. •

t: Indice que indica la componente que estamos decodificando. En la recomendación toma dos valores, 0 ó 1. Nosotros, por razones de indexado de los vectores le damos los valores 1, para la componente horizontal, y 2, para la vertical.



r_size: Entero sin signo de 1 byte obtenido a partir del valor de f_code, en función de los índices s y t que proporciona el máximo desplazamiento permitido por los vectores de movimiento.



motion_code(r,s,t): Entero de 1 byte obtenido a partir de la table_b10 y decodificación de códigos de longitud variable. Proporciona el valor de cada una de las componentes de los vectores de movimiento.



PMV: Predictor con los valores de los vectores de movimiento anteriores.



vector_prima: Vector de dimensiones 1x2 que contiene el vector de desplazamietno.

115

Desarrollo del decodificador

Decodificador vídeo MPEG-2

coded_block_pattern() Función que devuelve el valor de la variable cbp. •

cbp: Entero de 1 byte obtenido a partir de la table_b9 y decodificación de códigos de longitud variable. Se usa para determinar el valor de pattern_code.

next_start_code() Función que devuelve la posición del siguiente código de comienzo. Recibe como parámetro el vector donde se quiere buscar el código y el índice a partir del cual se quiere buscar. next_start_code_value() Función que devuelve la posición del siguiente código de comienzo con un valor concreto. Recibe como parámetro el vector donde se quiere buscar el código, el índice a partir del cual se quiere buscar y el valor del último byte del código de comienzo.

7.2 Estudio de tiempos 7.2.1 Compresión frente a velocidad de decodificación Cuando se explicaron las técnicas de codificación de vídeo y se habló de los distintos tipos de imágenes que podemos encontrar en un vídeo MPEG-2 se distinguió entre las que menos compresión producían (imágenes I) y las que mayor grado de compresión proporcionaban (imágenes B). Pues bien, se ha de saber que esta capacidad de compresión es inversamente proporcional a la velocidad de decodificación. Por esta razón, las imágenes que menos tardan en decodificarse serán las de tipo I y las que más serán las de tipo B. Vamos a hacer una comparación en un caso particular. En nuestro ejemplo decodificaremos un vídeo con un tamaño de imagen de 240x320 píxeles. Este tamaño de la imagen también influirá en el tiempo que emplea el decodificador. Si observamos los tiempos empleados en decodificar el primer GOP (con una estructura de IPBBPBBPBBPBBPBB) y el tamaño en bytes que ocupan las imágenes codificadas, obtenemos los siguientes resultados. Los resultados obtenidos en un GOP son extrapolables al resto de la secuencia de vídeo, puesto que el patrón se repite.

116

Desarrollo del decodificador

Decodificador vídeo MPEG-2

TIPO IMAGEN

TIEMPO (seg)

TAMAÑO (bytes)

I P B B P B B P B B P B B P B B

27,5469 562.0561 577,3877 619,7654 564,0327 600,2482 590,1005 572,2569 563,7148 605,2863 550,2397 580,6971 599,5148 560,1239 609,1587 615,2357

24681 6821 1229 1776 10681 1502 2030 10669 1786 1888 9619 1967 2302 11057 1773 2346

Tabla 7.1 Tiempos y espacio en memoria de decodificación en un GOP

Los tiempos mostrados para cada imagen transcurren desde que comienza a leerse la cabecera de cada imagen (picture_header), hasta que esta se obtiene la imagen decodificada en el espacio de color RGB. Podemos representar en un gráfico para cada grupo de imágenes qué parte del tiempo se pasa codificando cada tipo de imágenes. Si todas tardaran lo mismo en ser decodificadas, en el GOP de nuestro ejemplo con una imagen tipo I, cinco imágenes tipo P y 10 imágenes tipo B, el reparto de tiempo que se obtendría sería el representado en la figura 7.2.

Tipo I

Tipo I

Tipo P

Tipo P

Tipo B

Tipo B

Reparto de tiempo en el GOP de ejemplo

Reparto de tiempo en las 3 primeras imágenes

Figura 7.2 Reparto de tiempos considerando mismo tiempo de decodificación

117

Desarrollo del decodificador

Decodificador vídeo MPEG-2

Este reparto queda bastante lejos de la realidad, por lo que mostramos en la figura 7.3 el verdadero reparto. La verdadera diferencia se puede observar en el segundo de los gráficos.

Tipo I

Tipo I

Tipo P

Tipo P

Tipo B

Tipo B

Reparto de tiempo en el GOP de ejemplo

Reparto de tiempo en las 3 primeras imágenes

Figura 7.3 Reparto de tiempos real

Para comparar estos tiempos de decodificación con el espacio que ocupaban las imágenes antes de ser decodificadas representamos el reparto de capacidad ocupada en la figura 7.4.

Tipo I

Tipo I

Tipo P

Tipo P

Tipo B

TipoB

Reparto de capacidad en el GOP de ejemplo

Reparto de capacidad en las 3 primeras imágenes

Figura 7.4 Reparto de memoria ocupada

El espacio ocupado por la imagen codificada se ha calculado desde que empieza la cabecera de imagen hasta que aparece la siguiente cabecera de imagen. Vemos como en el reparto de capacidad en el GOP, habiendo una única imagen tipo I, ocupa prácticamente un cuarto de a capacidad total. Comparando los gráficos de las figuras 7.3 y 7.4 podemos comprobar como tiempos de decodificación pequeños (como las imágenes I) implican la ocupación de mayor cantidad de memoria y viceversa.

118

Desarrollo del decodificador

Decodificador vídeo MPEG-2

7.2.2 Reparto de tiempo en el proceso de decodificación En el proceso global de decodificación, podemos representar de igual forma un gráfico con los tiempos empleados en cada una de las fases. Podemos verlo en la figura 7.5.

1% 17%

21%

Extracción de cabeceras Decodificación VCL y cuantificación inversa DCT Inversa

36%

25%

Compensación de movimiento Transformación del espacio de color y display

Figura 7.5 Reparto de tiempo en el proceso de decodificación

Se observa, que la fase que más tiempo se lleva del total es la compensación de movimiento. Cuando explicamos las distintas técnicas de compresión de vídeo dijimos que esta sería la técnica que mayor factor de compresión proporcionaba. Nuevamente, tenemos enfrentados los intereses.

119

Get in touch

Social

© Copyright 2013 - 2024 MYDOKUMENT.COM - All rights reserved.