]> git.sesse.net Git - vlc/blob - doc/developer/interface.xml
.
[vlc] / doc / developer / interface.xml
1 <chapter> <title> VLC interface </title>
2
3   <sect1> <title> A typical VLC run course </title>
4
5     <para>
6 This section describes what happens when you launch the <application> 
7 vlc</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 :
11     </para>
12
13     <orderedlist>
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>
27     </orderedlist>
28
29     <para>
30 Following sections describe each of these steps in particular, and many more.
31     </para>
32
33   </sect1>
34
35   <sect1> <title> The message interface </title>
36
37     <para>
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.
43     </para>
44
45     <para>
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).
54     </para>
55
56     <para>
57 Functions available to print messages are :
58     </para>
59
60     <itemizedlist>
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>
65
66       <listitem> <para> <function> intf_ErrMsg </function> ( <parameter>
67       char * psz_format, ... </parameter> ) :
68       Print an error message to <constant> stderr </constant>. </para>
69       </listitem>
70
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>
78
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>
87
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.
93       </para> </listitem>
94
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>
101
102       <listitem> <para> <function> intf_FlushMsg </function> () :
103       Flush the message queue, if it is in use. </para> </listitem>
104     </itemizedlist>
105
106   </sect1>
107
108   <sect1> <title> Command line options </title>
109
110     <para>
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>.
116     </para>
117
118     <para>
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.
125     </para>
126
127     <warning> <para>
128 Please note that for thread-safety issues, you should not use
129 <function> main_Put*Variable </function> once the second thread has
130 been spawned.
131     </para> </warning>
132
133   </sect1>
134
135   <sect1> <title> Playlist management </title>
136
137     <para>
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.
144 </para>
145
146     <para>
147 The main interface loop <function> intf_Manage </function> is then
148 supposed to <emphasis> start and kill input threads </emphasis> when necessary.
149     </para>
150
151   </sect1>
152
153   <sect1> <title> Module bank </title>
154
155     <para>
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 :
160     </para>
161
162     <itemizedlist>
163       <listitem> <para> MODULE_CAPABILITY_INTF : An interface plugin ;
164       </para> </listitem>
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 ;
172       </para> </listitem>
173       <listitem> <para> MODULE_CAPABILITY_VDEC : A video decoder ;
174       </para> </listitem>
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 ;
180       </para> </listitem>
181       <listitem> <para> MODULE_CAPABILITY_VOUT : A video output module ;
182       </para> </listitem>
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>
189     </itemizedlist>
190
191     <para>
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.
199     </para>
200
201   </sect1>
202
203   <sect1> <title> The interface main loop </title>
204
205     <para>
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>.
211     </para>
212
213     <para>
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).
217     </para>
218
219   </sect1>
220
221   <sect1> <title> How to write an interface plugin </title>
222
223   <sect2> <title> API for the Module </title>
224     <para>
225 Have a look the files in directories
226 <filename>modules/misc/control</filename>, 
227 <filename> modules/misc/dummy</filename>, 
228 <filename> modules/misc/access</filename>, 
229 or <filename> modules/gui</filename>. However the GUI interfaces are
230 not very easy to understand, since they are quite big. I suggest to
231 start digging into a non-graphical interface modules first. For example
232 <filename>modules/control/hotkeys.c</filename>.</para>
233
234   <para>An interface module is made of 3 entry functions and a module
235 description:
236 </para>
237
238     <itemizedlist>
239
240       <listitem> <para> The module description is made of macros that
241    declares the capabilities of the module (interface, in this case)
242    with their priority, the module description as it will appear in
243    the preferences of GUI modules that implement them, some
244    configuration variables specific to the module, shortcuts,
245    sub-modules, etc. </para></listitem>
246
247      <listitem> <para> <function> Open </function> ( <parameter>
248            vlc_object_t* p_object </parameter> ): This is called by
249            VLC to initialize the module. </para></listitem>
250
251      <listitem> <para> <function> Run </function> ( <parameter>
252            vlc_object_t* p_object </parameter> ): really does the job
253            of the interface module (waiting for user input and
254            displaying info). It should check periodically that
255            <constant>p_intf->b_die</constant> is
256            not <constant>VLC_TRUE</constant>.
257      </para></listitem>
258
259       <listitem> <para> <function> Close ( <parameter> vcl_object_t *
260    p_object </parameter> ) </function> function is called by VLC to
261    uninitialize the module (basically, this consists in destroying
262    whatever have been allocated
263    by <function>Open</function>) </para></listitem>
264
265      </itemizedlist>
266
267 <para>The above functions take a <parameter>vlc_object_t*</parameter>
268 as argument, but that may need to be cast into
269 a <parameter>intf_thread_t*</parameter> depending on your needs. This
270 structure is often needed as a parameter for exported VLC functions,
271 such as <function>msg_Err()</function>, <function>msg_Warn()</function>,
272 ...</para>
273
274 <para>
275 Define <parameter>intf_sys_t</parameter> to contain any variable you
276 need (don't use static variables, they suck in a multi-threaded
277 application :-).</para>
278
279 <para>If additional capabilities (such as Open button,
280 playlist, menus, etc.) are needed, consult one of the GUI modules.
281 One of the simpler GUI modules to consult might be 
282 <filename>modules/gui/ncurses/ncurses.c</filename>. It is a quite
283 simple complete interface module with playlist interaction, and
284 progress bar, among other things.
285
286     </para>
287 </sect2>
288
289 <sect2><title>Arranging for your Module to get Compiled</title>
290
291 <para>If you create a new directory for your module, add
292 a <filename>Modules.am</filename> file in it.  In this file, put
293 something like : <constant>SOURCES_yourmodule = myfile1.c
294 myfile2.c</constant></para>
295
296 <para>Then go to the main <filename>configure.ac</filename> file, and
297 add in the <constant>AC_CONFIG_FILES</constant> section (towards the
298 end of the file) a line similar to the others.</para>
299
300 <para>If you don't create a directory for your plugin (but instead
301 just put it in an existing directory), you only have to add the two
302 SOURCES_... lines to the existing <filename>Modules.am</filename>
303 file</para>
304
305 <para>This declares your module; it does not arrange for it to be
306 automatically compiled; automatic compilatoin is described further
307 below.</para>
308
309 <para>You do not write a <filename>Makefile</filename> for your
310 module. Instead this is done via the bootstrap and configuration
311 process. So now run: 
312 </para>
313
314 <!---don't know if <xmp> or <example> works. Until then... -->
315 <para><filename>./bootstrap</filename></para>
316 <para><filename>./configure</filename> <emphasis>configure-options</emphasis></para>
317 <para><filename>make</filename></para>
318
319 <para>To build the module manually, go to the 
320 directory it resides and type
321 <constant>make libyourmodule_plugin.so</constant> (or .dll, or
322   whatever the file type for a shared library is on your Operating
323   System.)</para>
324
325 <para>To <emphasis>automatically</emphasis> have your module get
326 built, you also set this in the <filename>configure.ac</filename>
327 file; add your module name to the <constant>default modules</constant>
328 section in one of the
329 <constant>AX_ADD_PLUGINS</constant> directives.</para>
330 </sect2>
331
332   </sect1>
333
334 </chapter>