vlc/doc/developer/overview.xml

248 lines
9.7 KiB
XML

<chapter> <title> VLC Overview </title>
<sect1> <title> LibVLC </title>
<para> LibVLC is the core part of VLC. It is a library providing an
interface for programs such as VLC to a lot of functionalities such as
stream access, audio and video output, plugin handling, a thread system.
All the LibVLC source files are located in the <filename>src/</filename>
directory and its subdirectories: </para>
<itemizedlist>
<listitem> <para> <filename>interface/</filename>: contains code for
user interaction such as key presses and device ejection. </para>
</listitem>
<listitem> <para> <filename>playlist/</filename>: manages playlist
interaction such as stop, play, next, or random playback. </para>
</listitem>
<listitem> <para> <filename>input/</filename>: opens an input module,
reads packets, parses them and passes reconstituted elementary streams
to the decoder(s). </para> </listitem>
<listitem> <para> <filename>video_output/</filename>: 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. </para></listitem>
<listitem> <para> <filename>audio_output/</filename>: initializes the
audio mixer, ie. finds the right playing frequency, and then resamples
audio frames received from the decoder(s). </para> </listitem>
<listitem> <para> <filename>stream_output/</filename>: TODO </para>
</listitem>
<listitem> <para> <filename>misc/</filename>: 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. </para> </listitem>
</itemizedlist>
<mediaobject>
<imageobject>
<imagedata fileref="modules.png" format="PNG" scalefit="1" scale="80"/>
</imageobject>
<imageobject>
<imagedata fileref="modules.gif" format="GIF" />
</imageobject>
<textobject>
<phrase> Data flow between modules </phrase>
</textobject>
</mediaobject>
</sect1>
<sect1> <title> VLC </title>
<para> VLC is a simple program written around LibVLC. It is very small,
but is a fully featured multimedia player thanks to LibVLC's support for
dynamic modules. </para>
</sect1>
<sect1> <title> Modules </title>
<para> Modules are located in the <filename>modules/</filename>
subdirectory and are loaded at runtime. Every module may offer different
features that will best suit a particular file or a particular
environment. Besides, most portability works result in the writing of an
audio_output/video_output/interface module to support a new platform (eg.
BeOS or MacOS X). </para>
<para> Plugin modules are loaded and unloaded dynamically
by functions in <filename>src/misc/modules.c</filename> and
<filename>include/modules*.h</filename>. The API for writing modules will
be discussed in a following chapter. </para>
<para> Modules can also be built directly into the application which uses
LibVLC, for instance on an operating system that does not have support for
dynamically loadable code. Modules statically built into the application
are called builtins. </para>
</sect1>
<sect1> <title> Threads </title>
<sect2> <title> Thread management </title>
<para> VLC is heavily multi-threaded. We chose against a single-thread
approach because decoder preemptibility and scheduling would 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), and we currently have no plan to support a
single-threaded client. Multi-process decoders usually imply more overhead
(problems of shared memory) and communication between processes is harder.
</para>
<para> Our threading structure is modeled on pthreads.
However, for portability reasons, we don't call
<function>pthread_*</function> functions directly, but use a
similar wrapper, made of <function>vlc_thread_create</function>,
<function>vlc_thread_exit</function>,
<function>vlc_thread_join</function>,
<function>vlc_mutex_init</function>, <function>vlc_mutex_lock</function>,
<function>vlc_mutex_unlock</function>,
<function>vlc_mutex_destroy</function>,
<function>vlc_cond_init</function>, <function>vlc_cond_signal</function>,
<function>vlc_cond_broadcast</function>,
<function>vlc_cond_wait</function>, <function>vlc_cond_destroy</function>,
and structures <type>vlc_thread_t</type>, <type>vlc_mutex_t</type>, and
<type>vlc_cond_t</type>. </para>
</sect2>
<sect2> <title> Synchronization </title>
<para> 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.
</para>
<para> 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 liba52) cannot be used without using a global lock. </para>
<para> 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 <type>mtime_t</type> type
is a signed 64-bit integer. </para>
<para> The current date can be retrieved with
<function>mdate()</function>. The execution of a thread can be suspended
until a certain <parameter>date</parameter> via <function>mwait</function>
<parameter>( mtime_t date )</parameter>. You can sleep for a fixed number
of microseconds with <function>msleep</function> <parameter>( mtime_t
delay )</parameter>. </para>
<warning> <para> Please remember to wake up slightly
<emphasis>before</emphasis> the presentation date, if some particular
treatment needs to be done (e.g. a chroma transformation). For instance
in <filename>modules/codec/mpeg_video/synchro.c</filename>, track of the
average decoding times is kept to ensure pictures are not decoded too
late. </para> </warning>
</sect2>
</sect1>
<sect1> <title> Code conventions </title>
<sect2> <title> Function naming </title>
<para>
All functions are named accordingly : module name (in lower case) + _ +
function name (in mixed case, <emphasis> without underscores</emphasis>).
For instance : <function>intf_FooFunction</function>. Static functions
don't need usage of the module name.
</para>
</sect2>
<sect2> <title> Variable naming </title>
<para>
Hungarian notations are used, that means we have the following prefixes :
</para>
<itemizedlist>
<listitem> <para> i_ for integers (sometimes l_ for long integers) ;
</para> </listitem>
<listitem> <para> b_ for booleans ; </para> </listitem>
<listitem> <para> d_ for doubles (sometimes f_ for floats) ;
</para> </listitem>
<listitem> <para> pf_ for function pointers ; </para> </listitem>
<listitem> <para> psz_ for a Pointer to a String terminated by a
Zero (C-string) ;
</para> </listitem>
<listitem> <para> More generally, we add a p when the variable is
a pointer to a type. </para> </listitem>
</itemizedlist>
<para>
If one variable has no basic type (for instance a complex structure), don't
put any prefix (except p_* if it's a pointer). After one prefix, put
an <emphasis> explicit </emphasis> variable name <emphasis> in lower
case</emphasis>. If several words are required, join them with an
underscore (no mixed case). Examples :
</para>
<itemizedlist>
<listitem> <para>
<type> data_packet_t * </type> <varname> p_buffer; </varname>
</para> </listitem> <listitem> <para>
<type> char </type> <varname> psz_msg_date[42]; </varname>
</para> </listitem> <listitem> <para>
<type> int </type> <varname> pi_es_refcount[MAX_ES]; </varname>
</para> </listitem> <listitem> <para>
<type> void </type> <varname> (* pf_next_data_packet)( int * ); </varname>
</para> </listitem>
</itemizedlist>
</sect2>
<sect2> <title> A few words about white spaces </title>
<para>
First, never use tabs in the source (you're entitled to use them in the
Makefile :-). Use <command> set expandtab </command> under <application>
vim </application> or the equivalent under <application>
emacs</application>. Indents are 4 spaces long.
</para>
<para>
Second, put spaces <emphasis> before and after </emphasis> operators, and
inside brackets. For instance :
<programlisting> for( i = 0; i &lt; 12; i++, j += 42 ); </programlisting>
</para>
<para>
Third, leave braces alone on their lines (GNU style). For instance :
<programlisting>
if( i_es == 42 )
{
p_buffer[0] = 0x12;
}
</programlisting>
</para>
<para>
We write C, so use C-style comments /* ... */.
</para>
</sect2>
</sect1>
</chapter>