1 /*****************************************************************************
2 * media_player.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"
26 #include <vlc/libvlc.h>
27 #include <vlc_demux.h>
28 #include <vlc_input.h>
33 input_state_changed( const vlc_event_t * event, void * p_userdata );
36 input_seekable_changed( vlc_object_t * p_this, char const * psz_cmd,
37 vlc_value_t oldval, vlc_value_t newval,
40 input_pausable_changed( vlc_object_t * p_this, char const * psz_cmd,
41 vlc_value_t oldval, vlc_value_t newval,
44 input_position_changed( vlc_object_t * p_this, char const * psz_cmd,
45 vlc_value_t oldval, vlc_value_t newval,
48 input_time_changed( vlc_object_t * p_this, char const * psz_cmd,
49 vlc_value_t oldval, vlc_value_t newval,
52 static const libvlc_state_t vlc_to_libvlc_state_array[] =
54 [INIT_S] = libvlc_NothingSpecial,
55 [OPENING_S] = libvlc_Opening,
56 [BUFFERING_S] = libvlc_Buffering,
57 [PLAYING_S] = libvlc_Playing,
58 [PAUSE_S] = libvlc_Paused,
59 [STOP_S] = libvlc_Stopped,
60 [FORWARD_S] = libvlc_Forward,
61 [BACKWARD_S] = libvlc_Backward,
62 [END_S] = libvlc_Ended,
63 [ERROR_S] = libvlc_Error,
66 static inline libvlc_state_t vlc_to_libvlc_state( int vlc_state )
68 if( vlc_state < 0 || vlc_state > 6 )
71 return vlc_to_libvlc_state_array[vlc_state];
75 * Release the associated input thread
77 * Object lock is NOT held.
79 static void release_input_thread( libvlc_media_player_t *p_mi )
81 input_thread_t * p_input_thread;
83 if( !p_mi || !p_mi->p_input_thread )
86 p_input_thread = p_mi->p_input_thread;
88 /* No one is tracking this input_thread appart us. Destroy it */
89 if( p_mi->b_own_its_input_thread )
91 vlc_event_manager_t * p_em = input_get_event_manager( p_input_thread );
92 vlc_event_detach( p_em, vlc_InputStateChanged, input_state_changed, p_mi );
93 var_DelCallback( p_input_thread, "seekable", input_seekable_changed, p_mi );
94 var_DelCallback( p_input_thread, "pausable", input_pausable_changed, p_mi );
95 var_DelCallback( p_input_thread, "intf-change", input_position_changed, p_mi );
96 var_DelCallback( p_input_thread, "intf-change", input_time_changed, p_mi );
98 /* We owned this one */
99 input_StopThread( p_input_thread );
101 var_Destroy( p_input_thread, "drawable" );
104 vlc_object_release( p_input_thread );
106 p_mi->p_input_thread = NULL;
110 * Retrieve the input thread. Be sure to release the object
111 * once you are done with it. (libvlc Internal)
113 * Object lock is held.
115 input_thread_t *libvlc_get_input_thread( libvlc_media_player_t *p_mi,
116 libvlc_exception_t *p_e )
118 input_thread_t *p_input_thread;
120 if( !p_mi ) RAISENULL( "Media Instance is NULL" );
122 vlc_mutex_lock( &p_mi->object_lock );
124 if( !p_mi->p_input_thread )
126 vlc_mutex_unlock( &p_mi->object_lock );
127 RAISENULL( "Input is NULL" );
130 p_input_thread = p_mi->p_input_thread;
131 vlc_object_yield( p_input_thread );
133 vlc_mutex_unlock( &p_mi->object_lock );
135 return p_input_thread;
139 * input_state_changed (Private) (vlc_InputStateChanged callback)
142 input_state_changed( const vlc_event_t * event, void * p_userdata )
144 libvlc_media_player_t * p_mi = p_userdata;
145 libvlc_event_t forwarded_event;
146 libvlc_event_type_t type = event->u.input_state_changed.new_state;
151 libvlc_media_set_state( p_mi->p_md, libvlc_NothingSpecial, NULL);
152 forwarded_event.type = libvlc_MediaPlayerNothingSpecial;
155 libvlc_media_set_state( p_mi->p_md, libvlc_Opening, NULL);
156 forwarded_event.type = libvlc_MediaPlayerOpening;
159 libvlc_media_set_state( p_mi->p_md, libvlc_Buffering, NULL);
160 forwarded_event.type = libvlc_MediaPlayerBuffering;
163 libvlc_media_set_state( p_mi->p_md, libvlc_Playing, NULL);
164 forwarded_event.type = libvlc_MediaPlayerPlaying;
167 libvlc_media_set_state( p_mi->p_md, libvlc_Paused, NULL);
168 forwarded_event.type = libvlc_MediaPlayerPaused;
171 libvlc_media_set_state( p_mi->p_md, libvlc_Stopped, NULL);
172 forwarded_event.type = libvlc_MediaPlayerStopped;
175 libvlc_media_set_state( p_mi->p_md, libvlc_Forward, NULL);
176 forwarded_event.type = libvlc_MediaPlayerForward;
179 libvlc_media_set_state( p_mi->p_md, libvlc_Backward, NULL);
180 forwarded_event.type = libvlc_MediaPlayerBackward;
183 libvlc_media_set_state( p_mi->p_md, libvlc_Ended, NULL);
184 forwarded_event.type = libvlc_MediaPlayerEndReached;
186 libvlc_media_set_state( p_mi->p_md, libvlc_Error, NULL);
187 forwarded_event.type = libvlc_MediaPlayerEncounteredError;
194 libvlc_event_send( p_mi->p_event_manager, &forwarded_event );
199 input_seekable_changed( vlc_object_t * p_this, char const * psz_cmd,
200 vlc_value_t oldval, vlc_value_t newval,
206 libvlc_media_player_t * p_mi = p_userdata;
207 libvlc_event_t event;
209 libvlc_media_set_state( p_mi->p_md, libvlc_NothingSpecial, NULL);
210 event.type = libvlc_MediaPlayerSeekableChanged;
211 event.u.media_player_seekable_changed.new_seekable = newval.b_bool;
213 libvlc_event_send( p_mi->p_event_manager, &event );
218 input_pausable_changed( vlc_object_t * p_this, char const * psz_cmd,
219 vlc_value_t oldval, vlc_value_t newval,
225 libvlc_media_player_t * p_mi = p_userdata;
226 libvlc_event_t event;
228 libvlc_media_set_state( p_mi->p_md, libvlc_NothingSpecial, NULL);
229 event.type = libvlc_MediaPlayerPausableChanged;
230 event.u.media_player_pausable_changed.new_pausable = newval.b_bool;
232 libvlc_event_send( p_mi->p_event_manager, &event );
237 * input_position_changed (Private) (input var "intf-change" Callback)
240 input_position_changed( vlc_object_t * p_this, char const * psz_cmd,
241 vlc_value_t oldval, vlc_value_t newval,
245 libvlc_media_player_t * p_mi = p_userdata;
248 if (!strncmp(psz_cmd, "intf", 4 /* "-change" no need to go further */))
250 input_thread_t * p_input = (input_thread_t *)p_this;
252 var_Get( p_input, "state", &val );
253 if( val.i_int != PLAYING_S )
254 return VLC_SUCCESS; /* Don't send the position while stopped */
256 var_Get( p_input, "position", &val );
259 val.i_time = newval.i_time;
261 libvlc_event_t event;
262 event.type = libvlc_MediaPlayerPositionChanged;
263 event.u.media_player_position_changed.new_position = val.f_float;
265 libvlc_event_send( p_mi->p_event_manager, &event );
270 * input_time_changed (Private) (input var "intf-change" Callback)
273 input_time_changed( vlc_object_t * p_this, char const * psz_cmd,
274 vlc_value_t oldval, vlc_value_t newval,
278 libvlc_media_player_t * p_mi = p_userdata;
281 if (!strncmp(psz_cmd, "intf", 4 /* "-change" no need to go further */))
283 input_thread_t * p_input = (input_thread_t *)p_this;
285 var_Get( p_input, "state", &val );
286 if( val.i_int != PLAYING_S )
287 return VLC_SUCCESS; /* Don't send the position while stopped */
289 var_Get( p_input, "time", &val );
292 val.i_time = newval.i_time;
294 libvlc_event_t event;
295 event.type = libvlc_MediaPlayerTimeChanged;
296 event.u.media_player_time_changed.new_time = val.i_time;
297 libvlc_event_send( p_mi->p_event_manager, &event );
301 /**************************************************************************
302 * Create a Media Instance object
303 **************************************************************************/
304 libvlc_media_player_t *
305 libvlc_media_player_new( libvlc_instance_t * p_libvlc_instance,
306 libvlc_exception_t * p_e )
308 libvlc_media_player_t * p_mi;
310 if( !p_libvlc_instance )
312 libvlc_exception_raise( p_e, "invalid libvlc instance" );
316 p_mi = malloc( sizeof(libvlc_media_player_t) );
319 libvlc_exception_raise( p_e, "Not enough memory" );
324 p_mi->p_libvlc_instance = p_libvlc_instance;
325 p_mi->p_input_thread = NULL;
326 /* refcount strategy:
327 * - All items created by _new start with a refcount set to 1
328 * - Accessor _release decrease the refcount by 1, if after that
329 * operation the refcount is 0, the object is destroyed.
330 * - Accessor _retain increase the refcount by 1 (XXX: to implement) */
331 p_mi->i_refcount = 1;
332 p_mi->b_own_its_input_thread = true;
333 /* object_lock strategy:
334 * - No lock held in constructor
335 * - Lock when accessing all variable this lock is held
336 * - Lock when attempting to destroy the object the lock is also held */
337 vlc_mutex_init( &p_mi->object_lock );
338 p_mi->p_event_manager = libvlc_event_manager_new( p_mi,
339 p_libvlc_instance, p_e );
340 if( libvlc_exception_raised( p_e ) )
346 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
347 libvlc_MediaPlayerNothingSpecial, p_e );
348 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
349 libvlc_MediaPlayerOpening, p_e );
350 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
351 libvlc_MediaPlayerBuffering, p_e );
352 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
353 libvlc_MediaPlayerPlaying, p_e );
354 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
355 libvlc_MediaPlayerPaused, p_e );
356 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
357 libvlc_MediaPlayerStopped, p_e );
358 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
359 libvlc_MediaPlayerForward, p_e );
360 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
361 libvlc_MediaPlayerBackward, p_e );
362 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
363 libvlc_MediaPlayerEndReached, p_e );
364 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
365 libvlc_MediaPlayerEncounteredError, p_e );
367 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
368 libvlc_MediaPlayerPositionChanged, p_e );
369 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
370 libvlc_MediaPlayerTimeChanged, p_e );
371 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
372 libvlc_MediaPlayerSeekableChanged, p_e );
373 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
374 libvlc_MediaPlayerPausableChanged, p_e );
379 /**************************************************************************
380 * Create a Media Instance object with a media descriptor
381 **************************************************************************/
382 libvlc_media_player_t *
383 libvlc_media_player_new_from_media(
384 libvlc_media_t * p_md,
385 libvlc_exception_t *p_e )
387 libvlc_media_player_t * p_mi;
388 p_mi = libvlc_media_player_new( p_md->p_libvlc_instance, p_e );
393 libvlc_media_retain( p_md );
399 /**************************************************************************
400 * Create a new media instance object from an input_thread (Libvlc Internal)
401 **************************************************************************/
402 libvlc_media_player_t * libvlc_media_player_new_from_input_thread(
403 struct libvlc_instance_t *p_libvlc_instance,
404 input_thread_t *p_input,
405 libvlc_exception_t *p_e )
407 libvlc_media_player_t * p_mi;
411 libvlc_exception_raise( p_e, "invalid input thread" );
415 p_mi = libvlc_media_player_new( p_libvlc_instance, p_e );
420 p_mi->p_md = libvlc_media_new_from_input_item(
422 input_GetItem( p_input ), p_e );
426 libvlc_media_player_destroy( p_mi );
430 /* will be released in media_player_release() */
431 vlc_object_yield( p_input );
433 p_mi->p_input_thread = p_input;
434 p_mi->b_own_its_input_thread = false;
439 /**************************************************************************
440 * Destroy a Media Instance object (libvlc internal)
442 * Warning: No lock held here, but hey, this is internal.
443 **************************************************************************/
444 void libvlc_media_player_destroy( libvlc_media_player_t *p_mi )
446 input_thread_t *p_input_thread;
447 libvlc_exception_t p_e;
449 libvlc_exception_init( &p_e );
454 p_input_thread = libvlc_get_input_thread( p_mi, &p_e );
456 if( libvlc_exception_raised( &p_e ) )
458 libvlc_event_manager_release( p_mi->p_event_manager );
459 libvlc_exception_clear( &p_e );
461 return; /* no need to worry about no input thread */
463 vlc_mutex_destroy( &p_mi->object_lock );
465 vlc_object_release( p_input_thread );
467 libvlc_media_release( p_mi->p_md );
472 /**************************************************************************
473 * Release a Media Instance object
474 **************************************************************************/
475 void libvlc_media_player_release( libvlc_media_player_t *p_mi )
480 vlc_mutex_lock( &p_mi->object_lock );
484 if( p_mi->i_refcount > 0 )
486 vlc_mutex_unlock( &p_mi->object_lock );
489 vlc_mutex_unlock( &p_mi->object_lock );
490 vlc_mutex_destroy( &p_mi->object_lock );
492 release_input_thread( p_mi );
494 libvlc_event_manager_release( p_mi->p_event_manager );
496 libvlc_media_release( p_mi->p_md );
501 /**************************************************************************
502 * Retain a Media Instance object
503 **************************************************************************/
504 void libvlc_media_player_retain( libvlc_media_player_t *p_mi )
512 /**************************************************************************
513 * Set the Media descriptor associated with the instance
514 **************************************************************************/
515 void libvlc_media_player_set_media(
516 libvlc_media_player_t *p_mi,
517 libvlc_media_t *p_md,
518 libvlc_exception_t *p_e )
525 vlc_mutex_lock( &p_mi->object_lock );
527 release_input_thread( p_mi );
530 libvlc_media_set_state( p_mi->p_md, libvlc_NothingSpecial, p_e );
532 libvlc_media_release( p_mi->p_md );
537 vlc_mutex_unlock( &p_mi->object_lock );
538 return; /* It is ok to pass a NULL md */
541 libvlc_media_retain( p_md );
544 /* The policy here is to ignore that we were created using a different
545 * libvlc_instance, because we don't really care */
546 p_mi->p_libvlc_instance = p_md->p_libvlc_instance;
548 vlc_mutex_unlock( &p_mi->object_lock );
551 /**************************************************************************
552 * Get the Media descriptor associated with the instance
553 **************************************************************************/
555 libvlc_media_player_get_media(
556 libvlc_media_player_t *p_mi,
557 libvlc_exception_t *p_e )
564 libvlc_media_retain( p_mi->p_md );
568 /**************************************************************************
569 * Get the event Manager
570 **************************************************************************/
571 libvlc_event_manager_t *
572 libvlc_media_player_event_manager(
573 libvlc_media_player_t *p_mi,
574 libvlc_exception_t *p_e )
578 return p_mi->p_event_manager;
581 /**************************************************************************
583 **************************************************************************/
584 void libvlc_media_player_play( libvlc_media_player_t *p_mi,
585 libvlc_exception_t *p_e )
587 input_thread_t * p_input_thread;
589 if( (p_input_thread = libvlc_get_input_thread( p_mi, p_e )) )
591 /* A thread already exists, send it a play message */
592 input_Control( p_input_thread, INPUT_SET_STATE, PLAYING_S );
593 vlc_object_release( p_input_thread );
597 /* Ignore previous exception */
598 libvlc_exception_clear( p_e );
600 vlc_mutex_lock( &p_mi->object_lock );
604 libvlc_exception_raise( p_e, "no associated media descriptor" );
605 vlc_mutex_unlock( &p_mi->object_lock );
609 p_mi->p_input_thread = input_CreateThread( p_mi->p_libvlc_instance->p_libvlc_int,
610 p_mi->p_md->p_input_item );
613 if( !p_mi->p_input_thread )
615 vlc_mutex_unlock( &p_mi->object_lock );
619 p_input_thread = p_mi->p_input_thread;
624 val.i_int = p_mi->drawable;
625 var_Create( p_input_thread, "drawable", VLC_VAR_DOINHERIT );
626 var_Set( p_input_thread, "drawable", val );
629 vlc_event_manager_t * p_em = input_get_event_manager( p_input_thread );
630 vlc_event_attach( p_em, vlc_InputStateChanged, input_state_changed, p_mi );
632 var_AddCallback( p_input_thread, "seekable", input_seekable_changed, p_mi );
633 var_AddCallback( p_input_thread, "pausable", input_pausable_changed, p_mi );
634 var_AddCallback( p_input_thread, "intf-change", input_position_changed, p_mi );
635 var_AddCallback( p_input_thread, "intf-change", input_time_changed, p_mi );
637 vlc_mutex_unlock( &p_mi->object_lock );
640 /**************************************************************************
642 **************************************************************************/
643 void libvlc_media_player_pause( libvlc_media_player_t *p_mi,
644 libvlc_exception_t *p_e )
646 input_thread_t * p_input_thread = libvlc_get_input_thread( p_mi, p_e );
648 if( !p_input_thread )
651 libvlc_state_t state = libvlc_media_player_get_state( p_mi, p_e );
653 if( state == libvlc_Playing )
655 if( libvlc_media_player_can_pause( p_mi, p_e ) )
656 input_Control( p_input_thread, INPUT_SET_STATE, PAUSE_S );
658 libvlc_media_player_stop( p_mi, p_e );
661 input_Control( p_input_thread, INPUT_SET_STATE, PLAYING_S );
663 vlc_object_release( p_input_thread );
666 /**************************************************************************
668 **************************************************************************/
669 void libvlc_media_player_stop( libvlc_media_player_t *p_mi,
670 libvlc_exception_t *p_e )
672 libvlc_state_t state = libvlc_media_player_get_state( p_mi, p_e );
674 if( state == libvlc_Playing || state == libvlc_Paused )
676 /* Send a stop notification event only of we are in playing or paused states */
677 libvlc_media_set_state( p_mi->p_md, libvlc_Ended, p_e );
679 /* Construct and send the event */
680 libvlc_event_t event;
681 event.type = libvlc_MediaPlayerEndReached;
682 libvlc_event_send( p_mi->p_event_manager, &event );
685 if( p_mi->b_own_its_input_thread )
687 vlc_mutex_lock( &p_mi->object_lock );
688 release_input_thread( p_mi ); /* This will stop the input thread */
689 vlc_mutex_unlock( &p_mi->object_lock );
693 input_thread_t * p_input_thread = libvlc_get_input_thread( p_mi, p_e );
695 if( !p_input_thread )
698 input_StopThread( p_input_thread );
699 vlc_object_release( p_input_thread );
703 /**************************************************************************
705 **************************************************************************/
706 void libvlc_media_player_set_drawable( libvlc_media_player_t *p_mi,
707 libvlc_drawable_t drawable,
708 libvlc_exception_t *p_e )
710 input_thread_t *p_input_thread;
711 vout_thread_t *p_vout = NULL;
713 p_mi->drawable = drawable;
715 /* Allow on the fly drawable changing. This is tricky has this may
716 * not be supported by every vout. We though can't disable it
717 * because of some creepy drawable type that are not flexible enough
718 * (Win32 HWND for instance) */
719 p_input_thread = libvlc_get_input_thread( p_mi, p_e );
720 if( !p_input_thread ) {
721 /* No input, nothing more to do, we are fine */
722 libvlc_exception_clear( p_e );
726 p_vout = vlc_object_find( p_input_thread, VLC_OBJECT_VOUT, FIND_CHILD );
729 vout_Control( p_vout , VOUT_REPARENT, drawable);
730 vlc_object_release( p_vout );
732 vlc_object_release( p_input_thread );
735 /**************************************************************************
737 **************************************************************************/
739 libvlc_media_player_get_drawable ( libvlc_media_player_t *p_mi, libvlc_exception_t *p_e )
742 return p_mi->drawable;
745 /**************************************************************************
746 * Getters for stream information
747 **************************************************************************/
748 libvlc_time_t libvlc_media_player_get_length(
749 libvlc_media_player_t *p_mi,
750 libvlc_exception_t *p_e )
752 input_thread_t *p_input_thread;
755 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
756 if( !p_input_thread )
759 var_Get( p_input_thread, "length", &val );
760 vlc_object_release( p_input_thread );
762 return (val.i_time+500LL)/1000LL;
765 libvlc_time_t libvlc_media_player_get_time(
766 libvlc_media_player_t *p_mi,
767 libvlc_exception_t *p_e )
769 input_thread_t *p_input_thread;
772 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
773 if( !p_input_thread )
776 var_Get( p_input_thread , "time", &val );
777 vlc_object_release( p_input_thread );
778 return (val.i_time+500LL)/1000LL;
781 void libvlc_media_player_set_time(
782 libvlc_media_player_t *p_mi,
784 libvlc_exception_t *p_e )
786 input_thread_t *p_input_thread;
789 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
790 if( !p_input_thread )
793 value.i_time = time*1000LL;
794 var_Set( p_input_thread, "time", value );
795 vlc_object_release( p_input_thread );
798 void libvlc_media_player_set_position(
799 libvlc_media_player_t *p_mi,
801 libvlc_exception_t *p_e )
803 input_thread_t *p_input_thread;
805 val.f_float = position;
807 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
808 if( !p_input_thread )
811 var_Set( p_input_thread, "position", val );
812 vlc_object_release( p_input_thread );
815 float libvlc_media_player_get_position(
816 libvlc_media_player_t *p_mi,
817 libvlc_exception_t *p_e )
819 input_thread_t *p_input_thread;
822 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
823 if( !p_input_thread )
826 var_Get( p_input_thread, "position", &val );
827 vlc_object_release( p_input_thread );
832 void libvlc_media_player_set_chapter(
833 libvlc_media_player_t *p_mi,
835 libvlc_exception_t *p_e )
837 input_thread_t *p_input_thread;
841 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
842 if( !p_input_thread )
845 var_Set( p_input_thread, "chapter", val );
846 vlc_object_release( p_input_thread );
849 int libvlc_media_player_get_chapter(
850 libvlc_media_player_t *p_mi,
851 libvlc_exception_t *p_e )
853 input_thread_t *p_input_thread;
856 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
857 if( !p_input_thread )
860 var_Get( p_input_thread, "chapter", &val );
861 vlc_object_release( p_input_thread );
866 int libvlc_media_player_get_chapter_count(
867 libvlc_media_player_t *p_mi,
868 libvlc_exception_t *p_e )
870 input_thread_t *p_input_thread;
873 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
874 if( !p_input_thread )
877 var_Change( p_input_thread, "chapter", VLC_VAR_CHOICESCOUNT, &val, NULL );
878 vlc_object_release( p_input_thread );
883 float libvlc_media_player_get_fps(
884 libvlc_media_player_t *p_mi,
885 libvlc_exception_t *p_e)
887 input_thread_t *p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
892 if( input_Control( p_input_thread, INPUT_GET_VIDEO_FPS, &f_fps ) )
894 vlc_object_release( p_input_thread );
899 int libvlc_media_player_will_play( libvlc_media_player_t *p_mi,
900 libvlc_exception_t *p_e)
902 input_thread_t *p_input_thread =
903 libvlc_get_input_thread ( p_mi, p_e);
904 if ( !p_input_thread )
907 if ( !p_input_thread->b_die && !p_input_thread->b_dead )
909 vlc_object_release( p_input_thread );
912 vlc_object_release( p_input_thread );
916 void libvlc_media_player_set_rate(
917 libvlc_media_player_t *p_mi,
919 libvlc_exception_t *p_e )
921 input_thread_t *p_input_thread;
925 RAISEVOID( "Rate value is invalid" );
927 val.i_int = 1000.0f/rate;
929 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
930 if ( !p_input_thread )
933 var_Set( p_input_thread, "rate", val );
934 vlc_object_release( p_input_thread );
937 float libvlc_media_player_get_rate(
938 libvlc_media_player_t *p_mi,
939 libvlc_exception_t *p_e )
941 input_thread_t *p_input_thread;
944 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
945 if ( !p_input_thread )
948 var_Get( p_input_thread, "rate", &val );
949 vlc_object_release( p_input_thread );
951 return (float)1000.0f/val.i_int;
954 libvlc_state_t libvlc_media_player_get_state(
955 libvlc_media_player_t *p_mi,
956 libvlc_exception_t *p_e )
958 input_thread_t *p_input_thread;
961 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
962 if ( !p_input_thread )
964 /* We do return the right value, no need to throw an exception */
965 if( libvlc_exception_raised( p_e ) )
966 libvlc_exception_clear( p_e );
970 var_Get( p_input_thread, "state", &val );
971 vlc_object_release( p_input_thread );
973 return vlc_to_libvlc_state(val.i_int);
976 int libvlc_media_player_is_seekable( libvlc_media_player_t *p_mi,
977 libvlc_exception_t *p_e )
979 input_thread_t *p_input_thread;
982 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
983 if ( !p_input_thread )
985 /* We do return the right value, no need to throw an exception */
986 if( libvlc_exception_raised( p_e ) )
987 libvlc_exception_clear( p_e );
990 var_Get( p_input_thread, "seekable", &val );
991 vlc_object_release( p_input_thread );
996 int libvlc_media_player_can_pause( libvlc_media_player_t *p_mi,
997 libvlc_exception_t *p_e )
999 input_thread_t *p_input_thread;
1002 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
1003 if ( !p_input_thread )
1005 /* We do return the right value, no need to throw an exception */
1006 if( libvlc_exception_raised( p_e ) )
1007 libvlc_exception_clear( p_e );
1010 var_Get( p_input_thread, "can-pause", &val );
1011 vlc_object_release( p_input_thread );