VLC整體介紹

感謝網絡上的文章分享,此文部分內容節選自網絡。由於當時沒有記錄下網址,無法一一列出,敬請見諒。

VLC整體概念
在介紹VLC內部細節之前,我們想看一下VLC的整體結構:
這裏寫圖片描述

從上面的結構,我們知道我們知道VLC最底層是各個模塊,libVLCcore是管理VLC各個模塊的。libVLC是封裝的API。應用層使用libVLC庫編寫實現播放器。
對於一個視頻的播放,播放器的執行步驟大致如下:
讀取原始數據
解複用
解碼
顯示
VLC的整體框架是設計成一套module的管理機制,將功能分類並抽象成modules。
VLC main: player的main。初始化libVLC 並加載用戶界面。
libVLCcore:libvlc的核心,抽象出了一個libvlc_instance_t 對象,提供modules的裝載/卸載機制。
modules: modules提供具體的功能,比如上面的access,demux,decode就是以一個模塊的形式存在。
External libraries:外部開源庫。
模塊的加載方式:
首先模塊先將自身註冊到VLC中,然後在需要加載模塊的時候,調用module_need接口,去找到合適的模塊。找到合適的模塊後,會執行註冊中設置的回調方法。
同樣自己可以實現模塊,只需要按照VLC模塊的標準即可。VLC中很多模塊就是通過外部的開源庫實現的。
VLC模塊組成的播放器整體結構如下:
這裏寫圖片描述
VLC也是按照這個基礎步驟創建播發器的,不過有所升級。

根據圖我們知道,VLC抽象出一些新模塊:
access: access表示訪問,是VLC抽象的一個層,該層向下直接使用文件或網絡IO接口,向上爲stream層服務,提供IO接口。
stream: stream表示流,是VLC抽象的一個層,該層向下直接使用access層提供的IO接口,向上爲demux層服務,提供IO接口。
demux: demux表示解複用(分離音頻、視頻數據),是視頻技術中的概念,該層向下直接使用stream層提供的IO接口,數據出來後送 es_out。
es_out: es_out表示輸出,是VLC抽象的一個層,該層獲取demux後的數據,送decode解碼。
decode: decode表示解碼,是視頻技術中的概念,獲取es_out出來的數據(通過一個fifo交互),解碼後送output。此處會對應一個解碼線程
output: output表示輸出,獲取從decode出來的數據,送readerer。此處會對應一個輸出線程
readerer: readerer表示顯示,獲取從output出來的數據(通過一個fifo交互),然後顯示。
input: input表示輸入線程,當用戶通過界面輸入一個文件或者流地址時,input thread 被動態創建,該線程的生命週期直到本次播放結束。
playlist: playlist表示播放列表線程,VLC在啓動後,即創建一個playlist thread,用戶輸入後,動態創建input。

從上面,我們知道VLC是一個多線程應用,之所以採用多線程是因爲考慮到播放的流暢性,缺點是應用比較耗內存。
下面介紹一下VLC播放器運行的整體流程:
這裏寫圖片描述

VLC詳細介紹

主要根據官網的文章,添加翻譯。來了解vlc具體細節。
1、 Introduction to libVLCcore-介紹libVLCcore

The core of VLC media player is called libVLCcore.
It manages the threads, the modules (codecs, demuxers, etc...), the modules' layers, the clocks, 
the playlist and all low-level control in VLC.
For example, it is responsible for the synchronization management between all the audio, video and 
subtitle tracks.
On top of libVLCcore, there is libVLC that allow external application builders to access to all 
features of the core.
Modules are linked with libvlccore, to interact with the core.
Modules are built against libvlccore. External applications are built against libVLC.
VLC媒體播放器的核心是叫libVLCcore。
它管理線程、模塊(編解碼器,分配器,等等),模塊層,時鐘,播放列表和所有低級別的控制。 
例如,它負責所有音頻、視頻和字幕軌道之間的同步管理。
libvlccore層上面有libVLC,它允許外部應用訪問所有的核心特徵(相當於對外編程API)
模塊鏈接到與libvlccore,與核心相互工作。
模塊內置構成libVLCcore。外部應用程序通過調用libVLC構成。

2 VLC Pipeline and Modularity VLC流水線和模塊

