FFmpeg源代碼結(jié)構(gòu)圖-解碼

首先呈現(xiàn)分析出來的FFmpeg源代碼結(jié)構(gòu)圖。這張圖的尺寸非常的大,尺寸大約有4000x4000,有點(diǎn)像一張地圖(因此最好選擇“查看更清晰的圖片”之后,右鍵保存圖片到本機(jī)之后再查看)。它表明了FFmpeg在解碼一個(gè)視頻的時(shí)候的函數(shù)調(diào)用流程。為了保證結(jié)構(gòu)清晰,其中僅列出了最關(guān)鍵的函數(shù),剔除了其它不是特別重要的函數(shù)。


下面解釋一下圖中關(guān)鍵標(biāo)記的含義。

函數(shù)背景色

函數(shù)在圖中以方框的形式表現(xiàn)出來。不同的背景色標(biāo)志了該函數(shù)不同的作用:

粉紅色背景函數(shù):FFmpeg的API函數(shù)。

白色背景的函數(shù):FFmpeg的內(nèi)部函數(shù)。

黃色背景的函數(shù):URLProtocol結(jié)構(gòu)體中的函數(shù),包含處理協(xié)議(Protocol)的功能。

綠色背景的函數(shù):AVInputFormat結(jié)構(gòu)體中的函數(shù),包含處理封裝格式(Format)的功能。

藍(lán)色背景的函數(shù):AVCodec結(jié)構(gòu)體中的函數(shù),包含了編解碼器(Codec)的功能。

PS:URLProtocol,AVInputFormat,AVCodec在FFmpeg開始運(yùn)行并且注冊(cè)完組件之后,都會(huì)分別被連接成一個(gè)個(gè)的鏈表。因此實(shí)際上是有很多的URLProtocol,AVInputFormat,AVCodec的。圖中畫出了解碼一個(gè)輸入?yún)f(xié)議是“文件”(其實(shí)就是打開一個(gè)文件。“文件”也被當(dāng)做是一種廣義的協(xié)議),封裝格式為FLV,視頻編碼格式是H.264的數(shù)據(jù)的函數(shù)調(diào)用關(guān)系。

區(qū)域

整個(gè)架構(gòu)圖可以分為以下幾個(gè)區(qū)域:

左邊區(qū)域——架構(gòu)函數(shù)區(qū)域:這些函數(shù)并不針對(duì)某一特定的視頻格式。

右上方黃色區(qū)域——協(xié)議處理函數(shù)區(qū)域:不同的協(xié)議(RTP,RTMP,F(xiàn)ILE)會(huì)調(diào)用不同的協(xié)議處理函數(shù)。

右邊中間綠色區(qū)域——封裝格式處理函數(shù)區(qū)域:不同的封裝格式(MKV,F(xiàn)LV,MPEGTS,AVI)會(huì)調(diào)用不同的封裝格式處理函數(shù)。

右邊下方藍(lán)色區(qū)域——編解碼函數(shù)區(qū)域:不同的編碼標(biāo)準(zhǔn)(HEVC,H.264,MPEG2)會(huì)調(diào)用不同的編解碼函數(shù)。

箭頭線

為了把調(diào)用關(guān)系表示的更明顯,圖中的箭頭線也使用了不同的顏色:

黑色箭頭線:標(biāo)志了函數(shù)之間的調(diào)用關(guān)系。

紅色的箭頭線:標(biāo)志了解碼的流程。

其他顏色的箭頭線:標(biāo)志了函數(shù)之間的調(diào)用關(guān)系。其中:

調(diào)用URLProtocol結(jié)構(gòu)體中的函數(shù)用黃色箭頭線標(biāo)識(shí);

調(diào)用AVInputFormat結(jié)構(gòu)體中的函數(shù)用綠色箭頭線標(biāo)識(shí);

調(diào)用AVCodec結(jié)構(gòu)體中的函數(shù)用藍(lán)色箭頭線標(biāo)識(shí)。

