1 /*****************************************************************************
2 * video.c: libvlc new API video functions
3 *****************************************************************************
4 * Copyright (C) 2005 the VideoLAN team
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 *****************************************************************************/
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>
40 #include "media_player_internal.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
;
54 p_vout
= input_GetVout( p_input
);
57 libvlc_exception_raise( p_exception
, "No active video output" );
59 vlc_object_release( p_input
);
64 /**********************************************************************
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 */
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
);
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
);
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
);
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 */
122 libvlc_exception_raise( p_e
, "filepath is null" );
125 /* We must have an input */
126 if( !p_mi
->p_input_thread
)
128 libvlc_exception_raise( p_e
, "Input does not exist" );
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
)
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
);
161 int libvlc_video_get_width( libvlc_media_player_t
*p_mi
,
162 libvlc_exception_t
*p_e
)
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
);
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;
184 vout_thread_t
*p_vout
;
186 p_vout
= input_GetVout( p_input_thread
);
190 vlc_object_release( p_vout
);
192 vlc_object_release( p_input_thread
);
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
);
204 float f_scale
= var_GetFloat( p_vout
, "scale" );
205 if( var_GetBool( p_vout
, "autoscale" ) )
207 vlc_object_release( p_vout
);
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
);
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
);
243 if( !p_vout
) return;
245 i_ret
= var_SetString( p_vout
, "aspect-ratio", psz_aspect
);
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
;
263 if( !p_input_thread
) return -1;
265 i_ret
= var_Get( p_input_thread
, "spu-es", &val
);
268 libvlc_exception_raise( p_e
, "Getting subtitle information failed" );
269 vlc_object_release( p_input_thread
);
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
)
282 var_FreeList( &val_list
, NULL
);
283 vlc_object_release( p_input_thread
);
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
);
293 if( !p_input_thread
)
296 i_spu_count
= var_CountChoices( p_input_thread
, "spu-es" );
298 vlc_object_release( p_input_thread
);
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
;
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" );
327 if( (i_spu
< 0) || (i_spu
> val_list
.p_list
->i_count
) )
329 libvlc_exception_raise( p_e
, "Subtitle value out of range" );
333 newval
= val_list
.p_list
->p_values
[i_spu
];
334 i_ret
= var_Set( p_input_thread
, "spu-es", newval
);
337 libvlc_exception_raise( p_e
, "Setting subtitle value failed" );
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
);
354 if( !input_AddSubtitle( p_input_thread
, psz_subtitle
, true ) )
356 vlc_object_release( p_input_thread
);
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
,
371 libvlc_exception_t
*p_e
)
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
);
397 if( !p_vout
) return;
399 i_ret
= var_SetString( p_vout
, "crop", psz_geometry
);
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
);
414 if( !p_vout
) return i_ret
;
416 p_vbi
= (vlc_object_t
*) vlc_object_find_name( p_vout
, "zvbi",
420 i_ret
= var_GetInteger( p_vbi
, "vbi-page" );
421 vlc_object_release( p_vbi
);
424 vlc_object_release( p_vout
);
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
);
435 if( !p_vout
) return;
437 p_vbi
= (vlc_object_t
*) vlc_object_find_name( p_vout
, "zvbi",
441 i_ret
= var_SetInteger( p_vbi
, "vbi-page", i_page
);
442 vlc_object_release( p_vbi
);
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
;
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
);
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",
473 /* FIXME Gni, why that ? */
474 i_ret
= var_SetInteger( p_vbi
, "vbi-page",
475 var_GetInteger( p_vbi
, "vbi-page" ) );
477 libvlc_exception_raise( p_e
,
478 "Unexpected error while setting teletext page" );
483 i_ret
= var_SetBool( p_vbi
, "vbi-opaque",
484 !var_GetBool( p_vbi
, "vbi-opaque" ) );
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 );
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
);
515 if( !p_input_thread
)
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
;
541 if( !p_input_thread
)
544 i_ret
= var_Get( p_input_thread
, "video-es", &val
);
547 libvlc_exception_raise( p_e
, "Getting Video track information failed" );
548 vlc_object_release( p_input_thread
);
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
)
561 var_FreeList( &val_list
, NULL
);
562 vlc_object_release( p_input_thread
);
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
;
574 if( !p_input_thread
)
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
);
585 libvlc_exception_raise( p_e
, "Setting video track failed" );
589 libvlc_exception_raise( p_e
, "Video track out of range" );
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
);
607 libvlc_exception_raise( p_e
, "Unable to get video output" );
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
);
623 libvlc_exception_raise( p_e
, "Unsuported or bad deinterlace filter name" );
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
638 *****************************************************************************/
640 static const char *get_marquee_int_option_identifier(unsigned option
)
642 static const char tab
[][16] =
654 if( option
>= sizeof( tab
) / sizeof( tab
[0] ) )
659 static const char *get_marquee_string_option_identifier(unsigned option
)
661 static const char tab
[][16] =
665 if( option
>= sizeof( tab
) / sizeof( tab
[0] ) )
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
);
679 vlc_object_t
* object
= vlc_object_find_name( vout
, "marq", FIND_CHILD
);
680 vlc_object_release(vout
);
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
);
694 libvlc_exception_raise( p_e
, "This option is not available" );
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
);
710 libvlc_exception_raise( p_e
, "Marquee is not enabled" );
713 int ret
= var_GetInteger(marquee
, identifier
);
714 vlc_object_release(marquee
);
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
);
728 libvlc_exception_raise( p_e
, "This option is not available" );
732 vlc_object_t
* marquee
= get_marquee_object(p_mi
);
735 libvlc_exception_raise( p_e
, "Marquee is not enabled" );
738 char *ret
= var_GetString(marquee
, identifier
);
739 vlc_object_release(marquee
);
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
);
753 libvlc_exception_raise( p_e
, "This option is not available" );
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
);
766 vout_EnableFilter(vout
, identifier
, value
, false);
767 vlc_object_release(vout
);
771 libvlc_exception_raise( p_e
, "No Vout" );
776 vlc_object_t
* marquee
= get_marquee_object(p_mi
);
779 libvlc_exception_raise( p_e
, "Marquee is not enabled" );
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
,
792 libvlc_exception_t
*p_e
)
794 const char * identifier
= get_marquee_string_option_identifier(option
);
797 libvlc_exception_raise( p_e
, "This option is not available" );
800 vlc_object_t
* marquee
= get_marquee_object(p_mi
);
803 libvlc_exception_raise( p_e
, "Marquee is not enabled" );
806 var_SetString(marquee
, identifier
, value
);
807 vlc_object_release(marquee
);