One of the main concepts in VLC is "modularity".
VLC is, in fact, a complete multimedia framework (like DirectShow or GStreamer) where you can load 
and plug-in many modules dynamically, depending on the necessity.
The core framework is used to do the "wiring" and the media processing, from input 
(files, network streams) to output (audio or video, on a screen or a network). 
It uses modules to  do most of the work at every stage (various muxers, demuxers, decoders, filters and outputs).
Even the interfaces are plugins for libVLC.
VLC的主要概念之一是“模塊化”。
VLC事實上是一個完整的多媒體框架(如DirectShow或GStreamer)您可以根據必要性動態的加載和插件的多模塊。
核心框架用於進行“連線”和媒體處理,從輸入(文件、網絡流)到輸出(音頻或視頻、屏幕或網絡)。
它在每一個階段使用的模塊做大部分的工作(各種muxers,分配器,解碼器,濾波器和輸出)。
甚至接口也是VLC的插件。

2.1 The modules in VLC //VLC模塊

So, VLC uses modules to do most of the work, at every stage of the pipeline. 
Modules are loaded accordingly at runtime depending on the necessity. 
(See VLC Modules loading mechanism).
Every module offers different features that will best suit a particular use-case or a particular environment.
Besides, most portability of VLC results from writing audio_output/video_output/interface 
modules specific to the platform.
plugins modules are loaded and unloaded dynamically by functions in src/modules/modules.c .
Modules can also be built directly into the application which uses libVLC, for instance 
when VLC is on an operating system that does not have support for dynamically loadable code.
They are then called builtins.
In the source code, modules are usually located inside the modules/ subdirectory.
所以,VLC在每個不同層使用模塊來工作。
根據需要,模塊在運行時相應加載。
(見VLC模塊加載機制)。
每個模塊都提供了最適合特定用例或特定環境的不同特性。
此外,大多數VLC內核會編寫針對不同平臺的audio_output / video_output /interface 模塊代碼。
插件模塊是動態地加載和卸載的。
例如當VLC在一個不支持動態加載的操作系統上,也可以直接使用以libVLC中的模塊創建應用。
     他們被稱爲內部。
在源代碼中,模塊通常位於modules/子目錄中。

3 Thread management 線程管理

VLC is heavily multi-threaded.
VLC是高度多線程的。

The single-threaded approach would have introduced too much complexity because decoder preemptibility 
and scheduling would then be a mastermind (for instance decoders and outputs have to be separated, 
otherwise it cannot be warrantied that a frame will be played at the exact presentation time).
Multi-process approach wasn't chosen either, because multi-process decoders usually imply more overhead
 (problems of shared memory) and communication between processes is harder.
VLC's threading structure is modeled after POSIX threads (pthread). However, for portability reasons,
 VLC does not use pthread_* functions directly, but a similar custom set of APIs.
 單線程的方法會引入太多的複雜性,因爲解碼器搶佔和調度將是一個難題。
(例如解碼器和輸出必須分開,否則不能保證視頻將在準確的時間呈現)。
也沒有選擇多進程方法,因爲多進程解碼器通常意味着更多開銷,
(共享內存的問題)和進程之間的通信也更加困難。
VLC的線程結構是仿照POSIX線程(線程)。然而,出於可移植性的考慮,
VLC不使用pthread_ *的直接功能,但自定義類似的API集。(備註:VLC自己封裝了線程API,使用同一的名字對應不同的平臺)

3.1 Threads (vlc_thread_t)//線程集
vlc_clone()//Creates a thread.用於創建一個線程
vlc_join()//Waits for a thread to terminate and releases its resources 等待線程終止並釋放其資源。

3.2 Mutual exclusion (vlc_mutex_t)//互斥鎖

    vlc_mutex_init()//Creates a non-recursive mutex. 創建非遞歸互斥鎖。

    vlc_mutex_init_recursive()//Creates a recursive mutex (discouraged).創建遞歸互斥鎖(不建議使用)。

    vlc_mutex_lock()//Locks a mutex, waiting if required.鎖定互斥體,如果需要則等待。

    vlc_mutex_trylock()//Locks a mutex if it is not already locked, or returns an error otherwise.
                        //如果尚未鎖定,則鎖定互斥鎖,否則返回錯誤。
    vlc_mutex_unlock()//Unlocks a mutex.解鎖互斥鎖。

    vlc_mutex_destroy()//Destroys a mutex.銷燬互斥鎖。

3.3 Condition variable (vlc_cond_t)//環境變量(vlc_cond_t)

vlc_cond_init()
/*Creates a condition variable using the monotonic clock (mdate()) for timeouts.
使用單一時鐘創造環境變量(mdate())。  */

vlc_cond_init_daytime()
/*Creates a condition variable using the realtime clock / wall clock for timeouts.
創建一個環境變量使用實時時鐘/時鐘。*/

vlc_cond_signal()
/*Signals one thread waiting on a condition variable.
信號一個線程等待環境變量。*/

