En la codificación de vídeo, la partición de la imagen en unidades más pequeñas es una técnica fundamental que mejora tanto la eficiencia de compresión como la velocidad de decodificación. Entre las estructuras más comunes utilizadas en los códecs modernos, como H.264, HEVC y VVC, se encuentran las divisiones de la imagen en "tiles" y "slices", así como la introducción de unidades básicas flexibles de codificación como los bloques y unidades de predicción. Este enfoque modular permite que las tareas de codificación y decodificación se distribuyan de manera más eficiente, lo que es esencial cuando se trabaja con resoluciones altas como HD, 4K y superiores.

Las "slices" y "tiles" son divisiones importantes de la imagen codificada. Las "slices" no siempre son rectangulares, lo que las hace menos predecibles en términos de tamaño y distribución. En cambio, los "tiles" son siempre rectangulares, y su tamaño es fijo, lo que facilita la decodificación paralela. La segmentación en tiles permite que diferentes núcleos de un procesador manejen distintos fragmentos de la imagen al mismo tiempo, acelerando significativamente el proceso de decodificación. En este sentido, cada tile se convierte en una unidad independiente, que puede ser decodificada sin necesidad de esperar por los datos de otros tiles. Aunque esta segmentación puede conllevar una pequeña pérdida en la eficiencia de la compresión, debido a la imposibilidad de realizar algunas predicciones entre tiles adyacentes, el beneficio de la paralelización en el decodificador supera este inconveniente.

El uso de múltiples núcleos para procesar imágenes en tiles también hace posible un aumento notable en la velocidad de decodificación. Por ejemplo, si un procesador de cuatro núcleos puede manejar cuatro tiles de manera simultánea, el tiempo de decodificación se reduce proporcionalmente. Esta estructura se observa con claridad en los códecs más recientes, como HEVC, que emplean un formato específico para la partición de tiles y la codificación de la imagen en bloques más pequeños. Cada core en el procesador puede encargarse de la decodificación de un tile de manera independiente, lo que elimina posibles cuellos de botella en el procesamiento.

La flexibilidad en el tamaño de los bloques y unidades de predicción en códecs como HEVC y VVC es otro aspecto crucial. Las unidades básicas de codificación, conocidas como unidades de árbol de codificación (CTU, por sus siglas en inglés), permiten que cada unidad sea subdividida en bloques de diferentes tamaños según las necesidades de la imagen. Esta variabilidad no solo mejora la eficiencia en la compresión, sino que también optimiza la predicción de áreas estáticas o dinámicas de la imagen. Al adaptar el tamaño de los bloques a la complejidad y el contenido de la escena, los códecs pueden reducir el número de bits necesarios para representar áreas de la imagen con detalles más uniformes, mientras que para áreas con mayor movimiento o variabilidad, se utilizan bloques más pequeños y precisos.

Los códecs modernos, como H.265/HEVC y VVC, también permiten un control más detallado sobre los patrones de predicción, dividiendo la imagen en áreas de predicción (PU) que pueden tener diferentes tamaños y tipos. La predicción intra se basa en datos previamente codificados dentro de la misma imagen, mientras que la predicción inter utiliza cuadros previamente codificados para mejorar la eficiencia de compresión. La elección de las estructuras de predicción más adecuadas depende de la calidad de la predicción y de la cantidad de datos necesarios para codificar tanto la predicción en sí como los parámetros asociados, como los vectores de movimiento.

La evolución de estos métodos de codificación y decodificación refleja los avances en la potencia de procesamiento y las demandas de los nuevos formatos de vídeo. Las imágenes en alta resolución, como las de 4K o incluso 8K, requieren una infraestructura capaz de manejar grandes volúmenes de datos de manera eficiente, lo que solo es posible gracias a la división de la imagen en unidades manejables que pueden ser procesadas de manera paralela. La implementación de estos avances en hardware, como los procesadores multi-núcleo y la decodificación distribuida, permite que el vídeo de alta calidad sea accesible para dispositivos con recursos limitados.

Es esencial entender que la eficiencia de estos códecs no solo depende de la tecnología de codificación, sino también de la arquitectura del procesador y la forma en que los datos se manejan a nivel de hardware. Los códecs modernos están diseñados para aprovechar las capacidades de procesamiento paralelo de los sistemas actuales, pero la verdadera clave del rendimiento está en la capacidad de gestionar eficientemente las dependencias de datos entre los diferentes bloques y tiles.

¿Cómo funciona la codificación aritmética binaria y cómo se determina la secuencia de códigos?

La codificación aritmética binaria (BAC) se basa en la idea de representar una secuencia de valores binarios dentro de un intervalo de números decimales. Este proceso se realiza dividiendo continuamente el intervalo en subintervalos más pequeños, cuyas longitudes corresponden a las probabilidades de aparición de cada valor binario. De esta manera, se obtiene una representación eficiente de la información, en la que la longitud de la fracción binaria que se transmite al decodificador está directamente relacionada con la probabilidad de cada secuencia.

