1 /*****************************************************************************
2 * media_instance.c: Libvlc API Media Instance management functions
3 *****************************************************************************
4 * Copyright (C) 2005 the VideoLAN team
7 * Authors: Clément Stenac <zorglub@videolan.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 #include "libvlc_internal.h"
25 #include <vlc/libvlc.h>
26 #include <vlc_demux.h>
27 #include <vlc_input.h>
28 #include "input/input_internal.h"
31 * Retrieve the input thread. Be sure to release the object
32 * once you are done with it. (libvlc Internal)
34 input_thread_t *libvlc_get_input_thread( libvlc_media_instance_t *p_mi,
35 libvlc_exception_t *p_e )
37 input_thread_t *p_input_thread;
39 if( !p_mi || p_mi->i_input_id == -1 )
40 RAISENULL( "Input is NULL" );
42 p_input_thread = (input_thread_t*)vlc_object_get(
43 p_mi->p_libvlc_instance->p_libvlc_int,
46 RAISENULL( "Input does not exist" );
48 return p_input_thread;
51 /**************************************************************************
52 * Create a Media Instance object
53 **************************************************************************/
54 libvlc_media_instance_t *
55 libvlc_media_instance_new( libvlc_media_descriptor_t *p_md )
57 libvlc_media_instance_t * p_mi;
62 p_mi = malloc( sizeof(libvlc_media_instance_t) );
63 p_mi->p_md = libvlc_media_descriptor_duplicate( p_md );
64 p_mi->p_libvlc_instance = p_mi->p_md->p_libvlc_instance;
65 p_mi->i_input_id = -1;
70 /**************************************************************************
71 * Create a new media instance object from an input_thread (Libvlc Internal)
72 **************************************************************************/
73 libvlc_media_instance_t * libvlc_media_instance_new_from_input_thread(
74 struct libvlc_instance_t *p_libvlc_instance,
75 input_thread_t *p_input )
77 libvlc_media_instance_t * p_mi;
79 p_mi = malloc( sizeof(libvlc_media_instance_t) );
80 p_mi->p_md = libvlc_media_descriptor_new_from_input_item(
82 p_input->p->input.p_item );
83 p_mi->p_libvlc_instance = p_libvlc_instance;
84 p_mi->i_input_id = p_input->i_object_id;
86 /* will be released in media_instance_release() */
87 vlc_object_yield( p_input );
92 /**************************************************************************
93 * Destroy a Media Instance object
94 **************************************************************************/
95 void libvlc_media_instance_destroy( libvlc_media_instance_t *p_mi )
97 input_thread_t *p_input_thread;
98 libvlc_exception_t p_e;
101 libvlc_exception_init( &p_e );
106 p_input_thread = libvlc_get_input_thread( p_mi, &p_e );
108 if( libvlc_exception_raised( &p_e ) )
109 return; /* no need to worry about no input thread */
111 input_DestroyThread( p_input_thread );
113 libvlc_media_descriptor_destroy( p_mi->p_md );
118 /**************************************************************************
119 * Release a Media Instance object
120 **************************************************************************/
121 void libvlc_media_instance_release( libvlc_media_instance_t *p_mi )
123 input_thread_t *p_input_thread;
124 libvlc_exception_t p_e;
127 libvlc_exception_init( &p_e );
132 p_input_thread = libvlc_get_input_thread( p_mi, &p_e );
134 if( !libvlc_exception_raised( &p_e ) )
136 /* release for previous libvlc_get_input_thread */
137 vlc_object_release( p_input_thread );
139 /* release for initial p_input_thread yield (see _new()) */
140 vlc_object_release( p_input_thread );
142 /* No one is tracking this input_thread appart us. Destroy it */
143 if( p_input_thread->i_refcount <= 0 )
144 input_DestroyThread( p_input_thread );
145 /* btw, we still have an XXX locking here */
148 libvlc_media_descriptor_destroy( p_mi->p_md );
153 /**************************************************************************
155 **************************************************************************/
156 void libvlc_media_instance_play( libvlc_media_instance_t *p_mi,
157 libvlc_exception_t *p_e )
159 input_thread_t * p_input_thread;
161 if( p_mi->i_input_id != -1)
164 val.i_int = PLAYING_S;
166 /* A thread alread exists, send it a play message */
167 p_input_thread = libvlc_get_input_thread( p_mi, p_e );
169 if( libvlc_exception_raised( p_e ) )
172 input_Control( p_input_thread, INPUT_CONTROL_SET_STATE, PLAYING_S );
173 vlc_object_release( p_input_thread );
177 p_input_thread = input_CreateThread( p_mi->p_libvlc_instance->p_libvlc_int,
178 p_mi->p_md->p_input_item );
179 p_mi->i_input_id = p_input_thread->i_object_id;
181 /* will be released in media_instance_release() */
182 vlc_object_yield( p_input_thread );
185 /**************************************************************************
187 **************************************************************************/
188 void libvlc_media_instance_pause( libvlc_media_instance_t *p_mi,
189 libvlc_exception_t *p_e )
191 input_thread_t * p_input_thread;
195 p_input_thread = libvlc_get_input_thread( p_mi, p_e );
197 if( libvlc_exception_raised( p_e ) )
200 input_Control( p_input_thread, INPUT_CONTROL_SET_STATE, val );
201 vlc_object_release( p_input_thread );
204 /**************************************************************************
205 * Getters for stream information
206 **************************************************************************/
207 vlc_int64_t libvlc_media_instance_get_length(
208 libvlc_media_instance_t *p_mi,
209 libvlc_exception_t *p_e )
211 input_thread_t *p_input_thread;
214 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
215 if( !p_input_thread )
218 var_Get( p_input_thread, "length", &val );
219 vlc_object_release( p_input_thread );
221 return (val.i_time+500LL)/1000LL;
224 vlc_int64_t libvlc_media_instance_get_time(
225 libvlc_media_instance_t *p_mi,
226 libvlc_exception_t *p_e )
228 input_thread_t *p_input_thread;
231 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
232 if( !p_input_thread )
235 var_Get( p_input_thread , "time", &val );
236 vlc_object_release( p_input_thread );
237 return (val.i_time+500LL)/1000LL;
240 void libvlc_media_instance_set_time(
241 libvlc_media_instance_t *p_mi,
243 libvlc_exception_t *p_e )
245 input_thread_t *p_input_thread;
248 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
249 if( !p_input_thread )
252 value.i_time = time*1000LL;
253 var_Set( p_input_thread, "time", value );
254 vlc_object_release( p_input_thread );
257 void libvlc_media_instance_set_position(
258 libvlc_media_instance_t *p_mi,
260 libvlc_exception_t *p_e )
262 input_thread_t *p_input_thread;
264 val.f_float = position;
266 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
267 if( !p_input_thread )
270 var_Set( p_input_thread, "position", val );
271 vlc_object_release( p_input_thread );
274 float libvlc_media_instance_get_position(
275 libvlc_media_instance_t *p_mi,
276 libvlc_exception_t *p_e )
278 input_thread_t *p_input_thread;
281 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
282 if( !p_input_thread )
285 var_Get( p_input_thread, "position", &val );
286 vlc_object_release( p_input_thread );
291 float libvlc_media_instance_get_fps(
292 libvlc_media_instance_t *p_mi,
293 libvlc_exception_t *p_e)
296 input_thread_t *p_input_thread;
298 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
299 if( !p_input_thread )
302 if( (NULL == p_input_thread->p->input.p_demux)
303 || demux2_Control( p_input_thread->p->input.p_demux, DEMUX_GET_FPS, &f_fps )
306 vlc_object_release( p_input_thread );
311 vlc_object_release( p_input_thread );
316 vlc_bool_t libvlc_media_instance_will_play(
317 libvlc_media_instance_t *p_mi,
318 libvlc_exception_t *p_e)
320 input_thread_t *p_input_thread =
321 libvlc_get_input_thread ( p_mi, p_e);
322 if ( !p_input_thread )
325 if ( !p_input_thread->b_die && !p_input_thread->b_dead )
327 vlc_object_release( p_input_thread );
330 vlc_object_release( p_input_thread );
334 void libvlc_media_instance_set_rate(
335 libvlc_media_instance_t *p_mi,
337 libvlc_exception_t *p_e )
339 input_thread_t *p_input_thread;
343 RAISEVOID( "Rate value is invalid" );
345 val.i_int = 1000.0f/rate;
347 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
348 if ( !p_input_thread )
351 var_Set( p_input_thread, "rate", val );
352 vlc_object_release( p_input_thread );
355 float libvlc_media_instance_get_rate(
356 libvlc_media_instance_t *p_mi,
357 libvlc_exception_t *p_e )
359 input_thread_t *p_input_thread;
362 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
363 if ( !p_input_thread )
366 var_Get( p_input_thread, "rate", &val );
367 vlc_object_release( p_input_thread );
369 return (float)1000.0f/val.i_int;
372 int libvlc_media_instance_get_state(
373 libvlc_media_instance_t *p_mi,
374 libvlc_exception_t *p_e )
376 input_thread_t *p_input_thread;
379 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
380 if ( !p_input_thread )
383 var_Get( p_input_thread, "state", &val );
384 vlc_object_release( p_input_thread );