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 接口的数据结构,表示音视频编解码器,着重于功能函数,一种媒体类型对应一个
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 共有的属性(并且是在程
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 接口的数据结构,表示输入文件容器格式,着重于功能函数,一种文件容器格
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 结构表示程序运行的当前文件容器格式使用的上下文,着重于所有文件容器共有的属性(并
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 接口的数据结构,表示广义的输入文件,着重于功能函数,一种广义的输入文件
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 结构表示程序运行的当前广义输入文件使用的上下文,着重于所有广义输入文件共有的属性(并
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
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 结构表示当前媒体流的上下文,着重于所有媒体流共有的属性(并且是在程序运行时才能确定其值)
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
typedef struct AVPacketList{
AVPacket pkt;
struct AVPacketList *next;
} AVPacketList;
AVPacketList 把音视频AVPacket 组成一个小链表。
{
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