FFMPEG 结构体分析
FFMPEG
中结构体很多,最关键的结构体可以分成以下几类:
- 解协议(http,rtsp,rtmp,mms)
AVIOContext
,URLProtocol
,URLContext
主要存储视音频使用的协议的类型以及状态。
URLProtocol
存储输入视音频使用的封装格式。
每种协议都对应一个URLProtocol
结构。(注意:FFMPEG中文件也被当做一种协议“file”)
- 解封装(flv,avi,rmvb,mp4)
AVFormatContext
主要存储视音频封装格式中包含的信息;
AVInputFormat存储输入视音频使用的封装格式。
每种视音频封装格式都对应一个AVInputFormat 结构。
- 解码(h264,mpeg2,aac,mp3)
每个AVStream
存储一个视频/音频流的相关数据;
每个AVStream
对应一个AVCodecContext
,存储该视频/音频流使用解码方式的相关数据;
每个AVCodecContext
中对应一个AVCodec,包含该视频/音频对应的解码器。
每种解码器都对应一个AVCodec
结构。
- 存数据
视频的话,每个结构一般是存一帧;音频可能有好几帧
解码前数据:AVPacket
解码后数据:AVFrame
FFMPEG几个关键结构体对应的关系图:
FFMPEG 之 AVFrame
去掉注释部分,结构体定义实际没几行。整理了一下雷神的分享,
下面是AVFrame
结构体的声明:
typedef struct AVFrame {
#define AV_NUM_DATA_POINTERS 8
/* 解码后原始数据(对视频来说是YUV,RGB,对音频来说是PCM)*/
uint8_t *data[AV_NUM_DATA_POINTERS];
/* data中“一行”数据的大小。注意:未必等于图像的宽,一般大于图像的宽。 */
int linesize[AV_NUM_DATA_POINTERS];
uint8_t **extended_data;
/* 视频帧宽和高(1920x1080,1280x720...) */
int width, height;
/* 音频的一个AVFrame中可能包含多个音频帧,在此标记包含了几个 */
int nb_samples;
/* 解码后原始数据类型(YUV420,YUV422,RGB24...) */
int format;
/* 是否是关键帧 */
int key_frame;
/* 帧类型(I,B,P...) */
enum AVPictureType pict_type;
/* 宽高比(16:9,4:3...) */
AVRational sample_aspect_ratio;
/* 显示时间戳 */
int64_t pts;
#if FF_API_PKT_PTS
attribute_deprecated
int64_t pkt_pts;
#endif
int64_t pkt_dts;
/* 编码帧序号 */
int coded_picture_number;
/* 显示帧序号 */
int display_picture_number;
int quality;
void *opaque;
#if FF_API_ERROR_FRAME
attribute_deprecated
uint64_t error[AV_NUM_DATA_POINTERS];
#endif
int repeat_pict;
/* 是否是隔行扫描 */
int interlaced_frame;
int top_field_first;
int palette_has_changed;
int64_t reordered_opaque;
int sample_rate;
uint64_t channel_layout;
AVBufferRef *buf[AV_NUM_DATA_POINTERS];
AVBufferRef **extended_buf;
int nb_extended_buf;
AVFrameSideData **side_data;
int nb_side_data;
#define AV_FRAME_FLAG_CORRUPT (1 << 0)
#define AV_FRAME_FLAG_DISCARD (1 << 2)
int flags;
enum AVColorRange color_range;
enum AVColorPrimaries color_primaries;
enum AVColorTransferCharacteristic color_trc;
enum AVColorSpace colorspace;
enum AVChromaLocation chroma_location;
int64_t best_effort_timestamp;
int64_t pkt_pos;
int64_t pkt_duration;
AVDictionary *metadata;
int decode_error_flags;
#define FF_DECODE_ERROR_INVALID_BITSTREAM 1
#define FF_DECODE_ERROR_MISSING_REFERENCE 2
int channels;
int pkt_size;
#if FF_API_FRAME_QP
attribute_deprecated
/* QP表 */
int8_t *qscale_table;
attribute_deprecated
int qstride;
attribute_deprecated
int qscale_type;
AVBufferRef *qp_table_buf;
#endif
AVBufferRef *hw_frames_ctx;
AVBufferRef *opaque_ref;
size_t crop_top;
size_t crop_bottom;
size_t crop_left;
size_t crop_right;
} AVFrame;
FFMPEG 之 AVFormatContext
AVFormatContext
是解封装功能的结构体,
它的主要作用是描述一个媒体文件或媒体流的构成和基本信息。
下面是AVFormatContext
结构体的声明:
typedef struct AVFormatContext {
const AVClass *av_class;
struct AVInputFormat *iformat;
struct AVOutputFormat *oformat;
void *priv_data;
/* 输入数据的缓存 */
AVIOContext *pb;
int ctx_flags;
/* 视音频流的个数 */
unsigned int nb_streams;
/* 视音频流 */
AVStream **streams;
/* 文件名 */
char filename[1024];
int64_t start_time;
/* 时长(单位:微秒us,转换为秒需要除以1000000) */
int64_t duration;
/* 比特率(单位bps,转换为kbps需要除以1000) */
int64_t bit_rate;
unsigned int packet_size;
int max_delay;
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 ///< Do not buffer frames when possible
#define AVFMT_FLAG_CUSTOM_IO 0x0080 ///< The caller has supplied a custom AVIOContext, don't avio_close() it.
#define AVFMT_FLAG_DISCARD_CORRUPT 0x0100 ///< Discard frames marked corrupted
#define AVFMT_FLAG_FLUSH_PACKETS 0x0200 ///< Flush the AVIOContext every packet.
#define AVFMT_FLAG_BITEXACT 0x0400
#define AVFMT_FLAG_MP4A_LATM 0x8000 ///< Enable RTP MP4A-LATM payload
#define AVFMT_FLAG_SORT_DTS 0x10000 ///< try to interleave outputted packets by dts (using this flag can slow demuxing down)
#define AVFMT_FLAG_PRIV_OPT 0x20000 ///< Enable use of private options by delaying codec open (this could be made default once all code is converted)
#if FF_API_LAVF_KEEPSIDE_FLAG
#define AVFMT_FLAG_KEEP_SIDE_DATA 0x40000 ///< Don't merge side data but keep it separate. Deprecated, will be the default.
#endif
#define AVFMT_FLAG_FAST_SEEK 0x80000 ///< Enable fast, but inaccurate seeks for some formats
#define AVFMT_FLAG_SHORTEST 0x100000 ///< Stop muxing when the shortest stream stops.
#define AVFMT_FLAG_AUTO_BSF 0x200000 ///< Wait for packet data before writing a header, and add bitstream filters as requested by the muxer
int64_t probesize;
int64_t max_analyze_duration;
const uint8_t *key;
int keylen;
unsigned int nb_programs;
AVProgram **programs;
enum AVCodecID video_codec_id;
enum AVCodecID audio_codec_id;
enum AVCodecID subtitle_codec_id;
unsigned int max_index_size;
unsigned int max_picture_buffer;
unsigned int nb_chapters;
AVChapter **chapters;
/* 元数据,AVDictionary元数据分为key和value两个属性 */
AVDictionary *metadata;
int64_t start_time_realtime;
int fps_probe_size;
int error_recognition;
AVIOInterruptCB interrupt_callback;
int debug;
#define FF_FDEBUG_TS 0x0001
int64_t max_interleave_delta;
int strict_std_compliance;
int event_flags;
#define AVFMT_EVENT_FLAG_METADATA_UPDATED 0x0001 ///< The call resulted in updated metadata.
int max_ts_probe;
int avoid_negative_ts;
#define AVFMT_AVOID_NEG_TS_AUTO -1 ///< Enabled when required by target format
#define AVFMT_AVOID_NEG_TS_MAKE_NON_NEGATIVE 1 ///< Shift timestamps so they are non negative
#define AVFMT_AVOID_NEG_TS_MAKE_ZERO 2 ///< Shift timestamps so that they start at 0
int ts_id;
int audio_preload;
int max_chunk_duration;
int max_chunk_size;
int use_wallclock_as_timestamps;
int avio_flags;
enum AVDurationEstimationMethod duration_estimation_method;
int64_t skip_initial_bytes;
unsigned int correct_ts_overflow;
int seek2any;
int flush_packets;
int probe_score;
int format_probesize;
char *codec_whitelist;
char *format_whitelist;
AVFormatInternal *internal;
int io_repositioned;
AVCodec *video_codec;
AVCodec *audio_codec;
AVCodec *subtitle_codec;
AVCodec *data_codec;
int metadata_header_padding;
void *opaque;
av_format_control_message control_message_cb;
int64_t output_ts_offset;
uint8_t *dump_separator;
enum AVCodecID data_codec_id;
#if FF_API_OLD_OPEN_CALLBACKS
attribute_deprecated
int (*open_cb)(struct AVFormatContext *s, AVIOContext **p, const char *url, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options);
#endif
char *protocol_whitelist;
int (*io_open)(struct AVFormatContext *s, AVIOContext **pb, const char *url,
int flags, AVDictionary **options);
void (*io_close)(struct AVFormatContext *s, AVIOContext *pb);
char *protocol_blacklist;
int max_streams;
} AVFormatContext;
FFMPEG 之 AVInputFormat
AVInputFormat
是FFMPEG
的解复用器对象,位于avoformat.h
文件中。
下面是AVInputFormat
结构体的声明:
typedef struct AVInputFormat {
/* 短名称格式 */
const char *name;
/* 长名称格式,描述性名称,相对于name更可读。 */
const char *long_name;
int flags;
/* 文件扩展名称 */
const char *extensions;
/* 编码器标签 */
const struct AVCodecTag * const *codec_tag;
const AVClass *priv_class;
const char *mime_type;
/* 用于链接下一个AVInputFormat */
struct AVInputFormat *next;
int raw_codec_id;
int priv_data_size;
/* 一些封装格式处理的接口函数 */
int (*read_probe)(AVProbeData *);
int (*read_header)(struct AVFormatContext *);
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);
int64_t (*read_timestamp)(struct AVFormatContext *s, int stream_index,
int64_t *pos, int64_t pos_limit);
int (*read_play)(struct AVFormatContext *);
int (*read_pause)(struct AVFormatContext *);
int (*read_seek2)(struct AVFormatContext *s, int stream_index,
int64_t min_ts, int64_t ts, int64_t max_ts, int flags);
int (*get_device_list)(struct AVFormatContext *s,
struct AVDeviceInfoList *device_list);
int (*create_device_capabilities)(struct AVFormatContext *s,
struct AVDeviceCapabilitiesQuery *caps);
int (*free_device_capabilities)(struct AVFormatContext *s,
struct AVDeviceCapabilitiesQuery *caps);
} AVInputFormat;
FFMPEG 之 AVStream
AVStream
是存储每一个视频/音频流信息的结构体,用于视音频编解码。
位于avoformat.h
文件中。
下面是AVInputFormat
结构体的声明:
typedef struct AVStream {
/* 标识该视频/音频流 */
int index; /**< stream index in AVFormatContext */
int id;
#if FF_API_LAVF_AVCTX
attribute_deprecated
/* 指向该视频/音频流的AVCodecContext(它们是一一对应的关系) */
AVCodecContext *codec;
#endif
/* *
* 时基。通过该值可以把PTS,DTS转化为真正的时间。
* FFMPEG其他结构体中也有这个字段,但是根据我的经验,
* 只有AVStream中的time_base是可用的。
* PTS*time_base=真正的时间
* */
void *priv_data;
#if FF_API_LAVF_FRAC
attribute_deprecated
struct AVFrac pts;
#endif
AVRational time_base;
int64_t start_time;
/* 该视频/音频流长度 */
int64_t duration;
int64_t nb_frames;
int disposition;
enum AVDiscard discard;
AVRational sample_aspect_ratio;
/* 元数据信息 */
AVDictionary *metadata;
/* 帧率(注:对视频来说,这个挺重要的) */
AVRational avg_frame_rate;
/* 附带的图片。比如说一些MP3,AAC音频文件附带的专辑封面。 */
AVPacket attached_pic;
AVPacketSideData *side_data;
int nb_side_data;
int event_flags;
#define AVSTREAM_EVENT_FLAG_METADATA_UPDATED 0x0001 ///< The call resulted in updated metadata.
#define MAX_STD_TIMEBASES (30*12+30+3+6)
struct {
int64_t last_dts;
int64_t duration_gcd;
int duration_count;
int64_t rfps_duration_sum;
double (*duration_error)[2][MAX_STD_TIMEBASES];
int64_t codec_info_duration;
int64_t codec_info_duration_fields;
int found_decoder;
int64_t last_duration;
int64_t fps_first_dts;
int fps_first_dts_idx;
int64_t fps_last_dts;
int fps_last_dts_idx;
} *info;
int pts_wrap_bits;
int64_t first_dts;
int64_t cur_dts;
int64_t last_IP_pts;
int last_IP_duration;
int probe_packets;
int codec_info_nb_frames;
enum AVStreamParseType need_parsing;
struct AVCodecParserContext *parser;
struct AVPacketList *last_in_packet_buffer;
AVProbeData probe_data;
#define MAX_REORDER_DELAY 16
int64_t pts_buffer[MAX_REORDER_DELAY+1];
AVIndexEntry *index_entries;
int nb_index_entries;
unsigned int index_entries_allocated_size;
AVRational r_frame_rate;
int stream_identifier;
int64_t interleaver_chunk_size;
int64_t interleaver_chunk_duration;
int request_probe;
int skip_to_keyframe;
int skip_samples;
int64_t start_skip_samples;
int64_t first_discard_sample;
int64_t last_discard_sample;
int nb_decoded_frames;
int64_t mux_ts_offset;
int64_t pts_wrap_reference;
int pts_wrap_behavior;
int update_initial_durations_done;
int64_t pts_reorder_error[MAX_REORDER_DELAY+1];
uint8_t pts_reorder_error_count[MAX_REORDER_DELAY+1];
int64_t last_dts_for_order_check;
uint8_t dts_ordered;
uint8_t dts_misordered;
int inject_global_side_data;
char *recommended_encoder_configuration;
AVRational display_aspect_ratio;
struct FFFrac *priv_pts;
AVStreamInternal *internal;
AVCodecParameters *codecpar;
} AVStream;
FFMPEG 之 AVCodecContext
AVCodecContext
是存储每一个视频/音频流信息的结构体,
AVCodecContext
中很多的参数是编码的时候使用的,
而这里只针对解码的关键变量来说明。
结构体位于avcodec.h
文件中。
下面是 AVCodecContext 结构体的声明:
typedef struct AVCodecContext {
const AVClass *av_class;
int log_level_offset;
enum AVMediaType codec_type; /* see AVMEDIA_TYPE_xxx */
const struct AVCodec *codec;
#if FF_API_CODEC_NAME
attribute_deprecated
char codec_name[32];
#endif
enum AVCodecID codec_id; /* see AV_CODEC_ID_xxx */
unsigned int codec_tag;
#if FF_API_STREAM_CODEC_TAG
attribute_deprecated
unsigned int stream_codec_tag;
#endif
void *priv_data;
struct AVCodecInternal *internal;
void *opaque;
int64_t bit_rate;
int bit_rate_tolerance;
int global_quality;
int compression_level;
#define FF_COMPRESSION_DEFAULT -1
int flags;
int flags2;
uint8_t *extradata;
int extradata_size;
AVRational time_base;
int ticks_per_frame;
int delay;
int width, height;
int coded_width, coded_height;
#if FF_API_ASPECT_EXTENDED
#define FF_ASPECT_EXTENDED 15
#endif
int gop_size;
enum AVPixelFormat pix_fmt;
#if FF_API_MOTION_EST
attribute_deprecated int me_method;
#endif
void (*draw_horiz_band)(struct AVCodecContext *s,
const AVFrame *src, int offset[AV_NUM_DATA_POINTERS],
int y, int type, int height);
enum AVPixelFormat (*get_format)(struct AVCodecContext *s, const enum AVPixelFormat * fmt);
int max_b_frames;
float b_quant_factor;
#if FF_API_RC_STRATEGY
attribute_deprecated int rc_strategy;
#define FF_RC_STRATEGY_XVID 1
#endif
#if FF_API_PRIVATE_OPT
attribute_deprecated
int b_frame_strategy;
#endif
float b_quant_offset;
int has_b_frames;
#if FF_API_PRIVATE_OPT
attribute_deprecated
int mpeg_quant;
#endif
float i_quant_factor;
float i_quant_offset;
float lumi_masking;
float temporal_cplx_masking;
float spatial_cplx_masking;
float p_masking;
float dark_masking;
int slice_count;
#if FF_API_PRIVATE_OPT
attribute_deprecated
int prediction_method;
#define FF_PRED_LEFT 0
#define FF_PRED_PLANE 1
#define FF_PRED_MEDIAN 2
#endif
int *slice_offset;
AVRational sample_aspect_ratio;
int me_cmp;
int me_sub_cmp;
int mb_cmp;
int ildct_cmp;
#define FF_CMP_SAD 0
#define FF_CMP_SSE 1
#define FF_CMP_SATD 2
#define FF_CMP_DCT 3
#define FF_CMP_PSNR 4
#define FF_CMP_BIT 5
#define FF_CMP_RD 6
#define FF_CMP_ZERO 7
#define FF_CMP_VSAD 8
#define FF_CMP_VSSE 9
#define FF_CMP_NSSE 10
#define FF_CMP_W53 11
#define FF_CMP_W97 12
#define FF_CMP_DCTMAX 13
#define FF_CMP_DCT264 14
#define FF_CMP_MEDIAN_SAD 15
#define FF_CMP_CHROMA 256
int dia_size;
int last_predictor_count;
#if FF_API_PRIVATE_OPT
attribute_deprecated
int pre_me;
#endif
int me_pre_cmp;
int pre_dia_size;
int me_subpel_quality;
#if FF_API_AFD
attribute_deprecated int dtg_active_format;
#define FF_DTG_AFD_SAME 8
#define FF_DTG_AFD_4_3 9
#define FF_DTG_AFD_16_9 10
#define FF_DTG_AFD_14_9 11
#define FF_DTG_AFD_4_3_SP_14_9 13
#define FF_DTG_AFD_16_9_SP_14_9 14
#define FF_DTG_AFD_SP_4_3 15
#endif /* FF_API_AFD */
int me_range;
#if FF_API_QUANT_BIAS
attribute_deprecated int intra_quant_bias;
#define FF_DEFAULT_QUANT_BIAS 999999
attribute_deprecated int inter_quant_bias;
#endif
int slice_flags;
#define SLICE_FLAG_CODED_ORDER 0x0001 ///< draw_horiz_band() is called in coded order instead of display
#define SLICE_FLAG_ALLOW_FIELD 0x0002 ///< allow draw_horiz_band() with field slices (MPEG-2 field pics)
#define SLICE_FLAG_ALLOW_PLANE 0x0004 ///< allow draw_horiz_band() with 1 component at a time (SVQ1)
#if FF_API_XVMC
attribute_deprecated int xvmc_acceleration;
#endif /* FF_API_XVMC */
int mb_decision;
#define FF_MB_DECISION_SIMPLE 0 ///< uses mb_cmp
#define FF_MB_DECISION_BITS 1 ///< chooses the one which needs the fewest bits
#define FF_MB_DECISION_RD 2 ///< rate distortion
uint16_t *intra_matrix;
uint16_t *inter_matrix;
#if FF_API_PRIVATE_OPT
attribute_deprecated
int scenechange_threshold;
attribute_deprecated
int noise_reduction;
#endif
#if FF_API_MPV_OPT
attribute_deprecated
int me_threshold;
attribute_deprecated
int mb_threshold;
#endif
int intra_dc_precision;
int skip_top;
int skip_bottom;
#if FF_API_MPV_OPT
attribute_deprecated
float border_masking;
#endif
int mb_lmin;
int mb_lmax;
#if FF_API_PRIVATE_OPT
attribute_deprecated
int me_penalty_compensation;
#endif
int bidir_refine;
#if FF_API_PRIVATE_OPT
attribute_deprecated
int brd_scale;
#endif
int keyint_min;
int refs;
#if FF_API_PRIVATE_OPT
attribute_deprecated
int chromaoffset;
#endif
#if FF_API_UNUSED_MEMBERS
attribute_deprecated int scenechange_factor;
#endif
int mv0_threshold;
#if FF_API_PRIVATE_OPT
attribute_deprecated
int b_sensitivity;
#endif
enum AVColorPrimaries color_primaries;
enum AVColorTransferCharacteristic color_trc;
enum AVColorSpace colorspace;
enum AVColorRange color_range;
enum AVChromaLocation chroma_sample_location;
int slices;
enum AVFieldOrder field_order;
int sample_rate; ///< samples per second
int channels; ///< number of audio channels
enum AVSampleFormat sample_fmt; ///< sample format
int frame_size;
int frame_number;
int block_align;
int cutoff;
uint64_t channel_layout;
uint64_t request_channel_layout;
enum AVAudioServiceType audio_service_type;
enum AVSampleFormat request_sample_fmt;
int (*get_buffer2)(struct AVCodecContext *s, AVFrame *frame, int flags);
attribute_deprecated
int refcounted_frames;
float qcompress; ///< amount of qscale change between easy & hard scenes (0.0-1.0)
float qblur; ///< amount of qscale smoothing over time (0.0-1.0)
int qmin;
int qmax;
int max_qdiff;
#if FF_API_MPV_OPT
attribute_deprecated
float rc_qsquish;
attribute_deprecated
float rc_qmod_amp;
attribute_deprecated
int rc_qmod_freq;
#endif
int rc_buffer_size;
int rc_override_count;
RcOverride *rc_override;
#if FF_API_MPV_OPT
attribute_deprecated
const char *rc_eq;
#endif
int64_t rc_max_rate;
int64_t rc_min_rate;
#if FF_API_MPV_OPT
attribute_deprecated
float rc_buffer_aggressivity;
attribute_deprecated
float rc_initial_cplx;
#endif
float rc_max_available_vbv_use;
float rc_min_vbv_overflow_use;
int rc_initial_buffer_occupancy;
#if FF_API_CODER_TYPE
#define FF_CODER_TYPE_VLC 0
#define FF_CODER_TYPE_AC 1
#define FF_CODER_TYPE_RAW 2
#define FF_CODER_TYPE_RLE 3
#if FF_API_UNUSED_MEMBERS
#define FF_CODER_TYPE_DEFLATE 4
#endif /* FF_API_UNUSED_MEMBERS */
attribute_deprecated
int coder_type;
#endif /* FF_API_CODER_TYPE */
#if FF_API_PRIVATE_OPT
attribute_deprecated
int context_model;
#endif
#if FF_API_MPV_OPT
int lmin;
attribute_deprecated
int lmax;
#endif
#if FF_API_PRIVATE_OPT
attribute_deprecated
int frame_skip_threshold;
attribute_deprecated
int frame_skip_factor;
attribute_deprecated
int frame_skip_exp;
attribute_deprecated
int frame_skip_cmp;
#endif /* FF_API_PRIVATE_OPT */
int trellis;
#if FF_API_PRIVATE_OPT
attribute_deprecated
int min_prediction_order;
attribute_deprecated
int max_prediction_order;
attribute_deprecated
int64_t timecode_frame_start;
#endif
#if FF_API_RTP_CALLBACK
attribute_deprecated
void (*rtp_callback)(struct AVCodecContext *avctx, void *data, int size, int mb_nb);
#endif
#if FF_API_PRIVATE_OPT
/** @deprecated use encoder private options instead */
attribute_deprecated
int rtp_payload_size; /* The size of the RTP payload: the coder will */
/* do its best to deliver a chunk with size */
/* below rtp_payload_size, the chunk will start */
/* with a start code on some codecs like H.263. */
/* This doesn't take account of any particular */
/* headers inside the transmitted RTP payload. */
#endif
#if FF_API_STAT_BITS
/* statistics, used for 2-pass encoding */
attribute_deprecated
int mv_bits;
attribute_deprecated
int header_bits;
attribute_deprecated
int i_tex_bits;
attribute_deprecated
int p_tex_bits;
attribute_deprecated
int i_count;
attribute_deprecated
int p_count;
attribute_deprecated
int skip_count;
attribute_deprecated
int misc_bits;
attribute_deprecated
int frame_bits;
#endif
char *stats_out;
char *stats_in;
int workaround_bugs;
#define FF_BUG_AUTODETECT 1 ///< autodetection
#if FF_API_OLD_MSMPEG4
#define FF_BUG_OLD_MSMPEG4 2
#endif
#define FF_BUG_XVID_ILACE 4
#define FF_BUG_UMP4 8
#define FF_BUG_NO_PADDING 16
#define FF_BUG_AMV 32
#if FF_API_AC_VLC
#define FF_BUG_AC_VLC 0 ///< Will be removed, libavcodec can now handle these non-compliant files by default.
#endif
#define FF_BUG_QPEL_CHROMA 64
#define FF_BUG_STD_QPEL 128
#define FF_BUG_QPEL_CHROMA2 256
#define FF_BUG_DIRECT_BLOCKSIZE 512
#define FF_BUG_EDGE 1024
#define FF_BUG_HPEL_CHROMA 2048
#define FF_BUG_DC_CLIP 4096
#define FF_BUG_MS 8192 ///< Work around various bugs in Microsoft's broken decoders.
#define FF_BUG_TRUNCATED 16384
#define FF_BUG_IEDGE 32768
int strict_std_compliance;
#define FF_COMPLIANCE_VERY_STRICT 2 ///< Strictly conform to an older more strict version of the spec or reference software.
#define FF_COMPLIANCE_STRICT 1 ///< Strictly conform to all the things in the spec no matter what consequences.
#define FF_COMPLIANCE_NORMAL 0
#define FF_COMPLIANCE_UNOFFICIAL -1 ///< Allow unofficial extensions
#define FF_COMPLIANCE_EXPERIMENTAL -2 ///< Allow nonstandardized experimental things.
int error_concealment;
#define FF_EC_GUESS_MVS 1
#define FF_EC_DEBLOCK 2
#define FF_EC_FAVOR_INTER 256
int debug;
#define FF_DEBUG_PICT_INFO 1
#define FF_DEBUG_RC 2
#define FF_DEBUG_BITSTREAM 4
#define FF_DEBUG_MB_TYPE 8
#define FF_DEBUG_QP 16
#if FF_API_DEBUG_MV
#define FF_DEBUG_MV 32
#endif
#define FF_DEBUG_DCT_COEFF 0x00000040
#define FF_DEBUG_SKIP 0x00000080
#define FF_DEBUG_STARTCODE 0x00000100
#if FF_API_UNUSED_MEMBERS
#define FF_DEBUG_PTS 0x00000200
#endif /* FF_API_UNUSED_MEMBERS */
#define FF_DEBUG_ER 0x00000400
#define FF_DEBUG_MMCO 0x00000800
#define FF_DEBUG_BUGS 0x00001000
#if FF_API_DEBUG_MV
#define FF_DEBUG_VIS_QP 0x00002000
#define FF_DEBUG_VIS_MB_TYPE 0x00004000
#endif
#define FF_DEBUG_BUFFERS 0x00008000
#define FF_DEBUG_THREADS 0x00010000
#define FF_DEBUG_GREEN_MD 0x00800000
#define FF_DEBUG_NOMC 0x01000000
#if FF_API_DEBUG_MV
int debug_mv;
#define FF_DEBUG_VIS_MV_P_FOR 0x00000001 // visualize forward predicted MVs of P-frames
#define FF_DEBUG_VIS_MV_B_FOR 0x00000002 // visualize forward predicted MVs of B-frames
#define FF_DEBUG_VIS_MV_B_BACK 0x00000004 // visualize backward predicted MVs of B-frames
#endif
int err_recognition;
#define AV_EF_CRCCHECK (1<<0)
#define AV_EF_BITSTREAM (1<<1) ///< detect bitstream specification deviations
#define AV_EF_BUFFER (1<<2) ///< detect improper bitstream length
#define AV_EF_EXPLODE (1<<3) ///< abort decoding on minor error detection
#define AV_EF_IGNORE_ERR (1<<15) ///< ignore errors and continue
#define AV_EF_CAREFUL (1<<16) ///< consider things that violate the spec, are fast to calculate and have not been seen in the wild as errors
#define AV_EF_COMPLIANT (1<<17) ///< consider all spec non compliances as errors
#define AV_EF_AGGRESSIVE (1<<18) ///< consider things that a sane encoder should not do as an error
int64_t reordered_opaque;
struct AVHWAccel *hwaccel;
void *hwaccel_context;
uint64_t error[AV_NUM_DATA_POINTERS];
int dct_algo;
#define FF_DCT_AUTO 0
#define FF_DCT_FASTINT 1
#define FF_DCT_INT 2
#define FF_DCT_MMX 3
#define FF_DCT_ALTIVEC 5
#define FF_DCT_FAAN 6
int idct_algo;
#define FF_IDCT_AUTO 0
#define FF_IDCT_INT 1
#define FF_IDCT_SIMPLE 2
#define FF_IDCT_SIMPLEMMX 3
#define FF_IDCT_ARM 7
#define FF_IDCT_ALTIVEC 8
#if FF_API_ARCH_SH4
#define FF_IDCT_SH4 9
#endif
#define FF_IDCT_SIMPLEARM 10
#if FF_API_UNUSED_MEMBERS
#define FF_IDCT_IPP 13
#endif /* FF_API_UNUSED_MEMBERS */
#define FF_IDCT_XVID 14
#if FF_API_IDCT_XVIDMMX
#define FF_IDCT_XVIDMMX 14
#endif /* FF_API_IDCT_XVIDMMX */
#define FF_IDCT_SIMPLEARMV5TE 16
#define FF_IDCT_SIMPLEARMV6 17
#if FF_API_ARCH_SPARC
#define FF_IDCT_SIMPLEVIS 18
#endif
#define FF_IDCT_FAAN 20
#define FF_IDCT_SIMPLENEON 22
#if FF_API_ARCH_ALPHA
#define FF_IDCT_SIMPLEALPHA 23
#endif
#define FF_IDCT_NONE 24 /* Used by XvMC to extract IDCT coefficients with FF_IDCT_PERM_NONE */
#define FF_IDCT_SIMPLEAUTO 128
int bits_per_coded_sample;
int bits_per_raw_sample;
#if FF_API_LOWRES
int lowres;
#endif
#if FF_API_CODED_FRAME
attribute_deprecated AVFrame *coded_frame;
#endif
int thread_count;
int thread_type;
#define FF_THREAD_FRAME 1 ///< Decode more than one frame at once
#define FF_THREAD_SLICE 2 ///< Decode more than one part of a single frame at once
int active_thread_type;
int thread_safe_callbacks;
int (*execute)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg), void *arg2, int *ret, int count, int size);
int (*execute2)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count);
int nsse_weight;
int profile;
#define FF_PROFILE_UNKNOWN -99
#define FF_PROFILE_RESERVED -100
#define FF_PROFILE_AAC_MAIN 0
#define FF_PROFILE_AAC_LOW 1
#define FF_PROFILE_AAC_SSR 2
#define FF_PROFILE_AAC_LTP 3
#define FF_PROFILE_AAC_HE 4
#define FF_PROFILE_AAC_HE_V2 28
#define FF_PROFILE_AAC_LD 22
#define FF_PROFILE_AAC_ELD 38
#define FF_PROFILE_MPEG2_AAC_LOW 128
#define FF_PROFILE_MPEG2_AAC_HE 131
#define FF_PROFILE_DNXHD 0
#define FF_PROFILE_DNXHR_LB 1
#define FF_PROFILE_DNXHR_SQ 2
#define FF_PROFILE_DNXHR_HQ 3
#define FF_PROFILE_DNXHR_HQX 4
#define FF_PROFILE_DNXHR_444 5
#define FF_PROFILE_DTS 20
#define FF_PROFILE_DTS_ES 30
#define FF_PROFILE_DTS_96_24 40
#define FF_PROFILE_DTS_HD_HRA 50
#define FF_PROFILE_DTS_HD_MA 60
#define FF_PROFILE_DTS_EXPRESS 70
#define FF_PROFILE_MPEG2_422 0
#define FF_PROFILE_MPEG2_HIGH 1
#define FF_PROFILE_MPEG2_SS 2
#define FF_PROFILE_MPEG2_SNR_SCALABLE 3
#define FF_PROFILE_MPEG2_MAIN 4
#define FF_PROFILE_MPEG2_SIMPLE 5
#define FF_PROFILE_H264_CONSTRAINED (1<<9) // 8+1; constraint_set1_flag
#define FF_PROFILE_H264_INTRA (1<<11) // 8+3; constraint_set3_flag
#define FF_PROFILE_H264_BASELINE 66
#define FF_PROFILE_H264_CONSTRAINED_BASELINE (66|FF_PROFILE_H264_CONSTRAINED)
#define FF_PROFILE_H264_MAIN 77
#define FF_PROFILE_H264_EXTENDED 88
#define FF_PROFILE_H264_HIGH 100
#define FF_PROFILE_H264_HIGH_10 110
#define FF_PROFILE_H264_HIGH_10_INTRA (110|FF_PROFILE_H264_INTRA)
#define FF_PROFILE_H264_MULTIVIEW_HIGH 118
#define FF_PROFILE_H264_HIGH_422 122
#define FF_PROFILE_H264_HIGH_422_INTRA (122|FF_PROFILE_H264_INTRA)
#define FF_PROFILE_H264_STEREO_HIGH 128
#define FF_PROFILE_H264_HIGH_444 144
#define FF_PROFILE_H264_HIGH_444_PREDICTIVE 244
#define FF_PROFILE_H264_HIGH_444_INTRA (244|FF_PROFILE_H264_INTRA)
#define FF_PROFILE_H264_CAVLC_444 44
#define FF_PROFILE_VC1_SIMPLE 0
#define FF_PROFILE_VC1_MAIN 1
#define FF_PROFILE_VC1_COMPLEX 2
#define FF_PROFILE_VC1_ADVANCED 3
#define FF_PROFILE_MPEG4_SIMPLE 0
#define FF_PROFILE_MPEG4_SIMPLE_SCALABLE 1
#define FF_PROFILE_MPEG4_CORE 2
#define FF_PROFILE_MPEG4_MAIN 3
#define FF_PROFILE_MPEG4_N_BIT 4
#define FF_PROFILE_MPEG4_SCALABLE_TEXTURE 5
#define FF_PROFILE_MPEG4_SIMPLE_FACE_ANIMATION 6
#define FF_PROFILE_MPEG4_BASIC_ANIMATED_TEXTURE 7
#define FF_PROFILE_MPEG4_HYBRID 8
#define FF_PROFILE_MPEG4_ADVANCED_REAL_TIME 9
#define FF_PROFILE_MPEG4_CORE_SCALABLE 10
#define FF_PROFILE_MPEG4_ADVANCED_CODING 11
#define FF_PROFILE_MPEG4_ADVANCED_CORE 12
#define FF_PROFILE_MPEG4_ADVANCED_SCALABLE_TEXTURE 13
#define FF_PROFILE_MPEG4_SIMPLE_STUDIO 14
#define FF_PROFILE_MPEG4_ADVANCED_SIMPLE 15
#define FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_0 1
#define FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_1 2
#define FF_PROFILE_JPEG2000_CSTREAM_NO_RESTRICTION 32768
#define FF_PROFILE_JPEG2000_DCINEMA_2K 3
#define FF_PROFILE_JPEG2000_DCINEMA_4K 4
#define FF_PROFILE_VP9_0 0
#define FF_PROFILE_VP9_1 1
#define FF_PROFILE_VP9_2 2
#define FF_PROFILE_VP9_3 3
#define FF_PROFILE_HEVC_MAIN 1
#define FF_PROFILE_HEVC_MAIN_10 2
#define FF_PROFILE_HEVC_MAIN_STILL_PICTURE 3
#define FF_PROFILE_HEVC_REXT 4
int level;
#define FF_LEVEL_UNKNOWN -99
enum AVDiscard skip_loop_filter;
enum AVDiscard skip_idct;
enum AVDiscard skip_frame;
uint8_t *subtitle_header;
int subtitle_header_size;
#if FF_API_ERROR_RATE
attribute_deprecated
int error_rate;
#endif
#if FF_API_VBV_DELAY
attribute_deprecated
uint64_t vbv_delay;
#endif
#if FF_API_SIDEDATA_ONLY_PKT
attribute_deprecated
int side_data_only_packets;
#endif
int initial_padding;
AVRational framerate;
enum AVPixelFormat sw_pix_fmt;
AVRational pkt_timebase;
const AVCodecDescriptor *codec_descriptor;
#if !FF_API_LOWRES
int lowres;
#endif
int64_t pts_correction_num_faulty_pts; /// Number of incorrect PTS values so far
int64_t pts_correction_num_faulty_dts; /// Number of incorrect DTS values so far
int64_t pts_correction_last_pts; /// PTS of the last frame
int64_t pts_correction_last_dts; /// DTS of the last frame
char *sub_charenc;
int sub_charenc_mode;
#define FF_SUB_CHARENC_MODE_DO_NOTHING -1 ///< do nothing (demuxer outputs a stream supposed to be already in UTF-8, or the codec is bitmap for instance)
#define FF_SUB_CHARENC_MODE_AUTOMATIC 0 ///< libavcodec will select the mode itself
#define FF_SUB_CHARENC_MODE_PRE_DECODER 1 ///< the AVPacket data needs to be recoded to UTF-8 before being fed to the decoder, requires iconv
int skip_alpha;
int seek_preroll;
#if !FF_API_DEBUG_MV
int debug_mv;
#define FF_DEBUG_VIS_MV_P_FOR 0x00000001 //visualize forward predicted MVs of P frames
#define FF_DEBUG_VIS_MV_B_FOR 0x00000002 //visualize forward predicted MVs of B frames
#define FF_DEBUG_VIS_MV_B_BACK 0x00000004 //visualize backward predicted MVs of B frames
#endif
uint16_t *chroma_intra_matrix;
uint8_t *dump_separator;
char *codec_whitelist;
unsigned properties;
#define FF_CODEC_PROPERTY_LOSSLESS 0x00000001
#define FF_CODEC_PROPERTY_CLOSED_CAPTIONS 0x00000002
AVPacketSideData *coded_side_data;
int nb_coded_side_data;
AVBufferRef *hw_frames_ctx;
int sub_text_format;
#define FF_SUB_TEXT_FMT_ASS 0
#if FF_API_ASS_TIMING
#define FF_SUB_TEXT_FMT_ASS_WITH_TIMINGS 1
#endif
int trailing_padding;
int64_t max_pixels;
AVBufferRef *hw_device_ctx;
int hwaccel_flags;
int apply_cropping;
} AVCodecContext;
下面挑一些关键的变量来看看(这里只考虑解码):
enum AVMediaType codec_type:编解码器的类型(视频,音频…)
struct AVCodec *codec:采用的解码器AVCodec(H.264,MPEG2…)
int bit_rate:平均比特率
uint8_t *extradata; int extradata_size:针对特定编码器包含的附加信息(例如对于H.264解码器来说,存储SPS,PPS等)
AVRational time_base:根据该参数,可以把PTS转化为实际的时间(单位为秒s)
int width, height:如果是视频的话,代表宽和高
int refs:运动估计参考帧的个数(H.264的话会有多帧,MPEG2这类的一般就没有了)
int sample_rate:采样率(音频)
int channels:声道数(音频)
enum AVSampleFormat sample_fmt:采样格式
int profile:型(H.264里面就有,其他编码标准应该也有)
int level:级(和profile差不太多)
FFMPEG 之 AVCodec
AVCodec
是存储编解码器信息的结构体,
结构体声明位于avcodec.h
文件中。
下面是AVCodec
结构体的声明:
typedef struct AVCodec {
/* 短名称格式,AVInputFormat类似 */
const char *name;
/* 长名称格式,描述性名称,相对于name更可读。 */
const char *long_name;
/* 指明了类型,是视频,音频,还是字幕 */
enum AVMediaType type;
/* ID,不重复 */
enum AVCodecID id;
int capabilities;
/* 支持的帧率(仅视频) */
const AVRational *supported_framerates;
/* 支持的像素格式(仅视频) */
const enum AVPixelFormat *pix_fmts;
/* 支持的采样率(仅音频) */
const int *supported_samplerates;
/* 支持的采样格式(仅音频) */
const enum AVSampleFormat *sample_fmts;
/* 支持的声道数(仅音频) */
const uint64_t *channel_layouts;
uint8_t max_lowres;
const AVClass *priv_class;
const AVProfile *profiles;
/* 私有数据的大小 */
int priv_data_size;
struct AVCodec *next;
/* 一些编解码的接口函数 */
int (*init_thread_copy)(AVCodecContext *);
int (*update_thread_context)(AVCodecContext *dst, const AVCodecContext *src);
const AVCodecDefault *defaults;
void (*init_static_data)(struct AVCodec *codec);
int (*init)(AVCodecContext *);
int (*encode_sub)(AVCodecContext *, uint8_t *buf, int buf_size,
const struct AVSubtitle *sub);
int (*encode2)(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame,
int *got_packet_ptr);
int (*decode)(AVCodecContext *, void *outdata, int *outdata_size, AVPacket *avpkt);
int (*close)(AVCodecContext *);
int (*send_frame)(AVCodecContext *avctx, const AVFrame *frame);
int (*receive_packet)(AVCodecContext *avctx, AVPacket *avpkt);
int (*receive_frame)(AVCodecContext *avctx, AVFrame *frame);
void (*flush)(AVCodecContext *);
int caps_internal;
const char *bsfs;
} AVCodec;
FFMPEG 之 AVPacket
AVPacket
是存储压缩编码数据(视频对应H.264等码流数据,音频对应AAC/MP3等码流数据)相关信息的结构体,
结构体声明在avcodec.h文件中声明:
typedef struct AVPacket {
AVBufferRef *buf;
/* 显示时间戳 */
int64_t pts;
/* 解码时间戳 */
int64_t dts;
/* 压缩编码的数据 */
uint8_t *data;
/* 压缩编码数据大小 */
int size;
/* 标识该AVPacket所属的视频/音频流 */
int stream_index;
int flags;
AVPacketSideData *side_data;
int side_data_elems;
int64_t duration;
/* 数据的偏移地址 */
int64_t pos;
#if FF_API_CONVERGENCE_DURATION
attribute_deprecated
int64_t convergence_duration;
#endif
} AVPacket;
音视频部分基本概念的理解
码流
的概念:
码流越大,文件体积也越大,画面质量相应的也就越高,当然因此对播放设备解码能力的要求就越高。
它的单位是kb/s或者Mb/s来表示,计算公式:文件体积 = 时间 + 码率/8
。
举一个简单的例子,一部100分钟1Mbps码流的720P RMVB文件,套用上述公式可得该文件体积为:6000秒 x 1Mb/8 = 750MB
高清视频
的概念:
高清视频可以再区分出视频格式和视频编码,前者是容器,后者为容器里的内容。
视频格式:avi
、mp4
、rmvb
、ts
、mkv
等
视频编码:h.264
、h.265
、MPEG-2
、MPVG-4
、XVID
等
关于视频格式和视频编码的关系,可以通过实际的例子来去加深理解。
比如avi
格式的视频文件可以使用XVID
格式来编码;
ts
格式的高清视频文件通常使用h.264
编码方式。
视频的格式和编码并不能完全决定视频的清晰度,其受视频的分辨率、
码率、片源等多方面影响,但有一点可以确定的是,
即若采用同一种视频编码,视频越清晰,文件体积就越大。
复用器
的概念:
这里设计到两个概念,复用器
和解复用器
。
就是将音频流数据以及视频流的数据(有时候甚至还有字幕流数据等)按照一定的规则,
合并到一个封装格式数据里去。
例如将h.264视频流数据和aac音频流数据合并到一个mkv封装格式中去。
解复用器
则相反,将一个封装格式文件中的数据按一定的规则
拆分出音频流数据和视频流数据等。
本文档参考链接: