FFmpeg中的常用結構體分析

2023-09-08 18:01:23

一.前言

  在學習使用FFmpeg進行編解碼時,我們有必要先去熟悉FFmpeg中的常用結構體,只有對它們的含義和用途有深刻的瞭解,我們才能為後面的學習打下堅實的基礎。所以,這篇文章將會介紹這些常用的結構體有哪些,然後再介紹它們的具體用途。

二.常用的結構體分析

  1.AVFormatContext:

    它用於表示音視訊容器的格式特定資訊和狀態,它可以用來讀取和寫入各種格式的音視訊檔。AVFormatContext結構含有輸入或輸出格式的資訊,例如格式名稱、持續時間、位元率、流和後設資料,它是與FFmpeg中音視訊容器互動的主要介面。在讀取多媒體檔案時,通常使用avformat_open_input()函數開啟檔案,該函數會初始化一個AVFormatContext結構並填充所需的檔案格式資訊;在寫入多媒體檔案時,可以使用avformat_alloc_output_context2()函數建立一個AVFormatContext結構並填充所需的輸出格式資訊,然後可以使用avformat_new_stream()函數為AVFormatContext新增音視訊流,併為每個流設定必要的編解碼器引數。AVFormatContext結構還提供了從輸入檔案中讀入封包(av_read_frame())和向輸出檔案寫入封包(av_write_frame())以及其他功能。總的來說,AVFormatContext是FFmpeg中處理音視訊容器的關鍵元件,為讀取和寫入各種格式的多媒體檔案提供了抽象層。由於AVFormatContext結構體比較龐大,下面只列出該結構體中比較重要的成員,程式碼如下:

typedef struct AVFormatContext{
   const struct AVInputFormat *iformat; //指向輸入格式的指標,包含輸入檔案格式的資訊
   const struct AVOutputFormat *oformat; //指向輸出格式的指標,包含輸出檔案格式的資訊
   AVIOContext *pb; //指向輸入/輸出的AVIOContext結構體的指標
   AVDictionary *metadata; //指向後設資料字典的指標,它包含有關音視訊檔的後設資料資訊,如標題、作者、日期等
   unsigned int nb_streams; //表示流的數量,它指示在音視訊檔中存在多少個流(如音訊流、視訊流、字幕流等)
   AVStream **streams;  //指向音訊流或視訊流的指標
   int64_t duration;   //音視訊檔總時長
   int64_t bit_rate;  //位元速率,也稱位元率,單位時間傳輸的位元數
}AVFormatContext;

  2.AVInputFormat:

    它用來描述和處理輸入媒體檔案的格式資訊,它的作用主要有以下幾個方面:標識媒體檔案的格式、解析和讀取媒體檔案、提供編解碼器相關資訊。下面給出該結構體的部分定義,程式碼如下:

typedef struct AVInputFormat {
    const char *name; //輸入格式的名稱,縮寫
    const char *long_name;  //輸入格式的完整名稱
    int flags; //輸入格式的標誌,可用於指定一些特定的格式要求,如是否支援流式傳輸、是否支援實時解碼等。
    const char *extensions; //副檔名
    const struct AVCodecTag * const *codec_tag; //媒體檔案容器中所用的編解碼器標籤。    const char *mime_type; //支援該輸入格式的MIME型別,用於通過MIME型別識別和匹配輸入檔案格式
    int raw_codec_id; //媒體檔案容器所用的編解碼器IDint (*read_probe)(const AVProbeData *); //探測函數指標,用於探測輸入檔案的格式
    int (*read_header)(struct AVFormatContext *);  //讀取頭部函數指標,用於解析輸入檔案的頭部資訊
    int (*read_packet)(struct AVFormatContext *, AVPacket *pkt); //讀取封包函數指標,用於讀取輸入檔案中的封包
    int (*read_close)(struct AVFormatContext *); //關閉輸入流函數指標,用於在結束讀取檔案後釋放相關資源
} AVInputFormat;

  3.AVOutputFormat:

    它用來描述和處理輸出媒體檔案的格式資訊,和AVInputFormat很類似,它的結構體定義如下:

typedef struct AVOutputFormat {
    const char *name;
    const char *long_name;
    const char *mime_type;
    const char *extensions; 
    enum AVCodecID audio_codec; //音訊編碼器ID
    enum AVCodecID video_codec;    //視訊編碼器ID
    enum AVCodecID subtitle_codec;  //字幕編碼器ID
    int flags;
    const struct AVCodecTag * const *codec_tag;} AVOutputFormat;

  4.AVStream:

    它用來描述媒體檔案中的每個流,可以是音訊流,也可以是視訊流。它的結構體定義如下:

