¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

Первая часть: Conceptos básicos para trabajar con vídeos e imágenes.

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

¿Qué? Un códec de vídeo es una pieza de software/hardware que comprime y/o descomprime vídeo digital.

¿Por qué? A pesar de ciertas limitaciones tanto en términos de ancho de banda como
y en términos de espacio de almacenamiento de datos, el mercado exige vídeo de calidad cada vez mayor. ¿Recuerdas que en el último post calculamos el mínimo requerido para 30 fotogramas por segundo, 24 bits por píxel, con una resolución de 480x240? Recibimos 82,944 Mbit/s sin compresión. Actualmente, la compresión es la única forma de transmitir HD/FullHD/4K en general a las pantallas de televisión e Internet. ¿Cómo se logra esto? Ahora veamos brevemente los métodos principales.

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

La traducción se realizó con el apoyo de EDISON Software.

Estamos comprometidos en integración de sistemas de videovigilanciay estamos desarrollando una microtomografía.

Códec frente a contenedor

Un error común que cometen los principiantes es confundir el códec de vídeo digital y el contenedor de vídeo digital. Un contenedor es un formato determinado. Un contenedor que contiene metadatos de vídeo (y posiblemente de audio). El vídeo comprimido puede considerarse como una carga útil de contenedor.

Normalmente, la extensión de un archivo de vídeo indica su tipo de contenedor. Por ejemplo, el archivo video.mp4 probablemente sea un contenedor MPEG-4 Parte 14, y lo más probable es que exista un archivo llamado video.mkv. matrioska. Para estar completamente seguro del códec y formato del contenedor, puede utilizar FFmpeg o MediaInfo.

Un poco de historia

Antes de llegar a ¿Cómo?, profundicemos un poco en la historia para comprender un poco mejor algunos códecs más antiguos.

Códec de vídeo H.261 apareció en 1990 (técnicamente, en 1988) y fue creado para funcionar a una velocidad de transferencia de datos de 64 Kbps. Ya utilizaba ideas como submuestreo de colores, macrobloques, etc. El estándar de códec de vídeo se publicó en 1995. H.263, que se desarrolló hasta 2001.

La primera versión se completó en 2003. H.264 / AVC. Ese mismo año, TrueMotion lanzó su códec de vídeo con pérdida gratuito llamado VP3. Google compró la empresa en 2008 y lanzó VP8 el mismo año. En diciembre de 2012, Google lanzó VP9, y es compatible con aproximadamente ¾ del mercado de navegadores (incluidos los dispositivos móviles).

AV1 es un nuevo códec de vídeo gratuito y de código abierto desarrollado por Alianza para los medios abiertos (AOMedia), que incluye las empresas más famosas, como: Google, Mozilla, Microsoft, Amazon, Netflix, AMD, ARM, NVidia, Intel y Cisco. La primera versión del códec, 0.1.0, se publicó el 7 de abril de 2016.

Nacimiento de AV1

A principios de 2015, Google estaba trabajando en VP10Xiph (que es propiedad de Mozilla) estaba trabajando en Daalay Cisco creó su propio códec de vídeo gratuito llamado Thor.

Entonces MPEG-LA primeros límites anuales anunciados para HEVC (H.265) y una tarifa 8 veces mayor que la del H.264, pero pronto volvieron a cambiar las reglas:

sin límite anual,
tarifa de contenido (0,5% de los ingresos) y
la tarifa unitaria es aproximadamente 10 veces mayor que la de H.264.

Alianza para los medios abiertos fue creado por empresas de diferentes ámbitos: fabricantes de equipos (Intel, AMD, ARM, Nvidia, Cisco), proveedores de contenidos (Google, Netflix, Amazon), creadores de navegadores (Google, Mozilla) y otros.

Las empresas tenían un objetivo común: un códec de vídeo libre de derechos. Entonces aparece AV1 con una licencia de patente mucho más sencilla. Timothy B. Terryberry hizo una presentación impresionante que se convirtió en el origen del actual concepto AV1 y su modelo de licencia.

Te sorprenderá saber que puedes analizar el códec AV1 a través de un navegador (los interesados ​​pueden ir a aomanalyzer.org).

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

Códec universal

Veamos los principales mecanismos subyacentes al códec de vídeo universal. La mayoría de estos conceptos son útiles y se utilizan en códecs modernos como VP9, AV1 и HEVC. Os advierto que muchas de las cosas explicadas se simplificarán. A veces se utilizarán ejemplos del mundo real (como con H.264) para demostrar las tecnologías.

1er paso: dividir la imagen

