FFmpeg使用太复杂,一个重要的方面是包含的结构体太多,太复杂。我们来分析分析其中的几个重要的结构体。
AVFormatContext:该结构体在使用FFmpeg的过程中会一直使用到,它的定义如下
/**
* 格式化输入输出上下文.
* 使用avformat_alloc_context() 创建一个 AVFormatContext.
*/
typedef struct AVFormatContext {
/**
* AVClass最主要的作用就是给结构体(如AVFormatContext等)增加AVOption功能的
*支持。换句话说就是AVClass是AVOption和目标结构体之间的桥梁,AVClass要求必须
*为目标结构体声明的第一个变量。
*AVOption是用来设置ffmpeg中变量的结构体。后续会具体介绍
*/
const AVClass *av_class;
/**
* 输入文件的格式
* 在解复用是出现,由avformat_open_input()设置.
*/
struct AVInputFormat *iformat;
/**
* 输出文件的格式
* 复用的时候出现, 必须在avformat_write_header()之前由用户设置.
*/
struct AVOutputFormat *oformat;
/**
* 指向具体某个文件格式的私有数据. This is an AVOptions-enabled struct
* if and only if iformat/oformat.priv_class is not NULL.
*
* - 复用时由avformat_write_header()设置
* - 解复用时由avformat_open_input()设置
*/
void *priv_data;
/**
* 管理输入输出数据的结构体
* 通过对该变量的赋值可以改变输入源或输出目的地
* - 解复用: 在使用avformat_open_input()或者使avformat_open_input().
* 之前使用
* - 复用: 使用avformat_write_header()之前使用. 调用的时候需要注意释放IO
* 上下文
*
* Do NOT set this field if AVFMT_NOFILE flag is set in
* iformat/oformat.flags. In such a case, the (de)muxer will handle
* I/O in some other way and this field will be NULL.
*/
AVIOContext *pb;
/* 码流信息 */
/**
* 标志位又来表示码流的性能. A combination of AVFMTCTX_*.
* Set by libavformat.
*/
int ctx_flags;
/**
* AVFormatContext.streams的个数.
*
* Set by avformat_new_stream(),不能被随意修改.
*/
unsigned int nb_streams;
/**
* 输入文件的所有码流信息.新的码流信息可由
* avformat_new_stream()生成。
*
* - demuxing: streams are created by libavformat in avformat_open_input().
* If AVFMTCTX_NOHEADER is set in ctx_flags, then new streams may also
* appear in av_read_frame().
* - muxing: streams are created by the user before avformat_write_header().
*
* 通过avformat_free_context()释放内存.
*/
AVStream **streams;
/**
* 输入输出文件名
*
* - demuxing: set by avformat_open_input()
* - muxing: may be set by the caller before avformat_write_header()
*/
char filename[1024];
/**
* 定位第一帧的位置,利用
* AV_TIME_BASE fractional seconds. 不能直接设定:
* 可以从 AVStream values中推导得出.
*
* Demuxing only, set by libavformat.
*/
int64_t start_time;
/**
* 码流的时长, 也是利用 AV_TIME_BASE fractional
* seconds表征. 一般情况下由
* AVStream values 推导得出.
*
* Demuxing only, set by libavformat.
*/
int64_t duration;
/**
* 这个stream的码率, 0 if not
* available. ffmpeg可以根据file_size和duration自动计算出来,所以无需指定.
*/
int64_t bit_rate;
unsigned int packet_size;
int max_delay;
/**
* 标志位用来修改解/复用行为. A combination of AVFMT_FLAG_*.
* Set by the user before avformat_open_input() / avformat_write_header().
*/
int flags;
#define AVFMT_FLAG_GENPTS 0x0001 ///< Generate missing pts even if it requires parsing future frames.
#define AVFMT_FLAG_IGNIDX 0x0002 ///< Ignore index.
#define AVFMT_FLAG_NONBLOCK 0x0004 ///< Do not block when reading packets from input.
#define AVFMT_FLAG_IGNDTS 0x0008 ///< Ignore DTS on frames that contain both DTS & PTS
#define AVFMT_FLAG_NOFILLIN 0x0010 ///< Do not infer any values from other values, just return what is stored in the container
#define AVFMT_FLAG_NOPARSE 0x0020 ///< Do not use AVParsers, you also must set AVFMT_FLAG_NOFILLIN as the fillin code works on frames and no parsing -> no frames. Also seeking to frames can not work if parsing to find frame boundaries has been disabled
#define AVFMT_FLAG_NOBUFFER 0x0040