typedef struct AVStream {int index; //在AVFormatContext中的流索引
    int id; //流識別符號,用來區分音訊流和視訊流
    AVCodecParameters *codecpar; //編解碼器引數
    AVRational time_base;  //時間基
    int64_t start_time; //起始時間
    int64_t duration;   //時長
    int64_t nb_frames; //包含的幀的數量         
    AVDictionary *metadata;
    AVRational r_frame_rate;  //影格率
} AVStream;

  5.AVCodecContext:

    它用來表示音視訊編解碼器的上下文資訊,包含了各種引數,設定和狀態,用於初始化和控制音視訊編解碼器的行為,該結構體的部分定義如下:

typedef struct AVCodecContext{
    enum AVMediaType codec_type; //媒體檔案型別
    const struct AVCodec  *codec;  //指向的編解碼器
    enum AVCodecID     codec_id;  //編解碼器id
    int64_t bit_rate; //位元速率
    AVRational time_base; //時間基
    int width, height;
    enum AVPixelFormat pix_fmt; //畫素格式
    int channels; //聲道數
    int sample_rate; //取樣率
    enum AVSampleFormat sample_fmt; //取樣格式
    int frame_size; //幀大小
    void *priv_data; //指向編解碼器私有引數的指標
    int max_b_frames; //最大的b幀數量
    int gop_size; //關鍵幀間距,即兩個I幀之間的幀的數量
}AVCodecContext;

  6.AVCodec:

    它用來表示音視訊編解碼器,定義了編解碼器的屬性和功能,該結構體的定義如下:

typedef struct AVCodec {
    const char *name; //編解碼器的名稱,縮寫
    const char *long_name;  //編解碼器的完整名稱
    enum AVMediaType type; //媒體型別
    enum AVCodecID id;  //編解碼器ID
    int capabilities;  //編解碼器支援的功能和操作
    const AVRational *supported_framerates; //支援的影格率
    const enum AVPixelFormat *pix_fmts;    //支援的畫素格式
    const int *supported_samplerates;     //支援的取樣率 
    const enum AVSampleFormat *sample_fmts; //支援的取樣格式
} AVCodec;

  7.AVFrame:

    AVFrame結構體一般用於儲存原始資料,即未壓縮資料,對視訊來說是YUV,RGB,對音訊來說是PCM。該結構體的部分定義如下:

typedef struct AVFrame{
    uint8_t *data[AV_NUM_DATA_POINTERS];  //儲存音視訊資料的緩衝區指標陣列。不同的元素對應不同的資料平面,例如視訊的Y、U、V分量或音訊的聲道資料
    int linesize[AV_NUM_DATA_POINTERS]; //每個資料平面的行大小(以位元組為單位)
    int width, height;  //視訊幀的寬度和高度
    int nb_samples;  //取樣點個數
    int format; //對於音訊來說指的是音訊取樣格式,對於視訊來說指的是畫素格式
    int64_t pts;  //顯示時間戳
    AVRational time_base; //時間基
    int sample_rate; //取樣率
    int channels;  //聲道數
    int64_t duration; //時長
}AVFrame;

  8.AVPacket:

    它用來儲存編碼後的視訊幀資料,AVPacket儲存瞭解複用之後,解碼前的資料(仍然是壓縮後的資料)和關於這些資料的一些附加資訊,如顯示時間戳,解碼時間戳,資料時長和所在媒體流的索引等;該結構體的定義如下:

typedef struct AVPacket {
    AVBufferRef *buf;//用來管理data指標參照的資料快取
    int64_t pts;//顯示時間戳
    int64_t dts;//解碼時間戳
    uint8_t *data;//指向儲存壓縮資料的指標,這就是AVPacket實際的資料
    int   size;//壓縮資料的大小
    int   stream_index;//所屬的流的索引
    AVPacketSideData *side_data;//填充容器的一些附件資料
    int64_t duration;//時長
    AVRational time_base;//時間基
} AVPacket;

  9.AVIOContext:

    它用來管理輸入輸出操作,AVIOContext提供了讀取和寫入資料的介面。AVFormatContext結構體中的pb指標就是AVIOContext型別的,當開啟媒體檔案時,AVFormatContext會建立和設定一個AVIOContext,並將其分配給pb指標,以便後續的讀取操作可以使用該AVIOContext進行資料的讀取,如果想要實現自定義的I/O操作,可以建立自己的AVIOContext,並將其分配給pb指標,從而使AVFormatContext使用自定義的I/O函數來讀取或寫入資料。該結構體的定義如下:

typedef struct AVIOContext {
    unsigned char *buffer;  //指向緩衝區的指標
    int buffer_size;       //緩衝區的大小
    unsigned char *buf_ptr; //當前的讀取或寫入位置
    unsigned char *buf_end; //緩衝區有效資料的末尾位置
    void *opaque; //指向使用者自定義資料的指標        
    int (*read_packet)(void *opaque, uint8_t *buf, int buf_size); //讀取資料的回撥函數指標
    int (*write_packet)(void *opaque, uint8_t *buf, int buf_size); //寫入資料的回撥函數指標
    int64_t (*seek)(void *opaque, int64_t offset, int whence); //定位到指定位置的回撥函數指標
} AVIOContext;