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