Audio track and channel support for JavaScript API. The ActiveX vlc.audio.channel...
[vlc.git] / 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 ( libvlc_exception_raised( p_e ) )
201     {
202         if ( strcmp( "No active video output", libvlc_exception_get_message( p_e ) ) == 0 )
203         {
204             libvlc_exception_clear( p_e );
205         }
206         return VLC_FALSE;
207     }
208
209     vlc_object_release( p_vout );
210
211     return VLC_TRUE;
212 }
213
214 int libvlc_video_reparent( libvlc_input_t *p_input, libvlc_drawable_t d,
215                            libvlc_exception_t *p_e )
216 {
217     vout_thread_t *p_vout = GetVout( p_input, p_e );
218
219     if ( p_vout == NULL)
220     {
221         /// \todo: set exception
222         return 0;
223     }
224
225     vout_Control( p_vout , VOUT_REPARENT, d);
226     vlc_object_release( p_vout );
227
228     return 0;
229 }
230
231 void libvlc_video_resize( libvlc_input_t *p_input, int width, int height, libvlc_exception_t *p_e )
232 {
233     vout_thread_t *p_vout = GetVout( p_input, p_e );
234     vout_Control( p_vout, VOUT_SET_SIZE, width, height );
235     vlc_object_release( p_vout );
236 }
237
238 /* global video settings */
239
240 void libvlc_video_set_parent( libvlc_instance_t *p_instance, libvlc_drawable_t d,
241                               libvlc_exception_t *p_e )
242 {
243     /* set as default for future vout instances */
244     var_SetInteger(p_instance->p_libvlc_int, "drawable", (int)d);
245
246     if( libvlc_playlist_isplaying(p_instance, p_e) )
247     {
248         libvlc_input_t *p_input = libvlc_playlist_get_input(p_instance, p_e);
249         if( p_input )
250         {
251             vout_thread_t *p_vout = GetVout( p_input, p_e );
252             if( p_vout )
253             {
254                 /* tell running vout to re-parent */
255                 vout_Control( p_vout , VOUT_REPARENT, d);
256                 vlc_object_release( p_vout );
257             }
258             libvlc_input_free(p_input);
259         }
260     }
261 }
262
263 void libvlc_video_set_size( libvlc_instance_t *p_instance, int width, int height,
264                            libvlc_exception_t *p_e )
265 {
266     /* set as default for future vout instances */
267     config_PutInt(p_instance->p_libvlc_int, "width", width);
268     config_PutInt(p_instance->p_libvlc_int, "height", height);
269
270     if( libvlc_playlist_isplaying(p_instance, p_e) )
271     {
272         libvlc_input_t *p_input = libvlc_playlist_get_input(p_instance, p_e);
273         if( p_input )
274         {
275             vout_thread_t *p_vout = GetVout( p_input, p_e );
276             if( p_vout )
277             {
278                 /* tell running vout to re-size */
279                 vout_Control( p_vout , VOUT_SET_SIZE, width, height);
280                 vlc_object_release( p_vout );
281             }
282             libvlc_input_free(p_input);
283         }
284     }
285 }
286
287 void libvlc_video_set_viewport( libvlc_instance_t *p_instance,
288                             const libvlc_rectangle_t *view, const libvlc_rectangle_t *clip,
289                            libvlc_exception_t *p_e )
290 {
291     if( NULL == view )
292     {
293         libvlc_exception_raise( p_e, "viewport is NULL" );
294     }
295
296     /* if clip is NULL, then use view rectangle as clip */
297     if( NULL == clip )
298         clip = view;
299
300     /* set as default for future vout instances */
301     var_SetInteger( p_instance->p_libvlc_int, "drawable-view-top", view->top );
302     var_SetInteger( p_instance->p_libvlc_int, "drawable-view-left", view->left );
303     var_SetInteger( p_instance->p_libvlc_int, "drawable-view-bottom", view->bottom );
304     var_SetInteger( p_instance->p_libvlc_int, "drawable-view-right", view->right );
305     var_SetInteger( p_instance->p_libvlc_int, "drawable-clip-top", clip->top );
306     var_SetInteger( p_instance->p_libvlc_int, "drawable-clip-left", clip->left );
307     var_SetInteger( p_instance->p_libvlc_int, "drawable-clip-bottom", clip->bottom );
308     var_SetInteger( p_instance->p_libvlc_int, "drawable-clip-right", clip->right );
309
310     if( libvlc_playlist_isplaying(p_instance, p_e) )
311     {
312         libvlc_input_t *p_input = libvlc_playlist_get_input(p_instance, p_e);
313         if( p_input )
314         {
315             vout_thread_t *p_vout = GetVout( p_input, p_e );
316             if( p_vout )
317             {
318                 /* change viewport for running vout */
319                 vout_Control( p_vout , VOUT_SET_VIEWPORT,
320                                    view->top, view->left, view->bottom, view->right,
321                                    clip->top, clip->left, clip->bottom, clip->right );
322                 vlc_object_release( p_vout );
323             }
324             libvlc_input_free(p_input);
325         }
326     }
327 }
328
329 char *libvlc_video_get_aspect_ratio( libvlc_input_t *p_input,
330                                    libvlc_exception_t *p_e )
331 {
332     char *psz_aspect = 0;
333     vout_thread_t *p_vout = GetVout( p_input, p_e );
334
335     if( !p_vout )
336         return 0;
337
338     psz_aspect = var_GetString( p_vout, "aspect-ratio" );
339     vlc_object_release( p_vout );
340     return psz_aspect;
341 }
342
343 void libvlc_video_set_aspect_ratio( libvlc_input_t *p_input,
344                                     char *psz_aspect, libvlc_exception_t *p_e )
345 {
346     vout_thread_t *p_vout = GetVout( p_input, p_e );
347     int i_ret = -1;
348
349     if( !p_vout )
350         return;
351
352     i_ret = var_SetString( p_vout, "aspect-ratio", psz_aspect );
353     if( i_ret )
354         libvlc_exception_raise( p_e,
355                         "Unexpected error while setting aspect-ratio value" );
356
357     vlc_object_release( p_vout );
358 }
359
360 int libvlc_video_destroy( libvlc_input_t *p_input,
361                           libvlc_exception_t *p_e )
362 {
363     vout_thread_t *p_vout = GetVout( p_input, p_e );
364     vlc_object_detach( p_vout ); 
365     vlc_object_release( p_vout );
366     vout_Destroy( p_vout );
367
368     return 0;
369 }