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