10. Estructura AVFrame

4.0 estructura AVFrame

typedef struct AVFrame {
    
    
	#define AV_NUM_DATA_POINTERS 8
	uint8_t *data[AV_NUM_DATA_POINTERS];
	int linesize[AV_NUM_DATA_POINTERS];
	
	uint8_t **extended_data;
	
	/**宽高 */
	int width, height;
	
	int nb_samples;
	int format;
	
	/**是否是关键帧*/
	int key_frame;
	
	/**帧类型(I,B,P)*/
	enum AVPictureType pict_type;
	
	uint8_t *base[AV_NUM_DATA_POINTERS];
	AVRational sample_aspect_ratio;
	
	int64_t pts;
	int64_t pkt_pts;
	int64_t pkt_dts;
	
	int coded_picture_number;
	int display_picture_number;
	int quality;
	int reference;
	
	/**QP 表*/
	int8_t *qscale_table;
	
	int qstride;
	int qscale_type;
	
	/**跳过宏块表 */
	uint8_t *mbskip_table;
	
	/**运动矢量表*/
	int16_t (*motion_val[2])[2];
	
	/**宏块类型表 */
	uint32_t *mb_type;
	
	/**DCT 系数 */
	short *dct_coeff;
	
	/**参考帧列表 */
	int8_t *ref_index[2];
	
	void *opaque;
	uint64_t error[AV_NUM_DATA_POINTERS];
	
	int type;
	int repeat_pict;
	int interlaced_frame;
	int top_field_first;
	int palette_has_changed;
	int buffer_hints;
	
	AVPanScan *pan_scan;
	int64_t reordered_opaque;
	void *hwaccel_picture_private;
	struct AVCodecContext *owner;
	void *thread_opaque;
	
	/**
	* log2 of the size of the block which a single vector in motion_val represents:
	* (4->16x16, 3->8x8, 2-> 4x4, 1-> 2x2)
	* - encoding: unused
	* - decoding: Set by libavcodec.
	*/
	uint8_t motion_subsample_log2;
	
	/**(音频)采样率 */
	int sample_rate;
	
	uint64_t channel_layout;
	int64_t best_effort_timestamp;
	int64_t pkt_pos;
	int64_t pkt_duration;
	
	AVDictionary *metadata;
	
	int decode_error_flags;
	
	#define FF_DECODE_ERROR_INVALID_BITSTREAM 1
	#define FF_DECODE_ERROR_MISSING_REFERENCE 2
	
	int64_t channels;
	
	...
	
} AVFrame;

1. La estructura AVFrame se usa generalmente para almacenar datos sin procesar (es decir, datos sin comprimir, como YUV, RGB para video y PCM para audio) y
también contiene información relacionada. Por ejemplo, durante la decodificación se almacenan datos como la tabla de tipo macrobloque, la tabla QP y la tabla de vectores de movimiento.
Los datos relacionados también se almacenan durante la codificación. Por lo tanto, AVFrame es una estructura muy importante cuando se usa FFMPEG para analizar el flujo de código.

2. Veamos la función de varias variables principales (considerando la situación de decodificación aquí):
uint8_t * data [AV_NUM_DATA_POINTERS]: Los datos originales después de la decodificación (YUV, RGB para video, PCM para audio)

int linesize [AV_NUM_DATA_POINTERS]: el tamaño de los datos

int ancho, alto: ancho y alto del cuadro de video (1920x1080,1280x720 ...)

int nb_samples: un AVFrame de audio puede contener varios fotogramas de audio. Esta etiqueta contiene varios

formato int: el tipo de datos original después de la decodificación (YUV420, YUV422, RGB24 ...)

int key_frame: si es un fotograma clave

enum AVPictureType pict_type: tipo de marco (I, B, P ...)

AVRational sample_aspect_ratio: relación de aspecto (16: 9, 4: 3 ...)

int64_t pts: muestra la marca de tiempo

int coded_picture_number: número de fotograma codificado

int display_picture_number: muestra el número de fotograma

int8_t * qscale_table : QP 表

uint8_t * mbskip_table: omite la tabla de macrobloque

int16_t (* motion_val [2]) [2]: tabla de vectores de movimiento

uint32_t * mb_type: Tabla de tipos de macrobloque

