大自然的搬运工,所有内容来自VLC官网黑客手册。官网本文内容链路接
libVLCcore简介
VLC媒体播放器的核心是libVLCcore。它管理VLC中的线程、模块(编解码器、解复用器等)、模块层、时钟、播放列表和所有低级控制。例如,它负责所有音频、视频和字幕轨迹之间的同步管理。在libVLC core之上,还有libVLC允许外部应用程序构建器访问核心的所有特性。模块与libvlccore链接,以与核心交互。模块是根据libvlccore构建的。外部应用程序是根据libVLC构建的。
VLC流水线与模块化
VLC的主要概念之一是“模块化”。
实际上,VLC是一个完整的多媒体框架(如DirectShow或GStreamer),您可以根据需要动态加载和插入许多模块。
核心框架用于完成从输入(文件、网络流)到输出(音频或视频、屏幕或网络)的“布线”和媒体处理。它使用模块来完成每个阶段的大部分工作(各种muxer、demuxer、解码器、滤波器和输出)。
甚至接口也是libVLC的插件。
VLC模块
因此,VLC在管道的每个阶段都使用模块来完成大部分工作。根据需要,在运行时相应地加载模块。每个模块都提供不同的特性,这些特性最适合特定的用例或特定的环境。此外,VLC的可移植性主要来自于编写特定于平台的音频输出/视频输出/接口模块。插件模块由src/modules/modules.c中的函数动态加载和卸载。模块也可以直接构建到使用libVLC的应用程序中,例如,当VLC位于不支持动态可加载代码的操作系统上时。它们被称为内置的。
在源代码中,模块通常位于modules/子目录中。
线程管理
VLC是多线程的。
单线程方法会引入太多的复杂性,因为解码器的可抢占性和调度将是一个主谋(例如,解码器和输出必须分开,否则无法保证帧将在准确的呈现时间播放)。
也没有选择多进程方法,因为多进程解码器通常意味着更多的开销(共享内存的问题),进程之间的通信更困难。
VLC的线程结构是在POSIX线程(pthread)之后建模的。但是,出于可移植性的原因,VLC不直接使用pthread_ux函数,而是使用类似的自定义api集。
Threads (vlc_thread_t)
vlc_clone()
Creates a thread.
vlc_join()
Waits for a thread to terminate and releases its resources
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.
Condition variable (vlc_cond_t)
vlc_cond_init()
Creates a condition variable using the monotonic clock (mdate()) for timeouts.
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 spuriously).
vlc_cond_destroy()
Destroys a condition variable.
- 杂项
VLC还对slim读/写锁、自旋锁、线程特定变量进行了抽象,类似于POSIX线程。 - 原子变量
原子变量是很小的(sizeof(void*))值,可以从多个线程进行操作,而无需锁定。有关支持的操作的列表,请参见include/vlc_atomic.h。
同步
VLC的另一个关键特性是解码和播放是异步的:解码由解码器线程完成,播放由音频输出或视频输出线程完成。设计目标是确保音频或视频帧在正确的时间播放,而不阻塞任何解码器线程。这导致了接口、输入、解码器和输出之间的复杂通信结构。
允许有多个输入和视频输出线程同时读取多个文件,尽管当前接口不允许任何方式这样做(这在不久的将来会发生变化)。不管怎么说,客户是从一开始就考虑到这一点的。这也意味着不使用全局锁就不能使用不可重入的库(尤其包括liba52See talk page)。
位于流的系统层中的呈现时间戳被传递给解码器,并且所有产生的样本都相应地标注日期。输出层应该在正确的时间播放它们。日期转换为微秒,绝对日期是自纪元(1970年1月1日)以来的微秒数。mtime类型是有符号的64位整数。
可以使用mdate()检索当前日期。线程的执行可以通过mwait(mtime_t date)暂停到某个日期。您可以使用msleep(mtime_t delay)睡眠固定微秒数。
核源码细节
All the libVLCcore source files are located in the src directory and its subdirectories:
audio_output/
Initializes the audio mixer, ie. finds the right playing frequency, and then resamples audio frames received from the decoder(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.
extras/
Mostly platform-specific code
input/ //项目重点关注模块
Opens an input module, reads packets, parses them and passes reconstituted elementary streams to the decoder(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.
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 :)
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.