现在的位置: 首页 > 综合 > 正文

FFmpeg 源码分析 Part Two:重要的结构体

2013年09月12日 ⁄ 综合 ⁄ 共 2579字 ⁄ 字号 评论关闭

http://hi.baidu.com/absolutely1st/item/a9f7ce969db02f43f0421573

1. AVFormatContext 

    AVFormatContext在FFmpeg里是一个最大的容器,是输入,输出信息的容器。它包含有两个重要的

   成员变量:struct AVInputFormat *iformat (数据输入格式)和 struct AVOutputFormat *oformat(数据输出

   格式)。两者不可共存。

   AVFormatContext和 XXXContext(eg. AVIContext FLVContext etc.)之间存在着类似多态的关系。即:

   AVFormatContext记录着运行时大家共有的信息,而各个XXXContext记录着自己文件格式的信息。

   AVInputFormat->priv_data_size记录相应XXXContext的大小,AVFormatContext的void *priv_data记录

   XXXContext指针。

   AVFormatContext, AVInputFormat 和 XXXContext 这3者一起完成数据输入模块。可以这样认为:

   AVFormatContext是个类容器,AVInputFormat 是这个类的操作函数集合,XXXContext则代表该类的

   private数据对象。

2.AVInputFormat 和 AVOutputFormat 

   不错,这两个结构体相对于AVFormatContext 就是它的操作函数集合!AVInputFormat和AVOutputFormat

   对应的功能就是demuxer 和 muxer . (demuxer 和 muxer 作用就是 “脱衣服” 和 “穿衣服”,具体见

   PART ONE).

   DEMUXER <------> AVInputFormat  这表示输入模块的操作集合,就是解去输入文件的媒体格式,简称

   “脱衣服”

   开放的接口有:

   int(*read_probe)(AVProbeData *);

   int(*read_header)(struct AVFormatContext *, AVFormatParameters *ap);

   int(*read_packet)(struct AVFormatContext *, AVPacket *pkt);

   int(*read_close)(struct AVFormatContext *);

   int(*read_seek)(struct AVFormatContext *,int stream_index,int64_t  timestamp, int flags);

   MUXER <-------> AVOutputFormat 这表示输出模块的操作集合,就是去封装输出文件的媒体格式,简称

   “穿衣服”

   开放的接口有:

   int(*write_header)(struct AVFormatContext *);

   int(*write_packet)(struct AVFormatContext *,AVPacket *pkt);

   int(*write_trailer)(struct AVFormatContext *);

3.AVStream

   经过上面的文件格式解析后,读出来的数据保存在哪里呢?答案是AVStream.

   一个AVStream表示一个流对象,如音频流,视频流,nb_streams记录流对象个数。

   AVStream也是一个容器[可以把想成一个Context],它的void *priv_data指向具体的Stream类型对象。

   如AVIStream.在AVStream中包含成员 AVCodecContext *actx,记录具体的编解码容器。

   继续往下看。

4.AVCodec 和 AVCodecContext

   AVCodec对应的是encoder和 decoder 这里才是真正开始解码啦(参加PART ONE的图)。

   编码和解码开发的接口有:

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

   这里突然冒出了一个新的结构体 AVCodecContext,其实它和AVCodec的关系类似于:

   AVFormatContext 和 AVInputFormat .就是说:

   AVCodecContext 是解码模块的容器类,AVCodec 是操作函数的集合(以上开发的接口可以在AVCodec

   结构体中找到) ! AVCodecContext中保存了AVCodec的指针以及和codec相关的数据(如video的

   width,height ,audio的sample rate等)。

5.AVFrame AVPicture 和 AVPacket

  这3个东西不怎么好理解。我们可以这样想:

  一个文件被DEMUXER----> 解出一路Video Stream ---->该Video Stream 被封装成若干个AVPacket

  ---> 送入Decoder ----> Decoder拿到n个AVPacket 组成一个 AVFrame ---->解码出来。如此往复。  

  那AVPicture是啥呢?

  其实AVPicture 可以想成是一帧图像,是由AVFrame抽象出的概念。AVPicture是AVFrame开始的一部分,

  是AVFrame的子集。

  AVPicture 这东西 和 YUV 相关,这个我们下次补充一节,专门讲这东西。

抱歉!评论已关闭.