FFmpeg一些结构体

1. AVCodec 结构体
2. AVCodecContext 结构体
3. AVInputFormat 结构体
4. AVFormatContext 结构体
5. MovContext 结构体
6. URLProtocol 结构体
7. URLContext 结构体
8. AVIOContext 结构体(老版本为:ByteIOContext)
9. AVStream 结构体
10. MOVStreamContext 结构体
11. AVPacket 结构体
12. AVPacketList 结构体
13. AVFrame 结构体

1 AVCodec  结构体

typedef struct AVCodec
{
// 标示 Codec 的名字, 比如,"h264" "h263" 等。
const char *name;
// 标示 Codec 的类型,有 video ,audio 等类型。
enum CodecType type;
// 标示 Codec 的 ID,有 CODEC_ID_H264 等。
enum CodecID id;
// 标示具体的 Codec 对应的 Context 的 size,如:H264Context。
int priv_data_size;
// 以下标示 Codec 对外提供的操作,每一种解码器都会实现这些操作。
int(*init)(AVCodecContext*);
int(*encode)(AVCodecContext *, uint8_t *buf, int buf_size, void *data);
int(*close)(AVCodecContext*);
int(*decode)(AVCodecContext *, void *outdata, int *outdata_size, uint8_t *buf, int buf_size);
struct AVCodec *next;
}AVCodec;
H264 的主要结构的初始化如下:
AVCodec ff_h264_decoder = {
"h264",
AVMEDIA_TYPE_VIDEO,
CODEC_ID_H264,
sizeof(H264Context),
ff_h264_decode_init,
NULL,
ff_h264_decode_end,
decode_frame
}

说明:
AVCodec 是类似 COM 接口的数据结构,表示音视频编解码器,着重于功能函数,一种媒体类型对应一个
AVCodec 结构,在程序运行时有多个实例。next 变量用于把所有支持的编解码器连接成链表,便于遍历查找;id 确
定了 唯 一编 解 码器 ; priv_data_size 表示具 体 的 Codec 对应的 Context 结构大 小 ,比 如 MsrleContext
或 TSContext,这些具体的结够定义散落于各个.c 文件中,为避免太多的 if else 类语句判断类型再计算大小,这
里 就直接指明大小,因为这是一个编译时静态确定的字段,所以放在 AVCodec 而不是 AVCodecContext 中。


2 AVCodecContext  结构体

typedef struct AVCodecContext
{
int bit_rate;
int frame_number;
//扩展数据,如 mov 格式中 audio trak 中 aac 格式中 esds 的附加解码信息。
unsigned char *extradata;
//扩展数据的 size
int extradata_size;
//视频的原始的宽度与高度
int width, height; // 此逻辑段仅针对视频
//视频一帧图像的格式,如 YUV420
enum PixelFormat pix_fmt;
//音频的采样率
int sample_rate;
//音频的声道的数目
int channels;
int bits_per_sample;
int block_align;
// 指向相应的解码器,如:ff_h264_decoder
struct AVCodec *codec;
//指向具体相应的解码器的 context,如 H264Context
void *priv_data;
//公共操作函数
int(*get_buffer)(struct AVCodecContext *c, AVFrame *pic);
void(*release_buffer)(struct AVCodecContext *c, AVFrame *pic);
int(*reget_buffer)(struct AVCodecContext *c, AVFrame *pic);
}AVCodecContext;

说明:
AVCodecContext 结构表示程序运行的当前 Codec 使用的上下文,着重于所有 Codec 共有的属性(并且是在程
序运行时才能确定其值)和关联其他结构的字段。extradata 和 extradata_size 两个字段表述了相应 Codec 使用的私有
数据;codec 字段关联相应的编解码器;priv_data 字段关联各个具体编解码器独有的属性 context,和 AVCodec 结
构中的 priv_data_size 配对使用。

3 AVInputFormat  结构体

typedef struct AVInputFormat
{
// 标示 format 的名字, 比如,“mov” “mp4” 等。
const char *name;
// 标示具体的 format 对应的 Context 的 size,如:MovContext。
int priv_data_size;
//具体的操作函数
int(*read_probe)(AVProbeData*);
int(*read_header)(struct AVFormatContext *,AVFormatParameters *ap);
int(*read_packet)(struct AVFormatContext *, AVPacket *pkt);
int(*read_close)(struct AVFormatContext*);
struct AVInputFormat *next;
} AVInputFormat;
Mov 或 mp4 的主要结构的初始化如下:
AVInputFormat ff_mov_demuxer = {
"mov,mp4,m4a,3gp,3g2,mj2",
NULL_IF_CONFIG_SMALL("QuickTime/MPEG-4/Motion JPEG 2000 format"),
sizeof(MOVContext),
mov_probe,
mov_read_header,
mov_read_packet,
mov_read_close,
mov_read_seek,
}

