FFMPEG 结构体分析

FFMPEG 结构体分析

FFMPEG中结构体很多,最关键的结构体可以分成以下几类:

  • 解协议(http,rtsp,rtmp,mms)

AVIOContextURLProtocolURLContext主要存储视音频使用的协议的类型以及状态。
URLProtocol存储输入视音频使用的封装格式。
每种协议都对应一个URLProtocol结构。(注意:FFMPEG中文件也被当做一种协议“file”)

  • 解封装(flv,avi,rmvb,mp4)

AVFormatContext主要存储视音频封装格式中包含的信息;
AVInputFormat存储输入视音频使用的封装格式。
每种视音频封装格式都对应一个AVInputFormat 结构。

  • 解码(h264,mpeg2,aac,mp3)

每个AVStream存储一个视频/音频流的相关数据;
每个AVStream对应一个AVCodecContext,存储该视频/音频流使用解码方式的相关数据;
每个AVCodecContext中对应一个AVCodec,包含该视频/音频对应的解码器。
每种解码器都对应一个AVCodec结构。

  • 存数据

视频的话,每个结构一般是存一帧;音频可能有好几帧

解码前数据:AVPacket

解码后数据:AVFrame

FFMPEG几个关键结构体对应的关系图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6nnGfIuZ-1651844337799)(relationship_ffmpeg.jpg)]


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

AVInputFormatFFMPEG的解复用器对象,位于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

高清视频的概念:

高清视频可以再区分出视频格式和视频编码,前者是容器,后者为容器里的内容。

视频格式:avimp4rmvbtsmkv

视频编码:h.264h.265MPEG-2MPVG-4XVID

关于视频格式和视频编码的关系,可以通过实际的例子来去加深理解。

比如avi格式的视频文件可以使用XVID格式来编码;

ts格式的高清视频文件通常使用h.264编码方式。

视频的格式和编码并不能完全决定视频的清晰度,其受视频的分辨率、
码率、片源等多方面影响,但有一点可以确定的是,
即若采用同一种视频编码,视频越清晰,文件体积就越大。

复用器的概念:

这里设计到两个概念,复用器解复用器
就是将音频流数据以及视频流的数据(有时候甚至还有字幕流数据等)按照一定的规则,
合并到一个封装格式数据里去。
例如将h.264视频流数据和aac音频流数据合并到一个mkv封装格式中去。

解复用器则相反,将一个封装格式文件中的数据按一定的规则
拆分出音频流数据和视频流数据等。

本文档参考链接:

FFMPEG中最关键的结构体之间的关系_雷霄骅

FFMPEG结构体分析:AVFrame_雷霄骅

ffmpeg原理和架构_B站专栏

猜你喜欢

转载自blog.csdn.net/Stephen8848/article/details/124619532
今日推荐