En el ejemplo presentado, el codificador debe transmitir una secuencia de valores binarios b0,b1,b2b_0, b_1, b_2. Cada uno de estos valores puede ser 0 o 1, y la probabilidad de que cada valor sea 0 o 1 está predefinida. Para el primer valor b0b_0, las probabilidades son P(0)=0.3P(0) = 0.3 y P(1)=0.7P(1) = 0.7, lo que significa que b0=1b_0 = 1 es más probable que b0=0b_0 = 0. De manera similar, b1b_1 tiene probabilidades P(0)=0.1P(0) = 0.1 y P(1)=0.9P(1) = 0.9, lo que hace que b1=1b_1 = 1 también sea mucho más probable. Finalmente, b2b_2 tiene probabilidades equilibradas de 0.5 para 0 y 1.

El proceso de codificación comienza con un rango inicial que abarca el intervalo (0,1)(0, 1). Este rango se divide en subintervalos más pequeños, de acuerdo con las probabilidades de b0b_0. En este caso, el intervalo se divide en dos subintervalos: uno para b0=0b_0 = 0 (que cubre de 0 a 0.3) y otro para b0=1b_0 = 1 (que cubre de 0.3 a 1). Luego, se realiza lo mismo para b1b_1 y b2b_2, cada uno dividiendo su intervalo correspondiente en función de sus propias probabilidades.

El codificador, después de determinar en qué subintervalo se encuentra el valor de la secuencia, transmite una fracción binaria que representa un punto dentro de este subintervalo final. En el ejemplo dado, el punto de la fracción binaria es 0.01011b0.01011_b, que corresponde al valor decimal 0.343750.34375. Este número es el más corto que cae dentro del intervalo final para la secuencia 1, 0, 1. El decodificador, al recibir esta fracción binaria, utiliza la misma información sobre las probabilidades para reconstruir la secuencia original de valores binarios.

El proceso es completamente reversible. El decodificador sabe que cada subintervalo está asociado con un valor específico de b0b_0, b1b_1 y b2b_2 y puede, por lo tanto, identificar de forma precisa cada uno de los valores de la secuencia. En este caso, el decodificador determina que el valor de b0b_0 es 1, b1b_1 es 0 y b2b_2 es 1, utilizando la fracción binaria recibida.

El aspecto interesante de la codificación aritmética binaria es que no se transmite una secuencia de bits para cada valor binario individualmente. En lugar de eso, se transmite una fracción binaria que se encuentra dentro del rango final determinado por las probabilidades de la secuencia completa. Esta fracción puede ser más corta o más larga dependiendo de la probabilidad de que cada secuencia ocurra, lo que hace que la codificación aritmética sea muy eficiente desde el punto de vista del almacenamiento y la transmisión.

En un escenario general, si la secuencia de valores binarios cambia, el rango final en el que se encuentra la fracción binaria también cambiará. Por ejemplo, si la secuencia fuera 1, 1, 0, el intervalo final sería de 0.370.37 a 0.6850.685, y la fracción binaria más corta que se encuentra dentro de este intervalo sería 0.1b0.1_b, correspondiente al valor decimal 0.50.5. A medida que se cambian las secuencias, el intervalo final se ajusta y, por lo tanto, la longitud de la fracción binaria también se ajusta en consecuencia.

Es importante comprender que la longitud de la fracción binaria depende de la amplitud del intervalo final, lo que a su vez está determinado por las probabilidades de ocurrencia de la secuencia. Cuanto más probable sea una secuencia, más corta será la fracción binaria asociada. Por ejemplo, una secuencia con una probabilidad alta de ocurrir, como b0=1,b1=1,b2=0b_0 = 1, b_1 = 1, b_2 = 0, se representará con una fracción binaria más corta que una secuencia menos probable como b0=0,b1=0,b2=1b_0 = 0, b_1 = 0, b_2 = 1.

Además, el tamaño de la fracción binaria no es fijo y varía según la secuencia. Las secuencias con mayor probabilidad tienen subintervalos más pequeños, lo que permite representar las secuencias con menos bits. Esto hace que la codificación aritmética binaria sea más eficiente en términos de espacio de almacenamiento, especialmente cuando se codifican secuencias que siguen distribuciones de probabilidad conocidas y predecibles.

Es esencial que tanto el codificador como el decodificador tengan acceso a las probabilidades predefinidas para poder interpretar correctamente las secuencias codificadas. Sin esta información compartida, el proceso de codificación y decodificación no sería posible, ya que el decodificador no sabría en qué subintervalos buscar.