函數(shù)所在的文件

每個(gè)函數(shù)旁邊標(biāo)識(shí)了它所在的文件的路徑。

此外,還有一點(diǎn)需要注意的是,一些API函數(shù)內(nèi)部也調(diào)用了另一些API函數(shù)。也就是說,API函數(shù)并不一定全部都調(diào)用FFmpeg的內(nèi)部函數(shù),他也有可能調(diào)用其他的API函數(shù)。例如從圖中可以看出來,avformat_close_input()調(diào)用了avformat_free_context()和avio_close()。這些在內(nèi)部代碼中被調(diào)用的API函數(shù)也標(biāo)記為粉紅色。

函數(shù)調(diào)用關(guān)系

下面簡單列出幾個(gè)區(qū)域中函數(shù)之間的調(diào)用關(guān)系(函數(shù)之間的調(diào)用關(guān)系使用縮進(jìn)的方式表現(xiàn)出來)。詳細(xì)的函數(shù)分析可以參考相關(guān)的《FFmpeg源代碼分析》系列文章。

左邊區(qū)域(FFmpeg架構(gòu)函數(shù))

1. ?av_register_all()【函數(shù)簡單分析

1) ?avcodec_register_all()

(a)?REGISTER_HWACCEL()

(b)?REGISTER_ENCODER()

(c)?REGISTER_DECODER()

(d)?REGISTER_PARSER()

(e)?REGISTER_BSF()

2) ?REGISTER_MUXER()

3) ?REGISTER_DEMUXER()

4) ?REGISTER_PROTOCOL()

2. ?avformat_alloc_context()【函數(shù)簡單分析

1)?av_malloc(sizeof(AVFormatContext))

2)?avformat_get_context_defaults()

(a)?av_opt_set_defaults()

3. ?avformat_open_input()【函數(shù)簡單分析

1)?init_input()

(a)?avio_open2()【函數(shù)簡單分析

a)?ffurl_open()

i.?ffurl_alloc()

l?url_find_protocol()

l?url_alloc_for_protocol()

ii. ffurl_connect()

URLProtocol->url_open()

b)?ffio_fdopen()

i.?av_malloc(buffer_size)

ii.avio_alloc_context()

l?av_mallocz(sizeof(AVIOContext))

l?ffio_init_context()

(b)av_probe_input_buffer2()

a)avio_read()

i.AVInputFormat->read_packet()

b)av_probe_input_format2()

c)av_probe_input_format3()

i.av_iformat_next()

ii.av_match_name()

iii.av_match_ext()

iv.AVInputFormat->read_probe()

2)?AVInputFormat->read_header()

4.?avformat_find_stream_info()【函數(shù)簡單分析

1)?find_decoder()

(a)avcodec_find_decoder()

2)avcodec_open2()

3)?read_frame_internal()

4)?try_decode_frame()

(a)avcodec_decode_video2()

5)avcodec_close()

6)?estimate_timings()

(a)??estimate_timings_from_pts()

(b)??estimate_timings_from_bit_rate()

(c)??update_stream_timings()

5.?avcodec_find_decoder()【函數(shù)簡單分析

1)?find_encdec()

6.?avcodec_open2()【函數(shù)簡單分析

1)AVCodec->init()

7.?av_read_frame()【函數(shù)簡單分析

1)?read_from_packet_buffer()

2)?read_frame_internal()

(a)?ff_read_packet()

a)AVInputFormat->read_packet()

(b)?parse_packet()

a)?av_parser_parse2()

8.?avcodec_decode_video2()【函數(shù)簡單分析

1)?av_packet_split_side_data()

2)AVCodec->?decode()

3)?av_frame_set_pkt_pos()

4)?av_frame_set_best_effort_timestamp()

9.?avcodec_close()【函數(shù)簡單分析

1)AVCodec->close()

10.?avformat_close_input()【函數(shù)簡單分析

1)AVInputFormat->read_close()

2)?avformat_free_context()

