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