说明:
AVInputFormat 是类似 COM 接口的数据结构,表示输入文件容器格式,着重于功能函数,一种文件容器格式对应
一个 AVInputFormat 结构,在程序运行时有多个实例。next 变量用于把所有支持的输入文件容器格式连接成链表,
便于遍历查找。priv_data_size 标示具体的文件容器格式对应的 Context 的大小,在本例中是 MovContext,这些具体
的结够定义散落于各个.c 文件中。

4 AVFormatContext  结构体

typedef struct AVFormatContext
{
//指向 AVInputFormat,如对于 mp4 或 mov 为 ff_mov_demuxer
struct AVInputFormat *iformat;
// 指向具体的格式对应的 Context,如:MovContext。
void *priv_data;
//指向数据读取统一接口 context
ByteIOContext pb;
//流的数目
int nb_streams;
//至少 2 个指针元素分别指向 video stream 和 audio stream
AVStream *streams[MAX_STREAMS];
} AVFormatContext;

说明:
AVFormatContext 结构表示程序运行的当前文件容器格式使用的上下文,着重于所有文件容器共有的属性(并且是在
程序运行时才能确定其值)和关联其他结构的字段。iformat 字段关联相应的文件容器格式;pb 关联广义的输入文件;
streams 关联音视频流;priv_data 字段关联各个具体文件容器独有的属性上下文,和 priv_data_size 配对使用。


5 MovContext  结构体

typedef struct MovContext
{
//临时持有 AVFormatContext 的指针
AVFormatContext *fc;
//时间缩放因子
int time_scale;
//视频的时长
int64_t duration;
//拆包时是否发现”moov“头
int found_moov;
//拆包时是否发现"mdat"头
int found_mdat;
int isom;
MOVFragment fragment;
MOVTrackExt *trex_data;
unsigned trex_count;
int itunes_metadata; ///< metadata are itunes style
int chapter_track;
} MOVContext;

说明:
MOVContext 定义了 mp4 中流的一些属性。


6 URLProtocol  结构体

typedef struct URLProtocol
{
const char *name;
//用的统一的模板函数
int(*url_open)(URLContext *h, const char *filename, int flags);
int(*url_read)(URLContext *h, unsigned char *buf, int size);
int(*url_write)(URLContext *h, unsigned char *buf, int size);
offset_t(*url_seek)(URLContext *h, offset_t pos, int whence);
int(*url_close)(URLContext *h);
struct URLProtocol *next;
} URLProtocol;ffurl_connect
file 的主要结构的初始化如下:
URLProtocol ff_file_protocol = {
.name = "file",
.url_open = file_open,
.url_read = file_read,
.url_write = file_write,
.url_seek = file_seek,
.url_close = file_close,
.url_get_file_handle = file_get_handle,
.url_check = file_check,
}

说明:
URLProtocol 是类似 COM 接口的数据结构,表示广义的输入文件,着重于功能函数,一种广义的输入文件对应一
个 URLProtocol 结构,比如 file,pipe,tcp 等等,定义了对 file tcp 等方式的通用模板函数。next 变量用于把所有
支持的广义的输入文件连接成链表,便于遍历查找。


7 URLContext  结构体

typedef struct URLContext
{
//指向相应的协议(协议为从初始化链表中注册的),如 ff_file_protocol
struct URLProtocol *prot;
int flags;
int max_packet_size;
//相应通信方式的句柄,对于文件为 fd 句柄,对于网络为 socket 句柄等
void *priv_data;
//文件的名字,不区分本地和网络
char *filename;
} URLContext

说明:
URLContext 结构表示程序运行的当前广义输入文件使用的 context,着重于所有广义输入文件共有的属性(并且是在
程序运行时才能确定其值)和关联其他结构的字段。prot 字段关联相应的广义输入文件;priv_data 字段关联各个具
体广义输入文件的句柄。


8 AVIOContext  结构体( 老版本为:ByteIOContext)

typedef struct ByteIOContext
{
//数据缓冲区
unsigned char *buffer;
//数据缓冲 size
int buffer_size;
//数据读取标记指针
unsigned char *buf_ptr, *buf_end;
//该指针指向相应的 URLContext,关联 URLContext
void *opaque;
int (*read_packet)(void *opaque, uint8_t *buf, int buf_size);
int (*write_packet)(void *opaque, uint8_t *buf, int buf_size);
offset_t(*seek)(void *opaque, offset_t offset, int whence);
//当前 buffer 在文件中的位置
offset_t pos;
//表示要进行 seek,冲刷数据
int must_flush;
//是否到达了文件末尾
int eof_reached; // true if eof reached
int write_flag;
int max_packet_size;
int error; // contains the error code or 0 if no error happened
} ByteIOContext;

