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