音視頻開發之旅(60) -調試分析FFmpeg (解封裝部分的)常用結構體

目錄

  1. ffplay的斷點調試
  2. (解封裝部分)常用結構體以及之間的關系分析
  3. 資料
  4. 收獲

工欲善其事,必先利其器,斷點調試,對我們梳理流程排查問題十分重要,可以ffmpeg的調試可以在XCode、VS code以及QT等ide上進行方便的調試分析。本篇我們以XCode為例來先介紹下ffplay的斷點調試,以ffmpeg4.4版本來進行分析。

一、ffplay的斷點調試

首先下載和編譯ffmpeg,具體可以參考音視頻開發之旅(33) -交叉編譯android使用的FFmpeg(3.x和4.x)
區別在于,我們這次不是交叉編譯,而是在Mac上編譯安裝調試。

./configure --enable-static --disable-shared --enable-debug --disable-doc --disable-x86asm --enable-nonfree  --enable-libvpx --enable-gpl  --enable-opengl --enable-libx264  --enable-libx265 --enable-libvmaf
make -j8
sudo make install

編譯成功之后我們會看到幾個重要的可執行文件ffmpeg_g、ffprobe_g以及ffplay_g,而接下來的運行和調試就會用到他們。
如何在Xcode下配置調試ffmpeg源碼請參考:http://www.lxweimin.com/p/27a90b113413

我們在ffplay.c的main函數打斷點進行進行分析ffplay解封裝(read_thread)流程中用的的結構體。

打開媒體流

VideoState *stream_open(const char *filename,const AVInputFormat *iformat)

涉及到結構體:AVInputFormat

啟動readthread開始讀取

    is->read_tid     = SDL_CreateThread(read_thread, "read_thread", is);

分配AVFormatContext內存

 AVFormatContext   ic = avformat_alloc_context();

打開流媒體文件

int avformat_open_input(AVFormatContext **ps, const char *filename,
                        const AVInputFormat *fmt, AVDictionary **options)

涉及到結構體:AVFormatContext、AVInputFormat、AVDictionary

獲取流信息

int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)

涉及到結構體:AVStream AVCodecParameters AVRational

循環讀取frame數據

 for (;;) {
     ...
     int av_read_frame(AVFormatContext *s, AVPacket *pkt)
     ...
}

涉及到結構體:AVFormatContext、AVPacket等

解封裝的流程先到這里,可見如果想學習ffplay的源碼,首先要搞清楚主要流程以及過程中涉及的關鍵結構體。
下一節我們來具體分析這些結構體。

三、(解封裝部分)常用結構體以及之間的關系分析常用結構體以及之間的關系分析

3.1 常用結構體以及之間的關系

FFMPEG中結構體很多。最關鍵的結構體可以分成以下幾類:
a)        解協議(http,rtsp,rtmp,mms)

AVIOContext,URLProtocol,URLContext主要存儲視音頻使用的協議的類型以及狀態。URLProtocol存儲輸入視音頻使用的封裝格式。每種協議都對應一個URLProtocol結構。(注意:FFMPEG中文件也被當做一種協議“file”)

b)        解封裝(flv,avi,rmvb,mp4)

AVFormatContext主要存儲視音頻封裝格式中包含的信息;AVInputFormat存儲輸入視音頻使用的封裝格式。每種視音頻封裝格式都對應一個AVInputFormat 結構。

c)        解碼(h264,mpeg2,aac,mp3)

每個AVStream存儲一個視頻/音頻流的相關數據;每個AVStream對應一個AVCodecContext,存儲該視頻/音頻流使用解碼方式的相關數據;每個AVCodecContext中對應一個AVCodec,包含該視頻/音頻對應的解碼器。每種解碼器都對應一個AVCodec結構。

d) 存數據

視頻的話,每個結構一般是存一幀;音頻可能有好幾幀

解碼前數據:AVPacket

解碼后數據:AVFrame


