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