ffmpeg各个结构详解

typedef struct AVCodec{

const char *name; // 标示Codec 的名字, 比如,"msrle" "truespeech" 等。 enum CodecType type; // 标示Codec 的类型,有Video ,Audio,Data 等类型 enum CodecID id; // 标示Codec 的ID,有CODEC_ID_M SRLE,CODEC_ID_TRUESPEECH 等 int priv_data_size; // 标示具体的Codec 对应的Context 的大小,在本例中是MsrleContext// 或TSContext 的大小。 int(*init)(AVCodecContext*);// 标示Codec 对外提供的操作
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);
int capabilities; // 标示Codec 的能力,在瘦身后的ffplay 中没太大作用,可忽略
struct AVCodec *next; // 用于把所有Codec 串成一个链表,便于遍历
}AVCodec;
AVCodec 是类似COM 接口的数据结构,表示音视频编解码器,着重于功能函数,一种媒体类型对应一个
AVCodec 结构,在程序运行时有多个实例。next 变量用于把所有支持的编解码器连接成链表,便于遍历查找;id
确定了唯一编解码器; priv_data_size 表示具体的Codec 对应的Context 结构大小,比如MsrleContext 或
TSContext,这些具体的结够定义散落于各个.c 文件中,为避免太多的if else 类语句判断类型再计算大小,这里
就直接指明大小,因为这是一个编译时静态确定的字段,所以放在AVCodec 而不是AVCodecContext 中。

typedef struct AVCodecContext{

int bit_rate; int frame_number; unsigned char *extradata; // Codec 的私有数据,对Audio 是WAVEFORMATEX 结构扩展字节。 int extradata_size; // 对Video 是BITMAPINFOHEADER 后的扩展字节 int width, height; // 此逻辑段仅针对视频 enum PixelFormat pix_fmt; int sample_rate; // 此逻辑段仅针对音频 int channels; int bits_per_sample; int block_align; struct AVCodec *codec; // 指向当前AVCodec 的指针, void *priv_data; // 指向当前具体编解码器Codec 的上下文Context。 enum CodecType codec_type; // see CODEC_TYPE_xxx enum CodecID codec_id; // see CODEC_ID_xxx int(*get_buffer)(struct AVCodecContext *c, AVFrame *pic); void(*release_buffer)(struct AVCodecContext *c, AVFrame *pic); int(*reget_buffer)(struct AVCodecContext *c, AVFrame *pic); int internal_buffer_count; void *internal_buffer; struct AVPaletteControl *palctrl;
}AVCodecContext;
AVCodecContext 结构表示程序运行的当前Codec 使用的上下文,着重于所有Codec 共有的属性(并且是在程
序运行时才能确定其值)和关联其他结构的字段。extradata 和extradata_size 两个字段表述了相应Codec 使用的私
有数据,对Codec 全局有效,通常是一些标志信息;codec 字段关联相应的编解码器;priv_data 字段关联各个具
体编解码器独有的属性上下文,和AVCodec 结构中的priv_data_size 配对使用。