El primer paso es dividir el marco en varias secciones, subsecciones y más.

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

¿Para qué? Hay muchas razones. Cuando dividimos una imagen, podemos predecir con mayor precisión el vector de movimiento utilizando secciones pequeñas para partes móviles pequeñas. Mientras que para un fondo estático puedes limitarte a secciones más grandes.

Los códecs suelen organizar estas secciones en secciones (o fragmentos), macrobloques (o bloques de árbol de codificación) y múltiples subsecciones. El tamaño máximo de estas particiones varía, HEVC lo establece en 64x64 mientras que AVC usa 16x16 y las subparticiones se pueden dividir en tamaños de hasta 4x4.

¿Recuerdas los tipos de marcos del último artículo? Lo mismo se puede aplicar a los bloques, por lo que podemos tener un fragmento I, un bloque B, un macrobloque P, etc.

Para aquellos que quieran practicar, observen cómo se divide la imagen en secciones y subsecciones. Para ello, puedes utilizar el ya mencionado en el artículo anterior. Analizador de vídeo Intel Pro (la que es de pago, pero con una versión de prueba gratuita que está limitada a los 10 primeros fotogramas). Secciones analizadas aquí VP9:

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

2do paso - previsión

Una vez que tengamos secciones, podremos hacer pronósticos astrológicos para ellas. Para Previsiones del INTER debe ser transferido vectores de movimiento y el resto, y para la previsión INTRA se transmite dirección de pronóstico y el resto.

3er paso - transformación

Una vez que tenemos un bloque residual (sección predicha → sección real), es posible transformarlo de tal manera que sepamos qué píxeles se pueden descartar manteniendo la calidad general. Hay algunas transformaciones que proporcionan el comportamiento exacto.

Aunque existen otros métodos, veámoslos con más detalle. transformada de coseno discreta (DCT - de transformada discreta del coseno). Funciones principales de DCT:

  • Convierte bloques de píxeles en bloques de coeficientes de frecuencia del mismo tamaño.
  • Condensa energía para ayudar a eliminar la redundancia espacial.
  • Proporciona reversibilidad.

2 de febrero de 2017 Sintra R.J. (Cintra, RJ) y Bayer F.M. (Bayer FM) publicó un artículo sobre una transformación similar a DCT para la compresión de imágenes que requiere sólo 14 adiciones.

No te preocupes si no entiendes los beneficios de cada punto. Ahora usemos ejemplos específicos para ver su valor real.

Tomemos este bloque de píxeles de 8x8:

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

Este bloque se representa en la siguiente imagen de 8 por 8 píxeles:

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

Aplique DCT a este bloque de píxeles y obtenga un bloque de coeficientes de 8x8:

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

Y si renderizamos este bloque de coeficientes, obtendremos la siguiente imagen:

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

Como puedes ver, no se parece a la imagen original. Puedes ver que el primer coeficiente es muy diferente de todos los demás. Este primer coeficiente se conoce como coeficiente DC, que representa todas las muestras de la matriz de entrada, algo así como un promedio.

Este bloque de coeficientes tiene una propiedad interesante: separa los componentes de alta frecuencia de los de baja frecuencia.

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

En una imagen, la mayor parte de la potencia se concentra en frecuencias más bajas, por lo que si convierte la imagen en sus componentes de frecuencia y descarta los coeficientes de frecuencia más altos, puede reducir la cantidad de datos necesarios para describir la imagen sin sacrificar demasiada calidad de imagen.

La frecuencia se refiere a la rapidez con la que cambia la señal.

Intentemos aplicar el conocimiento adquirido en el caso de prueba convirtiendo la imagen original a su frecuencia (bloque de coeficientes) usando DCT y luego descartando parte de los coeficientes menos importantes.

Primero lo convertimos al dominio de la frecuencia.

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

A continuación, descartamos parte (67%) de los coeficientes, principalmente la parte inferior derecha.

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

Finalmente, reconstruimos la imagen a partir de este bloque de coeficientes descartado (recuerde, debe ser invertible) y la comparamos con el original.

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

Vemos que se parece a la imagen original, pero hay muchas diferencias con el original. Tiramos el 67,1875% y todavía obtuvimos algo parecido al original. Era posible descartar más cuidadosamente los coeficientes para obtener una imagen de calidad aún mejor, pero ese es el siguiente tema.

Cada coeficiente se genera utilizando todos los píxeles.

Importante: cada coeficiente no se asigna directamente a un píxel, sino que es una suma ponderada de todos los píxeles. Este sorprendente gráfico muestra cómo se calculan el primer y segundo coeficiente utilizando ponderaciones únicas para cada índice.

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

