1 <chapter> <title> VLC interface </title>
3 <sect1> <title> A typical VLC run course </title>
6 This section describes what happens when you launch the <application>
8 program. After the ELF dynamic loader blah blah blah, the main thread
9 becomes the interface thread and starts up in <filename>
10 src/interface/main.c </filename>. It passes through the following steps :
14 <listitem> <para> CPU detection : which CPU are we running on, what are
15 its capabilities (MMX, MMXEXT, 3DNow, AltiVec...) ? </para> </listitem>
16 <listitem> <para> Message interface initialization ; </para> </listitem>
17 <listitem> <para> Command line options parsing ; </para> </listitem>
18 <listitem> <para> Playlist creation ; </para> </listitem>
19 <listitem> <para> Module bank initialization ; </para> </listitem>
20 <listitem> <para> Interface opening ; </para> </listitem>
21 <listitem> <para> Signal handler installation : SIGHUP, SIGINT
22 and SIGQUIT are caught to manage a clean quit (please note that the SDL
23 library also catches SIGSEGV) ; </para> </listitem>
24 <listitem> <para> Audio output thread spawning ; </para> </listitem>
25 <listitem> <para> Video output thread spawning ; </para> </listitem>
26 <listitem> <para> Main loop : events management ; </para> </listitem>
30 Following sections describe each of these steps in particular, and many more.
35 <sect1> <title> The message interface </title>
38 It is a know fact that <function> printf() </function> functions are
39 not necessarily thread-safe. As a result,
40 one thread interrupted in a <function> printf() </function> call, followed
41 by another calls to it, will leave the program in an undetermined state. So
42 an API must be set up to print messages without crashing.
46 This API is implemented in two ways. If <constant> INTF_MSG_QUEUE </constant>
47 is defined in <filename> config.h </filename>, every <function>
48 printf</function>-like (see below) call will queue the message into a chained list.
49 This list will be printed and flushed by the interface thread once upon
50 an event loop. If <constant> INTF_MSG_QUEUE </constant> is undefined,
51 the calling thread will acquire the print lock (which prevents two
52 print operations to occur at the same time) and print the message
53 directly (default behaviour).
57 Functions available to print messages are :
61 <listitem> <para> <function> intf_Msg </function> ( <parameter>
62 char * psz_format, ... </parameter> ) :
63 Print a message to <constant> stdout </constant>, plain and
64 stupid (for instance "vlc 0.2.72 (Apr 16 2001)"). </para> </listitem>
66 <listitem> <para> <function> intf_ErrMsg </function> ( <parameter>
67 char * psz_format, ... </parameter> ) :
68 Print an error message to <constant> stderr </constant>. </para>
71 <listitem> <para> <function> intf_WarnMsg </function> ( <parameter>
72 int i_level, char * psz_format, ... </parameter> ) :
73 Print a message to <constant> stderr </constant> if the warning
74 level (determined by -v, -vv and -vvv) is low enough. </para>
75 <note> <para> Please note
76 that the lower the level, the less important the message is (dayou
77 spik ingliche ?). </para> </note> </listitem>
79 <listitem> <para> <function> intf_DbgMsg </function> ( <parameter>
80 char * psz_format, ... </parameter> ) :
81 This function is designed for optional checkpoint messages, such
82 as "we are now entering function dvd_foo_thingy". It does nothing
83 in non-trace mode. If the VLC is compiled with --enable-trace, the
84 message is either written to the file <filename> vlc-trace.log </filename>
85 (if TRACE_LOG is defined in config.h), or printed to <constant> stderr
86 </constant> (otherwise). </para> </listitem>
88 <listitem> <para> <function> intf_MsgImm, intf_ErrMsgImm, intf_WarnMsgImm,
89 intf_DbgMsgImm </function> :
90 Same as above, except that the message queue, in case <parameter>
91 INTF_MSG_QUEUE </parameter> is defined,
92 will be flushed before the function returns.
95 <listitem> <para> <function> intf_WarnHexDump </function> ( <parameter>
96 int i_level, void * p_data, int i_size </parameter> ) :
97 Dumps <parameter> i_size </parameter> bytes from <parameter>
98 p_data </parameter> in hexadecimal. <parameter> i_level </parameter>
99 works like <function> intf_WarnMsg </function>. This is useful for
100 debugging purposes. </para> </listitem>
102 <listitem> <para> <function> intf_FlushMsg </function> () :
103 Flush the message queue, if it is in use. </para> </listitem>
108 <sect1> <title> Command line options </title>
111 VLC uses GNU getopt to parse command line options. getopt structures are
112 defined in <filename> src/interface/main.c </filename> in the "Command
113 line options constants" section. To add a new option This section needs
114 to be changed, along with
115 <function> GetConfiguration </function> and <function> Usage</function>.
119 Most configuration directives are exchanged via the environment array,
120 using <function> main_Put*Variable </function> and <function>
121 main_Get*Variable</function>. As a result, <command>
122 ./vlc --height 240 </command> is strictly equivalent to : <command>
123 vlc_height=240 ./vlc</command>. That way configuration variables are
124 available everywhere, including plugins.
128 Please note that for thread-safety issues, you should not use
129 <function> main_Put*Variable </function> once the second thread has
135 <sect1> <title> Playlist management </title>
138 The playlist is created on startup from files given in the command line.
139 An appropriate interface plugin can then add or remove files from it.
140 Functions to be used are described in <filename>
141 src/interface/intf_playlist.c</filename>.
142 <function> intf_PlaylistAdd </function> and <function>
143 intf_PlaylistDelete</function> are typically the most common used.
147 The main interface loop <function> intf_Manage </function> is then
148 supposed to <emphasis> start and kill input threads </emphasis> when necessary.
153 <sect1> <title> Module bank </title>
156 On startup, VLC creates a bank of all available .so files (plugins) in
157 <filename>., ./lib, /usr/local/lib/videolan/vlc</filename> <constant>
158 (PLUGIN_PATH)</constant>, and built-in plugins. Every plugin is checked
159 with its capabilities, which are :
163 <listitem> <para> MODULE_CAPABILITY_INTF : An interface plugin ;
165 <listitem> <para> MODULE_CAPABILITY_ACCESS : A sam-ism, unused at
166 present ;</para> </listitem>
167 <listitem> <para> MODULE_CAPABILITY_INPUT : An input plugin, for
168 instance PS or DVD ;</para> </listitem>
169 <listitem> <para> MODULE_CAPABILITY_DECAPS : A sam-ism, unused at
170 present ;</para> </listitem>
171 <listitem> <para> MODULE_CAPABILITY_ADEC : An audio decoder ;
173 <listitem> <para> MODULE_CAPABILITY_VDEC : A video decoder ;
175 <listitem> <para> MODULE_CAPABILITY_MOTION : A motion compensation
176 module (for the video decoder) ;</para> </listitem>
177 <listitem> <para> MODULE_CAPABILITY_IDCT : An IDCT module (for
178 the video decoder) ;</para> </listitem>
179 <listitem> <para> MODULE_CAPABILITY_AOUT : An audio output module ;
181 <listitem> <para> MODULE_CAPABILITY_VOUT : A video output module ;
183 <listitem> <para> MODULE_CAPABILITY_YUV : A YUV module (for the
184 video output) ;</para> </listitem>
185 <listitem> <para> MODULE_CAPABILITY_AFX : An audio effects plugin
186 (for the audio output ; unimplemented) ;</para> </listitem>
187 <listitem> <para> MODULE_CAPABILITY_VFX : A video effects plugin
188 (for the video output ; unimplemented) ;</para> </listitem>
192 How to write a plugin is described in the latter sections. Other threads
193 can request a plugin descriptor with <function> module_Need </function>
194 <parameter> ( module_bank_t * p_bank, int i_capabilities, void * p_data ).
195 p_data </parameter> is an optional parameter (reserved for future use) for the
196 <function> pf_probe() </function> function. The returned module_t
197 structure contains pointers to the functions of the plug-in. See
198 <filename>include/modules.h</filename> for more information.
203 <sect1> <title> The interface main loop </title>
206 The interface thread will first look for a suitable interface plugin.
207 Then it enters the main interface loop, with the plugin's <function>
208 pf_run </function> function. This function will do what's appropriate,
209 and every 100 ms will call (typically via a GUI timer callback)
210 <function>intf_Manage</function>.
214 <function>intf_Manage</function> cleans up the module bank by unloading
215 unnecessary modules, manages the playlist, and flushes waiting
216 messages (if the message queue is in use).
221 <sect1> <title> How to write an interface plugin </title>
224 Have a look at <filename>plugins/dummy/intf_dummy.c</filename> and
225 <filename>plugins/gtk/intf_gtk.c</filename>. Basically, you have to
230 <listitem> <para> <function> intf_Probe </function> ( <parameter>
231 probedata_t * p_data </parameter> ) :
232 This is supposed to tell whether your plugin can work in this
233 environment or not. If it can, it returns a score between 1
234 and 999 indicating whether this plugin should be preferred
235 against others or not. <parameter> p_data </parameter> is
236 currently unused. </para> </listitem>
238 <listitem> <para> <function> intf_Open </function> ( <parameter>
239 intf_thread_t * p_intf </parameter> ) :
240 Initializes the interface (ie. opens a new window, etc.).
241 You can store your information in p_intf->p_sys.
244 <listitem> <para> <function> intf_Close </function> ( <parameter>
245 intf_thread_t * p_intf </parameter> ) :
246 Closes the interface and frees all allocated structures
247 (including p_intf->p_sys).
250 <listitem> <para> <function> intf_Run </function> ( <parameter>
251 intf_thread_t * p_intf </parameter> ) :
252 Launches the main loop, which shouldn't return
253 until p_intf->b_die is set to 1. Pay attention not to take all
254 CPU time with an infinite loop (add <function> msleep</function>).
259 Don't forget to define intf_sys_t to contain any variable you need
260 (don't use static variables, they suck in a multi-threaded
261 application :-). If additionnal
262 capabilities (such as Open button, playlist, menus, etc.) are needed,
263 look at the GTK+ plug-in in <filename> plugins/gtk</filename>.