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