AVFrame是包含码流参数较多的结构体。
参考结构体理解:http://www.jianshu.com/p/d109e7ef9749
uint8_t *data[AV_NUM_DATA_POINTERS]
:解码后原始数据(对视频来说是YUV,RGB,对音频来说是PCM)
对于packed格式的数据(例如RGB24),会存到data[0]里面。
对于planar格式的数据(例如YUV420P),则会分开成data[0],data[1],data[2]...(YUV420P中data[0]存Y,data[1]存U,data[2]存V)
int linesize[AV_NUM_DATA_POINTERS]
:data中“一行”数据的大小。注意:未必等于图像的宽,一般大于图像的宽。
int width, height
:视频帧宽和高(1920x1080,1280x720...)
int nb_samples
:音频的一个AVFrame中可能包含多个音频帧,在此标记包含了几个int format:解码后原始数据类型(YUV420,YUV422,RGB24...)
int key_frame
:是否是关键帧
enum AVPictureType pict_type
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
};
:帧类型(I,B,P...)
AVRational sample_aspect_ratio
:宽高比(16:9,4:3...)
宽高比是一个分数,FFMPEG中用AVRational表达分数:
int64_t pts
:显示时间戳
int coded_picture_number
:编码帧序号
int display_picture_number
:显示帧序号
int8_t *qscale_table
:QP表
QP表指向一块内存,里面存储的是每个宏块的QP值。宏块的标号是从左往右,一行一行的来的。每个宏块对应1个QP。
qscale_table[0]就是第1行第1列宏块的QP值;qscale_table[1]就是第1行第2列宏块的QP值;qscale_table[2]就是第1行第3列宏块的QP值。以此类推...
宏块的个数用下式计算:
注:宏块大小是16x16的。
每行宏块数:
int mb_stride = pCodecCtx->width/16+1
宏块的总数:
int mb_sum = ((pCodecCtx->height+15)>>4)*(pCodecCtx->width/16+1)
uint8_t *mbskip_table
:跳过宏块表
int16_t (*motion_val[2])[2]
:运动矢量表
运动矢量表存储了一帧视频中的所有运动矢量。
该值的存储方式比较特别:
int16_t (*motion_val[2])[2];
uint32_t *mb_type
:宏块类型表
short *dct_coeff
:DCT系数,这个没有提取过
int8_t *ref_index[2]
:运动估计参考帧列表(貌似H.264这种比较新的标准才会涉及到多参考帧)
int interlaced_frame
:是否是隔行扫描
uint8_t motion_subsample_log2
:一个宏块中的运动矢量采样个数,取log的
1个运动矢量所能代表的画面大小(用宽或者高表示,单位是像素),注意,这里取了log2。
代码注释中给出以下数据:
4->16x16, 3->8x8, 2-> 4x4, 1-> 2x2
即1个运动矢量代表16x16的画面的时候,该值取4;1个运动矢量代表8x8的画面的时候,该值取3...以此类推