Información seca | Optimización del algoritmo SAO de codificación H.265
Introducción a la tecnología SAO
El nombre completo de SAO es Sample adaptiveoffset, y el significado chino correspondiente es compensación adaptativa de muestreo. SAO es una tecnología de compresión importante en la especificación de codificación H.265. La idea de esta tecnología proviene de la propuesta de Samsung JCTVC-A124. Los resultados de las pruebas experimentales muestran que SAO puede generar una ganancia de compresión mucho mayor que Deblock y ALF.
La posición del módulo SAO en la estructura del codificador Figura 1 es la siguiente (parte roja):
Figura 1: La posición de SAO en el codificador
La posición de SAO en la estructura del decodificador en la Figura 2 es la siguiente (parte roja):
Figura 2 La posición de SAO en el decodificador
Se puede ver desde el diagrama de flujo Out, SAO y ALF son operaciones dentro del bucle, conectadas después de Deblock. La entrada incluye la imagen YUV original y la salida de Deblock. Los parámetros generados deben estar codificados en entropía. Consulte la Figura 3:
Figura 3 Descripción general del algoritmo SAO
2 Introducción al algoritmo SAO
Después de comprimir y descomprimir la imagen, la precisión aumentará perderse. Se puede ver en la fórmula de cálculo de psnr que la suma de los cuadrados de las diferencias entre los datos reconstruidos y los datos originales YUV determina psnr. SAO analiza los datos originales y los datos reconstruidos, y realiza operaciones de compensación de compensación después del desbloqueo para acercarlo lo más posible al valor de píxel original para lograr el propósito de mejorar psnr.
Error cuadrático medio:
Relación señal-ruido máxima:
¿Cómo calcular específicamente para mejorar el valor de PSNR? Una idea directa es desbloquear el datos reconstruidos Haga una diferencia con cada píxel en la misma posición en el YUV original y pase esta diferencia al decodificador, para que el YUV pueda restaurarse por completo. De hecho, hacerlo dará como resultado una tasa de bits muy alta y ningún efecto de compresión.
Para mejorar psnr y al mismo tiempo aumentar la velocidad de código en una cantidad muy pequeña, H.265 hace un equilibrio entre la velocidad de código y psnr. Veamos cómo se hace.
H.265 se basa en CTB para SAO Al analizar los datos originales y los datos reconstruidos después del desbloqueo, el píxel se divide en tres modos SAO:
SaoTypeIdx, hay tres. píxeles, los valores de píxeles son: 32, 35, 35, por lo que podemos saber que el valor de píxel promedio de la banda es (32 35 35)/3 = 34 y la banda correspondiente después del desbloqueo contiene tres píxeles, respectivamente 30; , 32 , 34, el valor promedio es (30 32 34) / 3 = 32. Se puede ver que en esta banda, el valor promedio de píxeles original es 34-32=2 mayor que el reconstruido. Por lo tanto, desplazamiento = 2. se puede asignar a esta banda, en el lado del decodificador, agregue 2 a cada valor de píxel de esta banda. Esto garantiza que el píxel reconstruido que aparece en esta banda sea igual al valor promedio original. Haga esto para los 32 y finalmente seleccione 4 consecutivos.
Para Band OffsetMode y Edge Offset Mode, si los parámetros SAO del CTB actual son los mismos que los parámetros SAO del CTB izquierdo o superior, entonces no hay necesidad de transmitir los parámetros SAO para el modo actual. CTB, pero utilícelos directamente los parámetros SAO del CTB izquierdo o superior.
Optimización de los tres algoritmos SAO
1. Algoritmos comúnmente utilizados antes de la optimización:
Para cada píxel en el CTB, es necesario calcular:
p >
1. Primero, calcule la diferencia entre el valor del píxel original y el valor del píxel reconstruido. La diferencia de cada píxel está representada por la variable offset_value;
2. Calcule cada valor de subtipo de cada píxel BO, EO0, EO1, EO2, EO3 por separado. Este tipo se denomina sao_class. De esta manera, la matriz cuadrada de 64 * 64 CTB debe recorrerse 5 veces y el número de visitas es aproximadamente. es: 5*64*64
3. Luego, para la matriz cuadrada de 64*64 de CTB, ***4096 píxeles cuentan la suma del valor_desplazamiento de cada tipo y el número de píxeles de cada tipo. cnt_of_class.
2. Algoritmo optimizado:
La característica de este algoritmo es desplazar el offset_value de cada píxel hacia la izquierda 12 bits, un entero de 32 bits, y colocar los 20 altos bits.valor de offset_value, los 12 bits inferiores contienen el número de píxeles. Para cada píxel, los 12 bits inferiores se inicializan en 1. Un bloque CTB de 64*64, el mismo subtipo SAO, solo puede tener 2^12 píxeles como máximo. así que use los 12 bits inferiores. La cantidad de subtipos guardados en 12 bits es suficiente para no desbordarse, como se muestra a continuación:
12 ~ 31 bits (offset_value)
0 ~ 11. (cnt_of_class)
Figura siete formatos de datos compuestos
De esta manera, offset_value y cnt_of_class se fusionan en un entero de 32 bits, de modo que los dos datos se pueden acumular y ejecutar al mismo tiempo. mismo tiempo, y la cantidad de cálculo se reduce a la mitad.
Suponiendo un bloque CTB de 64*64, el valor de compensación se define como la siguiente matriz:
Offset_value[64][64] = { … …} Cada formato de datos es; es consistente con el formato de datos
Rec_pixel_value[64][64] = { … …}; Valor de píxel reconstruido 0 ~ 255
BO_class[64][64] = { … … } ; El rango de valores es 0 ~ 31
EO0_class[64][64] = { … …} ; El rango de valores es 0 ~ 4
EO1_class[64][64] = { … …} ; El rango de valores es 0 ~ 4
EO2_class[64][64] = { … …} ; ][64] = { … …} ; Rango de valores 0 ~ 4
Definir una matriz:
Int BO_Class[32] = {0}
For(int i = 0; i lt; 64; i )
For(intj = 0; j lt; 64; j )
{
Int Rec_pixel_value[i] [j] gt; gt;
BO_Class[class] = Offset_value[i][j]
}
Una vez completada la operación anterior, puede separar cada subclase de BO_Class:
For(int i = 0; i lt; 32; i)
{
offset_value = BO_Class [i] gt; 12;
cnt_of_ BO_Class[i] amp;
}
Modo de compensación de borde:
1. Fusione EO0 y EO1 en una matriz: EO0 y EO1 contienen 5 subcategorías 0 ~ 4, lo que requiere 3 bits para fusionar las dos subcategorías, es necesario crear una matriz bidimensional, con dos subíndices respectivamente. Índice de subclase que representa dos tipos.
Supongamos que el subíndice de la izquierda representa el índice de subcategoría de EO1 y el subíndice de la derecha representa el índice de subcategoría de EO0:
EO_01[8][8]
2. Siga el método anterior Fusione EO2 y EO3 en una matriz:
EO_23[8][8]
3. Complete la siguiente operación:
{ p>
Intclass_0 = EO0_class[i][j];
Int class_1 = EO1_class[i][j]
Int offset = Offset_value[i][j]
EO_01[class_1][class_0] = desplazamiento
EO_23[class_3][class_2] = desplazamiento
4. EO3:
Ent EO0[5] = {0};
Ent EO1[5] = {0};
Ent EO2[5] = { 0 };
Int EO3[5] = {0};
Para(int i = 0; i lt; 5; i)
Para( int J =0; J lt; 5; J )
EO0[j] = EO_01[i][j]; ] ;
EO2[j] = EO_23[i][j];
Finalmente, separe el desplazamiento y el recuento de cada categoría.
Cuatro resumen
Después de la optimización, la cantidad de cálculo de las estadísticas de compensación en SAO se reduce a aproximadamente el 25%. El tiempo de cálculo de todo el módulo SAO 90 lo consume la parte estadística, por lo que la optimización de este algoritmo es más obvia en el nivel C. A nivel de ensamblaje, hay un cierto efecto, pero no es obvio porque se agrega una matriz de 8 * 8 en el medio de la operación. Esta matriz no es propicia para la implementación utilizando el método paralelo del conjunto de instrucciones multimedia.