vlc_cond_broadcast()
/*Signals all threads waiting on a condition variable.
指示等待環境變量的所有線程。*/

vlc_cond_wait()
/*Waits for a condition variable to be signaled (can also wake up spuriously).
等待環境變量來表示(也可以醒來貌似)*/

vlc_cond_timedwait()
/*Waits for a condition variable to be signaled up to a certain timeout (can also wake up spuriosuly).
等待環境變量來通知到某一時間(也可以喚醒spuriosuly)。*/

vlc_cond_destroy()
/*Destroys a condition variable.
破壞環境變量。*/

3.4 Misc其它

VLC also has abstractions for slim read/write locks, spin locks, thread-specific variables, similar to 
POSIX threads.
VLC也抽象爲讀寫鎖,自旋鎖,線程特定的變量,類似於POSIX線程。


3.5 Atomic variables //原子變量
Atomic variables are small (sizeof(void *)) values that can be manipulated from multiple threads 
without locking. See include/vlc_atomic.h for the list of supported operations.

原子變量是最小的值(sizeof(void *)),它可以從多個線程無鎖定操作。
在頭文件include/vlc_atomic.h。列出了它支持的操作

4、Synchronization 異步性

Another key feature of VLC is that decoding and playing are asynchronous: decoding is done by a decoder 
thread, playing is done by audio_output or video_output thread. 
The design goal is to ensure that an audio or video frame is played exactly at the right time,
without blocking any of the decoder threads.
This leads to a complex communication structure between the interface, the input, the decoders and the outputs.
VLC的另一個重要特點是,解碼和播放是異步的:解碼器在一個解碼線程工作。
播放是在audio_output 或者 video_output線程,
這樣設計目標是確保音頻或視頻幀在正確的時間準確地播放,
而不阻塞任何解碼器線程。這將導致接口、輸入、解碼器和輸出之間的複雜通信結構。

Having several input and video_output threads reading multiple files at the same time is permitted, 
despite the fact that the current interface doesn't allow any way to do it (this is subject to change 
in the near future). Anyway the client has been written from the ground up with this in mind. 
This also implies that a non-reentrant library (including in particular liba52See talk page)
cannot be used without using a global lock.
具有多個輸入和video_output線程同時讀取多個文件是允許的,儘管目前的接口不允許任何方式去做
 (這是在不久的將來改變)。不管怎樣,客戶都是從這一點寫出來的。這也意味着一個不可重入的圖書館
 (特別是liba52see討論頁)不能使用,不使用全局鎖。

Presentation Time Stamps located in the system layer of the stream are passed to the decoders, 
and all resulting samples are dated accordingly. The output layers are supposed to play them at 
the right time. Dates are converted to microseconds, an absolute date is the number of microseconds 
since Epoch (Jan 1st, 1970). The mtime_t type is a signed 64-bit integer.
系統層中流會添加時間戳位,然後傳遞到解碼器,所有結果樣本都根據相應的日期。
輸出層應該在適當的時候播放它們。日期轉換爲微秒,絕對日期是自紀元(1970年1月1日)以來的微秒數。
mtime_t類型是有符號的64位整數。

The current date can be retrieved with mdate(). The execution of a thread can be suspended until a 
certain date via mwait ( mtime_t date ). You can sleep for a fixed number of microseconds with 
msleep( mtime_t delay ).
 mdate()可以檢索當前日期。通過mwait(mtime_t date)函數,一個正在執行的線程可以暫停到某個確定的日期。
 msleep( mtime_t delay )可以讓你休眠一段微秒級的時間

Warning警告
Please remember to wake up slightly before the presentation date, if some particular treatment needs 
to be done (e.g. a chroma transformation). For instance in modules/codec/libmpeg2.c, track of the 
average decoding times is kept to ensure pictures are not decoded too late.

請記住在演示日期前稍微醒來,如果需要做一些特殊的處理(例如色度變換)。比如在模塊/解碼器/ libmpeg2
(modules/codec/libmpeg2.c),保持平均解碼時間的軌跡,以確保圖片不被解碼太晚

5、Core Source code details 核心源代碼細節

(備註:主要介紹libvlccore源文件的整體構成及作用)
All the libVLCcore source files are located in the src/ directory and its subdirectories:
所有的libvlccore源文件位於src/目錄及其子目錄:

audio_output/
Initializes the audio mixer, ie. finds the right playing frequency, and then resamples audio frames 
received from the decoder(s).
初始化音頻混合器等。找到正確的播放頻率,然後進行音頻幀從解碼器接收(S)。

