每個庫的功能作用
在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…
最後如果你對音視訊開發感興趣可掃碼關注,後續我們共同探討,共同進步。