libvlc: include config.h when needed
[vlc.git] / src / control / video.c
blob9274ea05ffd6e6beb5e3a077648002ed6db17be8
1 /*****************************************************************************
2 * video.c: libvlc new API video functions
3 *****************************************************************************
4 * Copyright (C) 2005 the VideoLAN team
6 * $Id$
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>
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.
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.
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 *****************************************************************************/
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
32 #include <vlc/libvlc.h>
33 #include <vlc/libvlc_media.h>
34 #include <vlc/libvlc_media_player.h>
36 #include <vlc_common.h>
37 #include <vlc_input.h>
38 #include <vlc_vout.h>
40 #include "media_player_internal.h"
41 #include <vlc_osd.h>
44 * Remember to release the returned vout_thread_t.
46 static vout_thread_t *GetVout( libvlc_media_player_t *p_mi,
47 libvlc_exception_t *p_exception )
49 input_thread_t *p_input = libvlc_get_input_thread( p_mi, p_exception );
50 vout_thread_t *p_vout = NULL;
52 if( p_input )
54 p_vout = input_GetVout( p_input );
55 if( !p_vout )
57 libvlc_exception_raise( p_exception, "No active video output" );
59 vlc_object_release( p_input );
61 return p_vout;
64 /**********************************************************************
65 * Exported functions
66 **********************************************************************/
68 void libvlc_set_fullscreen( libvlc_media_player_t *p_mi, int b_fullscreen,
69 libvlc_exception_t *p_e )
71 /* We only work on the first vout */
72 vout_thread_t *p_vout = GetVout( p_mi, p_e );
74 /* GetVout will raise the exception for us */
75 if( !p_vout ) return;
77 var_SetBool( p_vout, "fullscreen", b_fullscreen );
79 vlc_object_release( p_vout );
82 int libvlc_get_fullscreen( libvlc_media_player_t *p_mi,
83 libvlc_exception_t *p_e )
85 /* We only work on the first vout */
86 vout_thread_t *p_vout = GetVout( p_mi, p_e );
87 int i_ret;
89 /* GetVout will raise the exception for us */
90 if( !p_vout ) return 0;
92 i_ret = var_GetBool( p_vout, "fullscreen" );
94 vlc_object_release( p_vout );
96 return i_ret;
99 void libvlc_toggle_fullscreen( libvlc_media_player_t *p_mi,
100 libvlc_exception_t *p_e )
102 /* We only work on the first vout */
103 vout_thread_t *p_vout = GetVout( p_mi, p_e );
105 /* GetVout will raise the exception for us */
106 if( !p_vout ) return;
108 var_ToggleBool( p_vout, "fullscreen" );
110 vlc_object_release( p_vout );
113 void
114 libvlc_video_take_snapshot( libvlc_media_player_t *p_mi, const char *psz_filepath,
115 unsigned int i_width, unsigned int i_height, libvlc_exception_t *p_e )
117 vout_thread_t *p_vout;
119 /* The filepath must be not NULL */
120 if( !psz_filepath )
122 libvlc_exception_raise( p_e, "filepath is null" );
123 return;
125 /* We must have an input */
126 if( !p_mi->p_input_thread )
128 libvlc_exception_raise( p_e, "Input does not exist" );
129 return;
132 /* GetVout will raise the exception for us */
133 p_vout = GetVout( p_mi, p_e );
134 if( !p_vout ) return;
136 var_SetInteger( p_vout, "snapshot-width", i_width );
137 var_SetInteger( p_vout, "snapshot-height", i_height );
139 var_SetString( p_vout, "snapshot-path", psz_filepath );
140 var_SetString( p_vout, "snapshot-format", "png" );
142 var_TriggerCallback( p_vout, "video-snapshot" );
143 vlc_object_release( p_vout );
146 int libvlc_video_get_height( libvlc_media_player_t *p_mi,
147 libvlc_exception_t *p_e )
149 int height;
151 vout_thread_t *p_vout = GetVout( p_mi, p_e );
152 if( !p_vout ) return 0;
154 height = p_vout->i_window_height;
156 vlc_object_release( p_vout );
158 return height;
161 int libvlc_video_get_width( libvlc_media_player_t *p_mi,
162 libvlc_exception_t *p_e )
164 int width;
166 vout_thread_t *p_vout = GetVout( p_mi, p_e );
167 if( !p_vout ) return 0;
169 width = p_vout->i_window_width;
171 vlc_object_release( p_vout );
173 return width;
176 int libvlc_media_player_has_vout( libvlc_media_player_t *p_mi,
177 libvlc_exception_t *p_e )
179 input_thread_t *p_input_thread = libvlc_get_input_thread(p_mi, p_e);
180 bool has_vout = false;
182 if( p_input_thread )
184 vout_thread_t *p_vout;
186 p_vout = input_GetVout( p_input_thread );
187 if( p_vout )
189 has_vout = true;
190 vlc_object_release( p_vout );
192 vlc_object_release( p_input_thread );
194 return has_vout;
197 float libvlc_video_get_scale( libvlc_media_player_t *p_mp,
198 libvlc_exception_t *p_e )
200 vout_thread_t *p_vout = GetVout( p_mp, p_e );
201 if( !p_vout )
202 return 0.;
204 float f_scale = var_GetFloat( p_vout, "scale" );
205 if( var_GetBool( p_vout, "autoscale" ) )
206 f_scale = 0.;
207 vlc_object_release( p_vout );
208 return f_scale;
211 void libvlc_video_set_scale( libvlc_media_player_t *p_mp, float f_scale,
212 libvlc_exception_t *p_e )
214 vout_thread_t *p_vout = GetVout( p_mp, p_e );
215 if( !p_vout )
216 return;
218 if( f_scale != 0. )
219 var_SetFloat( p_vout, "scale", f_scale );
220 var_SetBool( p_vout, "autoscale", f_scale != 0. );
221 vlc_object_release( p_vout );
224 char *libvlc_video_get_aspect_ratio( libvlc_media_player_t *p_mi,
225 libvlc_exception_t *p_e )
227 char *psz_aspect = NULL;
228 vout_thread_t *p_vout = GetVout( p_mi, p_e );
230 if( !p_vout ) return NULL;
232 psz_aspect = var_GetNonEmptyString( p_vout, "aspect-ratio" );
233 vlc_object_release( p_vout );
234 return psz_aspect ? psz_aspect : strdup("");
237 void libvlc_video_set_aspect_ratio( libvlc_media_player_t *p_mi,
238 const char *psz_aspect, libvlc_exception_t *p_e )
240 vout_thread_t *p_vout = GetVout( p_mi, p_e );
241 int i_ret = -1;
243 if( !p_vout ) return;
245 i_ret = var_SetString( p_vout, "aspect-ratio", psz_aspect );
246 if( i_ret )
247 libvlc_exception_raise( p_e,
248 "Unexpected error while setting aspect-ratio value" );
250 vlc_object_release( p_vout );
253 int libvlc_video_get_spu( libvlc_media_player_t *p_mi,
254 libvlc_exception_t *p_e )
256 input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi, p_e );
257 vlc_value_t val_list;
258 vlc_value_t val;
259 int i_spu = -1;
260 int i_ret = -1;
261 int i;
263 if( !p_input_thread ) return -1;
265 i_ret = var_Get( p_input_thread, "spu-es", &val );
266 if( i_ret < 0 )
268 libvlc_exception_raise( p_e, "Getting subtitle information failed" );
269 vlc_object_release( p_input_thread );
270 return i_ret;
273 var_Change( p_input_thread, "spu-es", VLC_VAR_GETCHOICES, &val_list, NULL );
274 for( i = 0; i < val_list.p_list->i_count; i++ )
276 if( val.i_int == val_list.p_list->p_values[i].i_int )
278 i_spu = i;
279 break;
282 var_FreeList( &val_list, NULL );
283 vlc_object_release( p_input_thread );
284 return i_spu;
287 int libvlc_video_get_spu_count( libvlc_media_player_t *p_mi,
288 libvlc_exception_t *p_e )
290 input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi, p_e );
291 int i_spu_count;
293 if( !p_input_thread )
294 return -1;
296 i_spu_count = var_CountChoices( p_input_thread, "spu-es" );
298 vlc_object_release( p_input_thread );
299 return i_spu_count;
302 libvlc_track_description_t *
303 libvlc_video_get_spu_description( libvlc_media_player_t *p_mi,
304 libvlc_exception_t *p_e )
306 return libvlc_get_track_description( p_mi, "spu-es", p_e);
309 void libvlc_video_set_spu( libvlc_media_player_t *p_mi, int i_spu,
310 libvlc_exception_t *p_e )
312 input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi, p_e );
313 vlc_value_t val_list;
314 vlc_value_t newval;
315 int i_ret = -1;
317 if( !p_input_thread ) return;
319 var_Change( p_input_thread, "spu-es", VLC_VAR_GETCHOICES, &val_list, NULL );
321 if( val_list.p_list->i_count == 0 )
323 libvlc_exception_raise( p_e, "Subtitle value out of range" );
324 goto end;
327 if( (i_spu < 0) || (i_spu > val_list.p_list->i_count) )
329 libvlc_exception_raise( p_e, "Subtitle value out of range" );
330 goto end;
333 newval = val_list.p_list->p_values[i_spu];
334 i_ret = var_Set( p_input_thread, "spu-es", newval );
335 if( i_ret < 0 )
337 libvlc_exception_raise( p_e, "Setting subtitle value failed" );
340 end:
341 var_FreeList( &val_list, NULL );
342 vlc_object_release( p_input_thread );
345 int libvlc_video_set_subtitle_file( libvlc_media_player_t *p_mi,
346 const char *psz_subtitle,
347 libvlc_exception_t *p_e )
349 input_thread_t *p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
350 bool b_ret = false;
352 if( p_input_thread )
354 if( !input_AddSubtitle( p_input_thread, psz_subtitle, true ) )
355 b_ret = true;
356 vlc_object_release( p_input_thread );
358 return b_ret;
361 libvlc_track_description_t *
362 libvlc_video_get_title_description( libvlc_media_player_t *p_mi,
363 libvlc_exception_t * p_e )
365 return libvlc_get_track_description( p_mi, "title", p_e);
368 libvlc_track_description_t *
369 libvlc_video_get_chapter_description( libvlc_media_player_t *p_mi,
370 int i_title,
371 libvlc_exception_t *p_e )
373 char psz_title[12];
374 sprintf( psz_title, "title %2i", i_title );
375 return libvlc_get_track_description( p_mi, psz_title, p_e);
378 char *libvlc_video_get_crop_geometry( libvlc_media_player_t *p_mi,
379 libvlc_exception_t *p_e )
381 char *psz_geometry = 0;
382 vout_thread_t *p_vout = GetVout( p_mi, p_e );
384 if( !p_vout ) return 0;
386 psz_geometry = var_GetNonEmptyString( p_vout, "crop" );
387 vlc_object_release( p_vout );
388 return psz_geometry ? psz_geometry : strdup("");
391 void libvlc_video_set_crop_geometry( libvlc_media_player_t *p_mi,
392 const char *psz_geometry, libvlc_exception_t *p_e )
394 vout_thread_t *p_vout = GetVout( p_mi, p_e );
395 int i_ret = -1;
397 if( !p_vout ) return;
399 i_ret = var_SetString( p_vout, "crop", psz_geometry );
400 if( i_ret )
401 libvlc_exception_raise( p_e,
402 "Unexpected error while setting crop geometry" );
404 vlc_object_release( p_vout );
407 int libvlc_video_get_teletext( libvlc_media_player_t *p_mi,
408 libvlc_exception_t *p_e )
410 vout_thread_t *p_vout = GetVout( p_mi, p_e );
411 vlc_object_t *p_vbi;
412 int i_ret = -1;
414 if( !p_vout ) return i_ret;
416 p_vbi = (vlc_object_t *) vlc_object_find_name( p_vout, "zvbi",
417 FIND_CHILD );
418 if( p_vbi )
420 i_ret = var_GetInteger( p_vbi, "vbi-page" );
421 vlc_object_release( p_vbi );
424 vlc_object_release( p_vout );
425 return i_ret;
428 void libvlc_video_set_teletext( libvlc_media_player_t *p_mi, int i_page,
429 libvlc_exception_t *p_e )
431 vout_thread_t *p_vout = GetVout( p_mi, p_e );
432 vlc_object_t *p_vbi;
433 int i_ret = -1;
435 if( !p_vout ) return;
437 p_vbi = (vlc_object_t *) vlc_object_find_name( p_vout, "zvbi",
438 FIND_CHILD );
439 if( p_vbi )
441 i_ret = var_SetInteger( p_vbi, "vbi-page", i_page );
442 vlc_object_release( p_vbi );
443 if( i_ret )
444 libvlc_exception_raise( p_e,
445 "Unexpected error while setting teletext page" );
447 vlc_object_release( p_vout );
450 void libvlc_toggle_teletext( libvlc_media_player_t *p_mi,
451 libvlc_exception_t *p_e )
453 input_thread_t *p_input_thread;
454 vlc_object_t *p_vbi;
455 int i_ret;
457 p_input_thread = libvlc_get_input_thread(p_mi, p_e);
458 if( !p_input_thread ) return;
460 if( var_CountChoices( p_input_thread, "teletext-es" ) <= 0 )
462 vlc_object_release( p_input_thread );
463 return;
465 const bool b_selected = var_GetInteger( p_input_thread, "teletext-es" ) >= 0;
467 p_vbi = (vlc_object_t *)vlc_object_find_name( p_input_thread, "zvbi",
468 FIND_CHILD );
469 if( p_vbi )
471 if( b_selected )
473 /* FIXME Gni, why that ? */
474 i_ret = var_SetInteger( p_vbi, "vbi-page",
475 var_GetInteger( p_vbi, "vbi-page" ) );
476 if( i_ret )
477 libvlc_exception_raise( p_e,
478 "Unexpected error while setting teletext page" );
480 else
482 /* FIXME Gni^2 */
483 i_ret = var_SetBool( p_vbi, "vbi-opaque",
484 !var_GetBool( p_vbi, "vbi-opaque" ) );
485 if( i_ret )
486 libvlc_exception_raise( p_e,
487 "Unexpected error while setting teletext transparency" );
489 vlc_object_release( p_vbi );
491 else if( b_selected )
493 var_SetInteger( p_input_thread, "spu-es", -1 );
495 else
497 vlc_value_t list;
498 if( !var_Change( p_input_thread, "teletext-es", VLC_VAR_GETLIST, &list, NULL ) )
500 if( list.p_list->i_count > 0 )
501 var_SetInteger( p_input_thread, "spu-es", list.p_list->p_values[0].i_int );
503 var_FreeList( &list, NULL );
506 vlc_object_release( p_input_thread );
509 int libvlc_video_get_track_count( libvlc_media_player_t *p_mi,
510 libvlc_exception_t *p_e )
512 input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi, p_e );
513 int i_track_count;
515 if( !p_input_thread )
516 return -1;
518 i_track_count = var_CountChoices( p_input_thread, "video-es" );
520 vlc_object_release( p_input_thread );
521 return i_track_count;
524 libvlc_track_description_t *
525 libvlc_video_get_track_description( libvlc_media_player_t *p_mi,
526 libvlc_exception_t *p_e )
528 return libvlc_get_track_description( p_mi, "video-es", p_e);
531 int libvlc_video_get_track( libvlc_media_player_t *p_mi,
532 libvlc_exception_t *p_e )
534 input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi, p_e );
535 vlc_value_t val_list;
536 vlc_value_t val;
537 int i_track = -1;
538 int i_ret = -1;
539 int i;
541 if( !p_input_thread )
542 return -1;
544 i_ret = var_Get( p_input_thread, "video-es", &val );
545 if( i_ret < 0 )
547 libvlc_exception_raise( p_e, "Getting Video track information failed" );
548 vlc_object_release( p_input_thread );
549 return i_ret;
552 var_Change( p_input_thread, "video-es", VLC_VAR_GETCHOICES, &val_list, NULL );
553 for( i = 0; i < val_list.p_list->i_count; i++ )
555 if( val_list.p_list->p_values[i].i_int == val.i_int )
557 i_track = i;
558 break;
561 var_FreeList( &val_list, NULL );
562 vlc_object_release( p_input_thread );
563 return i_track;
566 void libvlc_video_set_track( libvlc_media_player_t *p_mi, int i_track,
567 libvlc_exception_t *p_e )
569 input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi, p_e );
570 vlc_value_t val_list;
571 int i_ret = -1;
572 int i;
574 if( !p_input_thread )
575 return;
577 var_Change( p_input_thread, "video-es", VLC_VAR_GETCHOICES, &val_list, NULL );
578 for( i = 0; i < val_list.p_list->i_count; i++ )
580 vlc_value_t val = val_list.p_list->p_values[i];
581 if( i_track == val.i_int )
583 i_ret = var_Set( p_input_thread, "video-es", val );
584 if( i_ret < 0 )
585 libvlc_exception_raise( p_e, "Setting video track failed" );
586 goto end;
589 libvlc_exception_raise( p_e, "Video track out of range" );
591 end:
592 var_FreeList( &val_list, NULL );
593 vlc_object_release( p_input_thread );
596 /******************************************************************************
597 * libvlc_video_set_deinterlace : enable deinterlace
598 *****************************************************************************/
599 void libvlc_video_set_deinterlace( libvlc_media_player_t *p_mi, int b_enable,
600 const char *psz_mode,
601 libvlc_exception_t *p_e )
603 vout_thread_t *p_vout = GetVout( p_mi, p_e );
605 if( !p_vout )
607 libvlc_exception_raise( p_e, "Unable to get video output" );
608 return;
611 if( b_enable )
613 /* be sure that the filter name given is supported */
614 if( !strcmp(psz_mode, "blend") || !strcmp(psz_mode, "bob")
615 || !strcmp(psz_mode, "discard") || !strcmp(psz_mode, "linear")
616 || !strcmp(psz_mode, "mean") || !strcmp(psz_mode, "x") )
618 /* set deinterlace filter chosen */
619 var_SetString( p_vout, "deinterlace", psz_mode );
621 else
623 libvlc_exception_raise( p_e, "Unsuported or bad deinterlace filter name" );
626 else
628 /* disable deinterlace filter */
629 var_SetString( p_vout, "deinterlace", "" );
632 vlc_object_release( p_vout );
635 /*****************************************************************************
636 * Marquee: FIXME: That implementation has no persistent state and requires
637 * a vout
638 *****************************************************************************/
640 static const char *get_marquee_int_option_identifier(unsigned option)
642 static const char tab[][16] =
644 "marq",
645 "marq-color",
646 "marq-opacity",
647 "marq-position",
648 "marq-refresh",
649 "marq-size",
650 "marq-timeout",
651 "marq-x",
652 "marq-y",
654 if( option >= sizeof( tab ) / sizeof( tab[0] ) )
655 return NULL;
656 return tab[option];
659 static const char *get_marquee_string_option_identifier(unsigned option)
661 static const char tab[][16] =
663 "marq-marquee",
665 if( option >= sizeof( tab ) / sizeof( tab[0] ) )
666 return NULL;
667 return tab[option];
671 static vlc_object_t *get_marquee_object( libvlc_media_player_t * p_mi )
673 libvlc_exception_t e;
674 libvlc_exception_init(&e);
675 vout_thread_t * vout = GetVout( p_mi, &e );
676 libvlc_exception_clear(&e);
677 if( !vout )
678 return NULL;
679 vlc_object_t * object = vlc_object_find_name( vout, "marq", FIND_CHILD );
680 vlc_object_release(vout);
681 return object;
684 /*****************************************************************************
685 * libvlc_video_get_marquee_option_as_int : get a marq option value
686 *****************************************************************************/
687 int libvlc_video_get_marquee_option_as_int( libvlc_media_player_t *p_mi,
688 libvlc_video_marquee_int_option_t option,
689 libvlc_exception_t *p_e )
691 const char * identifier = get_marquee_int_option_identifier(option);
692 if(!identifier)
694 libvlc_exception_raise( p_e, "This option is not available" );
695 return 0;
697 vlc_object_t * marquee = get_marquee_object(p_mi);
699 /* Handle the libvlc_marquee_Enabled separately */
700 if(option == libvlc_marquee_Enabled)
702 bool isEnabled = marquee != NULL;
703 vlc_object_release(marquee);
704 return isEnabled;
707 /* Generic case */
708 if(!identifier)
710 libvlc_exception_raise( p_e, "Marquee is not enabled" );
711 return 0;
713 int ret = var_GetInteger(marquee, identifier);
714 vlc_object_release(marquee);
715 return ret;
718 /*****************************************************************************
719 * libvlc_video_get_marquee_option_as_string : get a marq option value
720 *****************************************************************************/
721 char * libvlc_video_get_marquee_option_as_string( libvlc_media_player_t *p_mi,
722 libvlc_video_marquee_string_option_t option,
723 libvlc_exception_t *p_e )
725 const char * identifier = get_marquee_string_option_identifier(option);
726 if(!identifier)
728 libvlc_exception_raise( p_e, "This option is not available" );
729 return 0;
732 vlc_object_t * marquee = get_marquee_object(p_mi);
733 if(!marquee)
735 libvlc_exception_raise( p_e, "Marquee is not enabled" );
736 return 0;
738 char *ret = var_GetString(marquee, identifier);
739 vlc_object_release(marquee);
740 return ret;
743 /*****************************************************************************
744 * libvlc_video_set_marquee_option_as_int: enable, disable or set an int option
745 *****************************************************************************/
746 void libvlc_video_set_marquee_option_as_int( libvlc_media_player_t *p_mi,
747 libvlc_video_marquee_int_option_t option,
748 int value, libvlc_exception_t *p_e )
750 const char * identifier = get_marquee_int_option_identifier(option);
751 if(!identifier)
753 libvlc_exception_raise( p_e, "This option is not available" );
754 return;
757 /* Handle the libvlc_marquee_Enabled separately */
758 if(option == libvlc_marquee_Enabled)
760 libvlc_exception_t e;
761 libvlc_exception_init(&e);
762 vout_thread_t * vout = GetVout( p_mi, &e );
763 libvlc_exception_clear(&e);
764 if (vout)
766 vout_EnableFilter(vout, identifier, value, false);
767 vlc_object_release(vout);
769 else
771 libvlc_exception_raise( p_e, "No Vout" );
773 return;
776 vlc_object_t * marquee = get_marquee_object(p_mi);
777 if(!marquee)
779 libvlc_exception_raise( p_e, "Marquee is not enabled" );
780 return;
782 var_SetInteger(marquee, identifier, value);
783 vlc_object_release(marquee);
786 /*****************************************************************************
787 * libvlc_video_set_marquee_option_as_string: set a string option
788 *****************************************************************************/
789 void libvlc_video_set_marquee_option_as_string( libvlc_media_player_t *p_mi,
790 libvlc_video_marquee_string_option_t option,
791 const char * value,
792 libvlc_exception_t *p_e )
794 const char * identifier = get_marquee_string_option_identifier(option);
795 if(!identifier)
797 libvlc_exception_raise( p_e, "This option is not available" );
798 return;
800 vlc_object_t * marquee = get_marquee_object(p_mi);
801 if(!marquee)
803 libvlc_exception_raise( p_e, "Marquee is not enabled" );
804 return;
806 var_SetString(marquee, identifier, value);
807 vlc_object_release(marquee);