ffmpeg資料結構簡介

思想覺悟發表於2020-02-20

每個庫的功能作用

NDKr20使用clang編譯ffmpeg4.2.2一文中我們編譯出了6個so動態庫:

libavcodec.so libavfilter.so libavformat.so libavutil.so libswresample.so libswscale.so

那麼每個so庫的作用是什麼呢,都包含什麼功能呢?

libavcodec.so 是一個包含音訊/視訊編解碼器解碼器和編碼器的庫。 libavfilter.so 是一個包含媒體過濾器的庫 libavformat.so 是一個包含用於多媒體容器格式的解複用器和封裝複用器的庫。 libavutil.so 是一個包含簡化程式設計功能的庫,包括隨機數生成器,資料結構,數學例程,核心多媒體實用程式等等。 libswresample.so 是一個用於執行高度優化的音訊重取樣,重新矩陣化和取樣格式轉換操作的庫 libswscale.so 是一個執行高度優化的影像縮放和色彩空間/畫素格式轉換操作的庫。

常見的資料結構

1、 AVFormatContext 封裝格式上下文結構體,也是統領全域性的結構體,儲存了視訊檔案封裝 格式相關資訊。

  • iformat:輸入視訊的AVInputFormat
  • nb_streams :輸入視訊的AVStream 個數
  • streams :輸入視訊的AVStream []陣列
  • duration :輸入視訊的時長(以微秒為單位)
  • bit_rate :輸入視訊的位元速率

2、 AVInputFormat 每種封裝格式(例如FLV, MKV, MP4, AVI)對應一個該結構體。

  • name:封裝格式名稱
  • long_name:封裝格式的長名稱
  • extensions:封裝格式的副檔名
  • id:封裝格式ID
  • 一些封裝格式處理的介面函式

3、AVStream 視訊檔案中每個視訊(音訊)流對應一個該結構體。

  • id:序號
  • codec:該流對應的AVCodecContext
  • time_base:該流的時基
  • r_frame_rate:該流的幀率
  • AVCodecContext編碼器上下文結構體,儲存了視訊(音訊)編解碼相關資訊。
  • codec:編解碼器的AVCodec
  • width, height:影像的寬高(只針對視訊)
  • pix_fmt:畫素格式(只針對視訊)
  • sample_rate:取樣率(只針對音訊)
  • channels:聲道數(只針對音訊)
  • sample_fmt:取樣格式(只針對音訊)

4、AVCodec 每種視訊(音訊)編解碼器(例如H.264解碼器)對應一個該結構體。

  • name:編解碼器名稱
  • long_name:編解碼器長名稱
  • type:編解碼器型別
  • id:編解碼器ID
  • 一些編解碼的介面函式

5、 AVPacket 儲存一幀壓縮編碼資料。

  • pts:顯示時間戳
  • dts :解碼時間戳
  • data :壓縮編碼資料
  • size :壓縮編碼資料大小
  • stream_index :所屬的AVStream

6、 AVFrame儲存一幀解碼後畫素(取樣)資料。

  • data:解碼後的影像畫素資料(音訊取樣資料)。
  • linesize:對視訊來說是影像中一行畫素的大小;對音訊來說是音訊幀的大小。
  • width, height:影像的寬高(只針對視訊)。
  • key_frame:是否為關鍵幀(只針對視訊) 。
  • pict_type:幀型別(只針對視訊) 。例如I,P,B。

常用的函式

1、libavformat

  • int avformat_network_init (void) 初始化網路,直播推流、拉流或者播放線上資源會用到。
  • AVFormatContext * avformat_alloc_context (void) 初始化AVFormatContext結構體,解複用或者開啟多媒體資源的時候用到。
  • void avformat_free_context (AVFormatContext *s) 使用AVFormatContext,一般情況在呼叫了一個帶有alloc的函式,都會有一個帶有free的函式相對應。
  • int avformat_open_input (AVFormatContext **ps, const char *url, AVInputFormat *fmt, AVDictionary **options) 開啟多媒體資源
  • int av_find_best_stream (AVFormatContext *ic, enum AVMediaType type, int wanted_stream_nb, int related_stream, AVCodec **decoder_ret, int flags) 查詢特定型別的流索引。比如視訊索引、音訊索引等。
  • int av_read_frame (AVFormatContext *s, AVPacket *pkt) 讀取流中的下一幀資料
  • void avformat_close_input (AVFormatContext **s) 關閉一個AVFormatContext,一般使用了一個帶有open欄位的函式,也會有一個對應的帶有close的函式。

2、libavcodec

  • avcodec_register_all (void) 註冊所有編碼器也可以使用avcodec_register (AVCodec *codec)註冊單個編碼器。
  • AVCodecContext * avcodec_alloc_context3 (const AVCodec *codec) 初始化分配解碼器
  • void avcodec_free_context (AVCodecContext **avctx) 釋放解碼器
  • int avcodec_open2 (AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options) 開啟解碼器
  • int avcodec_close (AVCodecContext *avctx) 關閉解碼器
  • AVCodec * avcodec_find_decoder (enum AVCodecID id) 根據id查詢解碼器
  • AVCodec * avcodec_find_decoder_by_name (const char *name) 根據名字查詢解碼器

結語

今天的內容比較空洞,靜是些api的簡單解說,有點空中閣樓的感覺。ffmpeg是一個功能強大的庫,所以要學好它也不是一時半刻的事情,我們要先能學會用ffpemg做一些簡單的編解碼工作,大概理解了它的一些規律之後再在這個基礎上做一些炫酷的功能。 ffmpeg API官方參考文件ffmpeg.org/doxygen/4.1…

最後如果你對音視訊開發感興趣可掃碼關注,後續我們共同探討,共同進步。

ffmpeg資料結構簡介

相關文章