ffmpeg各个结构详解

<h3>typedef struct AVCodec{</h3>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 中。

<h3>typedef struct AVCodecContext{</h3>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 配对使用。

<h3>typedef struct AVInputFormat{</h3>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 中。

<h3>typedef struct AVFormatContext // format I/O context{</h3>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 配
对使用。
<h3>typedef struct AVIContext{</h3>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 变量
用于把所有支持的广义的输入文件连接成链表,便于遍历查找。

<h3>typedef struct URLContext{</h3>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 字段关
联各个具体广义输入文件的句柄。
<h3>typedef struct ByteIOContext{</h3>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 结构。
<h3>typedef struct AVStream // 解析文件容器内部使用的逻辑{</h3>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 字段关联解析各个具体媒体流
与文件容器有关的独有的属性;还有一些媒体帧索引和时钟信息。
<h3>typedef struct AVIStream{</h3>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 代表音视频数据帧,固有的属性是一些标记,时钟信息,和压缩数据首地址,大小等信息。

<h3>typedef struct AVPacketList{</h3>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 组成一个顺序队列,是数据交换中转站,当然
同步互斥控制逻辑是必不可少的。

<h3>typedef struct VideoState{</h3>SDL_Thread *parse_tid;
SDL_Thread *video_tid;
int abort_request;
AVInputFormat *iformat;
AVFormatContext *ic; // 关联的主要数据结构是ByteIOContext 和AVStream
<pre name="code" class="html">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
<span style="font-family: Arial, Helvetica, sans-serif; font-size: 12px;">AVStream *audio_st; // 关联的主要数据结构是AVCodecContext 和AVIStream</span>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值