说明:
ByteIOContext 结构扩展 URLProtocol 结构成内部有缓冲机制的广泛意义上的文件,改善广义输入文件的 IO 性能。
由其数据结构定义的字段可知,主要是缓冲区相关字段,标记字段,和一个关联字段 opaque 来完成广义文件读写
操作。opaque 关联字段用于关联 URLContext 结构,间接关联并扩展 URLProtocol 结构。

9 AVStream  结构体

typedef struct AVStream
{
//指向解码器 context,用于关联解码器
AVCodecContext *actx;
//codec 解析器,每一种编码器在进行压缩时都会对实际负载数据进行封装,加//入头信息,如 h264,需要解析 nal
单元,关联通过 avav_find_stream_info()
struct AVCodecParserContext *parser;
//指向解复用的流的 context,比如 mp4 的 MovStreamcontext
void *priv_data;
AVRational time_base;
//用于 seek 时使用,用于快速索引关键帧,如 flv 的 keyframes 索引表和 mp4 的 I
//帧的索引表都存于此,很重要
AVIndexEntry *index_entries;
//index_entries 的元素的个数
int nb_index_entries;
int index_entries_allocated_size;
double frame_last_delay;
} AVStream;

说明:
AVStream 结构表示当前媒体流的上下文,着重于所有媒体流共有的属性(并且是在程序运行时才能确定其值)和关联
其他结构的字段。actx 字段关联当前音视频媒体使用的编解码器的 context;priv_data 字段关联解析各个具体媒体
流解复用拆包用的 context;还有关键帧的索引表也存于此。


10 MOVStreamContext  结构体

typedef struct MOVStreamContext {
//流的索引,0 或者 1
int ffindex;
//临时变量,保存下一个 chunk 块的编号
int next_chunk;
//chunk 的个数(在 mp4 的文件格式中,从 stco 中取值肯定为 chunk 的总数)
unsigned int chunk_count;
//chunk 在文件中的偏移量数组(每个 chunk 中的 sample 在文件中的物理存储  //是连续 的),用于保存 scto 表
int64_t *chunk_offsets;
//stts 的元素的个数
unsigned int stts_count;
//stts 时间数据表
MOVStts *stts_data;
//ctts(用于在有 B 帧混合时进行纠正时间戳)的元素的个数
unsigned int ctts_count;
//ctts 数据表
MOVStts *ctts_data;
//stsc(空间分布表)的元素的个数
unsigned int stsc_count;
//stsc 数据表
MOVStsc *stsc_data;
//临时变量,记录当前使用的 ctts 表的索引
int ctts_index;
//记录当前的 ctts 元素作用的 sample 的索引
int ctts_sample;
//stsz 表中可能 smaple 的 size 相同,如果相同使用该值
unsigned int sample_size;
//stsz 中元素的个数
unsigned int sample_count;//sample 的个数
//stsz 数据表,记录每个 sample 的 size,如果 sample_size=0,该表才不会 //空
int *sample_sizes;
//stss(关键帧索引表)中元素的个数
unsigned int keyframe_count;
//关键帧数据表
int *keyframes;
//dref 的元素的个数,一般为 1
unsigned drefs_count;
//dref 数据表
MOVDref *drefs;
//tkhd 宽度
int width;
//tkhd 高度
int height;
} MOVStreamContext;

说明:
MOVStreamContext 结构用于保存从 mov 或 mp4 中进行拆包解复用从头部得到的信息。


11 AVPacket  结构体

typedef struct AVPacket
{
//显示时间戳
int64_t pts;
//解码时间戳
int64_t dts;
//记录在文件或网络中的流中的字节的位置
int64_t pos;
//实际数据指针
uint8_t *data;
//实际的数据的大小
int size;
//该 packet 所属的流的索引,一般为 0 或者 1
int stream_index;
int flags;
//析构函数
void(*destruct)(struct AVPacket*);
} AVPacket;

说明:
AVPacket 代表音视频数据帧,固有的属性是一些标记,时钟信息,和压缩数据首地址,大小等信息。


12 AVPacketList  结构体

typedef struct AVPacketList
{
AVPacket pkt;
struct AVPacketList *next;
} AVPacketList;

说明:AVPacketList 把音视频 AVPacket 组成一个小链表 。


13 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;

说明:AVFrame 结构体一般用于存储原始数据(即非压缩数据,例如对视频来说是 YUV,RGB,对音频来说是 PCM),
此外还包含了一些相关的信息。比如说,解码的时候存储了宏块类型表,QP 表,运动矢量表等数据。编码的时候
也存储了相关的数据。因此在使用 FFMPEG 进行码流分析的时候,AVFrame 是一个很重要的结构体。
 

上一篇:NDK编译FFmpeg


下一篇:详细的FFmpeg编译流程与脚本分析