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