También puedes intentar visualizar la DCT observando una formación de imagen simple basada en ella. Por ejemplo, aquí está el símbolo A generado usando cada ponderación de coeficiente:

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

4to paso - cuantificación

Después de descartar algunos coeficientes en el paso anterior, en el último paso (transformación) realizamos una forma especial de cuantificación. En esta etapa es aceptable perder información. O, más simplemente, cuantificaremos los coeficientes para lograr la compresión.

¿Cómo se puede cuantificar un bloque de coeficientes? Uno de los métodos más simples es la cuantificación uniforme, cuando tomamos un bloque lo dividimos por un valor (por 10) y redondeamos el resultado.

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

¿Podemos revertir este bloque de coeficientes? Sí podemos, multiplicando por el mismo valor por el que dividimos.

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

Este enfoque no es el mejor porque no tiene en cuenta la importancia de cada coeficiente. Se podría usar una matriz de cuantificadores en lugar de un valor único, y esta matriz podría explotar la propiedad DCT cuantificando la mayoría de la parte inferior derecha y la minoría de la parte superior izquierda.

Paso 5: codificación de entropía

Una vez que hayamos cuantificado los datos (bloques de imágenes, fragmentos, fotogramas), aún podemos comprimirlos sin pérdidas. Hay muchas formas algorítmicas de comprimir datos. Vamos a echar un vistazo rápido a algunos de ellos; para una comprensión más profunda, puede leer el libro Comprensión de la compresión: compresión de datos para desarrolladores modernos ("Comprensión de la compresión: compresión de datos para desarrolladores modernos").

Codificación de video usando VLC

Digamos que tenemos un flujo de personajes: a, e, r и t. En esta tabla se presenta la probabilidad (que varía de 0 a 1) de la frecuencia con la que aparece cada personaje en una secuencia.

a e r t
Probabilidad 0,3 0,3 0,2 0,2

Podemos asignar códigos binarios únicos (preferiblemente pequeños) a los más probables y códigos más grandes a los menos probables.

a e r t
Probabilidad 0,3 0,3 0,2 0,2
Código binario 0 10 110 1110

Comprimimos el flujo, asumiendo que terminaremos gastando 8 bits por cada carácter. Sin compresión, se necesitarían 24 bits por carácter. Si reemplazas cada carácter con su código, ¡obtendrás ahorros!

El primer paso es codificar el carácter. e, que es igual a 10, y el segundo carácter es a, al que se le suma (no de forma matemática): [10][0], y finalmente el tercer carácter t, lo que hace que nuestro flujo de bits comprimido final sea igual a [10][0][1110] o 1001110, que requiere sólo 7 bits (3,4 veces menos espacio que el original).

Tenga en cuenta que cada código debe ser un código único con un prefijo. Algoritmo de Huffman le ayudará a encontrar estos números. Aunque este método no está exento de defectos, existen códecs de vídeo que todavía ofrecen este método algorítmico de compresión.

Tanto el codificador como el decodificador deben tener acceso a una tabla de símbolos con sus códigos binarios. Por tanto, también es necesario enviar una tabla como entrada.

Codificación aritmética

Digamos que tenemos un flujo de personajes: a, e, r, s и t, y su probabilidad se presenta en esta tabla.

a e r s t
Probabilidad 0,3 0,3 0,15 0,05 0,2

Usando esta tabla, construiremos rangos que contengan todos los caracteres posibles, ordenados por el número más grande.

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

Ahora codifiquemos una secuencia de tres caracteres: comer.

Primero seleccione el primer personaje. e, que está en el subrango de 0,3 a 0,6 (sin incluir). Tomamos este subrango y lo volvemos a dividir en las mismas proporciones que antes, pero para este nuevo rango.

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

Sigamos codificando nuestra transmisión. comer. Ahora toma el segundo personaje. a, que está en el nuevo subrango de 0,3 a 0,39, y luego toma nuestro último carácter t y repitiendo el mismo proceso nuevamente, obtenemos el subrango final de 0,354 a 0,372.

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

Sólo necesitamos seleccionar un número en el último subrango de 0,354 a 0,372. Elijamos 0,36 (pero puedes elegir cualquier otro número en este subrango). Sólo con este número podremos restaurar nuestra transmisión original. Es como si estuviéramos trazando una línea dentro de los rangos para codificar nuestra transmisión.

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

La operación inversa (es decir, descodificación) es igual de simple: con nuestro número 0,36 y nuestro rango inicial, podemos ejecutar el mismo proceso. Pero ahora, usando este número, identificamos la transmisión codificada con este número.

