HTTP: fix possible crash in vlc_http_res_get_redirect
[vlc.git] / lib / video.c
blobf6e16ba601f5929485a00d5c53d8e57cd844f5d7
1 /*****************************************************************************
2 * video.c: libvlc new API video functions
3 *****************************************************************************
4 * Copyright (C) 2005-2010 VLC authors and VideoLAN
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 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.
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.
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 *****************************************************************************/
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
32 #include <vlc/libvlc.h>
33 #include <vlc/libvlc_renderer_discoverer.h>
34 #include <vlc/libvlc_media.h>
35 #include <vlc/libvlc_media_player.h>
37 #include <vlc_common.h>
38 #include <vlc_modules.h>
39 #include <vlc_input.h>
40 #include <vlc_vout.h>
42 #include "libvlc_internal.h"
43 #include "media_player_internal.h"
44 #include <math.h>
45 #include <assert.h>
48 * Remember to release the returned vout_thread_t.
50 static vout_thread_t **GetVouts( libvlc_media_player_t *p_mi, size_t *n )
52 input_thread_t *p_input = libvlc_get_input_thread( p_mi );
53 if( !p_input )
55 *n = 0;
56 return NULL;
59 vout_thread_t **pp_vouts;
60 if (input_Control( p_input, INPUT_GET_VOUTS, &pp_vouts, n))
62 *n = 0;
63 pp_vouts = NULL;
65 vlc_object_release (p_input);
66 return pp_vouts;
69 static vout_thread_t *GetVout (libvlc_media_player_t *mp, size_t num)
71 vout_thread_t *p_vout = NULL;
72 size_t n;
73 vout_thread_t **pp_vouts = GetVouts (mp, &n);
74 if (pp_vouts == NULL)
75 goto err;
77 if (num < n)
78 p_vout = pp_vouts[num];
80 for (size_t i = 0; i < n; i++)
81 if (i != num)
82 vlc_object_release (pp_vouts[i]);
83 free (pp_vouts);
85 if (p_vout == NULL)
86 err:
87 libvlc_printerr ("Video output not active");
88 return p_vout;
91 /**********************************************************************
92 * Exported functions
93 **********************************************************************/
95 void libvlc_set_fullscreen( libvlc_media_player_t *p_mi, int b_fullscreen )
97 /* This will work even if the video is not currently active */
98 var_SetBool (p_mi, "fullscreen", !!b_fullscreen);
100 /* Apply to current video outputs (if any) */
101 size_t n;
102 vout_thread_t **pp_vouts = GetVouts (p_mi, &n);
103 for (size_t i = 0; i < n; i++)
105 var_SetBool (pp_vouts[i], "fullscreen", b_fullscreen);
106 vlc_object_release (pp_vouts[i]);
108 free (pp_vouts);
111 int libvlc_get_fullscreen( libvlc_media_player_t *p_mi )
113 return var_GetBool (p_mi, "fullscreen");
116 void libvlc_toggle_fullscreen( libvlc_media_player_t *p_mi )
118 bool b_fullscreen = var_ToggleBool (p_mi, "fullscreen");
120 /* Apply to current video outputs (if any) */
121 size_t n;
122 vout_thread_t **pp_vouts = GetVouts (p_mi, &n);
123 for (size_t i = 0; i < n; i++)
125 vout_thread_t *p_vout = pp_vouts[i];
127 var_SetBool (p_vout, "fullscreen", b_fullscreen);
128 vlc_object_release (p_vout);
130 free (pp_vouts);
133 void libvlc_video_set_key_input( libvlc_media_player_t *p_mi, unsigned on )
135 var_SetBool (p_mi, "keyboard-events", !!on);
138 void libvlc_video_set_mouse_input( libvlc_media_player_t *p_mi, unsigned on )
140 var_SetBool (p_mi, "mouse-events", !!on);
144 libvlc_video_take_snapshot( libvlc_media_player_t *p_mi, unsigned num,
145 const char *psz_filepath,
146 unsigned int i_width, unsigned int i_height )
148 assert( psz_filepath );
150 vout_thread_t *p_vout = GetVout (p_mi, num);
151 if (p_vout == NULL)
152 return -1;
154 /* FIXME: This is not atomic. All parameters should be passed at once
155 * (obviously _not_ with var_*()). Also, the libvlc object should not be
156 * used for the callbacks: that breaks badly if there are concurrent
157 * media players in the instance. */
158 var_Create( p_vout, "snapshot-width", VLC_VAR_INTEGER );
159 var_SetInteger( p_vout, "snapshot-width", i_width);
160 var_Create( p_vout, "snapshot-height", VLC_VAR_INTEGER );
161 var_SetInteger( p_vout, "snapshot-height", i_height );
162 var_Create( p_vout, "snapshot-path", VLC_VAR_STRING );
163 var_SetString( p_vout, "snapshot-path", psz_filepath );
164 var_Create( p_vout, "snapshot-format", VLC_VAR_STRING );
165 var_SetString( p_vout, "snapshot-format", "png" );
166 var_TriggerCallback( p_vout, "video-snapshot" );
167 vlc_object_release( p_vout );
168 return 0;
171 int libvlc_video_get_size( libvlc_media_player_t *p_mi, unsigned num,
172 unsigned *restrict px, unsigned *restrict py )
174 libvlc_media_track_info_t *info;
175 int ret = -1;
176 if (!p_mi->p_md)
177 return ret;
178 int infos = libvlc_media_get_tracks_info(p_mi->p_md, &info);
179 if (infos <= 0)
180 return ret;
182 for (int i = 0; i < infos; i++)
183 if (info[i].i_type == libvlc_track_video && num-- == 0) {
184 *px = info[i].u.video.i_width;
185 *py = info[i].u.video.i_height;
186 ret = 0;
187 break;
190 free(info);
191 return ret;
194 int libvlc_video_get_height( libvlc_media_player_t *p_mi )
196 unsigned width, height;
198 if (libvlc_video_get_size (p_mi, 0, &width, &height))
199 return 0;
200 return height;
203 int libvlc_video_get_width( libvlc_media_player_t *p_mi )
205 unsigned width, height;
207 if (libvlc_video_get_size (p_mi, 0, &width, &height))
208 return 0;
209 return width;
212 int libvlc_video_get_cursor( libvlc_media_player_t *mp, unsigned num,
213 int *restrict px, int *restrict py )
215 vout_thread_t *p_vout = GetVout (mp, num);
216 if (p_vout == NULL)
217 return -1;
219 var_GetCoords (p_vout, "mouse-moved", px, py);
220 vlc_object_release (p_vout);
221 return 0;
224 unsigned libvlc_media_player_has_vout( libvlc_media_player_t *p_mi )
226 size_t n;
227 vout_thread_t **pp_vouts = GetVouts (p_mi, &n);
228 for (size_t i = 0; i < n; i++)
229 vlc_object_release (pp_vouts[i]);
230 free (pp_vouts);
231 return n;
234 float libvlc_video_get_scale( libvlc_media_player_t *mp )
236 float f_scale = var_GetFloat (mp, "zoom");
237 if (var_GetBool (mp, "autoscale"))
238 f_scale = 0.f;
239 return f_scale;
242 void libvlc_video_set_scale( libvlc_media_player_t *p_mp, float f_scale )
244 if (isfinite(f_scale) && f_scale != 0.f)
245 var_SetFloat (p_mp, "zoom", f_scale);
246 var_SetBool (p_mp, "autoscale", f_scale == 0.f);
248 /* Apply to current video outputs (if any) */
249 size_t n;
250 vout_thread_t **pp_vouts = GetVouts (p_mp, &n);
251 for (size_t i = 0; i < n; i++)
253 vout_thread_t *p_vout = pp_vouts[i];
255 if (isfinite(f_scale) && f_scale != 0.f)
256 var_SetFloat (p_vout, "zoom", f_scale);
257 var_SetBool (p_vout, "autoscale", f_scale == 0.f);
258 vlc_object_release (p_vout);
260 free (pp_vouts);
263 char *libvlc_video_get_aspect_ratio( libvlc_media_player_t *p_mi )
265 return var_GetNonEmptyString (p_mi, "aspect-ratio");
268 void libvlc_video_set_aspect_ratio( libvlc_media_player_t *p_mi,
269 const char *psz_aspect )
271 if (psz_aspect == NULL)
272 psz_aspect = "";
273 var_SetString (p_mi, "aspect-ratio", psz_aspect);
275 size_t n;
276 vout_thread_t **pp_vouts = GetVouts (p_mi, &n);
277 for (size_t i = 0; i < n; i++)
279 vout_thread_t *p_vout = pp_vouts[i];
281 var_SetString (p_vout, "aspect-ratio", psz_aspect);
282 vlc_object_release (p_vout);
284 free (pp_vouts);
287 libvlc_video_viewpoint_t *libvlc_video_new_viewpoint(void)
289 libvlc_video_viewpoint_t *p_vp = malloc(sizeof *p_vp);
290 if (unlikely(p_vp == NULL))
291 return NULL;
292 p_vp->f_yaw = p_vp->f_pitch = p_vp->f_roll = p_vp->f_field_of_view = 0.0f;
293 return p_vp;
296 int libvlc_video_update_viewpoint( libvlc_media_player_t *p_mi,
297 const libvlc_video_viewpoint_t *p_viewpoint,
298 bool b_absolute )
300 vlc_viewpoint_t update = {
301 .yaw = p_viewpoint->f_yaw,
302 .pitch = p_viewpoint->f_pitch,
303 .roll = p_viewpoint->f_roll,
304 .fov = p_viewpoint->f_field_of_view,
307 input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
308 if( p_input_thread != NULL )
310 if( input_UpdateViewpoint( p_input_thread, &update,
311 b_absolute ) != VLC_SUCCESS )
313 vlc_object_release( p_input_thread );
314 return -1;
316 vlc_object_release( p_input_thread );
317 return 0;
320 /* Save the viewpoint in case the input is not created yet */
321 if( !b_absolute )
323 p_mi->viewpoint.yaw += update.yaw;
324 p_mi->viewpoint.pitch += update.pitch;
325 p_mi->viewpoint.roll += update.roll;
326 p_mi->viewpoint.fov += update.fov;
328 else
329 p_mi->viewpoint = update;
331 vlc_viewpoint_clip( &p_mi->viewpoint );
333 return 0;
336 int libvlc_video_get_spu( libvlc_media_player_t *p_mi )
338 input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
340 if( !p_input_thread )
342 libvlc_printerr( "No active input" );
343 return -1;
346 int i_spu = var_GetInteger( p_input_thread, "spu-es" );
347 vlc_object_release( p_input_thread );
348 return i_spu;
351 int libvlc_video_get_spu_count( libvlc_media_player_t *p_mi )
353 input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
354 int i_spu_count;
356 if( !p_input_thread )
357 return 0;
359 i_spu_count = var_CountChoices( p_input_thread, "spu-es" );
360 vlc_object_release( p_input_thread );
361 return i_spu_count;
364 libvlc_track_description_t *
365 libvlc_video_get_spu_description( libvlc_media_player_t *p_mi )
367 return libvlc_get_track_description( p_mi, "spu-es" );
370 int libvlc_video_set_spu( libvlc_media_player_t *p_mi, int i_spu )
372 input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
373 vlc_value_t list;
374 int i_ret = -1;
376 if( !p_input_thread )
377 return -1;
379 var_Change (p_input_thread, "spu-es", VLC_VAR_GETCHOICES, &list, NULL);
380 for (int i = 0; i < list.p_list->i_count; i++)
382 if( i_spu == list.p_list->p_values[i].i_int )
384 if( var_SetInteger( p_input_thread, "spu-es", i_spu ) < 0 )
385 break;
386 i_ret = 0;
387 goto end;
390 libvlc_printerr( "Track identifier not found" );
391 end:
392 vlc_object_release (p_input_thread);
393 var_FreeList (&list, NULL);
394 return i_ret;
397 int libvlc_video_set_subtitle_file( libvlc_media_player_t *p_mi,
398 const char *psz_subtitle )
400 input_thread_t *p_input_thread = libvlc_get_input_thread ( p_mi );
401 bool b_ret = false;
403 if( p_input_thread )
405 if( !input_AddSubtitle( p_input_thread, psz_subtitle, true ) )
406 b_ret = true;
407 vlc_object_release( p_input_thread );
409 return b_ret;
412 int64_t libvlc_video_get_spu_delay( libvlc_media_player_t *p_mi )
414 input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
415 int64_t val = 0;
417 if( p_input_thread )
419 val = var_GetInteger( p_input_thread, "spu-delay" );
420 vlc_object_release( p_input_thread );
422 else
424 libvlc_printerr( "No active input" );
427 return val;
430 int libvlc_video_set_spu_delay( libvlc_media_player_t *p_mi,
431 int64_t i_delay )
433 input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
434 int ret = -1;
436 if( p_input_thread )
438 var_SetInteger( p_input_thread, "spu-delay", i_delay );
439 vlc_object_release( p_input_thread );
440 ret = 0;
442 else
444 libvlc_printerr( "No active input" );
447 return ret;
450 libvlc_track_description_t *
451 libvlc_video_get_title_description( libvlc_media_player_t *p_mi )
453 return libvlc_get_track_description( p_mi, "title" );
456 libvlc_track_description_t *
457 libvlc_video_get_chapter_description( libvlc_media_player_t *p_mi,
458 int i_title )
460 char psz_title[sizeof ("title ") + 3 * sizeof (int)];
461 sprintf( psz_title, "title %2u", i_title );
462 return libvlc_get_track_description( p_mi, psz_title );
465 char *libvlc_video_get_crop_geometry (libvlc_media_player_t *p_mi)
467 return var_GetNonEmptyString (p_mi, "crop");
470 void libvlc_video_set_crop_geometry( libvlc_media_player_t *p_mi,
471 const char *psz_geometry )
473 if (psz_geometry == NULL)
474 psz_geometry = "";
476 var_SetString (p_mi, "crop", psz_geometry);
478 size_t n;
479 vout_thread_t **pp_vouts = GetVouts (p_mi, &n);
481 for (size_t i = 0; i < n; i++)
483 vout_thread_t *p_vout = pp_vouts[i];
485 var_SetString (p_vout, "crop", psz_geometry);
486 vlc_object_release (p_vout);
488 free (pp_vouts);
491 int libvlc_video_get_teletext( libvlc_media_player_t *p_mi )
493 return var_GetInteger (p_mi, "vbi-page");
496 static void teletext_enable( input_thread_t *p_input_thread, bool b_enable )
498 if( b_enable )
500 vlc_value_t list;
501 if( !var_Change( p_input_thread, "teletext-es", VLC_VAR_GETCHOICES,
502 &list, NULL ) )
504 if( list.p_list->i_count > 0 )
505 var_SetInteger( p_input_thread, "spu-es",
506 list.p_list->p_values[0].i_int );
508 var_FreeList( &list, NULL );
511 else
512 var_SetInteger( p_input_thread, "spu-es", -1 );
515 void libvlc_video_set_teletext( libvlc_media_player_t *p_mi, int i_page )
517 input_thread_t *p_input_thread;
518 vlc_object_t *p_zvbi = NULL;
519 int telx;
520 bool b_key = false;
522 if( i_page >= 0 && i_page < 1000 )
523 var_SetInteger( p_mi, "vbi-page", i_page );
524 else if( i_page >= 1000 )
526 switch (i_page)
528 case libvlc_teletext_key_red:
529 case libvlc_teletext_key_green:
530 case libvlc_teletext_key_yellow:
531 case libvlc_teletext_key_blue:
532 case libvlc_teletext_key_index:
533 b_key = true;
534 break;
535 default:
536 libvlc_printerr("Invalid key action");
537 return;
540 else
542 libvlc_printerr("Invalid page number");
543 return;
546 p_input_thread = libvlc_get_input_thread( p_mi );
547 if( !p_input_thread ) return;
549 if( var_CountChoices( p_input_thread, "teletext-es" ) <= 0 )
551 vlc_object_release( p_input_thread );
552 return;
555 if( i_page == 0 )
557 teletext_enable( p_input_thread, false );
559 else
561 telx = var_GetInteger( p_input_thread, "teletext-es" );
562 if( telx >= 0 )
564 if( input_GetEsObjects( p_input_thread, telx, &p_zvbi, NULL, NULL )
565 == VLC_SUCCESS )
567 var_SetInteger( p_zvbi, "vbi-page", i_page );
568 vlc_object_release( p_zvbi );
571 else if (!b_key)
573 /* the "vbi-page" will be selected on es creation */
574 teletext_enable( p_input_thread, true );
576 else
577 libvlc_printerr("Key action sent while the teletext is disabled");
579 vlc_object_release( p_input_thread );
582 void libvlc_toggle_teletext( libvlc_media_player_t *p_mi )
584 input_thread_t *p_input_thread;
586 p_input_thread = libvlc_get_input_thread(p_mi);
587 if( !p_input_thread ) return;
589 if( var_CountChoices( p_input_thread, "teletext-es" ) <= 0 )
591 vlc_object_release( p_input_thread );
592 return;
594 const bool b_selected = var_GetInteger( p_input_thread, "teletext-es" ) >= 0;
595 teletext_enable( p_input_thread, !b_selected );
596 vlc_object_release( p_input_thread );
599 int libvlc_video_get_track_count( libvlc_media_player_t *p_mi )
601 input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
602 int i_track_count;
604 if( !p_input_thread )
605 return -1;
607 i_track_count = var_CountChoices( p_input_thread, "video-es" );
609 vlc_object_release( p_input_thread );
610 return i_track_count;
613 libvlc_track_description_t *
614 libvlc_video_get_track_description( libvlc_media_player_t *p_mi )
616 return libvlc_get_track_description( p_mi, "video-es" );
619 int libvlc_video_get_track( libvlc_media_player_t *p_mi )
621 input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
623 if( !p_input_thread )
624 return -1;
626 int id = var_GetInteger( p_input_thread, "video-es" );
627 vlc_object_release( p_input_thread );
628 return id;
631 int libvlc_video_set_track( libvlc_media_player_t *p_mi, int i_track )
633 input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
634 vlc_value_t val_list;
635 int i_ret = -1;
637 if( !p_input_thread )
638 return -1;
640 var_Change( p_input_thread, "video-es", VLC_VAR_GETCHOICES, &val_list, NULL );
641 for( int i = 0; i < val_list.p_list->i_count; i++ )
643 if( i_track == val_list.p_list->p_values[i].i_int )
645 if( var_SetInteger( p_input_thread, "video-es", i_track ) < 0 )
646 break;
647 i_ret = 0;
648 goto end;
651 libvlc_printerr( "Track identifier not found" );
652 end:
653 var_FreeList( &val_list, NULL );
654 vlc_object_release( p_input_thread );
655 return i_ret;
658 /******************************************************************************
659 * libvlc_video_set_deinterlace : enable deinterlace
660 *****************************************************************************/
661 void libvlc_video_set_deinterlace( libvlc_media_player_t *p_mi,
662 const char *psz_mode )
664 if (psz_mode == NULL)
665 psz_mode = "";
666 if (*psz_mode
667 && strcmp (psz_mode, "blend") && strcmp (psz_mode, "bob")
668 && strcmp (psz_mode, "discard") && strcmp (psz_mode, "linear")
669 && strcmp (psz_mode, "mean") && strcmp (psz_mode, "x")
670 && strcmp (psz_mode, "yadif") && strcmp (psz_mode, "yadif2x")
671 && strcmp (psz_mode, "phosphor") && strcmp (psz_mode, "ivtc"))
672 return;
674 if (*psz_mode)
676 var_SetString (p_mi, "deinterlace-mode", psz_mode);
677 var_SetInteger (p_mi, "deinterlace", 1);
679 else
680 var_SetInteger (p_mi, "deinterlace", 0);
682 size_t n;
683 vout_thread_t **pp_vouts = GetVouts (p_mi, &n);
684 for (size_t i = 0; i < n; i++)
686 vout_thread_t *p_vout = pp_vouts[i];
688 if (*psz_mode)
690 var_SetString (p_vout, "deinterlace-mode", psz_mode);
691 var_SetInteger (p_vout, "deinterlace", 1);
693 else
694 var_SetInteger (p_vout, "deinterlace", 0);
695 vlc_object_release (p_vout);
697 free (pp_vouts);
700 /* ************** */
701 /* module helpers */
702 /* ************** */
704 static int get_filter_str( vlc_object_t *p_parent, const char *psz_name,
705 bool b_add, const char **ppsz_filter_type,
706 char **ppsz_filter_value)
708 char *psz_parser;
709 char *psz_string;
710 const char *psz_filter_type;
712 module_t *p_obj = module_find( psz_name );
713 if( !p_obj )
715 msg_Err( p_parent, "Unable to find filter module \"%s\".", psz_name );
716 return VLC_EGENERIC;
719 if( module_provides( p_obj, "video filter" ) )
721 psz_filter_type = "video-filter";
723 else if( module_provides( p_obj, "sub source" ) )
725 psz_filter_type = "sub-source";
727 else if( module_provides( p_obj, "sub filter" ) )
729 psz_filter_type = "sub-filter";
731 else
733 msg_Err( p_parent, "Unknown video filter type." );
734 return VLC_EGENERIC;
737 psz_string = var_GetString( p_parent, psz_filter_type );
739 /* Todo : Use some generic chain manipulation functions */
740 if( !psz_string ) psz_string = strdup("");
742 psz_parser = strstr( psz_string, psz_name );
743 if( b_add )
745 if( !psz_parser )
747 psz_parser = psz_string;
748 if( asprintf( &psz_string, (*psz_string) ? "%s:%s" : "%s%s",
749 psz_string, psz_name ) == -1 )
751 free( psz_parser );
752 return VLC_EGENERIC;
754 free( psz_parser );
756 else
758 free( psz_string );
759 return VLC_EGENERIC;
762 else
764 if( psz_parser )
766 memmove( psz_parser, psz_parser + strlen(psz_name) +
767 (*(psz_parser + strlen(psz_name)) == ':' ? 1 : 0 ),
768 strlen(psz_parser + strlen(psz_name)) + 1 );
770 /* Remove trailing : : */
771 if( *(psz_string+strlen(psz_string ) -1 ) == ':' )
772 *(psz_string+strlen(psz_string ) -1 ) = '\0';
774 else
776 free( psz_string );
777 return VLC_EGENERIC;
781 *ppsz_filter_type = psz_filter_type;
782 *ppsz_filter_value = psz_string;
783 return VLC_SUCCESS;
786 static bool find_sub_source_by_name( libvlc_media_player_t *p_mi, const char *restrict name )
788 vout_thread_t *vout = GetVout( p_mi, 0 );
789 if (!vout)
790 return false;
792 char *psz_sources = var_GetString( vout, "sub-source" );
793 if( !psz_sources )
795 libvlc_printerr( "%s not enabled", name );
796 vlc_object_release( vout );
797 return false;
800 /* Find 'name' */
801 char *p = strstr( psz_sources, name );
802 free( psz_sources );
803 vlc_object_release( vout );
804 return (p != NULL);
807 typedef const struct {
808 const char name[20];
809 unsigned type;
810 } opt_t;
812 static void
813 set_value( libvlc_media_player_t *p_mi, const char *restrict name,
814 const opt_t *restrict opt, unsigned i_expected_type,
815 const vlc_value_t *val, bool b_sub_source )
817 if( !opt ) return;
819 int i_type = opt->type;
820 vlc_value_t new_val = *val;
821 const char *psz_opt_name = opt->name;
822 switch( i_type )
824 case 0: /* the enabler */
826 int i_ret = get_filter_str( VLC_OBJECT( p_mi ), opt->name, val->i_int,
827 &psz_opt_name, &new_val.psz_string );
828 if( i_ret != VLC_SUCCESS )
829 return;
830 i_type = VLC_VAR_STRING;
831 break;
833 case VLC_VAR_INTEGER:
834 case VLC_VAR_FLOAT:
835 case VLC_VAR_STRING:
836 if( i_expected_type != opt->type )
838 libvlc_printerr( "Invalid argument to %s", name );
839 return;
841 break;
842 default:
843 libvlc_printerr( "Invalid argument to %s", name );
844 return;
847 /* Set the new value to the media player. Next vouts created from this
848 * media player will inherit this new value */
849 var_SetChecked( p_mi, psz_opt_name, i_type, new_val );
851 /* Set the new value to every loaded vouts */
852 size_t i_vout_count;
853 vout_thread_t **pp_vouts = GetVouts( p_mi, &i_vout_count );
854 for( size_t i = 0; i < i_vout_count; ++i )
856 var_SetChecked( pp_vouts[i], psz_opt_name, i_type, new_val );
857 if( b_sub_source )
858 var_TriggerCallback( pp_vouts[i], "sub-source" );
859 vlc_object_release( pp_vouts[i] );
862 if( opt->type == 0 )
863 free( new_val.psz_string );
866 static int
867 get_int( libvlc_media_player_t *p_mi, const char *restrict name,
868 const opt_t *restrict opt )
870 if( !opt ) return 0;
872 switch( opt->type )
874 case 0: /* the enabler */
876 bool b_enabled = find_sub_source_by_name( p_mi, name );
877 return b_enabled ? 1 : 0;
879 case VLC_VAR_INTEGER:
880 return var_GetInteger(p_mi, opt->name);
881 case VLC_VAR_FLOAT:
882 return lroundf(var_GetFloat(p_mi, opt->name));
883 default:
884 libvlc_printerr( "Invalid argument to %s in %s", name, "get int" );
885 return 0;
889 static float
890 get_float( libvlc_media_player_t *p_mi, const char *restrict name,
891 const opt_t *restrict opt )
893 if( !opt ) return 0.0;
895 if( opt->type != VLC_VAR_FLOAT )
897 libvlc_printerr( "Invalid argument to %s in %s", name, "get float" );
898 return 0.0;
901 return var_GetFloat( p_mi, opt->name );
904 static char *
905 get_string( libvlc_media_player_t *p_mi, const char *restrict name,
906 const opt_t *restrict opt )
908 if( !opt ) return NULL;
910 if( opt->type != VLC_VAR_STRING )
912 libvlc_printerr( "Invalid argument to %s in %s", name, "get string" );
913 return NULL;
916 return var_GetString( p_mi, opt->name );
919 static const opt_t *
920 marq_option_bynumber(unsigned option)
922 static const opt_t optlist[] =
924 { "marq", 0 },
925 { "marq-marquee", VLC_VAR_STRING },
926 { "marq-color", VLC_VAR_INTEGER },
927 { "marq-opacity", VLC_VAR_INTEGER },
928 { "marq-position", VLC_VAR_INTEGER },
929 { "marq-refresh", VLC_VAR_INTEGER },
930 { "marq-size", VLC_VAR_INTEGER },
931 { "marq-timeout", VLC_VAR_INTEGER },
932 { "marq-x", VLC_VAR_INTEGER },
933 { "marq-y", VLC_VAR_INTEGER },
935 enum { num_opts = sizeof(optlist) / sizeof(*optlist) };
937 const opt_t *r = option < num_opts ? optlist+option : NULL;
938 if( !r )
939 libvlc_printerr( "Unknown marquee option" );
940 return r;
943 /*****************************************************************************
944 * libvlc_video_get_marquee_int : get a marq option value
945 *****************************************************************************/
946 int libvlc_video_get_marquee_int( libvlc_media_player_t *p_mi,
947 unsigned option )
949 return get_int( p_mi, "marq", marq_option_bynumber(option) );
952 /*****************************************************************************
953 * libvlc_video_get_marquee_string : get a marq option value
954 *****************************************************************************/
955 char * libvlc_video_get_marquee_string( libvlc_media_player_t *p_mi,
956 unsigned option )
958 return get_string( p_mi, "marq", marq_option_bynumber(option) );
961 /*****************************************************************************
962 * libvlc_video_set_marquee_int: enable, disable or set an int option
963 *****************************************************************************/
964 void libvlc_video_set_marquee_int( libvlc_media_player_t *p_mi,
965 unsigned option, int value )
967 set_value( p_mi, "marq", marq_option_bynumber(option), VLC_VAR_INTEGER,
968 &(vlc_value_t) { .i_int = value }, true );
971 /*****************************************************************************
972 * libvlc_video_set_marquee_string: set a string option
973 *****************************************************************************/
974 void libvlc_video_set_marquee_string( libvlc_media_player_t *p_mi,
975 unsigned option, const char * value )
977 set_value( p_mi, "marq", marq_option_bynumber(option), VLC_VAR_STRING,
978 &(vlc_value_t){ .psz_string = (char *)value }, true );
982 /* logo module support */
984 static const opt_t *
985 logo_option_bynumber( unsigned option )
987 static const opt_t vlogo_optlist[] =
988 /* depends on libvlc_video_logo_option_t */
990 { "logo", 0 },
991 { "logo-file", VLC_VAR_STRING },
992 { "logo-x", VLC_VAR_INTEGER },
993 { "logo-y", VLC_VAR_INTEGER },
994 { "logo-delay", VLC_VAR_INTEGER },
995 { "logo-repeat", VLC_VAR_INTEGER },
996 { "logo-opacity", VLC_VAR_INTEGER },
997 { "logo-position", VLC_VAR_INTEGER },
999 enum { num_vlogo_opts = sizeof(vlogo_optlist) / sizeof(*vlogo_optlist) };
1001 const opt_t *r = option < num_vlogo_opts ? vlogo_optlist+option : NULL;
1002 if( !r )
1003 libvlc_printerr( "Unknown logo option" );
1004 return r;
1007 void libvlc_video_set_logo_string( libvlc_media_player_t *p_mi,
1008 unsigned option, const char *psz_value )
1010 set_value( p_mi,"logo",logo_option_bynumber(option), VLC_VAR_STRING,
1011 &(vlc_value_t){ .psz_string = (char *)psz_value }, true );
1015 void libvlc_video_set_logo_int( libvlc_media_player_t *p_mi,
1016 unsigned option, int value )
1018 set_value( p_mi, "logo", logo_option_bynumber(option), VLC_VAR_INTEGER,
1019 &(vlc_value_t) { .i_int = value }, true );
1023 int libvlc_video_get_logo_int( libvlc_media_player_t *p_mi,
1024 unsigned option )
1026 return get_int( p_mi, "logo", logo_option_bynumber(option) );
1030 /* adjust module support */
1033 static const opt_t *
1034 adjust_option_bynumber( unsigned option )
1036 static const opt_t optlist[] =
1038 { "adjust", 0 },
1039 { "contrast", VLC_VAR_FLOAT },
1040 { "brightness", VLC_VAR_FLOAT },
1041 { "hue", VLC_VAR_FLOAT },
1042 { "saturation", VLC_VAR_FLOAT },
1043 { "gamma", VLC_VAR_FLOAT },
1045 enum { num_opts = sizeof(optlist) / sizeof(*optlist) };
1047 const opt_t *r = option < num_opts ? optlist+option : NULL;
1048 if( !r )
1049 libvlc_printerr( "Unknown adjust option" );
1050 return r;
1054 void libvlc_video_set_adjust_int( libvlc_media_player_t *p_mi,
1055 unsigned option, int value )
1057 set_value( p_mi, "adjust", adjust_option_bynumber(option), VLC_VAR_INTEGER,
1058 &(vlc_value_t) { .i_int = value }, false );
1062 int libvlc_video_get_adjust_int( libvlc_media_player_t *p_mi,
1063 unsigned option )
1065 return get_int( p_mi, "adjust", adjust_option_bynumber(option) );
1069 void libvlc_video_set_adjust_float( libvlc_media_player_t *p_mi,
1070 unsigned option, float value )
1072 set_value( p_mi, "adjust", adjust_option_bynumber(option), VLC_VAR_FLOAT,
1073 &(vlc_value_t) { .f_float = value }, false );
1077 float libvlc_video_get_adjust_float( libvlc_media_player_t *p_mi,
1078 unsigned option )
1080 return get_float( p_mi, "adjust", adjust_option_bynumber(option) );