typedef struct AVInputFormat{

const char *name; int priv_data_size; // 标示具体的文件容器格式对应的Context 的大小,在本例中是AVIContext int(*read_probe)(AVProbeData*); int(*read_header)(struct AVFormatContext *, AVFormatParameters *ap); int(*read_packet)(struct AVFormatContext *, AVPacket *pkt); int(*read_close)(struct AVFormatContext*); const char *extensions; // 文件扩展名 struct AVInputFormat *next; } AVInputFormat;
AVInputFormat 是类似COM 接口的数据结构,表示输入文件容器格式,着重于功能函数,一种文件容器格
式对应一个AVInputFormat 结构,在程序运行时有多个实例。next 变量用于把所有支持的输入文件容器格式连接
成链表,便于遍历查找;priv_data_size 标示具体的文件容器格式对应的Context 的大小,在本例中是AVIContext,
这些具体的结够定义散落于各个.c 文件中,为避免太多的if else 类语句判断类型再计算大小,这里就直接指明
大小,因为这是一个编译时静态确定的字段,所以放在AVInputFormat 而不是AVFormatContext 中。

typedef struct AVFormatContext // format I/O context{

struct AVInputFormat *iformat; void *priv_data; // 指向具体的文件容器格式的上下文Context,在本例中是AVIContext ByteIOContext pb; // 广泛意义的输入文件 int nb_streams; AVStream *streams[MAX_STREAMS]; } AVFormatContext;
AVFormatContext 结构表示程序运行的当前文件容器格式使用的上下文,着重于所有文件容器共有的属性(并
且是在程序运行时才能确定其值)和关联其他结构的字段。iformat 字段关联相应的文件容器格式;pb 关联广义的
输入文件;streams 关联音视频流;priv_data 字段关联各个具体文件容器独有的属性上下文,和priv_data_size 配
对使用。

typedef struct AVIContext{

int64_t riff_end; int64_t movi_end; offset_t movi_list; int non_interleaved; int stream_index_2; // 为了和AVPacket 中的stream_index 相区别,添加后缀标记。 } AVIContext;
AVIContext 定义了AVI 中流的一些属性,其中stream_index_2 定义了当前应该读取流的索引。
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;
URLProtocol 是类似COM 接口的数据结构,表示广义的输入文件,着重于功能函数,一种广义的输入文件
对应一个URLProtocol 结构,比如file,pipe,tcp 等等,但瘦身后的ffplay 只支持file 一种输入文件。next 变量
用于把所有支持的广义的输入文件连接成链表,便于遍历查找。

typedef struct URLContext{

struct URLProtocol *prot; int flags; int max_packet_size; // if non zero, the stream is packetized with this max packet size void *priv_data; // 文件句柄fd,网络通信Scoket 等 char filename[1]; // specified filename } URLContext;
URLContext 结构表示程序运行的当前广义输入文件使用的上下文,着重于所有广义输入文件共有的属性(并
且是在程序运行时才能确定其值)和关联其他结构的字段。prot 字段关联相应的广义输入文件;priv_data 字段关
联各个具体广义输入文件的句柄。

typedef struct ByteIOContext{

unsigned char *buffer; int buffer_size; unsigned char *buf_ptr, *buf_end; void *opaque; // 关联URLContext int (*read_buf)(void *opaque, uint8_t *buf, int buf_size); int (*write_buf)(void *opaque, uint8_t *buf, int buf_size); offset_t(*seek)(void *opaque, offset_t offset, int whence); offset_t pos; // position in the file of the current buffer int must_flush; // true if the next seek should flush int eof_reached; // true if eof reached int write_flag; // true if open for writing int max_packet_size; int error; // contains the error code or 0 if no error happened } ByteIOContext;
ByteIOContext 结构扩展URLProtocol 结构成内部有缓冲机制的广泛意义上的文件,改善广义输入文件的IO
性能。由其数据结构定义的字段可知,主要是缓冲区相关字段,标记字段,和一个关联字段opaque 来完成广义
文件读写操作。opaque 关联字段用于关联URLContext 结构,间接关联并扩展URLProtocol 结构。

typedef struct AVStream // 解析文件容器内部使用的逻辑{

AVCodecContext *actx; // codec context, change from AVCodecContext *codec; void *priv_data; // AVIStream AVRational time_base; // 由av_set_pts_info()函数初始化 AVIndexEntry *index_entries; // only used if the format does not support seeking natively int nb_index_entries; int index_entries_allocated_size; double frame_last_delay; } AVStream;
AVStream 结构表示当前媒体流的上下文,着重于所有媒体流共有的属性(并且是在程序运行时才能确定其值)
和关联其他结构的字段。actx 字段关联当前音视频媒体使用的编解码器;priv_data 字段关联解析各个具体媒体流
与文件容器有关的独有的属性;还有一些媒体帧索引和时钟信息。

typedef struct AVIStream{

int64_t frame_offset; // current frame(video) or byte(audio) counter(used to compute the pts) int remaining; int packet_size; int scale; int rate; int sample_size; // size of one sample (or packet) (in the rate/scale sense) in bytes int64_t cum_len; // temporary storage (used during seek) int prefix; // normally 'd'<<8 + 'c' or 'w'<<8 + 'b' int prefix_count; } AVIStream;
AVIStream 结构定义了AVI 文件中媒体流的一些属性,用于解析AVI 文件。
typedef struct AVPacket{
int64_t pts; // presentation time stamp in time_base units
int64_t dts; // decompression time stamp in time_base units
int64_t pos; // byte position in stream, -1 if unknown
uint8_t *data;
int size;
int stream_index;
int flags;
void(*destruct)(struct AVPacket*);
} AVPacket;
AVPacket 代表音视频数据帧,固有的属性是一些标记,时钟信息,和压缩数据首地址,大小等信息。

typedef struct AVPacketList{

AVPacket pkt; struct AVPacketList *next; } AVPacketList;
AVPacketList 把音视频AVPacket 组成一个小链表。

typedef struct PacketQueue

{
AVPacketList *first_pkt, *last_pkt;
int size;
int abort_request;
SDL_mutex *mutex;
SDL_cond *cond;
} PacketQueue;


PacketQueue 通过小链表AVPacketList 把音视频帧AVPacket 组成一个顺序队列,是数据交换中转站,当然
同步互斥控制逻辑是必不可少的。

typedef struct VideoState{

SDL_Thread *parse_tid; SDL_Thread *video_tid; int abort_request; AVInputFormat *iformat; AVFormatContext *ic; // 关联的主要数据结构是ByteIOContext 和AVStream
AVStream *audio_st; // 关联的主要数据结构是AVCodecContext 和AVIStream
AVStream *video_st;
int audio_stream; // 音频流索引,实际表示AVFormatContext 结构中AVStream *streams[]数组中的索引
int video_stream; // 视频流索引,实际表示AVFormatContext 结构中AVStream *streams[]数组中的索引
PacketQueue audioq; // 音频数据包队列,注意一包音频数据可能包含几个音频帧
PacketQueue videoq; // 视频数据包队列,注意瘦身后的ffplay 一包视频数据是完整的一帧
VideoPicture pictq[VIDEO_PICTURE_QUEUE_SIZE]; // 输出视频队列,瘦身后的ffplay 只有一项
double frame_last_delay;
uint8_t audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE *3) / 2]; // 输出的音频缓存
unsigned int audio_buf_size;
int audio_buf_index;
AVPacket audio_pkt; // 音频包属性,只一个指针指向原始音频包数据,非直接包含音频数据包数据
uint8_t *audio_pkt_data;
int audio_pkt_size;
SDL_mutex *video_decoder_mutex; // 视频线程同步互斥变量
SDL_mutex *audio_decoder_mutex; // 音频线程同步互斥变量
char filename[240]; // 媒体文件名
} VideoState;


 
  

SDL_Thread *parse_tid;
SDL_Thread *video_tid;
int abort_request;
AVInputFormat *iformat;
AVFormatContext *ic; // 关联的主要数据结构是ByteIOContext 和AVStream
AVStream *audio_st; // 关联的主要数据结构是AVCodecContext 和AVIStream

你可能感兴趣的:(ffmpeg,ffmpeg学习笔记)