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