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