]> git.sesse.net Git - vlc/blob - lib/video.c
libvlc: refactor sfilter enabling/disabling
[vlc] / lib / video.c
1 /*****************************************************************************
2  * video.c: libvlc new API video functions
3  *****************************************************************************
4  * Copyright (C) 2005-2010 VLC authors and VideoLAN
5  *
6  * $Id$
7  *
8  * Authors: ClĂ©ment Stenac <zorglub@videolan.org>
9  *          Filippo Carone <littlejohn@videolan.org>
10  *          Jean-Paul Saman <jpsaman _at_ m2x _dot_ nl>
11  *          Damien Fouilleul <damienf a_t videolan dot org>
12  *
13  * This program is free software; you can redistribute it and/or modify it
14  * under the terms of the GNU Lesser General Public License as published by
15  * the Free Software Foundation; either version 2.1 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU Lesser General Public License for more details.
22  *
23  * You should have received a copy of the GNU Lesser General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
26  *****************************************************************************/
27
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <vlc/libvlc.h>
33 #include <vlc/libvlc_media.h>
34 #include <vlc/libvlc_media_player.h>
35
36 #include <vlc_common.h>
37 #include <vlc_input.h>
38 #include <vlc_vout.h>
39
40 #include "media_player_internal.h"
41 #include <assert.h>
42
43 /*
44  * Remember to release the returned vout_thread_t.
45  */
46 static vout_thread_t **GetVouts( libvlc_media_player_t *p_mi, size_t *n )
47 {
48     input_thread_t *p_input = libvlc_get_input_thread( p_mi );
49     if( !p_input )
50     {
51         *n = 0;
52         return NULL;
53     }
54
55     vout_thread_t **pp_vouts;
56     if (input_Control( p_input, INPUT_GET_VOUTS, &pp_vouts, n))
57     {
58         *n = 0;
59         pp_vouts = NULL;
60     }
61     vlc_object_release (p_input);
62     return pp_vouts;
63 }
64
65 static vout_thread_t *GetVout (libvlc_media_player_t *mp, size_t num)
66 {
67     vout_thread_t *p_vout = NULL;
68     size_t n;
69     vout_thread_t **pp_vouts = GetVouts (mp, &n);
70     if (pp_vouts == NULL)
71         goto err;
72
73     if (num < n)
74         p_vout = pp_vouts[num];
75
76     for (size_t i = 0; i < n; i++)
77         if (i != num)
78             vlc_object_release (pp_vouts[i]);
79     free (pp_vouts);
80
81     if (p_vout == NULL)
82 err:
83         libvlc_printerr ("Video output not active");
84     return p_vout;
85 }
86
87 /**********************************************************************
88  * Exported functions
89  **********************************************************************/
90
91 void libvlc_set_fullscreen( libvlc_media_player_t *p_mi, int b_fullscreen )
92 {
93     /* This will work even if the video is not currently active */
94     var_SetBool (p_mi, "fullscreen", !!b_fullscreen);
95
96     /* Apply to current video outputs (if any) */
97     size_t n;
98     vout_thread_t **pp_vouts = GetVouts (p_mi, &n);
99     for (size_t i = 0; i < n; i++)
100     {
101         var_SetBool (pp_vouts[i], "fullscreen", b_fullscreen);
102         vlc_object_release (pp_vouts[i]);
103     }
104     free (pp_vouts);
105 }
106
107 int libvlc_get_fullscreen( libvlc_media_player_t *p_mi )
108 {
109     return var_GetBool (p_mi, "fullscreen");
110 }
111
112 void libvlc_toggle_fullscreen( libvlc_media_player_t *p_mi )
113 {
114     bool b_fullscreen = var_ToggleBool (p_mi, "fullscreen");
115
116     /* Apply to current video outputs (if any) */
117     size_t n;
118     vout_thread_t **pp_vouts = GetVouts (p_mi, &n);
119     for (size_t i = 0; i < n; i++)
120     {
121         vout_thread_t *p_vout = pp_vouts[i];
122
123         var_SetBool (p_vout, "fullscreen", b_fullscreen);
124         vlc_object_release (p_vout);
125     }
126     free (pp_vouts);
127 }
128
129 void libvlc_video_set_key_input( libvlc_media_player_t *p_mi, unsigned on )
130 {
131     var_SetBool (p_mi, "keyboard-events", !!on);
132 }
133
134 void libvlc_video_set_mouse_input( libvlc_media_player_t *p_mi, unsigned on )
135 {
136     var_SetBool (p_mi, "mouse-events", !!on);
137 }
138
139 int
140 libvlc_video_take_snapshot( libvlc_media_player_t *p_mi, unsigned num,
141                             const char *psz_filepath,
142                             unsigned int i_width, unsigned int i_height )
143 {
144     assert( psz_filepath );
145
146     vout_thread_t *p_vout = GetVout (p_mi, num);
147     if (p_vout == NULL)
148         return -1;
149
150     /* FIXME: This is not atomic. All parameters should be passed at once
151      * (obviously _not_ with var_*()). Also, the libvlc object should not be
152      * used for the callbacks: that breaks badly if there are concurrent
153      * media players in the instance. */
154     var_Create( p_vout, "snapshot-width", VLC_VAR_INTEGER );
155     var_SetInteger( p_vout, "snapshot-width", i_width);
156     var_Create( p_vout, "snapshot-height", VLC_VAR_INTEGER );
157     var_SetInteger( p_vout, "snapshot-height", i_height );
158     var_Create( p_vout, "snapshot-path", VLC_VAR_STRING );
159     var_SetString( p_vout, "snapshot-path", psz_filepath );
160     var_Create( p_vout, "snapshot-format", VLC_VAR_STRING );
161     var_SetString( p_vout, "snapshot-format", "png" );
162     var_TriggerCallback( p_vout, "video-snapshot" );
163     vlc_object_release( p_vout );
164     return 0;
165 }
166
167 int libvlc_video_get_size( libvlc_media_player_t *p_mi, unsigned num,
168                            unsigned *restrict px, unsigned *restrict py )
169 {
170     libvlc_media_track_info_t *info;
171     int ret = -1;
172     if (!p_mi->p_md)
173         return ret;
174     int infos = libvlc_media_get_tracks_info(p_mi->p_md, &info);
175     if (infos <= 0)
176         return ret;
177
178     for (int i = 0; i < infos; i++)
179         if (info[i].i_type == libvlc_track_video && num-- == 0) {
180             *px = info[i].u.video.i_width;
181             *py = info[i].u.video.i_height;
182             ret = 0;
183             break;
184         }
185
186     free(info);
187     return ret;
188 }
189
190 int libvlc_video_get_height( libvlc_media_player_t *p_mi )
191 {
192     unsigned width, height;
193
194     if (libvlc_video_get_size (p_mi, 0, &width, &height))
195         return 0;
196     return height;
197 }
198
199 int libvlc_video_get_width( libvlc_media_player_t *p_mi )
200 {
201     unsigned width, height;
202
203     if (libvlc_video_get_size (p_mi, 0, &width, &height))
204         return 0;
205     return width;
206 }
207
208 int libvlc_video_get_cursor( libvlc_media_player_t *mp, unsigned num,
209                              int *restrict px, int *restrict py )
210 {
211     vout_thread_t *p_vout = GetVout (mp, num);
212     if (p_vout == NULL)
213         return -1;
214
215     var_GetCoords (p_vout, "mouse-moved", px, py);
216     vlc_object_release (p_vout);
217     return 0;
218 }
219
220 unsigned libvlc_media_player_has_vout( libvlc_media_player_t *p_mi )
221 {
222     size_t n;
223     vout_thread_t **pp_vouts = GetVouts (p_mi, &n);
224     for (size_t i = 0; i < n; i++)
225         vlc_object_release (pp_vouts[i]);
226     free (pp_vouts);
227     return n;
228 }
229
230 float libvlc_video_get_scale( libvlc_media_player_t *mp )
231 {
232     float f_scale = var_GetFloat (mp, "scale");
233     if (var_GetBool (mp, "autoscale"))
234         f_scale = 0.;
235     return f_scale;
236 }
237
238 void libvlc_video_set_scale( libvlc_media_player_t *p_mp, float f_scale )
239 {
240     if (f_scale != 0.)
241         var_SetFloat (p_mp, "scale", f_scale);
242     var_SetBool (p_mp, "autoscale", f_scale == 0.);
243
244     /* Apply to current video outputs (if any) */
245     size_t n;
246     vout_thread_t **pp_vouts = GetVouts (p_mp, &n);
247     for (size_t i = 0; i < n; i++)
248     {
249         vout_thread_t *p_vout = pp_vouts[i];
250
251         if (f_scale != 0.)
252             var_SetFloat (p_vout, "scale", f_scale);
253         var_SetBool (p_vout, "autoscale", f_scale == 0.);
254         vlc_object_release (p_vout);
255     }
256     free (pp_vouts);
257 }
258
259 char *libvlc_video_get_aspect_ratio( libvlc_media_player_t *p_mi )
260 {
261     return var_GetNonEmptyString (p_mi, "aspect-ratio");
262 }
263
264 void libvlc_video_set_aspect_ratio( libvlc_media_player_t *p_mi,
265                                     const char *psz_aspect )
266 {
267     if (psz_aspect == NULL)
268         psz_aspect = "";
269     var_SetString (p_mi, "aspect-ratio", psz_aspect);
270
271     size_t n;
272     vout_thread_t **pp_vouts = GetVouts (p_mi, &n);
273     for (size_t i = 0; i < n; i++)
274     {
275         vout_thread_t *p_vout = pp_vouts[i];
276
277         var_SetString (p_vout, "aspect-ratio", psz_aspect);
278         vlc_object_release (p_vout);
279     }
280     free (pp_vouts);
281 }
282
283 int libvlc_video_get_spu( libvlc_media_player_t *p_mi )
284 {
285     input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
286
287     if( !p_input_thread )
288     {
289         libvlc_printerr( "No active input" );
290         return -1;
291     }
292
293     int i_spu = var_GetInteger( p_input_thread, "spu-es" );
294     vlc_object_release( p_input_thread );
295     return i_spu;
296 }
297
298 int libvlc_video_get_spu_count( libvlc_media_player_t *p_mi )
299 {
300     input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
301     int i_spu_count;
302
303     if( !p_input_thread )
304         return 0;
305
306     i_spu_count = var_CountChoices( p_input_thread, "spu-es" );
307     vlc_object_release( p_input_thread );
308     return i_spu_count;
309 }
310
311 libvlc_track_description_t *
312         libvlc_video_get_spu_description( libvlc_media_player_t *p_mi )
313 {
314     return libvlc_get_track_description( p_mi, "spu-es" );
315 }
316
317 int libvlc_video_set_spu( libvlc_media_player_t *p_mi, int i_spu )
318 {
319     input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
320     vlc_value_t list;
321     int i_ret = -1;
322
323     if( !p_input_thread )
324         return -1;
325
326     var_Change (p_input_thread, "spu-es", VLC_VAR_GETCHOICES, &list, NULL);
327     for (int i = 0; i < list.p_list->i_count; i++)
328     {
329         if( i_spu == list.p_list->p_values[i].i_int )
330         {
331             if( var_SetInteger( p_input_thread, "spu-es", i_spu ) < 0 )
332                 break;
333             i_ret = 0;
334             goto end;
335         }
336     }
337     libvlc_printerr( "Track identifier not found" );
338 end:
339     vlc_object_release (p_input_thread);
340     var_FreeList (&list, NULL);
341     return i_ret;
342 }
343
344 int libvlc_video_set_subtitle_file( libvlc_media_player_t *p_mi,
345                                     const char *psz_subtitle )
346 {
347     input_thread_t *p_input_thread = libvlc_get_input_thread ( p_mi );
348     bool b_ret = false;
349
350     if( p_input_thread )
351     {
352         if( !input_AddSubtitle( p_input_thread, psz_subtitle, true ) )
353             b_ret = true;
354         vlc_object_release( p_input_thread );
355     }
356     return b_ret;
357 }
358
359 int64_t libvlc_video_get_spu_delay( libvlc_media_player_t *p_mi )
360 {
361     input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
362     int64_t val = 0;
363
364     if( p_input_thread )
365     {
366         val = var_GetTime( p_input_thread, "spu-delay" );
367         vlc_object_release( p_input_thread );
368     }
369     else
370     {
371         libvlc_printerr( "No active input" );
372     }
373
374     return val;
375 }
376
377 int libvlc_video_set_spu_delay( libvlc_media_player_t *p_mi,
378                                 int64_t i_delay )
379 {
380     input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
381     int ret = -1;
382
383     if( p_input_thread )
384     {
385         var_SetTime( p_input_thread, "spu-delay", i_delay );
386         vlc_object_release( p_input_thread );
387         ret = 0;
388     }
389     else
390     {
391         libvlc_printerr( "No active input" );
392     }
393
394     return ret;
395 }
396
397 libvlc_track_description_t *
398         libvlc_video_get_title_description( libvlc_media_player_t *p_mi )
399 {
400     return libvlc_get_track_description( p_mi, "title" );
401 }
402
403 libvlc_track_description_t *
404         libvlc_video_get_chapter_description( libvlc_media_player_t *p_mi,
405                                               int i_title )
406 {
407     char psz_title[12];
408     sprintf( psz_title,  "title %2i", i_title );
409     return libvlc_get_track_description( p_mi, psz_title );
410 }
411
412 char *libvlc_video_get_crop_geometry (libvlc_media_player_t *p_mi)
413 {
414     return var_GetNonEmptyString (p_mi, "crop");
415 }
416
417 void libvlc_video_set_crop_geometry( libvlc_media_player_t *p_mi,
418                                      const char *psz_geometry )
419 {
420     if (psz_geometry == NULL)
421         psz_geometry = "";
422
423     var_SetString (p_mi, "crop", psz_geometry);
424
425     size_t n;
426     vout_thread_t **pp_vouts = GetVouts (p_mi, &n);
427
428     for (size_t i = 0; i < n; i++)
429     {
430         vout_thread_t *p_vout = pp_vouts[i];
431         vlc_value_t val;
432
433         /* Make sure the geometry is in the choice list */
434         /* Earlier choices are removed to not grow a long list over time. */
435         /* FIXME: not atomic - lock? */
436         val.psz_string = (char *)psz_geometry;
437         var_Change (p_vout, "crop", VLC_VAR_CLEARCHOICES, NULL, NULL);
438         var_Change (p_vout, "crop", VLC_VAR_ADDCHOICE, &val, &val);
439         var_SetString (p_vout, "crop", psz_geometry);
440         vlc_object_release (p_vout);
441     }
442     free (pp_vouts);
443 }
444
445 int libvlc_video_get_teletext( libvlc_media_player_t *p_mi )
446 {
447     return var_GetInteger (p_mi, "vbi-page");
448 }
449
450 void libvlc_video_set_teletext( libvlc_media_player_t *p_mi, int i_page )
451 {
452     input_thread_t *p_input_thread;
453     vlc_object_t *p_zvbi = NULL;
454     int telx;
455
456     var_SetInteger (p_mi, "vbi-page", i_page);
457
458     p_input_thread = libvlc_get_input_thread( p_mi );
459     if( !p_input_thread ) return;
460
461     if( var_CountChoices( p_input_thread, "teletext-es" ) <= 0 )
462     {
463         vlc_object_release( p_input_thread );
464         return;
465     }
466
467     telx = var_GetInteger( p_input_thread, "teletext-es" );
468     if( input_GetEsObjects( p_input_thread, telx, &p_zvbi, NULL, NULL )
469         == VLC_SUCCESS )
470     {
471         var_SetInteger( p_zvbi, "vbi-page", i_page );
472         vlc_object_release( p_zvbi );
473     }
474     vlc_object_release( p_input_thread );
475 }
476
477 void libvlc_toggle_teletext( libvlc_media_player_t *p_mi )
478 {
479     input_thread_t *p_input_thread;
480
481     p_input_thread = libvlc_get_input_thread(p_mi);
482     if( !p_input_thread ) return;
483
484     if( var_CountChoices( p_input_thread, "teletext-es" ) <= 0 )
485     {
486         vlc_object_release( p_input_thread );
487         return;
488     }
489     const bool b_selected = var_GetInteger( p_input_thread, "teletext-es" ) >= 0;
490     if( b_selected )
491     {
492         var_SetInteger( p_input_thread, "spu-es", -1 );
493     }
494     else
495     {
496         vlc_value_t list;
497         if( !var_Change( p_input_thread, "teletext-es", VLC_VAR_GETLIST, &list, NULL ) )
498         {
499             if( list.p_list->i_count > 0 )
500                 var_SetInteger( p_input_thread, "spu-es", list.p_list->p_values[0].i_int );
501
502             var_FreeList( &list, NULL );
503         }
504     }
505     vlc_object_release( p_input_thread );
506 }
507
508 int libvlc_video_get_track_count( libvlc_media_player_t *p_mi )
509 {
510     input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
511     int i_track_count;
512
513     if( !p_input_thread )
514         return -1;
515
516     i_track_count = var_CountChoices( p_input_thread, "video-es" );
517
518     vlc_object_release( p_input_thread );
519     return i_track_count;
520 }
521
522 libvlc_track_description_t *
523         libvlc_video_get_track_description( libvlc_media_player_t *p_mi )
524 {
525     return libvlc_get_track_description( p_mi, "video-es" );
526 }
527
528 int libvlc_video_get_track( libvlc_media_player_t *p_mi )
529 {
530     input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
531
532     if( !p_input_thread )
533         return -1;
534
535     int id = var_GetInteger( p_input_thread, "video-es" );
536     vlc_object_release( p_input_thread );
537     return id;
538 }
539
540 int libvlc_video_set_track( libvlc_media_player_t *p_mi, int i_track )
541 {
542     input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
543     vlc_value_t val_list;
544     int i_ret = -1;
545
546     if( !p_input_thread )
547         return -1;
548
549     var_Change( p_input_thread, "video-es", VLC_VAR_GETCHOICES, &val_list, NULL );
550     for( int i = 0; i < val_list.p_list->i_count; i++ )
551     {
552         if( i_track == val_list.p_list->p_values[i].i_int )
553         {
554             if( var_SetInteger( p_input_thread, "video-es", i_track ) < 0 )
555                 break;
556             i_ret = 0;
557             goto end;
558         }
559     }
560     libvlc_printerr( "Track identifier not found" );
561 end:
562     var_FreeList( &val_list, NULL );
563     vlc_object_release( p_input_thread );
564     return i_ret;
565 }
566
567 /******************************************************************************
568  * libvlc_video_set_deinterlace : enable deinterlace
569  *****************************************************************************/
570 void libvlc_video_set_deinterlace( libvlc_media_player_t *p_mi,
571                                    const char *psz_mode )
572 {
573     if (psz_mode == NULL)
574         psz_mode = "";
575     if (*psz_mode
576      && strcmp (psz_mode, "blend")    && strcmp (psz_mode, "bob")
577      && strcmp (psz_mode, "discard")  && strcmp (psz_mode, "linear")
578      && strcmp (psz_mode, "mean")     && strcmp (psz_mode, "x")
579      && strcmp (psz_mode, "yadif")    && strcmp (psz_mode, "yadif2x")
580      && strcmp (psz_mode, "phosphor") && strcmp (psz_mode, "ivtc"))
581         return;
582
583     if (*psz_mode)
584     {
585         var_SetString (p_mi, "deinterlace-mode", psz_mode);
586         var_SetInteger (p_mi, "deinterlace", 1);
587     }
588     else
589         var_SetInteger (p_mi, "deinterlace", 0);
590
591     size_t n;
592     vout_thread_t **pp_vouts = GetVouts (p_mi, &n);
593     for (size_t i = 0; i < n; i++)
594     {
595         vout_thread_t *p_vout = pp_vouts[i];
596
597         if (*psz_mode)
598         {
599             var_SetString (p_vout, "deinterlace-mode", psz_mode);
600             var_SetInteger (p_vout, "deinterlace", 1);
601         }
602         else
603             var_SetInteger (p_vout, "deinterlace", 0);
604         vlc_object_release (p_vout);
605     }
606     free (pp_vouts);
607 }
608
609 /* ************** */
610 /* module helpers */
611 /* ************** */
612
613 static bool find_sub_source_by_name( libvlc_media_player_t *p_mi, const char *restrict name )
614 {
615     vout_thread_t *vout = GetVout( p_mi, 0 );
616     if (!vout)
617         return false;
618
619     char *psz_sources = var_GetString( vout, "sub-source" );
620     if( !psz_sources )
621     {
622         libvlc_printerr( "%s not enabled", name );
623         vlc_object_release( vout );
624         return false;
625     }
626
627     /* Find 'name'  */
628     char *p = strstr( psz_sources, name );
629     free( psz_sources );
630     vlc_object_release( vout );
631     return (p != NULL);
632 }
633
634 typedef const struct {
635     const char name[20];
636     unsigned type;
637 } opt_t;
638
639 static void
640 set_int( libvlc_media_player_t *p_mi, const char *restrict name,
641          const opt_t *restrict opt, int value )
642 {
643     if( !opt ) return;
644
645     if( !opt->type ) /* the enabler */
646     {
647         vout_thread_t *vout = GetVout( p_mi, 0 );
648         if (vout)
649         {
650             /* Fill sub-source */
651             vout_EnableFilter( vout, opt->name, value, false );
652             var_TriggerCallback( vout, "sub-source" );
653             vlc_object_release( vout );
654         }
655         return;
656     }
657
658     if( opt->type != VLC_VAR_INTEGER )
659     {
660         libvlc_printerr( "Invalid argument to %s in %s", name, "set int" );
661         return;
662     }
663
664     var_SetInteger( p_mi, opt->name, value );
665 }
666
667 static int
668 get_int( libvlc_media_player_t *p_mi, const char *restrict name,
669          const opt_t *restrict opt )
670 {
671     if( !opt ) return 0;
672
673     switch( opt->type )
674     {
675         case 0: /* the enabler */
676         {
677             bool b_enabled = find_sub_source_by_name( p_mi, name );
678             return b_enabled ? 1 : 0;
679         }
680     case VLC_VAR_INTEGER:
681         return var_GetInteger(p_mi, opt->name);
682     default:
683         libvlc_printerr( "Invalid argument to %s in %s", name, "get int" );
684         return 0;
685     }
686 }
687
688 static void
689 set_float( libvlc_media_player_t *p_mi, const char *restrict name,
690             const opt_t *restrict opt, float value )
691 {
692     if( !opt ) return;
693
694     if( opt->type != VLC_VAR_FLOAT )
695     {
696         libvlc_printerr( "Invalid argument to %s in %s", name, "set float" );
697         return;
698     }
699
700     var_SetFloat( p_mi, opt->name, value );
701 }
702
703 static float
704 get_float( libvlc_media_player_t *p_mi, const char *restrict name,
705             const opt_t *restrict opt )
706 {
707     if( !opt ) return 0.0;
708
709     if( opt->type != VLC_VAR_FLOAT )
710     {
711         libvlc_printerr( "Invalid argument to %s in %s", name, "get float" );
712         return 0.0;
713     }
714
715     return var_GetFloat( p_mi, opt->name );
716 }
717
718 static void
719 set_string( libvlc_media_player_t *p_mi, const char *restrict name,
720             const opt_t *restrict opt, const char *restrict psz_value )
721 {
722     if( !opt ) return;
723
724     if( opt->type != VLC_VAR_STRING )
725     {
726         libvlc_printerr( "Invalid argument to %s in %s", name, "set string" );
727         return;
728     }
729
730     var_SetString( p_mi, opt->name, psz_value );
731 }
732
733 static char *
734 get_string( libvlc_media_player_t *p_mi, const char *restrict name,
735             const opt_t *restrict opt )
736 {
737     if( !opt ) return NULL;
738
739     if( opt->type != VLC_VAR_STRING )
740     {
741         libvlc_printerr( "Invalid argument to %s in %s", name, "get string" );
742         return NULL;
743     }
744
745     return var_GetString( p_mi, opt->name );
746 }
747
748 static const opt_t *
749 marq_option_bynumber(unsigned option)
750 {
751     static const opt_t optlist[] =
752     {
753         { "marq",          0 },
754         { "marq-marquee",  VLC_VAR_STRING },
755         { "marq-color",    VLC_VAR_INTEGER },
756         { "marq-opacity",  VLC_VAR_INTEGER },
757         { "marq-position", VLC_VAR_INTEGER },
758         { "marq-refresh",  VLC_VAR_INTEGER },
759         { "marq-size",     VLC_VAR_INTEGER },
760         { "marq-timeout",  VLC_VAR_INTEGER },
761         { "marq-x",        VLC_VAR_INTEGER },
762         { "marq-y",        VLC_VAR_INTEGER },
763     };
764     enum { num_opts = sizeof(optlist) / sizeof(*optlist) };
765
766     const opt_t *r = option < num_opts ? optlist+option : NULL;
767     if( !r )
768         libvlc_printerr( "Unknown marquee option" );
769     return r;
770 }
771
772 /*****************************************************************************
773  * libvlc_video_get_marquee_int : get a marq option value
774  *****************************************************************************/
775 int libvlc_video_get_marquee_int( libvlc_media_player_t *p_mi,
776                                   unsigned option )
777 {
778     return get_int( p_mi, "marq", marq_option_bynumber(option) );
779 }
780
781 /*****************************************************************************
782  * libvlc_video_get_marquee_string : get a marq option value
783  *****************************************************************************/
784 char * libvlc_video_get_marquee_string( libvlc_media_player_t *p_mi,
785                                         unsigned option )
786 {
787     return get_string( p_mi, "marq", marq_option_bynumber(option) );
788 }
789
790 /*****************************************************************************
791  * libvlc_video_set_marquee_int: enable, disable or set an int option
792  *****************************************************************************/
793 void libvlc_video_set_marquee_int( libvlc_media_player_t *p_mi,
794                          unsigned option, int value )
795 {
796     set_int( p_mi, "marq", marq_option_bynumber(option), value );
797 }
798
799 /*****************************************************************************
800  * libvlc_video_set_marquee_string: set a string option
801  *****************************************************************************/
802 void libvlc_video_set_marquee_string( libvlc_media_player_t *p_mi,
803                 unsigned option, const char * value )
804 {
805     set_string( p_mi, "marq", marq_option_bynumber(option), value );
806 }
807
808
809 /* logo module support */
810
811 static const opt_t *
812 logo_option_bynumber( unsigned option )
813 {
814     static const opt_t vlogo_optlist[] =
815     /* depends on libvlc_video_logo_option_t */
816     {
817         { "logo",          0 },
818         { "logo-file",     VLC_VAR_STRING },
819         { "logo-x",        VLC_VAR_INTEGER },
820         { "logo-y",        VLC_VAR_INTEGER },
821         { "logo-delay",    VLC_VAR_INTEGER },
822         { "logo-repeat",   VLC_VAR_INTEGER },
823         { "logo-opacity",  VLC_VAR_INTEGER },
824         { "logo-position", VLC_VAR_INTEGER },
825     };
826     enum { num_vlogo_opts = sizeof(vlogo_optlist) / sizeof(*vlogo_optlist) };
827
828     const opt_t *r = option < num_vlogo_opts ? vlogo_optlist+option : NULL;
829     if( !r )
830         libvlc_printerr( "Unknown logo option" );
831     return r;
832 }
833
834 void libvlc_video_set_logo_string( libvlc_media_player_t *p_mi,
835                                    unsigned option, const char *psz_value )
836 {
837     set_string( p_mi,"logo",logo_option_bynumber(option), psz_value );
838 }
839
840
841 void libvlc_video_set_logo_int( libvlc_media_player_t *p_mi,
842                                 unsigned option, int value )
843 {
844     set_int( p_mi, "logo", logo_option_bynumber(option), value );
845 }
846
847
848 int libvlc_video_get_logo_int( libvlc_media_player_t *p_mi,
849                                unsigned option )
850 {
851     return get_int( p_mi, "logo", logo_option_bynumber(option) );
852 }
853
854
855 /* adjust module support */
856
857
858 static const opt_t *
859 adjust_option_bynumber( unsigned option )
860 {
861     static const opt_t optlist[] =
862     {
863         { "adjust",     0 },
864         { "contrast",   VLC_VAR_FLOAT },
865         { "brightness", VLC_VAR_FLOAT },
866         { "hue",        VLC_VAR_INTEGER },
867         { "saturation", VLC_VAR_FLOAT },
868         { "gamma",      VLC_VAR_FLOAT },
869     };
870     enum { num_opts = sizeof(optlist) / sizeof(*optlist) };
871
872     const opt_t *r = option < num_opts ? optlist+option : NULL;
873     if( !r )
874         libvlc_printerr( "Unknown adjust option" );
875     return r;
876 }
877
878
879 void libvlc_video_set_adjust_int( libvlc_media_player_t *p_mi,
880                                   unsigned option, int value )
881 {
882     set_int( p_mi, "adjust", adjust_option_bynumber(option), value );
883 }
884
885
886 int libvlc_video_get_adjust_int( libvlc_media_player_t *p_mi,
887                                  unsigned option )
888 {
889     return get_int( p_mi, "adjust", adjust_option_bynumber(option) );
890 }
891
892
893 void libvlc_video_set_adjust_float( libvlc_media_player_t *p_mi,
894                                     unsigned option, float value )
895 {
896     set_float( p_mi, "adjust", adjust_option_bynumber(option), value );
897 }
898
899
900 float libvlc_video_get_adjust_float( libvlc_media_player_t *p_mi,
901                                      unsigned option )
902 {
903     return get_float( p_mi, "adjust", adjust_option_bynumber(option) );
904 }