引用自: https://blog.csdn.net/leixiaohua1020/article/details/11693997

他們之間的關系如下:


圖片來自:FFMPEG中最關鍵的結構體之間的關系

3.2。AVFormatContext
該結構體定義在libavformat/Avformat.h中,它是一個貫穿始終的數據結構,很多函數都要用到它作為參數。幾個主要變量的作用如下:

struct AVInputFormat *iformat:輸入數據的封裝格式
struct AVOutputFormat *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:元數據

3.3 AVInputFormat
該結構體定義也在libavformat/Avformat.h中,是解封裝器對象主要的變量的作用如下

const char *name: 格式的名稱
const char *mime_type: mime類型如 video/avc video/hevc audio/aac等

以及一系列函數指針
int (*read_probe)(const AVProbeData *);
int (*read_packet)(struct AVFormatContext *, AVPacket *pkt);
int (*read_close)(struct AVFormatContext *);
int (*read_seek)(struct AVFormatContext *,
                     int stream_index, int64_t timestamp, int flags);
int (*read_play)(struct AVFormatContext *);

int (*read_pause)(struct AVFormatContext *);
int (*read_seek2)(struct AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags);

3.4 AVStream
每個AVStream存儲一個視頻/音頻流的相關數據;是解封裝器分離出來的流對象,即解封裝的產物,它保存在AVFormatcontext中。

該結構體定義也在libavformat/Avformat.h中, 主要變量如下:

int index;  流索引
int id; 流id
void *priv_data; 流數據
AVRational time_base; 時間基,通過該值可以把PTS,DTS轉化為真正的時間;PTS*time_base=真正的時間
int64_t duration:流長度
AVRational sample_aspect_ratio; 采樣率
AVRational avg_frame_rate:幀率
AVCodecContext *codec:指向該視頻/音頻流的AVCodecContext(它們是一一對應的關系)

AVStream是解封裝環節的輸出,同時也是解碼環節的輸入,每個AVStream對應一個AVCodecContext,存儲該視頻/音頻流使用解碼方式的相關數據;每個AVCodecContext中對應一個AVCodec,包含該視頻/音頻對應的解碼器。每種解碼器都對應一個AVCodec結構。
解碼部分的數據結構分析我們下一篇再來分析學習。

3.5 AVPacket
存儲壓縮編碼數據相關信息的結構體,保存了解封裝之后,解碼之前的數據以及PTS、DTS、Duration以及streamId等信息
該結構體定義位于libavcodec/Packet.h中,主要變量如下:

  uint8_t *data; 對于H.264來說。1個AVPacket的data通常對應一個NAL。
int   size:data的大小
int64_t pts:顯示時間戳
int64_t dts:解碼時間戳
AVPacketSideData *side_data;附加信息

三、資料

《Android音視頻開發》-第八章
Xcode調試ffmpeg源碼(十五)
FFMPEG中最關鍵的結構體之間的關系
FFMPEG結構體分析:AVFormatContext
FFMPEG結構體分析:AVStream
FFMPEG結構體分析:AVPacket

四、收獲

通過本篇的學習實踐,我們學習到了

  1. 如何在Xcode下斷點調試ffmpeg并進行ffplay解封裝流程的分析
  2. 了解常用結構體之間的關系:解協議、解封裝、解碼對應的結構體以及之間的關系
  3. 了解解封裝相關的幾個關鍵結構的的主要變量和函數。AVFormatContext、AVInputFormat、AVStream

感謝你的閱讀
下一篇我們分析ffmpeg解碼部分的常用結構體,歡迎關注公眾號“音視頻開發之旅”,一起學習成長。
歡迎交流

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,327評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,996評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,316評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,406評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,128評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,524評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,576評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,759評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,310評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,065評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,249評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,821評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,479評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,909評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,140評論 1 290
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,984評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,228評論 2 375

推薦閱讀更多精彩內容