Con el primer rango, notamos que nuestro número corresponde al segmento, por lo tanto este es nuestro primer carácter. Ahora volvemos a dividir este subrango siguiendo el mismo proceso que antes. Aquí puedes ver que 0,36 corresponde al símbolo a, y luego de repetir el proceso llegamos al último carácter t (formando nuestra secuencia codificada original comer).

Tanto el codificador como el decodificador deben tener una tabla de probabilidades de símbolos, por lo que es necesario enviarla también en los datos de entrada.

Bastante elegante, ¿no? A quien se le ocurrió esta solución fue muy inteligente. Algunos códecs de vídeo utilizan esta técnica (o al menos la ofrecen como opción).

La idea es comprimir sin pérdidas un flujo de bits cuantificado. Seguramente a este artículo le faltan toneladas de detalles, razones, compensaciones, etc. Pero si eres desarrollador, deberías saber más. Los nuevos códecs intentan utilizar diferentes algoritmos de codificación de entropía, como ANS.

Paso 6: formato de flujo de bits

Después de hacer todo esto, solo queda descomprimir los fotogramas comprimidos en el contexto de los pasos realizados. El decodificador debe ser informado explícitamente de las decisiones tomadas por el codificador. El decodificador debe contar con toda la información necesaria: profundidad de bits, espacio de color, resolución, información de predicción (vectores de movimiento, predicción INTER direccional), perfil, nivel, velocidad de fotogramas, tipo de fotograma, número de fotograma y mucho más.

Echaremos un vistazo rápido al flujo de bits. H.264. Nuestro primer paso es crear un flujo de bits H.264 mínimo (FFmpeg agrega de forma predeterminada todas las opciones de codificación, como SEI NAL — descubriremos de qué se trata un poco más adelante). Podemos hacer esto usando nuestro propio repositorio y FFmpeg.

./s/ffmpeg -i /files/i/minimal.png -pix_fmt yuv420p /files/v/minimal_yuv420.h264

Este comando generará un flujo de bits sin formato. H.264 con un cuadro, resolución 64×64, con espacio de color YUV420. En este caso se utiliza la siguiente imagen como marco.

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

flujo de bits H.264

Estándar AVC (H.264) determina que la información se enviará en macrotramas (en el sentido de red), llamadas NAL (Este es un nivel de abstracción de red). El objetivo principal de NAL es proporcionar una presentación en vídeo "apto para web". Este estándar debería funcionar en televisores (basado en transmisión), Internet (basado en paquetes).

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

Hay un marcador de sincronización para definir los límites de los elementos NAL. Cada token de sincronización contiene un valor 0x00 0x00 0x01, excepto el primero, que es igual a 0x00 0x00 0x00 0x01. si lanzamos volcado hexadecimal Para el flujo de bits H.264 generado, identificamos al menos tres patrones NAL al principio del archivo.

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

Como ya hemos dicho, el decodificador debe conocer no sólo los datos de la imagen, sino también los detalles del vídeo, el fotograma, los colores, los parámetros utilizados y mucho más. El primer byte de cada NAL define su categoría y tipo.

Identificador de tipo NAL Descripción
0 Consejo nuevo
1 Fragmento de imagen codificada sin IDR
2 Sección de datos de corte codificados A
3 Sección de datos de corte codificados B
4 Sección de datos de corte codificados C
5 Fragmento IDR codificado de una imagen IDR
6 Más información sobre la extensión SEI
7 Conjunto de parámetros de secuencia SPS
8 Conjunto de parámetros de imagen PPS
9 Separador de acceso
10 Fin de secuencia
11 Fin del hilo
... ...

Normalmente, el primer NAL de un flujo de bits es PLC. Este tipo de NAL se encarga de informar sobre variables de codificación comunes como perfil, nivel, resolución, etc.

Si nos saltamos el primer marcador de sincronización, podemos decodificar el primer byte para averiguar qué tipo NAL es el primero.

Por ejemplo, el primer byte después del token de sincronización es 01100111, donde el primer bit (0) está en el campo fbit_cero_orbitado. Siguientes 2 bits (11) nos dice el campo nal_ref_idc, que indica si este NAL es un campo de referencia o no. Y los 5 bits restantes (00111) nos dice el campo tipo_unidad_nal, en este caso es el bloque SPS (7) NAL.

Segundo byte (binario=01100100, hexagonal=0x64, dic=100) en SPS NAL es el campo perfil_idc, que muestra el perfil que utilizó el codificador. En este caso, se utilizó un perfil alto limitado (es decir, un perfil alto sin soporte bidireccional del segmento B).

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