short * dct_coeff: coeficiente DCT, esto no se ha extraído

int8_t * ref_index [2]: Lista de cuadros de referencia de estimación de movimiento (parece que H.264 es un estándar relativamente nuevo que involucra múltiples cuadros de referencia)

int interlaced_frame: si está entrelazado

uint8_t motion_subsample_log2: El número de muestras de vectores de movimiento en un macrobloque. Otras variables que toman log no se enumerarán una por una. El código fuente tiene instrucciones detalladas.

3. Aquí nos centraremos en analizar varias variables que requieren cierta comprensión:
1) data []
almacenará datos en formato empaquetado (como RGB24) en data [0].
Para datos en formato plano (como YUV420P), se dividirá en datos [0], datos [1], datos [2] ...
(en YUV420P, los datos [0] almacenan Y, los datos [1] almacenan U, datos [2] Guardar V) Para
obtener más información, consulte: FFMPEG realiza la conversión entre YUV y RGB varios datos de imagen sin procesar (escala de escala)

2) pict_type
contiene los siguientes tipos:

enum AVPictureType {
    
    
	AV_PICTURE_TYPE_NONE = 0, ///< Undefined
	AV_PICTURE_TYPE_I, ///< Intra
	AV_PICTURE_TYPE_P, ///< Predicted
	AV_PICTURE_TYPE_B, ///< Bi-dir predicted
	AV_PICTURE_TYPE_S, ///< S(GMC)-VOP MPEG4
	AV_PICTURE_TYPE_SI, ///< Switching Intra
	AV_PICTURE_TYPE_SP, ///< Switching Predicted
	AV_PICTURE_TYPE_BI, ///< BI type
};

3) La
relación de aspecto de sample_aspect_ratio es una puntuación. AVRational se utiliza para expresar la puntuación en FFMPEG:

/**
* rational number numerator/denominator
*/
typedef struct AVRational{
    
    
	int num; ///< numerator
	int den; ///< denominator
} AVRational;

4) La
tabla QP qscale_table apunta a un bloque de memoria, que almacena el valor QP de cada macrobloque.
La etiqueta del macrobloque es de izquierda a derecha, línea por línea. Cada macrobloque corresponde a 1 QP.
qscale_table [0] es el valor QP del macrobloque en la primera fila y columna 1;
qscale_table [1] es el valor QP del macrobloque en la primera fila y segunda columna;
qscale_table [2] es el valor QP del macrobloque en la primera fila y la tercera columna.
Y así...

El número de macrobloques se calcula mediante la siguiente fórmula:
Nota: El tamaño del macrobloque es 16x16.

Número de macrobloques por línea:
int mb_stride = pCodecCtx-> width / 16 + 1

Número total de macrobloques:
int mb_sum = ((pCodecCtx-> height + 15) >> 4) * (pCodecCtx-> width / 16 + 1)

5) motion_subsample_log2 El
tamaño de la imagen que puede representar un vector de movimiento (en términos de ancho o alto, en píxeles) Tenga en cuenta que aquí se toma log2.
Los siguientes datos se dan en los comentarios del código: (2 4, 2 3, 2 2, 2 1)
4-> 16x16, 3-> 8x8, 2-> 4x4, 1-> 2x2

Es decir, cuando un vector de movimiento representa una imagen de 16x16, el valor es 4; cuando
un vector de movimiento representa una imagen de 8x8, el valor es 3
y así sucesivamente ...

6) La
tabla de vectores de movimiento motion_val almacena todos los vectores de movimiento en un cuadro de video. Este valor se almacena de una forma especial:

int16_t (*motion_val[2])[2];

Se da un fragmento de código en los comentarios:

int mv_sample_log2= 4 - motion_subsample_log2;
int mb_width= (width+15)>>4;
int mv_stride= (mb_width << mv_sample_log2) + 1;
motion_val[direction][x + y*mv_stride][0->mv_x, 1->mv_y];

Probablemente conozca la estructura de los datos:
1. Primero, se divide en dos listas L0 y L1
2. Cada lista (L0 o L1) almacena una serie de MV (cada MV corresponde a una imagen, el tamaño está determinado por motion_subsample_log2 )
3. Cada VM se divide en abscisas y ordenadas (x, y)

