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