]> git.sesse.net Git - vlc/blob - src/control/video.c
libvlc_video_take_snapshot: removed kludge and fixed path_sanitize for win32
[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     /* GetVout will raise the exception for us */
162     if( !p_vout )
163     {
164         return;
165     }
166
167     if( !psz_filepath )
168     {
169         libvlc_exception_raise( p_e, "filepath is null" );
170         return;
171     }
172
173
174     p_input_thread = (input_thread_t*)vlc_object_get(
175                                  p_input->p_instance->p_libvlc_int,
176                                  p_input->i_input_id );
177     if( !p_input_thread )
178     {
179         libvlc_exception_raise( p_e, "Input does not exist" );
180         return;
181     }
182
183     var_SetString( p_vout, "snapshot-path", psz_filepath );
184     var_SetString( p_vout, "snapshot-format", "png" );
185
186     vout_Control( p_vout, VOUT_SNAPSHOT );
187     vlc_object_release( p_vout );
188     vlc_object_release( p_input_thread );
189 }
190
191 int libvlc_video_get_height( libvlc_input_t *p_input,
192                              libvlc_exception_t *p_e ) 
193 {
194     vout_thread_t *p_vout1 = GetVout( p_input, p_e );
195     if( !p_vout1 )
196         return 0;
197
198     vlc_object_release( p_vout1 );
199
200     return p_vout1->i_window_height;
201 }
202
203 int libvlc_video_get_width( libvlc_input_t *p_input,
204                             libvlc_exception_t *p_e ) 
205 {
206     vout_thread_t *p_vout1 = GetVout( p_input, p_e );
207     if( !p_vout1 )
208         return 0;
209
210     vlc_object_release( p_vout1 );
211
212     return p_vout1->i_window_width;
213 }
214
215 vlc_bool_t libvlc_input_has_vout( libvlc_input_t *p_input,
216                                   libvlc_exception_t *p_e )
217 {
218     input_thread_t *p_input_thread = GetInputThread(p_input, p_e);
219     vlc_bool_t has_vout = VLC_FALSE;
220
221     if( p_input_thread )
222     {
223         vout_thread_t *p_vout;
224
225         p_vout = vlc_object_find( p_input_thread, VLC_OBJECT_VOUT, FIND_CHILD );
226         if( p_vout )
227         {
228             has_vout = VLC_TRUE;
229             vlc_object_release( p_vout );
230         }
231         vlc_object_release( p_input_thread );
232     }
233     return has_vout;
234 }
235
236 int libvlc_video_reparent( libvlc_input_t *p_input, libvlc_drawable_t d,
237                            libvlc_exception_t *p_e )
238 {
239     vout_thread_t *p_vout = GetVout( p_input, p_e );
240
241     if( p_vout )
242     {
243         vout_Control( p_vout , VOUT_REPARENT, d);
244         vlc_object_release( p_vout );
245     }
246     return 0;
247 }
248
249 void libvlc_video_resize( libvlc_input_t *p_input, int width, int height, libvlc_exception_t *p_e )
250 {
251     vout_thread_t *p_vout = GetVout( p_input, p_e );
252     if( p_vout )
253     {
254         vout_Control( p_vout, VOUT_SET_SIZE, width, height );
255         vlc_object_release( p_vout );
256     }
257 }
258
259 void libvlc_video_redraw_rectangle( libvlc_input_t *p_input,
260                            const libvlc_rectangle_t *area,
261                            libvlc_exception_t *p_e )
262 {
263     if( (NULL != area)
264      && ((area->bottom - area->top) > 0)
265      && ((area->right - area->left) > 0) )
266     {
267         vout_thread_t *p_vout = GetVout( p_input, p_e );
268         if( p_vout )
269         {
270             /* tell running vout to redraw area */
271             vout_Control( p_vout , VOUT_REDRAW_RECT,
272                                area->top, area->left, area->bottom, area->right );
273             vlc_object_release( p_vout );
274         }
275     }
276 }
277
278 /* global video settings */
279
280 void libvlc_video_set_parent( libvlc_instance_t *p_instance, libvlc_drawable_t d,
281                               libvlc_exception_t *p_e )
282 {
283     /* set as default for future vout instances */
284     var_SetInteger(p_instance->p_libvlc_int, "drawable", (int)d);
285
286     if( libvlc_playlist_isplaying(p_instance, p_e) )
287     {
288         libvlc_input_t *p_input = libvlc_playlist_get_input(p_instance, p_e);
289         if( p_input )
290         {
291             vout_thread_t *p_vout = GetVout( p_input, p_e );
292             if( p_vout )
293             {
294                 /* tell running vout to re-parent */
295                 vout_Control( p_vout , VOUT_REPARENT, d);
296                 vlc_object_release( p_vout );
297             }
298             libvlc_input_free(p_input);
299         }
300     }
301 }
302
303 libvlc_drawable_t libvlc_video_get_parent( libvlc_instance_t *p_instance, libvlc_exception_t *p_e )
304 {
305     libvlc_drawable_t result;
306     
307     result = var_GetInteger( p_instance->p_libvlc_int, "drawable" );
308     
309     return result;
310 }
311
312
313 void libvlc_video_set_size( libvlc_instance_t *p_instance, int width, int height,
314                            libvlc_exception_t *p_e )
315 {
316     /* set as default for future vout instances */
317     config_PutInt(p_instance->p_libvlc_int, "width", width);
318     config_PutInt(p_instance->p_libvlc_int, "height", height);
319
320     if( libvlc_playlist_isplaying(p_instance, p_e) )
321     {
322         libvlc_input_t *p_input = libvlc_playlist_get_input(p_instance, p_e);
323         if( p_input )
324         {
325             vout_thread_t *p_vout = GetVout( p_input, p_e );
326             if( p_vout )
327             {
328                 /* tell running vout to re-size */
329                 vout_Control( p_vout , VOUT_SET_SIZE, width, height);
330                 vlc_object_release( p_vout );
331             }
332             libvlc_input_free(p_input);
333         }
334     }
335 }
336
337 void libvlc_video_set_viewport( libvlc_instance_t *p_instance,
338                             const libvlc_rectangle_t *view, const libvlc_rectangle_t *clip,
339                            libvlc_exception_t *p_e )
340 {
341     if( NULL == view )
342     {
343         libvlc_exception_raise( p_e, "viewport is NULL" );
344     }
345
346     /* if clip is NULL, then use view rectangle as clip */
347     if( NULL == clip )
348         clip = view;
349
350     /* set as default for future vout instances */
351     var_SetInteger( p_instance->p_libvlc_int, "drawable-view-top", view->top );
352     var_SetInteger( p_instance->p_libvlc_int, "drawable-view-left", view->left );
353     var_SetInteger( p_instance->p_libvlc_int, "drawable-view-bottom", view->bottom );
354     var_SetInteger( p_instance->p_libvlc_int, "drawable-view-right", view->right );
355     var_SetInteger( p_instance->p_libvlc_int, "drawable-clip-top", clip->top );
356     var_SetInteger( p_instance->p_libvlc_int, "drawable-clip-left", clip->left );
357     var_SetInteger( p_instance->p_libvlc_int, "drawable-clip-bottom", clip->bottom );
358     var_SetInteger( p_instance->p_libvlc_int, "drawable-clip-right", clip->right );
359
360     if( libvlc_playlist_isplaying(p_instance, p_e) )
361     {
362         libvlc_input_t *p_input = libvlc_playlist_get_input(p_instance, p_e);
363         if( p_input )
364         {
365             vout_thread_t *p_vout = GetVout( p_input, p_e );
366             if( p_vout )
367             {
368                 /* change viewport for running vout */
369                 vout_Control( p_vout , VOUT_SET_VIEWPORT,
370                                    view->top, view->left, view->bottom, view->right,
371                                    clip->top, clip->left, clip->bottom, clip->right );
372                 vlc_object_release( p_vout );
373             }
374             libvlc_input_free(p_input);
375         }
376     }
377 }
378
379 char *libvlc_video_get_aspect_ratio( libvlc_input_t *p_input,
380                                      libvlc_exception_t *p_e )
381 {
382     char *psz_aspect = 0;
383     vout_thread_t *p_vout = GetVout( p_input, p_e );
384
385     if( !p_vout )
386         return 0;
387
388     psz_aspect = var_GetString( p_vout, "aspect-ratio" );
389     vlc_object_release( p_vout );
390     return psz_aspect;
391 }
392
393 void libvlc_video_set_aspect_ratio( libvlc_input_t *p_input,
394                                     char *psz_aspect, libvlc_exception_t *p_e )
395 {
396     vout_thread_t *p_vout = GetVout( p_input, p_e );
397     int i_ret = -1;
398
399     if( !p_vout )
400         return;
401
402     i_ret = var_SetString( p_vout, "aspect-ratio", psz_aspect );
403     if( i_ret )
404         libvlc_exception_raise( p_e,
405                         "Unexpected error while setting aspect-ratio value" );
406
407     vlc_object_release( p_vout );
408 }
409
410 int libvlc_video_get_spu( libvlc_input_t *p_input,
411                           libvlc_exception_t *p_e )
412 {
413     input_thread_t *p_input_thread = GetInputThread( p_input, p_e );
414     vlc_value_t val_list;
415     vlc_value_t val;
416     int i_spu = -1;
417     int i_ret = -1;
418     int i;
419
420     if( !p_input_thread )
421         return -1;
422
423     i_ret = var_Get( p_input_thread, "spu-es", &val );
424     if( i_ret < 0 )
425     {
426         libvlc_exception_raise( p_e, "Getting subtitle information failed" );
427         vlc_object_release( p_input_thread );
428         return i_ret;
429     }
430
431     var_Change( p_input_thread, "spu-es", VLC_VAR_GETCHOICES, &val_list, NULL );
432     for( i = 0; i < val_list.p_list->i_count; i++ )
433     {
434         vlc_value_t spu_val = val_list.p_list->p_values[i];
435         if( val.i_int == spu_val.i_int )
436         {
437             i_spu = i;
438             break;
439         }
440     }
441     vlc_object_release( p_input_thread );
442     return i_spu;
443 }
444
445 void libvlc_video_set_spu( libvlc_input_t *p_input, int i_spu,
446                            libvlc_exception_t *p_e )
447 {
448     input_thread_t *p_input_thread = GetInputThread( p_input, p_e );
449     vlc_value_t val_list;
450     int i_ret = -1;
451     int i;
452
453     if( !p_input_thread )
454         return;
455
456     var_Change( p_input_thread, "spu-es", VLC_VAR_GETCHOICES, &val_list, NULL );
457     for( i = 0; i < val_list.p_list->i_count; i++ )
458     {
459         vlc_value_t val = val_list.p_list->p_values[i];
460         if( i_spu == i )
461         {
462             vlc_value_t new_val;
463
464             new_val.i_int = val.i_int;
465             i_ret = var_Set( p_input_thread, "spu-es", new_val );
466             if( i_ret < 0 )
467             {
468                 libvlc_exception_raise( p_e, "Setting subtitle value failed" );
469             }
470             vlc_object_release( p_input_thread );
471             return;
472         }
473     }
474     libvlc_exception_raise( p_e, "Subtitle value out of range" );
475     vlc_object_release( p_input_thread );
476 }
477
478 char *libvlc_video_get_crop_geometry( libvlc_input_t *p_input,
479                                    libvlc_exception_t *p_e )
480 {
481     char *psz_geometry = 0;
482     vout_thread_t *p_vout = GetVout( p_input, p_e );
483
484     if( !p_vout )
485         return 0;
486
487     psz_geometry = var_GetString( p_vout, "crop" );
488     vlc_object_release( p_vout );
489     return psz_geometry;
490 }
491
492 void libvlc_video_set_crop_geometry( libvlc_input_t *p_input,
493                                     char *psz_geometry, libvlc_exception_t *p_e )
494 {
495     vout_thread_t *p_vout = GetVout( p_input, p_e );
496     int i_ret = -1;
497
498     if( !p_vout )
499         return;
500
501     i_ret = var_SetString( p_vout, "crop", psz_geometry );
502     if( i_ret )
503         libvlc_exception_raise( p_e,
504                         "Unexpected error while setting crop geometry" );
505
506     vlc_object_release( p_vout );
507 }
508
509 int libvlc_video_destroy( libvlc_input_t *p_input,
510                           libvlc_exception_t *p_e )
511 {
512     vout_thread_t *p_vout = GetVout( p_input, p_e );
513     vlc_object_detach( p_vout ); 
514     vlc_object_release( p_vout );
515     vout_Destroy( p_vout );
516
517     return 0;
518 }