Tenga en cuenta que, en el MV FFMPEG MB y almacenado en la estructura no hay asociación, un primer MV es la esquina superior izquierda de la pantalla en el MV (el
tamaño del dibujo depende de la superficie motion_subsample_log2), la segunda pantalla es el primer MV 1 El MV de la imagen en la segunda columna de la fila, y así sucesivamente. Por lo tanto
, es probable que el vector de movimiento de un macrobloque (16x16) sea como se muestra en la figura siguiente (la línea representa el número de vectores de movimiento en una fila):
Figura 10.1. La relación entre el vector de movimiento dividido por 8x8 y la bloque
La relación entre el vector de movimiento dividido por 8x8 y el macrobloque
7) mb_type
tabla de tipos de macrobloques Se almacenan los tipos de todos los macrobloques en un cuadro de vídeo. Su método de almacenamiento es similar a la tabla QP.
Es solo que es de tipo uint32 y QP es de tipo uint8. Cada macrobloque corresponde a una variable de tipo macrobloque.

El tipo de macrobloque se define de la siguiente manera:

//The following defines may change, don't expect compatibility if you use them.
#define MB_TYPE_INTRA4x4 0x0001
#define MB_TYPE_INTRA16x16 0x0002 //FIXME H.264-specific
#define MB_TYPE_INTRA_PCM 0x0004 //FIXME H.264-specific
#define MB_TYPE_16x16 0x0008
#define MB_TYPE_16x8 0x0010
#define MB_TYPE_8x16 0x0020
#define MB_TYPE_8x8 0x0040
#define MB_TYPE_INTERLACED 0x0080
#define MB_TYPE_DIRECT2 0x0100 //FIXME
#define MB_TYPE_ACPRED 0x0200
#define MB_TYPE_GMC 0x0400
#define MB_TYPE_SKIP 0x0800
#define MB_TYPE_P0L0 0x1000
#define MB_TYPE_P1L0 0x2000
#define MB_TYPE_P0L1 0x4000
#define MB_TYPE_P1L1 0x8000
#define MB_TYPE_L0 (MB_TYPE_P0L0 | MB_TYPE_P1L0)
#define MB_TYPE_L1 (MB_TYPE_P0L1 | MB_TYPE_P1L1)
#define MB_TYPE_L0L1 (MB_TYPE_L0 | MB_TYPE_L1)
#define MB_TYPE_QUANT 0x00010000
#define MB_TYPE_CBP 0x0002000
//Note bits 24-31 are reserved for codec specific use (h264 ref0, mpeg1 0mv, ...)

Si un macrobloque contiene una o dos de las definiciones anteriores, el bit correspondiente de la variable de macrobloque correspondiente se establecerá en 1.
Nota: Un macrobloque puede contener varios tipos, pero algunos tipos no se pueden incluir repetidamente. Por ejemplo, un macrobloque no puede ser tanto de 16x16 como de 8x8.

8) La
lista de cuadros de referencia de estimación de movimiento ref_index almacena los índices de cuadros de referencia de todos los macrobloques en un cuadro de vídeo.
Esta lista es realmente inútil en los estándares de codificación de compresión anteriores.
Solo los estándares de codificación como H.264 tienen el concepto de múltiples marcos de referencia.
Cada macrobloque contiene 4 de estos valores, que reflejan el índice del marco de referencia.

Figura 10.2. Cuadro de video Figura 10.3.
Inserte la descripción de la imagen aquí
Resultados de la extracción del parámetro QP
Inserte la descripción de la imagen aquí
Figura 10.4. Embellecido (con color agregado)
Inserte la descripción de la imagen aquí
Figura 10.5. Resultado de la extracción de parámetros de tipo macrobloque
Inserte la descripción de la imagen aquí
Figura 10.6. Embellecido (con color agregado, más claro, S significa omitir macrobloque)
Inserte la descripción de la imagen aquí
Figura 10.7 .El resultado de la extracción del parámetro del vector de movimiento (aquí está List0)
Inserte la descripción de la imagen aquí
Figura 10.8. El resultado de la extracción del parámetro del marco de referencia de la estimación del movimiento
Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/yanghangwww/article/details/104529238
Recomendado
Clasificación