]> git.sesse.net Git - vlc/blob - src/control/video.c
- control APIs: do not crash if exception parameter is null, that means caller is...
[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  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24  *****************************************************************************/
25
26 #include "libvlc_internal.h"
27 #include <vlc/libvlc.h>
28 #include <vlc_input.h>
29 #include <vlc_vout.h>
30
31 /*
32  * Remember to release the returned vout_thread_t since it is locked at
33  * the end of this function.
34  */
35 static vout_thread_t *GetVout( libvlc_input_t *p_input,
36                                libvlc_exception_t *p_exception )
37 {
38     input_thread_t *p_input_thread;
39     vout_thread_t *p_vout;
40
41     if( !p_input )
42     {
43         libvlc_exception_raise( p_exception, "Input is NULL" );
44         return NULL;
45     }
46
47     p_input_thread = (input_thread_t*)vlc_object_get(
48                                  p_input->p_instance->p_libvlc_int,
49                                  p_input->i_input_id );
50     if( !p_input_thread )
51     {
52         libvlc_exception_raise( p_exception, "Input does not exist" );
53         return NULL;
54     }
55
56     p_vout = vlc_object_find( p_input_thread, VLC_OBJECT_VOUT, FIND_CHILD );
57     if( !p_vout )
58     {
59         vlc_object_release( p_input_thread );
60         libvlc_exception_raise( p_exception, "No active video output" );
61         return NULL;
62     }
63     vlc_object_release( p_input_thread );
64
65     return p_vout;
66 }
67 /**********************************************************************
68  * Exported functions
69  **********************************************************************/
70
71 void libvlc_set_fullscreen( libvlc_input_t *p_input, int b_fullscreen,
72                             libvlc_exception_t *p_e )
73 {
74     /* We only work on the first vout */
75     vout_thread_t *p_vout1 = GetVout( p_input, p_e );
76     vlc_value_t val; int i_ret;
77
78     /* GetVout will raise the exception for us */
79     if( !p_vout1 )
80     {
81         return;
82     }
83
84     if( b_fullscreen ) val.b_bool = VLC_TRUE;
85     else               val.b_bool = VLC_FALSE;
86
87     i_ret = var_Set( p_vout1, "fullscreen", val );
88     if( i_ret )
89         libvlc_exception_raise( p_e,
90                         "Unexpected error while setting fullscreen value" );
91
92     vlc_object_release( p_vout1 );
93 }
94
95 int libvlc_get_fullscreen( libvlc_input_t *p_input,
96                             libvlc_exception_t *p_e )
97 {
98     /* We only work on the first vout */
99     vout_thread_t *p_vout1 = GetVout( p_input, p_e );
100     vlc_value_t val; int i_ret;
101
102     /* GetVout will raise the exception for us */
103     if( !p_vout1 )
104         return 0;
105
106     i_ret = var_Get( p_vout1, "fullscreen", &val );
107     if( i_ret )
108         libvlc_exception_raise( p_e,
109                         "Unexpected error while looking up fullscreen value" );
110
111     return val.b_bool == VLC_TRUE ? 1 : 0;
112 }
113
114 void libvlc_toggle_fullscreen( libvlc_input_t *p_input,
115                                libvlc_exception_t *p_e )
116 {
117     /* We only work on the first vout */
118     vout_thread_t *p_vout1 = GetVout( p_input, p_e );
119     vlc_value_t val; int i_ret;
120
121     /* GetVout will raise the exception for us */
122     if( !p_vout1 )
123         return;
124
125     i_ret = var_Get( p_vout1, "fullscreen", &val );
126     if( i_ret )
127         libvlc_exception_raise( p_e,
128                         "Unexpected error while looking up fullscreen value" );
129
130     val.b_bool = !val.b_bool;
131     i_ret = var_Set( p_vout1, "fullscreen", val );
132     if( i_ret )
133         libvlc_exception_raise( p_e,
134                         "Unexpected error while setting fullscreen value" );
135
136     vlc_object_release( p_vout1 );
137 }
138
139 void
140 libvlc_video_take_snapshot( libvlc_input_t *p_input, char *psz_filepath,
141                        libvlc_exception_t *p_e )
142 {
143     vout_thread_t *p_vout = GetVout( p_input, p_e );
144     input_thread_t *p_input_thread;
145
146     char path[256];
147
148     /* GetVout will raise the exception for us */
149     if( !p_vout )
150     {
151         return;
152     }
153
154     p_input_thread = (input_thread_t*)vlc_object_get(
155                                  p_input->p_instance->p_libvlc_int,
156                                  p_input->i_input_id );
157     if( !p_input_thread )
158     {
159         libvlc_exception_raise( p_e, "Input does not exist" );
160         return;
161     }
162
163     snprintf( path, 255, "%s", psz_filepath );
164     var_SetString( p_vout, "snapshot-path", path );
165     var_SetString( p_vout, "snapshot-format", "png" );
166
167     vout_Control( p_vout, VOUT_SNAPSHOT );
168     vlc_object_release( p_vout );
169     vlc_object_release( p_input_thread );
170 }
171
172 int libvlc_video_get_height( libvlc_input_t *p_input,
173                              libvlc_exception_t *p_e ) 
174 {
175     vout_thread_t *p_vout1 = GetVout( p_input, p_e );
176     if( !p_vout1 )
177         return 0;
178
179     vlc_object_release( p_vout1 );
180
181     return p_vout1->i_window_height;
182 }
183
184 int libvlc_video_get_width( libvlc_input_t *p_input,
185                             libvlc_exception_t *p_e ) 
186 {
187     vout_thread_t *p_vout1 = GetVout( p_input, p_e );
188     if( !p_vout1 )
189         return 0;
190
191     vlc_object_release( p_vout1 );
192
193     return p_vout1->i_window_width;
194 }
195
196 vlc_bool_t libvlc_input_has_vout( libvlc_input_t *p_input,
197                                   libvlc_exception_t *p_e )
198 {
199     vout_thread_t *p_vout = GetVout( p_input, p_e );
200     if ( NULL == p_vout )
201     {
202         if ( libvlc_exception_raised( p_e )
203          &&  strcmp( "No active video output", libvlc_exception_get_message( p_e ) ) == 0 )
204         {
205             libvlc_exception_clear( p_e );
206         }
207         return VLC_FALSE;
208     }
209
210     vlc_object_release( p_vout );
211
212     return VLC_TRUE;
213 }
214
215 int libvlc_video_reparent( libvlc_input_t *p_input, libvlc_drawable_t d,
216                            libvlc_exception_t *p_e )
217 {
218     vout_thread_t *p_vout = GetVout( p_input, p_e );
219
220     if ( p_vout == NULL)
221     {
222         /// \todo: set exception
223         return 0;
224     }
225
226     vout_Control( p_vout , VOUT_REPARENT, d);
227     vlc_object_release( p_vout );
228
229     return 0;
230 }
231
232 void libvlc_video_resize( libvlc_input_t *p_input, int width, int height, libvlc_exception_t *p_e )
233 {
234     vout_thread_t *p_vout = GetVout( p_input, p_e );
235     vout_Control( p_vout, VOUT_SET_SIZE, width, height );
236     vlc_object_release( p_vout );
237 }
238
239 /* global video settings */
240
241 void libvlc_video_set_parent( libvlc_instance_t *p_instance, libvlc_drawable_t d,
242                               libvlc_exception_t *p_e )
243 {
244     /* set as default for future vout instances */
245     var_SetInteger(p_instance->p_libvlc_int, "drawable", (int)d);
246
247     if( libvlc_playlist_isplaying(p_instance, p_e) )
248     {
249         libvlc_input_t *p_input = libvlc_playlist_get_input(p_instance, p_e);
250         if( p_input )
251         {
252             vout_thread_t *p_vout = GetVout( p_input, p_e );
253             if( p_vout )
254             {
255                 /* tell running vout to re-parent */
256                 vout_Control( p_vout , VOUT_REPARENT, d);
257                 vlc_object_release( p_vout );
258             }
259             libvlc_input_free(p_input);
260         }
261     }
262 }
263
264 libvlc_drawable_t libvlc_video_get_parent( libvlc_instance_t *p_instance, libvlc_exception_t *p_e )
265 {
266     libvlc_drawable_t result;
267     
268     result = var_GetInteger( p_instance->p_libvlc_int, "drawable" );
269     
270     return result;
271 }
272
273
274 void libvlc_video_set_size( libvlc_instance_t *p_instance, int width, int height,
275                            libvlc_exception_t *p_e )
276 {
277     /* set as default for future vout instances */
278     config_PutInt(p_instance->p_libvlc_int, "width", width);
279     config_PutInt(p_instance->p_libvlc_int, "height", height);
280
281     if( libvlc_playlist_isplaying(p_instance, p_e) )
282     {
283         libvlc_input_t *p_input = libvlc_playlist_get_input(p_instance, p_e);
284         if( p_input )
285         {
286             vout_thread_t *p_vout = GetVout( p_input, p_e );
287             if( p_vout )
288             {
289                 /* tell running vout to re-size */
290                 vout_Control( p_vout , VOUT_SET_SIZE, width, height);
291                 vlc_object_release( p_vout );
292             }
293             libvlc_input_free(p_input);
294         }
295     }
296 }
297
298 void libvlc_video_set_viewport( libvlc_instance_t *p_instance,
299                             const libvlc_rectangle_t *view, const libvlc_rectangle_t *clip,
300                            libvlc_exception_t *p_e )
301 {
302     if( NULL == view )
303     {
304         libvlc_exception_raise( p_e, "viewport is NULL" );
305     }
306
307     /* if clip is NULL, then use view rectangle as clip */
308     if( NULL == clip )
309         clip = view;
310
311     /* set as default for future vout instances */
312     var_SetInteger( p_instance->p_libvlc_int, "drawable-view-top", view->top );
313     var_SetInteger( p_instance->p_libvlc_int, "drawable-view-left", view->left );
314     var_SetInteger( p_instance->p_libvlc_int, "drawable-view-bottom", view->bottom );
315     var_SetInteger( p_instance->p_libvlc_int, "drawable-view-right", view->right );
316     var_SetInteger( p_instance->p_libvlc_int, "drawable-clip-top", clip->top );
317     var_SetInteger( p_instance->p_libvlc_int, "drawable-clip-left", clip->left );
318     var_SetInteger( p_instance->p_libvlc_int, "drawable-clip-bottom", clip->bottom );
319     var_SetInteger( p_instance->p_libvlc_int, "drawable-clip-right", clip->right );
320
321     if( libvlc_playlist_isplaying(p_instance, p_e) )
322     {
323         libvlc_input_t *p_input = libvlc_playlist_get_input(p_instance, p_e);
324         if( p_input )
325         {
326             vout_thread_t *p_vout = GetVout( p_input, p_e );
327             if( p_vout )
328             {
329                 /* change viewport for running vout */
330                 vout_Control( p_vout , VOUT_SET_VIEWPORT,
331                                    view->top, view->left, view->bottom, view->right,
332                                    clip->top, clip->left, clip->bottom, clip->right );
333                 vlc_object_release( p_vout );
334             }
335             libvlc_input_free(p_input);
336         }
337     }
338 }
339
340 char *libvlc_video_get_aspect_ratio( libvlc_input_t *p_input,
341                                    libvlc_exception_t *p_e )
342 {
343     char *psz_aspect = 0;
344     vout_thread_t *p_vout = GetVout( p_input, p_e );
345
346     if( !p_vout )
347         return 0;
348
349     psz_aspect = var_GetString( p_vout, "aspect-ratio" );
350     vlc_object_release( p_vout );
351     return psz_aspect;
352 }
353
354 void libvlc_video_set_aspect_ratio( libvlc_input_t *p_input,
355                                     char *psz_aspect, libvlc_exception_t *p_e )
356 {
357     vout_thread_t *p_vout = GetVout( p_input, p_e );
358     int i_ret = -1;
359
360     if( !p_vout )
361         return;
362
363     i_ret = var_SetString( p_vout, "aspect-ratio", psz_aspect );
364     if( i_ret )
365         libvlc_exception_raise( p_e,
366                         "Unexpected error while setting aspect-ratio value" );
367
368     vlc_object_release( p_vout );
369 }
370
371 char *libvlc_video_get_crop_geometry( libvlc_input_t *p_input,
372                                    libvlc_exception_t *p_e )
373 {
374     char *psz_geometry = 0;
375     vout_thread_t *p_vout = GetVout( p_input, p_e );
376
377     if( !p_vout )
378         return 0;
379
380     psz_geometry = var_GetString( p_vout, "crop" );
381     vlc_object_release( p_vout );
382     return psz_geometry;
383 }
384
385 void libvlc_video_set_crop_geometry( libvlc_input_t *p_input,
386                                     char *psz_geometry, libvlc_exception_t *p_e )
387 {
388     vout_thread_t *p_vout = GetVout( p_input, p_e );
389     int i_ret = -1;
390
391     if( !p_vout )
392         return;
393
394     i_ret = var_SetString( p_vout, "crop", psz_geometry );
395     if( i_ret )
396         libvlc_exception_raise( p_e,
397                         "Unexpected error while setting crop geometry" );
398
399     vlc_object_release( p_vout );
400 }
401
402 int libvlc_video_destroy( libvlc_input_t *p_input,
403                           libvlc_exception_t *p_e )
404 {
405     vout_thread_t *p_vout = GetVout( p_input, p_e );
406     vlc_object_detach( p_vout ); 
407     vlc_object_release( p_vout );
408     vout_Destroy( p_vout );
409
410     return 0;
411 }