(a)?ff_free_stream()

3)?avio_close()

(a)?avio_flush()

a)?flush_buffer()

(b)?ffurl_close()

a)?ffurl_closep()

URLProtocol->url_close()

右上區(qū)域(URLProtocol協(xié)議處理函數(shù))

URLProtocol結(jié)構(gòu)體包含如下協(xié)議處理函數(shù)指針:

url_open():打開

url_read():讀取

url_write():寫入

url_seek():調(diào)整進(jìn)度

url_close():關(guān)閉

【例子】不同的協(xié)議對(duì)應(yīng)著上述接口有不同的實(shí)現(xiàn)函數(shù),舉幾個(gè)例子:

File協(xié)議(即文件)對(duì)應(yīng)的URLProtocol結(jié)構(gòu)體ff_file_protocol:

url_open() -> file_open() -> open()

url_read() -> file_read() -> read()

url_write() -> file_write() -> write()

url_seek() -> file_seek() -> lseek()

url_close() -> file_close() -> close()

RTMP協(xié)議(libRTMP)對(duì)應(yīng)的URLProtocol結(jié)構(gòu)體ff_librtmp_protocol:

url_open() -> rtmp_open() -> RTMP_Init(), RTMP_SetupURL(), RTMP_Connect(), RTMP_ConnectStream()

url_read() -> rtmp_read() -> RTMP_Read()

url_write() -> rtmp_write() -> RTMP_Write()

url_seek() -> rtmp_read_seek() -> RTMP_SendSeek()

url_close() -> rtmp_close() -> RTMP_Close()

UDP協(xié)議對(duì)應(yīng)的URLProtocol結(jié)構(gòu)體ff_udp_protocol:

url_open() -> udp_open()

url_read() -> udp_read()

url_write() -> udp_write()

url_seek() -> udp_close()

url_close() -> udp_close()

右中區(qū)域(AVInputFormat封裝格式處理函數(shù))

AVInputFormat包含如下封裝格式處理函數(shù)指針:

read_probe():檢查格式

read_header():讀取文件頭

read_packet():讀取一幀數(shù)據(jù)

read_seek():調(diào)整進(jìn)度

read_close():關(guān)閉

【例子】不同的封裝格式對(duì)應(yīng)著上述接口有不同的實(shí)現(xiàn)函數(shù),舉幾個(gè)例子:

FLV封裝格式對(duì)應(yīng)的AVInputFormat結(jié)構(gòu)體ff_flv_demuxer:

read_probe() -> flv_probe() –> probe()

read_header() -> flv_read_header() -> create_stream() -> avformat_new_stream()

read_packet() -> flv_read_packet()

read_seek() -> flv_read_seek()

read_close() -> flv_read_close()

MKV封裝格式對(duì)應(yīng)的AVInputFormat結(jié)構(gòu)體ff_matroska_demuxer:

read_probe() -> matroska_probe()

read_header() -> matroska_read_header()

read_packet() -> matroska_read_packet()

read_seek() -> matroska_read_seek()

read_close() -> matroska_read_close()

MPEG2TS封裝格式對(duì)應(yīng)的AVInputFormat結(jié)構(gòu)體ff_mpegts_demuxer:

read_probe() -> mpegts_probe()

read_header() -> mpegts_read_header()

read_packet() -> mpegts_read_packet()

read_close() -> mpegts_read_close()

AVI封裝格式對(duì)應(yīng)的AVInputFormat結(jié)構(gòu)體ff_avi_demuxer:

read_probe() -> avi_probe()

read_header() -> avi_read_header()

read_packet() -> avi_read_packet()

read_seek() -> avi_read_seek()

read_close() -> avi_read_close()

右下區(qū)域(AVCodec編解碼函數(shù))

AVCodec包含如下編解碼函數(shù)指針:

init():初始化

decode():解碼一幀數(shù)據(jù)

close():關(guān)閉

