一.前言
在學習使用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;