<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.eps" format="EPS" 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>