【例子】不同的編解碼器對(duì)應(yīng)著上述接口有不同的實(shí)現(xiàn)函數(shù),舉幾個(gè)例子:

HEVC解碼對(duì)應(yīng)的AVCodec結(jié)構(gòu)體ff_hevc_decoder:

init() -> hevc_decode_init()

decode() -> hevc_decode_frame() -> decode_nal_units()

close() -> hevc_decode_free()

H.264解碼對(duì)應(yīng)的AVCodec結(jié)構(gòu)體ff_h264_decoder:

init() -> ff_h264_decode_init()

decode() -> h264_decode_frame() -> decode_nal_units()

close() -> h264_decode_end()

VP8解碼(libVPX)對(duì)應(yīng)的AVCodec結(jié)構(gòu)體ff_libvpx_vp8_decoder:

init() -> vpx_init() -> vpx_codec_dec_init()

decode() -> vp8_decode() -> vpx_codec_decode(), vpx_codec_get_frame()

close() -> vp8_free() -> vpx_codec_destroy()

MPEG2解碼對(duì)應(yīng)的AVCodec結(jié)構(gòu)體ff_mpeg2video_decoder:

init() -> mpeg_decode_init()

decode() -> mpeg_decode_frame()

close() -> mpeg_decode_end()

1、具有1-5工作經(jīng)驗(yàn)的,面對(duì)目前流行的技術(shù)不知從何下手,

需要突破技術(shù)瓶頸的可以加。

2、在公司待久了,過得很安逸,

但跳槽時(shí)面試碰壁。

需要在短時(shí)間內(nèi)進(jìn)修、跳槽拿高薪的可以加。

3、如果沒有工作經(jīng)驗(yàn),但基礎(chǔ)非常扎實(shí),對(duì)java工作機(jī)制,

常用設(shè)計(jì)思想,常用java開發(fā)框架掌握熟練的,可以加。

4、覺得自己很牛B,一般需求都能搞定。

但是所學(xué)的知識(shí)點(diǎn)沒有系統(tǒng)化,很難在技術(shù)領(lǐng)域繼續(xù)突破的可以加。

5. 群號(hào):高級(jí)架構(gòu)群 Java進(jìn)階群:180705916.備注好信息!送架構(gòu)視頻。

6.阿里Java高級(jí)大牛直播講解知識(shí)點(diǎn),分享知識(shí),

多年工作經(jīng)驗(yàn)的梳理和總結(jié),帶著大家全面、

科學(xué)地建立自己的技術(shù)體系和技術(shù)認(rèn)知!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,527評(píng)論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,687評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,640評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,957評(píng)論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,682評(píng)論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,011評(píng)論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,009評(píng)論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,183評(píng)論 0 290
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,714評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,435評(píng)論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,665評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,148評(píng)論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,838評(píng)論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,251評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,588評(píng)論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,379評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,627評(píng)論 2 380

推薦閱讀更多精彩內(nèi)容

  • 初抵廈門 最美的星空下,必然有最美的海,最美的城。如有,我將這美譽(yù)賜給我心中的最美海之城:廈門。 浪跡天涯夢(mèng)、人生...
    駑馬渡江閱讀 2,388評(píng)論 55 37
  • 突然心血來潮,覺得活到現(xiàn)在是不是缺少的什么?看網(wǎng)上的回答說,應(yīng)該有一項(xiàng)業(yè)余愛好來打發(fā)工作之外的時(shí)間。我選擇了我認(rèn)為...
    fan0925閱讀 2,067評(píng)論 0 0
  • 贊美就像是送禮物,不需要有目的或者回報(bào)。許多人都誤以為贊美要帶有某些目的或者是期待,才能幫助孩子進(jìn)步。殊不知,有目...
    心_472c閱讀 179評(píng)論 0 2
  • rsync-r 同步目錄-l --links 復(fù)制symlink-P 顯示進(jìn)度-v 顯示復(fù)制的文件
    RPI3閱讀 224評(píng)論 0 0