]> git.sesse.net Git - vlc/blob - src/control/video.c
ba60fe07b26a5c72aa10c0dad773bc16299aa9ac
[vlc] / src / control / video.c
1 /*****************************************************************************
2  * video.c: libvlc new API video functions
3  *****************************************************************************
4  * Copyright (C) 2005 the VideoLAN team
5  *
6  * $Id$
7  *
8  * Authors: Cl�ent 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 #include "libvlc_internal.h"
29
30 #include <vlc/libvlc.h>
31 #include <vlc_input.h>
32 #include <vlc_vout.h>
33
34 /*
35  * Remember to release the returned vout_thread_t.
36  */
37 static vout_thread_t *GetVout( libvlc_media_player_t *p_mi,
38                                libvlc_exception_t *p_exception )
39 {
40     input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi, p_exception );
41     vout_thread_t *p_vout = NULL;
42
43     if( p_input_thread )
44     {
45         p_vout = vlc_object_find( p_input_thread, VLC_OBJECT_VOUT, FIND_CHILD );
46         if( !p_vout )
47         {
48             libvlc_exception_raise( p_exception, "No active video output" );
49         }
50         vlc_object_release( p_input_thread );
51     }
52     return p_vout;
53 }
54
55 /**********************************************************************
56  * Exported functions
57  **********************************************************************/
58
59 void libvlc_set_fullscreen( libvlc_media_player_t *p_mi, int b_fullscreen,
60                             libvlc_exception_t *p_e )
61 {
62     /* We only work on the first vout */
63     vout_thread_t *p_vout1 = GetVout( p_mi, p_e );
64     vlc_value_t val; int i_ret;
65
66     /* GetVout will raise the exception for us */
67     if( !p_vout1 )
68     {
69         return;
70     }
71
72     if( b_fullscreen ) val.b_bool = true;
73     else               val.b_bool = false;
74
75     i_ret = var_Set( p_vout1, "fullscreen", val );
76     if( i_ret )
77         libvlc_exception_raise( p_e,
78                         "Unexpected error while setting fullscreen value" );
79
80     vlc_object_release( p_vout1 );
81 }
82
83 int libvlc_get_fullscreen( libvlc_media_player_t *p_mi,
84                             libvlc_exception_t *p_e )
85 {
86     /* We only work on the first vout */
87     vout_thread_t *p_vout1 = GetVout( p_mi, p_e );
88     vlc_value_t val; int i_ret;
89
90     /* GetVout will raise the exception for us */
91     if( !p_vout1 )
92         return 0;
93
94     i_ret = var_Get( p_vout1, "fullscreen", &val );
95     if( i_ret )
96         libvlc_exception_raise( p_e,
97                         "Unexpected error while looking up fullscreen value" );
98
99     return val.b_bool == true ? 1 : 0;
100 }
101
102 void libvlc_toggle_fullscreen( libvlc_media_player_t *p_mi,
103                                libvlc_exception_t *p_e )
104 {
105     /* We only work on the first vout */
106     vout_thread_t *p_vout1 = GetVout( p_mi, p_e );
107     vlc_value_t val; int i_ret;
108
109     /* GetVout will raise the exception for us */
110     if( !p_vout1 )
111         return;
112
113     i_ret = var_Get( p_vout1, "fullscreen", &val );
114     if( i_ret )
115         libvlc_exception_raise( p_e,
116                         "Unexpected error while looking up fullscreen value" );
117
118     val.b_bool = !val.b_bool;
119     i_ret = var_Set( p_vout1, "fullscreen", val );
120     if( i_ret )
121         libvlc_exception_raise( p_e,
122                         "Unexpected error while setting fullscreen value" );
123
124     vlc_object_release( p_vout1 );
125 }
126
127 void
128 libvlc_video_take_snapshot( libvlc_media_player_t *p_mi, char *psz_filepath,
129         unsigned int i_width, unsigned int i_height, libvlc_exception_t *p_e )
130 {
131     vout_thread_t *p_vout = GetVout( p_mi, p_e );
132     input_thread_t *p_input_thread;
133
134     /* GetVout will raise the exception for us */
135     if( !p_vout )
136     {
137         return;
138     }
139
140     if( !psz_filepath )
141     {
142         libvlc_exception_raise( p_e, "filepath is null" );
143         return;
144     }
145
146     var_SetInteger( p_vout, "snapshot-width", i_width );
147     var_SetInteger( p_vout, "snapshot-height", i_height );
148
149     p_input_thread = p_mi->p_input_thread;
150     if( !p_mi->p_input_thread )
151     {
152         libvlc_exception_raise( p_e, "Input does not exist" );
153         return;
154     }
155
156     var_SetString( p_vout, "snapshot-path", psz_filepath );
157     var_SetString( p_vout, "snapshot-format", "png" );
158
159     vout_Control( p_vout, VOUT_SNAPSHOT );
160     vlc_object_release( p_vout );
161 }
162
163 int libvlc_video_get_height( libvlc_media_player_t *p_mi,
164                              libvlc_exception_t *p_e )
165 {
166     vout_thread_t *p_vout1 = GetVout( p_mi, p_e );
167     if( !p_vout1 )
168         return 0;
169
170     vlc_object_release( p_vout1 );
171
172     return p_vout1->i_window_height;
173 }
174
175 int libvlc_video_get_width( libvlc_media_player_t *p_mi,
176                             libvlc_exception_t *p_e )
177 {
178     vout_thread_t *p_vout1 = GetVout( p_mi, p_e );
179     if( !p_vout1 )
180         return 0;
181
182     vlc_object_release( p_vout1 );
183
184     return p_vout1->i_window_width;
185 }
186
187 int libvlc_media_player_has_vout( libvlc_media_player_t *p_mi,
188                                      libvlc_exception_t *p_e )
189 {
190     input_thread_t *p_input_thread = libvlc_get_input_thread(p_mi, p_e);
191     bool has_vout = false;
192
193     if( p_input_thread )
194     {
195         vout_thread_t *p_vout;
196
197         p_vout = vlc_object_find( p_input_thread, VLC_OBJECT_VOUT, FIND_CHILD );
198         if( p_vout )
199         {
200             has_vout = true;
201             vlc_object_release( p_vout );
202         }
203         vlc_object_release( p_input_thread );
204     }
205     return has_vout;
206 }
207
208 int libvlc_video_reparent( libvlc_media_player_t *p_mi, libvlc_drawable_t d,
209                            libvlc_exception_t *p_e )
210 {
211     vout_thread_t *p_vout = GetVout( p_mi, p_e );
212
213     if( p_vout )
214     {
215         vout_Control( p_vout , VOUT_REPARENT, d);
216         vlc_object_release( p_vout );
217     }
218     return 0;
219 }
220
221 void libvlc_video_resize( libvlc_media_player_t *p_mi, int width, int height, libvlc_exception_t *p_e )
222 {
223     vout_thread_t *p_vout = GetVout( p_mi, p_e );
224     if( p_vout )
225     {
226         vout_Control( p_vout, VOUT_SET_SIZE, width, height );
227         vlc_object_release( p_vout );
228     }
229 }
230
231 void libvlc_video_redraw_rectangle( libvlc_media_player_t *p_mi,
232                            const libvlc_rectangle_t *area,
233                            libvlc_exception_t *p_e )
234 {
235     if( (NULL != area)
236      && ((area->bottom - area->top) > 0)
237      && ((area->right - area->left) > 0) )
238     {
239         vout_thread_t *p_vout = GetVout( p_mi, p_e );
240         if( p_vout )
241         {
242             /* tell running vout to redraw area */
243             vout_Control( p_vout , VOUT_REDRAW_RECT,
244                                area->top, area->left, area->bottom, area->right );
245             vlc_object_release( p_vout );
246         }
247     }
248 }
249
250 /* global video settings */
251
252 void libvlc_video_set_parent( libvlc_instance_t *p_instance, libvlc_drawable_t d,
253                               libvlc_exception_t *p_e )
254 {
255     /* set as default for future vout instances */
256     var_SetInteger(p_instance->p_libvlc_int, "drawable", (int)d);
257
258     if( libvlc_playlist_isplaying(p_instance, p_e) )
259     {
260         libvlc_media_player_t *p_mi = libvlc_playlist_get_media_player(p_instance, p_e);
261         if( p_mi )
262         {
263             vout_thread_t *p_vout = GetVout( p_mi, p_e );
264             if( p_vout )
265             {
266                 /* tell running vout to re-parent */
267                 vout_Control( p_vout , VOUT_REPARENT, d);
268                 vlc_object_release( p_vout );
269             }
270             libvlc_media_player_release(p_mi);
271         }
272     }
273 }
274
275 libvlc_drawable_t libvlc_video_get_parent( libvlc_instance_t *p_instance, libvlc_exception_t *p_e )
276 {
277     VLC_UNUSED(p_e);
278
279     libvlc_drawable_t result;
280  
281     result = var_GetInteger( p_instance->p_libvlc_int, "drawable" );
282  
283     return result;
284 }
285
286
287 void libvlc_video_set_size( libvlc_instance_t *p_instance, int width, int height,
288                            libvlc_exception_t *p_e )
289 {
290     /* set as default for future vout instances */
291     config_PutInt(p_instance->p_libvlc_int, "width", width);
292     config_PutInt(p_instance->p_libvlc_int, "height", height);
293
294     if( libvlc_playlist_isplaying(p_instance, p_e) )
295     {
296         libvlc_media_player_t *p_mi = libvlc_playlist_get_media_player(p_instance, p_e);
297         if( p_mi )
298         {
299             vout_thread_t *p_vout = GetVout( p_mi, p_e );
300             if( p_vout )
301             {
302                 /* tell running vout to re-size */
303                 vout_Control( p_vout , VOUT_SET_SIZE, width, height);
304                 vlc_object_release( p_vout );
305             }
306             libvlc_media_player_release(p_mi);
307         }
308     }
309 }
310
311 void libvlc_video_set_viewport( libvlc_instance_t *p_instance,
312                             const libvlc_rectangle_t *view, const libvlc_rectangle_t *clip,
313                            libvlc_exception_t *p_e )
314 {
315     if( NULL == view )
316     {
317         libvlc_exception_raise( p_e, "viewport is NULL" );
318     }
319
320     /* if clip is NULL, then use view rectangle as clip */
321     if( NULL == clip )
322         clip = view;
323
324     /* set as default for future vout instances */
325     var_SetInteger( p_instance->p_libvlc_int, "drawable-view-top", view->top );
326     var_SetInteger( p_instance->p_libvlc_int, "drawable-view-left", view->left );
327     var_SetInteger( p_instance->p_libvlc_int, "drawable-view-bottom", view->bottom );
328     var_SetInteger( p_instance->p_libvlc_int, "drawable-view-right", view->right );
329     var_SetInteger( p_instance->p_libvlc_int, "drawable-clip-top", clip->top );
330     var_SetInteger( p_instance->p_libvlc_int, "drawable-clip-left", clip->left );
331     var_SetInteger( p_instance->p_libvlc_int, "drawable-clip-bottom", clip->bottom );
332     var_SetInteger( p_instance->p_libvlc_int, "drawable-clip-right", clip->right );
333
334     if( libvlc_playlist_isplaying(p_instance, p_e) )
335     {
336         libvlc_media_player_t *p_mi = libvlc_playlist_get_media_player(p_instance, p_e);
337         if( p_mi )
338         {
339             vout_thread_t *p_vout = GetVout( p_mi, p_e );
340             if( p_vout )
341             {
342                 /* change viewport for running vout */
343                 vout_Control( p_vout , VOUT_SET_VIEWPORT,
344                                    view->top, view->left, view->bottom, view->right,
345                                    clip->top, clip->left, clip->bottom, clip->right );
346                 vlc_object_release( p_vout );
347             }
348             libvlc_media_player_release(p_mi);
349         }
350     }
351 }
352
353 char *libvlc_video_get_aspect_ratio( libvlc_media_player_t *p_mi,
354                                      libvlc_exception_t *p_e )
355 {
356     char *psz_aspect = 0;
357     vout_thread_t *p_vout = GetVout( p_mi, p_e );
358
359     if( !p_vout )
360         return 0;
361
362     psz_aspect = var_GetNonEmptyString( p_vout, "aspect-ratio" );
363     vlc_object_release( p_vout );
364     return psz_aspect ? psz_aspect : strdup("");
365 }
366
367 void libvlc_video_set_aspect_ratio( libvlc_media_player_t *p_mi,
368                                     char *psz_aspect, libvlc_exception_t *p_e )
369 {
370     vout_thread_t *p_vout = GetVout( p_mi, p_e );
371     int i_ret = -1;
372
373     if( !p_vout )
374         return;
375
376     i_ret = var_SetString( p_vout, "aspect-ratio", psz_aspect );
377     if( i_ret )
378         libvlc_exception_raise( p_e,
379                         "Unexpected error while setting aspect-ratio value" );
380
381     vlc_object_release( p_vout );
382 }
383
384 int libvlc_video_get_spu( libvlc_media_player_t *p_mi,
385                           libvlc_exception_t *p_e )
386 {
387     input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi, p_e );
388     vlc_value_t val_list;
389     vlc_value_t val;
390     int i_spu = -1;
391     int i_ret = -1;
392     int i;
393
394     if( !p_input_thread )
395         return -1;
396
397     i_ret = var_Get( p_input_thread, "spu-es", &val );
398     if( i_ret < 0 )
399     {
400         libvlc_exception_raise( p_e, "Getting subtitle information failed" );
401         vlc_object_release( p_input_thread );
402         return i_ret;
403     }
404
405     var_Change( p_input_thread, "spu-es", VLC_VAR_GETCHOICES, &val_list, NULL );
406     for( i = 0; i < val_list.p_list->i_count; i++ )
407     {
408         vlc_value_t spu_val = val_list.p_list->p_values[i];
409         if( val.i_int == spu_val.i_int )
410         {
411             i_spu = i;
412             break;
413         }
414     }
415     vlc_object_release( p_input_thread );
416     return i_spu;
417 }
418
419 void libvlc_video_set_spu( libvlc_media_player_t *p_mi, int i_spu,
420                            libvlc_exception_t *p_e )
421 {
422     input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi, p_e );
423     vlc_value_t val_list;
424     int i_ret = -1;
425     int i;
426
427     if( !p_input_thread )
428         return;
429
430     var_Change( p_input_thread, "spu-es", VLC_VAR_GETCHOICES, &val_list, NULL );
431     for( i = 0; i < val_list.p_list->i_count; i++ )
432     {
433         vlc_value_t val = val_list.p_list->p_values[i];
434         if( i_spu == i )
435         {
436             vlc_value_t new_val;
437
438             new_val.i_int = val.i_int;
439             i_ret = var_Set( p_input_thread, "spu-es", new_val );
440             if( i_ret < 0 )
441             {
442                 libvlc_exception_raise( p_e, "Setting subtitle value failed" );
443             }
444             vlc_object_release( p_input_thread );
445             return;
446         }
447     }
448     libvlc_exception_raise( p_e, "Subtitle value out of range" );
449     vlc_object_release( p_input_thread );
450 }
451
452 int libvlc_video_set_subtitle_file( libvlc_media_player_t *p_mi,
453                                     char *psz_subtitle,
454                                     libvlc_exception_t *p_e )
455 {
456     input_thread_t *p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
457     bool b_ret = false;
458
459     if( p_input_thread )
460     {
461         if( input_AddSubtitles( p_input_thread, psz_subtitle, true ) )
462             b_ret = true;
463         vlc_object_release( p_input_thread );
464     }
465     return b_ret;
466 }
467
468 char *libvlc_video_get_crop_geometry( libvlc_media_player_t *p_mi,
469                                    libvlc_exception_t *p_e )
470 {
471     char *psz_geometry = 0;
472     vout_thread_t *p_vout = GetVout( p_mi, p_e );
473
474     if( !p_vout )
475         return 0;
476
477     psz_geometry = var_GetNonEmptyString( p_vout, "crop" );
478     vlc_object_release( p_vout );
479     return psz_geometry ? psz_geometry : strdup("");
480 }
481
482 void libvlc_video_set_crop_geometry( libvlc_media_player_t *p_mi,
483                                     char *psz_geometry, libvlc_exception_t *p_e )
484 {
485     vout_thread_t *p_vout = GetVout( p_mi, p_e );
486     int i_ret = -1;
487
488     if( !p_vout )
489         return;
490
491     i_ret = var_SetString( p_vout, "crop", psz_geometry );
492     if( i_ret )
493         libvlc_exception_raise( p_e,
494                         "Unexpected error while setting crop geometry" );
495
496     vlc_object_release( p_vout );
497 }
498
499 int libvlc_video_get_teletext( libvlc_media_player_t *p_mi,
500                                libvlc_exception_t *p_e )
501 {
502     vout_thread_t *p_vout = GetVout( p_mi, p_e );
503     vlc_object_t *p_vbi;
504     int i_ret = -1;
505
506     if( !p_vout )
507         return i_ret;
508
509     p_vbi = (vlc_object_t *) vlc_object_find_name( p_vout, "zvbi",
510                                                    FIND_ANYWHERE );
511     if( p_vbi )
512     {
513         i_ret = var_GetInteger( p_vbi, "vbi-page" );
514         vlc_object_release( p_vbi );
515     }
516
517     vlc_object_release( p_vout );
518     return i_ret;
519 }
520
521 void libvlc_video_set_teletext( libvlc_media_player_t *p_mi, int i_page,
522                                 libvlc_exception_t *p_e )
523 {
524     vout_thread_t *p_vout = GetVout( p_mi, p_e );
525     vlc_object_t *p_vbi;
526     int i_ret = -1;
527
528     if( !p_vout )
529         return;
530
531     p_vbi = (vlc_object_t *) vlc_object_find_name( p_vout, "zvbi",
532                                                    FIND_ANYWHERE );
533     if( p_vbi )
534     {
535         i_ret = var_SetInteger( p_vbi, "vbi-page", i_page );
536         vlc_object_release( p_vbi );
537     }
538     if( i_ret )
539         libvlc_exception_raise( p_e,
540                         "Unexpected error while setting teletext page" );
541     vlc_object_release( p_vout );
542 }
543
544 void libvlc_toggle_teletext( libvlc_media_player_t *p_mi,
545                              libvlc_exception_t *p_e )
546 {
547     /* We only work on the first vout */
548     vout_thread_t *p_vout = GetVout( p_mi, p_e );
549     vlc_value_t val; int i_ret;
550
551     /* GetVout will raise the exception for us */
552     if( !p_vout )
553         return;
554
555     i_ret = var_Get( p_vout, "vbi-opaque", &val );
556     if( i_ret )
557         libvlc_exception_raise( p_e,
558                         "Unexpected error while looking up teletext value" );
559
560     val.b_bool = !val.b_bool;
561     i_ret = var_Set( p_vout, "vbi-opaque", val );
562     if( i_ret )
563         libvlc_exception_raise( p_e,
564                         "Unexpected error while setting teletext value" );
565
566     vlc_object_release( p_vout );
567 }
568
569 int libvlc_video_destroy( libvlc_media_player_t *p_mi,
570                           libvlc_exception_t *p_e )
571 {
572     vout_thread_t *p_vout = GetVout( p_mi, p_e );
573     vlc_object_detach( p_vout );
574     vlc_object_release( p_vout );
575     vlc_object_release( p_vout );
576
577     return 0;
578 }