config/
Load the configuration from command line and configuration file, provides functions for
the modules to read and write to configuration
從命令行和配置文件加載配置,爲模塊的讀寫寄存器提供功能。

control/
Functions to control the behaviour of libVLCcore, like Play/Pause, volume management, 
fullscreen, log verbosity, etc.
控制libvlccore功能行爲,如播放/暫停、音量管理,全屏,日誌冗長,等。

extras/
Mostly platform-specific code
主要是特定於平臺的代碼

input/
Opens an input module, reads packets, parses them and passes reconstituted elementary 
streams to the decoder(s).
打開一個輸入模塊,讀取數據包,解析它們並傳遞經過重組的基礎流到解碼器(s)。

interface/
Contains code for user interaction such as key presses and device ejection.
包含用於用戶交互的代碼,如按鍵和設備彈出。

misc/
Miscellaneous utilities used in other parts of libvlc, such as the thread system,
the message queue, CPU detection, the object lookup system, or platform-specific code.
雜項工具用於其他部分libVLC,,如thread system,
消息隊列、CPU檢測、對象查找系統或特定於平臺的代碼。

modules/
Modules management
模塊管理

network/
Network interface (socket management, network errors, etc.)
網絡接口(套接字管理、網絡錯誤等)

osd/
On Screen Display manipulation
屏幕顯示操作

playlist/
Manages playlist interaction such as stop, play, next, or random playback.
管理播放列表交互,如停止、播放、下一個或隨機播放。

stream_output/
Functions to stream audio and video to the network
向網絡傳輸音頻和視頻的功能。

test/
libVLC needs to be tested, and not only by users :)
libVLC需要測試,用戶不只是:)

text/
Charset stuff
字符集的東西

video_output/
Initializes the video display, gets all pictures and subpictures (ie. subtitles) from the decoder(s), 
optionally converts them to another format (such as YUV to RGB), and displays them.
初始化視頻顯示,獲取所有圖片和子(即字幕)從解碼器(S),
可以將它們轉換爲另一種格式(例如YUV到RGB),並顯示。

Documentation:VLC Modules Loading

VLC modules loading //VLC模塊的加載
下面介紹VLC如何加載各個模塊。
Contents //目錄
1 How does VLC load modules? //VLC如何加載模塊
1.1 Introduction about Modules //模塊介紹
1.2 How does the loading of modules happen //加載模塊的過程
1.3 Advanced info about modules loading //加載模塊的高級信息
1.3.1 Score of 0 //Score 0
1.3.2 all, none and other special tweaks //所有、沒有其他特殊的調整
1.3.3 examples //實例
1.4 How to list Modules //怎麼列出模塊
2 Major Capabilities of Modules //模塊的主要功能

1、How does VLC load modules?//VLC如何加載模塊

1.1 Introduction about Modules//模塊介紹

    VLC has a core and a lot of modules (between 200 and 400 depending on the build).
    VLC具有一個核心模塊和許多功能模塊(介於200和400取決於編譯)。

    VLC cannot do much without modules, since modules are providing most of the functionalities we expect.
     See the "Major Capabilites" sections.
     VLC沒有模塊就不能做許多事,因爲模塊提供了我們期望的大多數功能。參見“Major Capabilites”章節。

    A VLC module has 2 major properties:
    一個VLC模塊有2個主要的特性:

    the capability, VLC_MODULE_CAPABILITY, that describes the category of the module
    類別,VLC_MODULE_CAPABILITY描述了這個模塊的類別。
    the score, VLC_MODULE_SCORE, that holds the priority of the module
    優先級,VLC_MODULE_SCORE保留模塊的優先級。

