ffmpeg基礎知識二

常用庫:

avcodec:編解碼(最重要的庫)

avformat:封裝格式處理

avfilter:濾鏡特效處理

avdevice:各種設備的輸入輸出

avutil:工具庫(大部分庫都需要該庫支持)

postproc:後加工

swresample:音頻採樣數據格式轉換

swscale:視頻像素數據格式轉換

 

常用數據結構:

AVFormatContext:

typedef struct AVFormatContext
{
    //指向 AVInputFormat,如對於 mp4 或 mov 爲 ff_mov_demuxer
    struct AVInputFormat *iformat;
    /**
     * The output container format.
     *
     * Muxing only, must be set by the caller before avformat_write_header().
     */
    struct AVOutputFormat *oformat;
    // 指向具體的格式對應的 Context,如:MovContext。
    void *priv_data;
    //指向數據讀取統一接口 context
    ByteIOContext pb;
    //流的數目
    int nb_streams;
    //至少 2 個指針元素分別指向 video stream 和 audio stream
    AVStream *streams[MAX_STREAMS];
} AVFormatContext;

AVFormatContext結構表示程序運行的當前文件容器格式所使用的上下文,着重於所有文件容器共有的屬性(並且是在
程序運行時才能確定其值)和關聯其他結構的字段。priv_data 字段關聯各個具體文件容器獨有的屬性上下文,和 priv_data_size 配對使用

struct AVInputFormat *iformat:輸入數據的封裝格式

struct AVInputFormat *oformat:輸出數據的封裝格式

AVIOContext *pb:輸入數據的緩存

unsigned int nb_streams:視音頻流的個數

AVStream **streams:視音頻流

char filename[1024]:文件名

int64_t duration:時長(單位:微秒us,轉換爲秒需要除以1000000)

int bit_rate:比特率(單位bps,轉換爲kbps需要除以1000)

AVDictionary *metadata:元數據

AVOutputFormat:

AVOutputFormat 結構主要包含的信息有:封裝名稱描述,編碼格式信息(video/audio 默認編碼格式,支持的編碼格式列表),一些對封裝的操作函數(write_header,write_packet,write_tailer等)。其中,AVOutputFormat沒有實現AVClass接口,但它保存了一個AVClass接口,具體怎樣被使用則由後續決定。例如:MOV類的AVOutputFormat封裝保存的是 針對 MOVMuxContext 結構的 AVClass 接口實現。

typedef struct AVOutputFormat {
    const char *name;
    /**
     * Descriptive name for the format, meant to be more human-readable
     * than name. You should use the NULL_IF_CONFIG_SMALL() macro
     * to define it.
     */
    //編碼格式信息(video/audio 默認編碼格式,支持的編碼格式列表)
    enum AVCodecID audio_codec;    /**< default audio codec */
    enum AVCodecID video_codec;    /**< default video codec */
    enum AVCodecID subtitle_codec; /**< default subtitle codec */

} AVOutputFormat;

AVInputFormat:

AVInputFormat是類似COM接口的數據結構,表示輸入文件容器格式,着重於功能函數,一種文件容器格式對應一個AVInputFOrmat結構,在程序運行時有多個實例,next變量用於把所有支持的輸入文件容器格式連接成鏈表,便於便利查找,priv_data_size標示具體的文件容器格式對應的Context大小

typedef struct AVInputFormat
{
    // 標示 format 的名字, 比如,“mov” “mp4” 等。
    const char *name;
    // 標示具體的 format 對應的 Context 的 size,如:MovContext。
    int priv_data_size;
    //具體的操作函數
    int(*read_probe)(AVProbeData*);
    int(*read_header)(struct AVFormatContext *,AVFormatParameters *ap);
    int(*read_packet)(struct AVFormatContext *, AVPacket *pkt);
    int(*read_close)(struct AVFormatContext*);
    struct AVInputFormat *next;
} AVInputFormat;

AVCodecContext:

AVCodecContext結構表示程序運行的當前Codec的上下文,着重於當前所有Codec共有的屬性(並且是在程序運行時才能確定其值)和關聯其他結構的字段。extradata 和 extradata_size 兩個字段表述了相應 Codec 使用的私有數據;codec 字段關聯相應的編解碼器;priv_data 字段關聯各個具體編解碼器獨有的屬性 context,和 AVCodec 結構中的 priv_data_size 配對使用

typedef struct AVCodecContext
{
    int bit_rate;
    int frame_number;
    //擴展數據,如 mov 格式中 audio trak 中 aac 格式中 esds 的附加解碼信息。
    unsigned char *extradata;
    //擴展數據的 size
    int extradata_size;
    //視頻的原始的寬度與高度
    int width, height; // 此邏輯段僅針對視頻
    //視頻一幀圖像的格式,如 YUV420
    enum PixelFormat pix_fmt;
    //音頻的採樣率
    int sample_rate;
    //音頻的聲道的數目
    int channels;
    int bits_per_sample;
    int block_align;
    // 指向相應的解碼器,如:ff_h264_decoder
    struct AVCodec *codec;
    //指向具體相應的解碼器的 context,如 H264Context
    void *priv_data;
    //公共操作函數
    int(*get_buffer)(struct AVCodecContext *c, AVFrame *pic);
    void(*release_buffer)(struct AVCodecContext *c, AVFrame *pic);
    int(*reget_buffer)(struct AVCodecContext *c, AVFrame *pic);
}AVCodecContext;

