]> git.sesse.net Git - vlc/blob - lib/video.c
Add libvlc_video_get_spu_delay and libvlc_video_set_spu_delay
[vlc] / lib / video.c
1 /*****************************************************************************
2  * video.c: libvlc new API video functions
3  *****************************************************************************
4  * Copyright (C) 2005-2010 VLC authors and VideoLAN
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 it
14  * under the terms of the GNU Lesser General Public License as published by
15  * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
22  *
23  * You should have received a copy of the GNU Lesser General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * 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 width, height;
181
182     if (libvlc_video_get_size (p_mi, 0, &width, &height))
183         return 0;
184     return height;
185 }
186
187 int libvlc_video_get_width( libvlc_media_player_t *p_mi )
188 {
189     unsigned width, height;
190
191     if (libvlc_video_get_size (p_mi, 0, &width, &height))
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 int64_t libvlc_video_get_spu_delay( libvlc_media_player_t *p_mi )
369 {
370     input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
371     int64_t val = 0;
372
373     if( p_input_thread )
374     {
375         val = var_GetTime( p_input_thread, "spu-delay" );
376         vlc_object_release( p_input_thread );
377     }
378     else
379     {
380         libvlc_printerr( "No active input" );
381     }
382
383     return val;
384 }
385
386 int libvlc_video_set_spu_delay( libvlc_media_player_t *p_mi,
387                                 int64_t i_delay )
388 {
389     input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
390     int ret = -1;
391
392     if( p_input_thread )
393     {
394         var_SetTime( p_input_thread, "spu-delay", i_delay );
395         vlc_object_release( p_input_thread );
396         ret = 0;
397     }
398     else
399     {
400         libvlc_printerr( "No active input" );
401     }
402
403     return ret;
404 }
405
406 libvlc_track_description_t *
407         libvlc_video_get_title_description( libvlc_media_player_t *p_mi )
408 {
409     return libvlc_get_track_description( p_mi, "title" );
410 }
411
412 libvlc_track_description_t *
413         libvlc_video_get_chapter_description( libvlc_media_player_t *p_mi,
414                                               int i_title )
415 {
416     char psz_title[12];
417     sprintf( psz_title,  "title %2i", i_title );
418     return libvlc_get_track_description( p_mi, psz_title );
419 }
420
421 char *libvlc_video_get_crop_geometry (libvlc_media_player_t *p_mi)
422 {
423     return var_GetNonEmptyString (p_mi, "crop");
424 }
425
426 void libvlc_video_set_crop_geometry( libvlc_media_player_t *p_mi,
427                                      const char *psz_geometry )
428 {
429     if (psz_geometry == NULL)
430         psz_geometry = "";
431
432     var_SetString (p_mi, "crop", psz_geometry);
433
434     size_t n;
435     vout_thread_t **pp_vouts = GetVouts (p_mi, &n);
436
437     for (size_t i = 0; i < n; i++)
438     {
439         vout_thread_t *p_vout = pp_vouts[i];
440         vlc_value_t val;
441
442         /* Make sure the geometry is in the choice list */
443         /* Earlier choices are removed to not grow a long list over time. */
444         /* FIXME: not atomic - lock? */
445         val.psz_string = (char *)psz_geometry;
446         var_Change (p_vout, "crop", VLC_VAR_CLEARCHOICES, NULL, NULL);
447         var_Change (p_vout, "crop", VLC_VAR_ADDCHOICE, &val, &val);
448         var_SetString (p_vout, "crop", psz_geometry);
449         vlc_object_release (p_vout);
450     }
451     free (pp_vouts);
452 }
453
454 int libvlc_video_get_teletext( libvlc_media_player_t *p_mi )
455 {
456     return var_GetInteger (p_mi, "vbi-page");
457 }
458
459 void libvlc_video_set_teletext( libvlc_media_player_t *p_mi, int i_page )
460 {
461     input_thread_t *p_input_thread;
462     vlc_object_t *p_zvbi = NULL;
463     int telx;
464
465     var_SetInteger (p_mi, "vbi-page", i_page);
466
467     p_input_thread = libvlc_get_input_thread( p_mi );
468     if( !p_input_thread ) return;
469
470     if( var_CountChoices( p_input_thread, "teletext-es" ) <= 0 )
471     {
472         vlc_object_release( p_input_thread );
473         return;
474     }
475
476     telx = var_GetInteger( p_input_thread, "teletext-es" );
477     if( input_GetEsObjects( p_input_thread, telx, &p_zvbi, NULL, NULL )
478         == VLC_SUCCESS )
479     {
480         var_SetInteger( p_zvbi, "vbi-page", i_page );
481         vlc_object_release( p_zvbi );
482     }
483     vlc_object_release( p_input_thread );
484 }
485
486 void libvlc_toggle_teletext( libvlc_media_player_t *p_mi )
487 {
488     input_thread_t *p_input_thread;
489
490     p_input_thread = libvlc_get_input_thread(p_mi);
491     if( !p_input_thread ) return;
492
493     if( var_CountChoices( p_input_thread, "teletext-es" ) <= 0 )
494     {
495         vlc_object_release( p_input_thread );
496         return;
497     }
498     const bool b_selected = var_GetInteger( p_input_thread, "teletext-es" ) >= 0;
499     if( b_selected )
500     {
501         var_SetInteger( p_input_thread, "spu-es", -1 );
502     }
503     else
504     {
505         vlc_value_t list;
506         if( !var_Change( p_input_thread, "teletext-es", VLC_VAR_GETLIST, &list, NULL ) )
507         {
508             if( list.p_list->i_count > 0 )
509                 var_SetInteger( p_input_thread, "spu-es", list.p_list->p_values[0].i_int );
510
511             var_FreeList( &list, NULL );
512         }
513     }
514     vlc_object_release( p_input_thread );
515 }
516
517 int libvlc_video_get_track_count( libvlc_media_player_t *p_mi )
518 {
519     input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
520     int i_track_count;
521
522     if( !p_input_thread )
523         return -1;
524
525     i_track_count = var_CountChoices( p_input_thread, "video-es" );
526
527     vlc_object_release( p_input_thread );
528     return i_track_count;
529 }
530
531 libvlc_track_description_t *
532         libvlc_video_get_track_description( libvlc_media_player_t *p_mi )
533 {
534     return libvlc_get_track_description( p_mi, "video-es" );
535 }
536
537 int libvlc_video_get_track( libvlc_media_player_t *p_mi )
538 {
539     input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
540     vlc_value_t val_list;
541     vlc_value_t val;
542     int i_track = -1;
543
544     if( !p_input_thread )
545         return -1;
546
547     if( var_Get( p_input_thread, "video-es", &val ) < 0 )
548     {
549         libvlc_printerr( "Video track information not found" );
550         vlc_object_release( p_input_thread );
551         return -1;
552     }
553
554     var_Change( p_input_thread, "video-es", VLC_VAR_GETCHOICES, &val_list, NULL );
555     for( int i = 0; i < val_list.p_list->i_count; i++ )
556     {
557         if( val_list.p_list->p_values[i].i_int == val.i_int )
558         {
559             i_track = i;
560             break;
561         }
562     }
563     var_FreeList( &val_list, NULL );
564     vlc_object_release( p_input_thread );
565     return i_track;
566 }
567
568 int libvlc_video_set_track( libvlc_media_player_t *p_mi, int i_track )
569 {
570     input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
571     vlc_value_t val_list;
572     int i_ret = -1;
573
574     if( !p_input_thread )
575         return -1;
576
577     var_Change( p_input_thread, "video-es", VLC_VAR_GETCHOICES, &val_list, NULL );
578     for( int i = 0; i < val_list.p_list->i_count; i++ )
579     {
580         if( i_track == val_list.p_list->p_values[i].i_int )
581         {
582             if( var_SetInteger( p_input_thread, "video-es", i_track ) < 0 )
583                 break;
584             i_ret = 0;
585             goto end;
586         }
587     }
588     libvlc_printerr( "Video track number out of range" );
589 end:
590     var_FreeList( &val_list, NULL );
591     vlc_object_release( p_input_thread );
592     return i_ret;
593 }
594
595 /******************************************************************************
596  * libvlc_video_set_deinterlace : enable deinterlace
597  *****************************************************************************/
598 void libvlc_video_set_deinterlace( libvlc_media_player_t *p_mi,
599                                    const char *psz_mode )
600 {
601     if (psz_mode == NULL)
602         psz_mode = "";
603     if (*psz_mode
604      && strcmp (psz_mode, "blend")    && strcmp (psz_mode, "bob")
605      && strcmp (psz_mode, "discard")  && strcmp (psz_mode, "linear")
606      && strcmp (psz_mode, "mean")     && strcmp (psz_mode, "x")
607      && strcmp (psz_mode, "yadif")    && strcmp (psz_mode, "yadif2x")
608      && strcmp (psz_mode, "phosphor") && strcmp (psz_mode, "ivtc"))
609         return;
610
611     if (*psz_mode)
612     {
613         var_SetString (p_mi, "deinterlace-mode", psz_mode);
614         var_SetInteger (p_mi, "deinterlace", 1);
615     }
616     else
617         var_SetInteger (p_mi, "deinterlace", 0);
618
619     size_t n;
620     vout_thread_t **pp_vouts = GetVouts (p_mi, &n);
621     for (size_t i = 0; i < n; i++)
622     {
623         vout_thread_t *p_vout = pp_vouts[i];
624
625         if (*psz_mode)
626         {
627             var_SetString (p_vout, "deinterlace-mode", psz_mode);
628             var_SetInteger (p_vout, "deinterlace", 1);
629         }
630         else
631             var_SetInteger (p_vout, "deinterlace", 0);
632         vlc_object_release (p_vout);
633     }
634     free (pp_vouts);
635 }
636
637 /* ************** */
638 /* module helpers */
639 /* ************** */
640
641
642 static vlc_object_t *get_object( libvlc_media_player_t * p_mi,
643                                  const char *name )
644 {
645     vlc_object_t *object;
646     vout_thread_t *vout = GetVout( p_mi, 0 );
647
648     if( vout )
649     {
650         object = vlc_object_find_name( vout, name );
651         vlc_object_release(vout);
652     }
653     else
654         object = NULL;
655
656     if( !object )
657         libvlc_printerr( "%s not enabled", name );
658     return object;
659 }
660
661
662 typedef const struct {
663     const char name[20];
664     unsigned type;
665 } opt_t;
666
667
668 static void
669 set_int( libvlc_media_player_t *p_mi, const char *restrict name,
670          const opt_t *restrict opt, int value )
671 {
672     if( !opt ) return;
673
674     if( !opt->type ) /* the enabler */
675     {
676         vout_thread_t *vout = GetVout( p_mi, 0 );
677         if (vout)
678         {
679             vout_EnableFilter( vout, opt->name, value, false );
680             vlc_object_release( vout );
681         }
682         return;
683     }
684
685     if( opt->type != VLC_VAR_INTEGER )
686     {
687         libvlc_printerr( "Invalid argument to %s in %s", name, "set int" );
688         return;
689     }
690
691     var_SetInteger(p_mi, opt->name, value);
692     vlc_object_t *object = get_object( p_mi, name );
693     if( object )
694     {
695         var_SetInteger(object, opt->name, value);
696         vlc_object_release( object );
697     }
698 }
699
700
701 static int
702 get_int( libvlc_media_player_t *p_mi, const char *restrict name,
703          const opt_t *restrict opt )
704 {
705     if( !opt ) return 0;
706
707     switch( opt->type )
708     {
709         case 0: /* the enabler */
710         {
711             vlc_object_t *object = get_object( p_mi, name );
712             vlc_object_release( object );
713             return object != NULL;
714         }
715     case VLC_VAR_INTEGER:
716         return var_GetInteger(p_mi, opt->name);
717     default:
718         libvlc_printerr( "Invalid argument to %s in %s", name, "get int" );
719         return 0;
720     }
721 }
722
723
724 static void
725 set_float( libvlc_media_player_t *p_mi, const char *restrict name,
726             const opt_t *restrict opt, float value )
727 {
728     if( !opt ) return;
729
730     if( opt->type != VLC_VAR_FLOAT )
731     {
732         libvlc_printerr( "Invalid argument to %s in %s", name, "set float" );
733         return;
734     }
735
736     var_SetFloat( p_mi, opt->name, value );
737
738     vlc_object_t *object = get_object( p_mi, name );
739     if( object )
740     {
741         var_SetFloat(object, opt->name, value );
742         vlc_object_release( object );
743     }
744 }
745
746
747 static float
748 get_float( libvlc_media_player_t *p_mi, const char *restrict name,
749             const opt_t *restrict opt )
750 {
751     if( !opt ) return 0.0;
752
753
754     if( opt->type != VLC_VAR_FLOAT )
755     {
756         libvlc_printerr( "Invalid argument to %s in %s", name, "get float" );
757         return 0.0;
758     }
759
760     return var_GetFloat( p_mi, opt->name );
761 }
762
763
764 static void
765 set_string( libvlc_media_player_t *p_mi, const char *restrict name,
766             const opt_t *restrict opt, const char *restrict psz_value )
767 {
768     if( !opt ) return;
769
770     if( opt->type != VLC_VAR_STRING )
771     {
772         libvlc_printerr( "Invalid argument to %s in %s", name, "set string" );
773         return;
774     }
775
776     var_SetString( p_mi, opt->name, psz_value );
777
778     vlc_object_t *object = get_object( p_mi, name );
779     if( object )
780     {
781         var_SetString(object, opt->name, psz_value );
782         vlc_object_release( object );
783     }
784 }
785
786
787 static char *
788 get_string( libvlc_media_player_t *p_mi, const char *restrict name,
789             const opt_t *restrict opt )
790 {
791     if( !opt ) return NULL;
792
793     if( opt->type != VLC_VAR_STRING )
794     {
795         libvlc_printerr( "Invalid argument to %s in %s", name, "get string" );
796         return NULL;
797     }
798
799     return var_GetString( p_mi, opt->name );
800 }
801
802
803 static const opt_t *
804 marq_option_bynumber(unsigned option)
805 {
806     static const opt_t optlist[] =
807     {
808         { "marq",          0 },
809         { "marq-marquee",  VLC_VAR_STRING },
810         { "marq-color",    VLC_VAR_INTEGER },
811         { "marq-opacity",  VLC_VAR_INTEGER },
812         { "marq-position", VLC_VAR_INTEGER },
813         { "marq-refresh",  VLC_VAR_INTEGER },
814         { "marq-size",     VLC_VAR_INTEGER },
815         { "marq-timeout",  VLC_VAR_INTEGER },
816         { "marq-x",        VLC_VAR_INTEGER },
817         { "marq-y",        VLC_VAR_INTEGER },
818     };
819     enum { num_opts = sizeof(optlist) / sizeof(*optlist) };
820
821     const opt_t *r = option < num_opts ? optlist+option : NULL;
822     if( !r )
823         libvlc_printerr( "Unknown marquee option" );
824     return r;
825 }
826
827 static vlc_object_t *get_object( libvlc_media_player_t *, const char *);
828
829 /*****************************************************************************
830  * libvlc_video_get_marquee_int : get a marq option value
831  *****************************************************************************/
832 int libvlc_video_get_marquee_int( libvlc_media_player_t *p_mi,
833                                   unsigned option )
834 {
835     return get_int( p_mi, "marq", marq_option_bynumber(option) );
836 }
837
838 /*****************************************************************************
839  * libvlc_video_get_marquee_string : get a marq option value
840  *****************************************************************************/
841 char * libvlc_video_get_marquee_string( libvlc_media_player_t *p_mi,
842                                         unsigned option )
843 {
844     return get_string( p_mi, "marq", marq_option_bynumber(option) );
845 }
846
847 /*****************************************************************************
848  * libvlc_video_set_marquee_int: enable, disable or set an int option
849  *****************************************************************************/
850 void libvlc_video_set_marquee_int( libvlc_media_player_t *p_mi,
851                          unsigned option, int value )
852 {
853     set_int( p_mi, "marq", marq_option_bynumber(option), value );
854 }
855
856 /*****************************************************************************
857  * libvlc_video_set_marquee_string: set a string option
858  *****************************************************************************/
859 void libvlc_video_set_marquee_string( libvlc_media_player_t *p_mi,
860                 unsigned option, const char * value )
861 {
862     set_string( p_mi, "marq", marq_option_bynumber(option), value );
863 }
864
865
866 /* logo module support */
867
868
869 static const opt_t *
870 logo_option_bynumber( unsigned option )
871 {
872     static const opt_t vlogo_optlist[] =
873     /* depends on libvlc_video_logo_option_t */
874     {
875         { "logo",          0 },
876         { "logo-file",     VLC_VAR_STRING },
877         { "logo-x",        VLC_VAR_INTEGER },
878         { "logo-y",        VLC_VAR_INTEGER },
879         { "logo-delay",    VLC_VAR_INTEGER },
880         { "logo-repeat",   VLC_VAR_INTEGER },
881         { "logo-opacity",  VLC_VAR_INTEGER },
882         { "logo-position", VLC_VAR_INTEGER },
883     };
884     enum { num_vlogo_opts = sizeof(vlogo_optlist) / sizeof(*vlogo_optlist) };
885
886     const opt_t *r = option < num_vlogo_opts ? vlogo_optlist+option : NULL;
887     if( !r )
888         libvlc_printerr( "Unknown logo option" );
889     return r;
890 }
891
892
893 void libvlc_video_set_logo_string( libvlc_media_player_t *p_mi,
894                                    unsigned option, const char *psz_value )
895 {
896     set_string( p_mi,"logo",logo_option_bynumber(option),psz_value );
897 }
898
899
900 void libvlc_video_set_logo_int( libvlc_media_player_t *p_mi,
901                                 unsigned option, int value )
902 {
903     set_int( p_mi, "logo", logo_option_bynumber(option), value );
904 }
905
906
907 int libvlc_video_get_logo_int( libvlc_media_player_t *p_mi,
908                                unsigned option )
909 {
910     return get_int( p_mi, "logo", logo_option_bynumber(option) );
911 }
912
913
914 /* adjust module support */
915
916
917 static const opt_t *
918 adjust_option_bynumber( unsigned option )
919 {
920     static const opt_t optlist[] =
921     {
922         { "adjust",               0 },
923         { "contrast",             VLC_VAR_FLOAT },
924         { "brightness",           VLC_VAR_FLOAT },
925         { "hue",                  VLC_VAR_INTEGER },
926         { "saturation",           VLC_VAR_FLOAT },
927         { "gamma",                VLC_VAR_FLOAT },
928     };
929     enum { num_opts = sizeof(optlist) / sizeof(*optlist) };
930
931     const opt_t *r = option < num_opts ? optlist+option : NULL;
932     if( !r )
933         libvlc_printerr( "Unknown adjust option" );
934     return r;
935 }
936
937
938 void libvlc_video_set_adjust_int( libvlc_media_player_t *p_mi,
939                                   unsigned option, int value )
940 {
941     set_int( p_mi, "adjust", adjust_option_bynumber(option), value );
942 }
943
944
945 int libvlc_video_get_adjust_int( libvlc_media_player_t *p_mi,
946                                  unsigned option )
947 {
948     return get_int( p_mi, "adjust", adjust_option_bynumber(option) );
949 }
950
951
952 void libvlc_video_set_adjust_float( libvlc_media_player_t *p_mi,
953                                     unsigned option, float value )
954 {
955     set_float( p_mi, "adjust", adjust_option_bynumber(option), value );
956 }
957
958
959 float libvlc_video_get_adjust_float( libvlc_media_player_t *p_mi,
960                                      unsigned option )
961 {
962     return get_float( p_mi, "adjust", adjust_option_bynumber(option) );
963 }