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