1.2 How does the loading of modules happen//加載模塊的過程

    The first time you load VLC, it will scan the default plugins directories that 
    should contain VLC modules and generate a cache (named the plugins cache) so that the modules 
    can be loaded quickly the next time VLC launches. Modules can be organized into directories 
    (up to 5 layers deep) beneath the plugins directory.
    你第一次加載的VLC,它會掃描默認的插件目錄,加載包含的VLC模塊和生成緩存(稱爲插件緩存),
    當VLC再次調用時,便於模塊的快速加載。模塊可以在插件目錄下組織目錄(多達5層)。

    Recent versions of VLC require that the modules follow a specific naming convention or they 
    will not be loaded. Modules must be named in the following format: libmodule_name_plugin.
    ext where module_name should be the name of your module in lower case, and ext is the
     system's shared library extension. For example, the http access module is named 
     libaccess_http_plugin.dll on a Windows machine.
     VLC最新版本要求模塊遵循特定的命名約定否則他們將不會加載。模塊必須按以下格式命名:
     libmodule_name_plugin.ext,其中的module_name應該用小寫字母命名你的模塊名,ext是系統的共享庫擴展名,
    例如,在Windows上,HTTP模塊命名爲libaccess_http_plugin.dll

    When VLC needs a module, it tries to open the module with the highest score that has 
    the required capability and accepts the request.
    當VLC需要一個模塊,它試圖打開在同一類別中最高優先級的模塊並加載模塊。

    Let's do an example.//讓我們看一個例子。
    When VLC needs a "decoder" ("decoder" is one category/capability), it opens all "decoder" modules, until one matches.
    It opens them in decreasing score order (biggest score first, smaller ones at the end), and runs
     the Open() function of the modules. When one module returns OK, VLC uses this module.
    當VLC需要一個“解碼器”(“解碼器”是一種類/能力),它打開了所有“解碼器”模塊,直到找到匹配的。
    它優先級按照遞減次序打開他們(最大優先級第一,小在最後),並運行模塊的open()函數。當一個模塊返回OK,VLC就使用此模塊。

1.3 Advanced info about modules loading//加載模塊的高級信息

    1.3.1 Score of 0
        If a module has a score of 0, it needs to be explicitly requested by the user or vlc 
        (like forcing --codec, --vout or module_need("foo")) to be loaded.
        如果一個模塊有0級,需要由用戶或VLC的明確要求被加載。
        (比如,編解碼器,- VOUT或module_need(“foo”))

    1.3.2 all, none and other special tweaks//所有、沒有、其他特殊的調整
        The "all" mode means all modules will be tested in decreasing order of score.
        “all”模式意味着所有模塊都將以分數遞減的順序進行測試。

        The "none" mode means no modules will be tested.
        “all”模式意味着沒有模塊被測試
        Any module can be requested by using its direct shortname. This is useful for 0-scored modules.
        任何模塊都可以通過其直接名加載。這0優先級模塊是有用的。

    1.3.3 examples//例子
        Modules requests can be chained, as the examples show
        如示例所示,模塊請求可以被鏈接:

        --codec avcodec,all
        try the avcodec module than all modules as a "decoder"
        從所有的“decoder”模塊中嘗試查找avcodec模塊 。

        --demux avformat,none
         try the avformat module and no other module
         嘗試avformat模塊並且沒有其他模塊

        By default, modules requests are in the "all" mode, and "all" can be omitted.
        默認情況下,模塊請求處於“全部”模式,“全部”可以省略。

1.4 How to list Modules

    Using Console//使用終端
    vlc --list//命令
    Using the Qt GUI使用圖形界面
    Menu -> Tools -> Plugins and extensions

2.Major Capabilities of Modules//主要的功能模塊

audio filter
An audio filter, like an equalizer
音頻濾波器
音頻濾波器,如均衡器

audio mixer
An audio channel mixer, like a downmixer
音頻混合器
一個音頻通道混合器,像下混頻器

audio output
An audio output, like Windows DirectX audio output
音頻輸出
音頻輸出,如Windows DirectX音頻輸出

decoder
A codec decoder, like theora
解碼器
一個編解碼器解碼,就像Theora

demux
A demuxer, to open a file format, like mkv
解複用器(用於分離視頻和音頻數據)
一個介面,打開一個文件格式,如MKV

encoder
A codec encoder, like x264
編碼器
一編碼器,如x264

interface
An interface, like the Qt interface
接口
一個接口,像qt接口

meta reader
A meta reader, to read metadata
元讀者
元閱讀器,讀取元數據

packetizer
A packetizer
打包器
一個打包器

playlist export
A module to write playlist, like .m3u
播放列表導出
一個模塊寫的播放列表m3u

services_discovery
A module to get extra content from your computer or the network, like Upnp, DLNA
services_discovery
一個模塊,從您的計算機或網絡,得到額外的內容,如UPnP、DLNA

sout access
An access for the streaming
流的接口,主要是解析網絡包

sout mux
A muxer when streaming and encoding
sout mux
一個複用器當流和編碼

stream_filter
A stream filter
stream_filter
流過濾器

text renderer
A way to display subtitles and other text on top of the video
文本渲染
一種在視頻頂部顯示字幕和其他文本的方法。

video filter
A video filter, like contrast adjusting
視頻濾波器
一種像對比度調節的視頻濾波器

visualization2
A visualizer, to create videos from the music
visualization2
可視化工具,從音樂製作視頻

vout display
A video output, to display videos like Direct3D or Xv
輸出顯示
視頻輸出,顯示錄像

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章