AVCodec:

AVCodec是類似COM接口的數據結構,表示音視頻編解碼器,着重於功能函數,一種媒體類型對應一個AVCodec結構,在程序運行時有多個實例。next 變量用於把所有支持的編解碼器連接成鏈表,便於遍歷查找;id 確定了 唯 一編 解 碼器 ; priv_data_size 表示具 體 的 Codec 對應的 Context 結構大 小

typedef struct AVCodec
{
    // 標示 Codec 的名字, 比如,"h264" "h263" 等。
    const char *name;
    // 標示 Codec 的類型,有 video ,audio 等類型。
    enum CodecType type;
    // 標示 Codec 的 ID,有 CODEC_ID_H264 等。
    enum CodecID id;
    // 標示具體的 Codec 對應的 Context 的 size,如:H264Context。
    int priv_data_size;
    // 以下標示 Codec 對外提供的操作,每一種解碼器都會實現這些操作。
    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);
    struct AVCodec *next;
}AVCodec;

AVStream:

AVStream結構表示當前媒體流的上下文,着重於所有媒體流共有的屬性(並且是在程序運行時才能確定其值)和關聯其他結構的字段,actx字段關聯當前音視頻媒體所使用的編解碼器的context;priv_data 字段關聯解析各個具體媒體流解複用拆包用的ontext;還有關鍵幀的索引表也存於此

typedef struct AVStream
{
    //指向解碼器 context,用於關聯解碼器
    AVCodecContext *actx;
    //codec 解析器,每一種編碼器在進行壓縮時都會對實際負載數據進行封裝,加//入頭信息,如 h264,需    
    //要解析 nal單元,關聯通過 avav_find_stream_info()
    struct AVCodecParserContext *parser;
    //指向解複用的流的 context,比如 mp4 的 MovStreamcontext
    void *priv_data;
    AVRational time_base;
    //用於 seek 時使用,用於快速索引關鍵幀,如 flv 的 keyframes 索引表和 mp4 的 I
    //幀的索引表都存於此,很重要
    AVIndexEntry *index_entries;
    //index_entries 的元素的個數
    int nb_index_entries;
    int index_entries_allocated_size;
    double frame_last_delay;
} AVStream;

AVPacket:

AVPacket 代表音視頻數據幀,固有的屬性是一些標記,時鐘信息,和壓縮數據首地址,大小等信息

typedef struct AVPacket
{
    //顯示時間戳
    int64_t pts;
    //解碼時間戳
    int64_t dts;
    //記錄在文件或網絡中的流中的字節的位置
    int64_t pos;
    //實際數據指針
    uint8_t *data;
    //實際的數據的大小
    int size;
    //該 packet 所屬的流的索引,一般爲 0 或者 1
    int stream_index;
    int flags;
    //析構函數
    void(*destruct)(struct AVPacket*);
} AVPacket;

AVFrame:

AVFrame結構體一般用於存儲原始數據(即非壓縮數據,例如對視頻來說是 YUV,RGB,對音頻來說是 PCM),此外還包含了一些相關的信息。比如說,解碼的時候存儲了宏塊類型表,QP 表,運動矢量表等數據。編碼的時候也存儲了相關的數據。因此在使用 FFMPEG 進行碼流分析的時候,AVFrame 是一個很重要的結構體

typedef struct AVFrame {
    #define AV_NUM_DATA_POINTERS 8
    uint8_t *data[AV_NUM_DATA_POINTERS];
    int linesize[AV_NUM_DATA_POINTERS];
    uint8_t **extended_data;
    /**寬高 */
    int width, height;
    int nb_samples;
    int format;
    /**是否是關鍵幀*/
    int key_frame;
    /**幀類型(I,B,P)*/
    enum AVPictureType pict_type;
    uint8_t *base[AV_NUM_DATA_POINTERS];
    AVRational sample_aspect_ratio;
    int64_t pts;
    int64_t pkt_pts;
    int64_t pkt_dts;
    int coded_picture_number;
    int display_picture_number;
    int quality;
    int reference;
    /**QP 表*/
    int8_t *qscale_table;
    int qstride;
    int qscale_type;
    /**跳過宏塊表 */
    uint8_t *mbskip_table;
    /**運動矢量表*/
    int16_t (*motion_val[2])[2];
    /**宏塊類型表 */
    uint32_t *mb_type;
    /**DCT 係數 */
    short *dct_coeff;
    /**參考幀列表 */
    int8_t *ref_index[2];
    void *opaque;
    uint64_t error[AV_NUM_DATA_POINTERS];
    int type;
    int repeat_pict;
    int interlaced_frame;
    int top_field_first;
    int palette_has_changed;
    int buffer_hints;
    AVPanScan *pan_scan;
    int64_t reordered_opaque;
    void *hwaccel_picture_private;
    struct AVCodecContext *owner;
    void *thread_opaque;
    /**
    * log2 of the size of the block which a single vector in motion_val represents:
    * (4->16x16, 3->8x8, 2-> 4x4, 1-> 2x2)
    * - encoding: unused
    * - decoding: Set by libavcodec.
    */
    uint8_t motion_subsample_log2;
    /**(音頻)採樣率 */
    int sample_rate;
    uint64_t channel_layout;
    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
    int64_t channels;
} AVFrame;

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章