Si nos fijamos en la especificación de flujo de bits H.264 para SPS NAL, encontraremos muchos valores para el nombre del parámetro, la categoría y la descripción. Por ejemplo, veamos los campos. pic_width_in_mbs_minus_1 и pic_height_in_map_units_minus_1.

Nombre del parámetro categoría Descripción
pic_width_in_mbs_minus_1 0 ue (v)
pic_height_in_map_units_minus_1 0 ue (v)

Si realizamos algunas operaciones matemáticas con los valores de estos campos obtendremos resolución. Se puede representar 1920 x 1080 usando pic_width_in_mbs_minus_1 con un valor de 119 ((119 + 1) * macroblock_size = 120 * 16 = 1920). Nuevamente, para ahorrar espacio, en lugar de codificar 1920, lo hicimos con 119.

Si continuamos revisando nuestro video creado en forma binaria (por ejemplo: xxd -b -c 11v/minimal_yuv420.h264), luego puedes ir al último NAL, que es el marco en sí.

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

Aquí vemos sus primeros valores de 6 bytes: 01100101 10001000 10000100 00000000 00100001 11111111. Dado que se sabe que el primer byte indica el tipo NAL, en este caso (00101) es un fragmento IDR (5), y luego puedes explorarlo más a fondo:

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

Usando la información de la especificación, será posible decodificar el tipo de fragmento (tipo_de_corte) y número de fotograma (núm_cuadro) entre otros campos importantes.

Para obtener los valores de algunos campos (ue(v), me(v), se(v) O te(v)), necesitamos decodificar el fragmento usando un decodificador especial basado en código Golomb exponencial. Este método es muy eficaz para codificar valores de variables, especialmente cuando hay muchos valores predeterminados.

Significados tipo_de_corte и núm_cuadro de este video son 7 (fragmento I) y 0 (primer cuadro).

Un flujo de bits puede considerarse como un protocolo. Si desea saber más sobre el flujo de bits, debe consultar la especificación. UIT H.264. Aquí hay un diagrama macro que muestra dónde están los datos de la imagen (YUV en forma comprimida).

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

Se pueden examinar otros flujos de bits, como VP9, H.265 (HEVC) o incluso nuestro nuevo mejor flujo de bits AV1. ¿Son todos similares? No, pero una vez que entiendes al menos uno, es mucho más fácil entender el resto.

¿Quieres practicar? Explora el flujo de bits H.264

Puede generar un vídeo de un solo cuadro y utilizar MediaInfo para examinar el flujo de bits. H.264. De hecho, nada le impide siquiera mirar el código fuente que analiza el flujo de bits. H.264 (AVC).

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

Para practicar, puedes utilizar Intel Video Pro Analyzer (¿ya dije que el programa es de pago, pero existe una versión de prueba gratuita con un límite de 10 fotogramas?).

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

Descripción

Tenga en cuenta que muchos códecs modernos utilizan el mismo modelo que acabamos de estudiar. Aquí, echemos un vistazo al diagrama de bloques del códec de video. Thor. Contiene todos los pasos que hemos seguido. El objetivo de esta publicación es al menos brindarle una mejor comprensión de las innovaciones y la documentación en esta área.

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

Anteriormente, se calculaba que se necesitarían 139 GB de espacio en disco para almacenar un archivo de vídeo de una hora de duración con calidad 720p y 30 fps. Si utiliza los métodos discutidos en este artículo (predicciones internas y entre fotogramas, transformación, cuantificación, codificación de entropía, etc.), entonces puede lograr (basándonos en el hecho de que gastamos 0,031 bits por píxel), un vídeo de bastante Calidad satisfactoria, ocupando sólo 367,82 MB, no 139 GB de memoria.

¿Cómo logra H.265 una mejor relación de compresión que H.264?

Ahora que sabemos más sobre cómo funcionan los códecs, es más fácil entender cómo los códecs más nuevos pueden ofrecer resoluciones más altas con menos bits.

Si comparas AVC и HEVC, vale la pena recordar que casi siempre se trata de elegir entre una mayor carga de CPU y una mayor relación de compresión.

HEVC tiene más opciones de sección (y subsección) que AVC, más direcciones de predicción internas, codificación de entropía mejorada y más. Todas estas mejoras se han realizado H.265 capaz de comprimir un 50% más que H.264.

¿Cómo funciona un códec de vídeo? Parte 2. Qué, por qué, cómo

Первая часть: Conceptos básicos para trabajar con vídeos e imágenes.

Fuente: habr.com

Añadir un comentario