VLC采用多線程并行解碼架構,線程之間通過單獨的一個線程控制所有線程的狀態,解碼器采用filter模式.組織方式為模塊架構
模塊簡述:
libvlc 是VLC的核心部分。它是一個提供接口的庫,比如給VLC提供功能接口:流的接入,音頻視頻的輸出,插件管理,線程系統。
interface 包含與用戶交互的按鍵和設備彈出。
Playlist 管理播放列表的交互,如停止,播放,下一個,或者隨機播放。
Video_output 初始化video顯示器,從解碼器得到所有的圖片和子圖片。隨意將他們轉換為其他的格式并且播放(如YUV到RGB)
Stream_output 類似Audio_output
Misc 是被其他部分使用的雜項,如線程系統,消息隊列,CPU探測,對象查詢系統,或者特定平臺代碼。
1.main負責初始化所有結構體,全局資源,派生出:
---> 2.playlist,初始化和管理播放器的播放列表。
---> 3.一個中間線程,
---> 4.SigThread控制播放器的播放暫停等,管理最終的程序退出,在接到信號(待定)后執行libvlc_Quit()銷毀所有與libvlc相關的線程和資源.。播放完畢后,音視頻的輸出線程先退出(可能由他們自己管理自己,完成后自動退出 )
接著渲染(或者驅動)線程退出。2個視頻解碼渲染,1個音頻解碼渲染。
( 7-Vout, 9-video_output, 10-xcb.c/Thread()
11-xdg.c/Thread()
8-Aout, 12-audio_output/alsa.c/ALSAThread()循環調用ALSAFill(p_aout))
---> 5.RunInterface: setups necessary data and give control to the interface
執行Run(),控制所有線程開始,其他線程得到消息之后并行運行。 Run()函數中ReadCommand( p_intf, p_buffer, &i_size );解析外部命令。這里是一個命令模式
線程2 派生出
線程6.input/Run(),該線程阻塞在while( !LoopInput( p_playlist ) ) vlc_cond_wait( &p_sys->signal, &p_sys->lock ); 上。并且通過 LoopRequest( p_playlist );循環解析播放列表,播放所有的資源。
線程6派生出:
線程7.input/DecoderThread(),這個線程被VoutCreate函數創建,使用Ffmpeg作為解碼庫
線程8.input/DecoderThread(),這個線程被audio_output/alsa.c/Open()函數創建
線程7是Video的解碼線程,它派生出:
線程9.video_output/RunThread(),這個線程作為視頻解碼器使用,這是它的調用棧的回溯表:
FT_Get_Glyph () from /usr/lib/i386-linux-gnu/libfreetype.so.6
RenderText () at freetype.c:1212
SpuRenderText () at video_output/vout_subpictures.c:1093
SpuRenderRegion () at video_output/vout_subpictures.c:1361
RenderText () at freetype.c:1212
SpuRenderText () at video_output/vout_subpictures.c:1093
SpuRenderRegion () at video_output/vout_subpictures.c:1361
spu_RenderSubpictures () at video_output/vout_subpictures.c:507
vout_RenderPicture () at video_output/vout_pictures.c:383
RunThread () at video_output/video_output.c:1148
vout_RenderPicture () at video_output/vout_pictures.c:383
RunThread () at video_output/video_output.c:1148
線程9派生出兩個渲染器線程線程分別為:
---> 線程10.video_output/xcb/Thread()
---> 線程11.modules/misc/inhibit/xdg.c/Thread()
線程8.是音頻解碼線程,通過aout_outputNew創建,它派生出線程12.audio_output/alsa.c/ALSAThreade()作為音頻的渲染。
整個程序可以通過將斷點打在ALSAThread()上觀察,數據從文件或者網絡流到最終被解碼的數據的流程,其中幾個比較關鍵的概念是ES,PES,PS,TS。
這個地方對VLC模塊的講解非常清晰:
http://www.enjoythearchitecture.com/vlc-architecture.html
附一張EMACS+GDB調試VLC播放器的截圖

這個地方對VLC模塊的講解非常清晰:
http://www.enjoythearchitecture.com/vlc-architecture.html
附一張EMACS+GDB調試VLC播放器的截圖


抱歉,我郵箱里面沒有搜到你的郵件,大概是被我無意間刪了。
這個博客上也沒有看到哪里可以直接回復你,點你的名字也是跳到我自己的博客,所以只能在這里和你說了,希望你可以看得到,我的郵箱是tianshidebaigu@icloud.com,如果你看到這個回復的話請郵件與我溝通。
這里提一下你說的問題:
如果是卡頓,要看聲音是不是也卡頓。若都卡頓。說明在流數據的傳輸過程中有瓶頸,VLC是以流處理作為設計核心的,一般而言access不會卡頓,所以你從demux->codec->rendering的路線找一下性能瓶頸。也許是你的視頻文件的某種封裝包在dmeux過程中丟包了,多半是demux不識別該包的格式造成的,demux對于自己不認識的壓縮包,就是采用丟包策略。所以也許是代碼中缺少相應的媒體包處理程序,最好是編譯最新的源碼,我最近在做儀表系統的移植,只能幫你從框架上分析一下。
vlc根據版本的不同,demux的入口線程句柄也不同,但是頂層函數的名稱應該是沒有變的。你用gdb去跟蹤所有線程找到demux的線程入口函數,再具體跟進吧。
我認為vlc里面RunInterface是demux的入口函數,你可以從這個函數開始分析數據的走向。(運行時去看)
流媒體的概念類似于一系列由管道連接起來的染料桶,access先獲取原料,demux將原料區分處理一下交給codec,codec將原料解開并放進染缸,rendering將染缸中的顏色染到布上面,然后展示。 這些原料都是以特定的方向向另一個方向走的,所以叫做流。 這些你應該都懂吧,不過為了避免溝通的誤差,還是解釋下比較好。