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 );
100 vlc_thread_join( p_input_thread );
102 var_Destroy( p_input_thread, "drawable" );
105 vlc_object_release( p_input_thread );
107 p_mi->p_input_thread = NULL;
111 * Retrieve the input thread. Be sure to release the object
112 * once you are done with it. (libvlc Internal)
114 * Object lock is held.
116 input_thread_t *libvlc_get_input_thread( libvlc_media_player_t *p_mi,
117 libvlc_exception_t *p_e )
119 input_thread_t *p_input_thread;
121 if( !p_mi ) RAISENULL( "Media Instance is NULL" );
123 vlc_mutex_lock( &p_mi->object_lock );
125 if( !p_mi->p_input_thread )
127 vlc_mutex_unlock( &p_mi->object_lock );
128 RAISENULL( "Input is NULL" );
131 p_input_thread = p_mi->p_input_thread;
132 vlc_object_hold( p_input_thread );
134 vlc_mutex_unlock( &p_mi->object_lock );
136 return p_input_thread;
140 * input_state_changed (Private) (vlc_InputStateChanged callback)
143 input_state_changed( const vlc_event_t * event, void * p_userdata )
145 libvlc_media_player_t * p_mi = p_userdata;
146 libvlc_event_t forwarded_event;
147 libvlc_event_type_t type = event->u.input_state_changed.new_state;
152 libvlc_media_set_state( p_mi->p_md, libvlc_NothingSpecial, NULL);
153 forwarded_event.type = libvlc_MediaPlayerNothingSpecial;
156 libvlc_media_set_state( p_mi->p_md, libvlc_Opening, NULL);
157 forwarded_event.type = libvlc_MediaPlayerOpening;
160 libvlc_media_set_state( p_mi->p_md, libvlc_Buffering, NULL);
161 forwarded_event.type = libvlc_MediaPlayerBuffering;
164 libvlc_media_set_state( p_mi->p_md, libvlc_Playing, NULL);
165 forwarded_event.type = libvlc_MediaPlayerPlaying;
168 libvlc_media_set_state( p_mi->p_md, libvlc_Paused, NULL);
169 forwarded_event.type = libvlc_MediaPlayerPaused;
172 libvlc_media_set_state( p_mi->p_md, libvlc_Stopped, NULL);
173 forwarded_event.type = libvlc_MediaPlayerStopped;
176 libvlc_media_set_state( p_mi->p_md, libvlc_Forward, NULL);
177 forwarded_event.type = libvlc_MediaPlayerForward;
180 libvlc_media_set_state( p_mi->p_md, libvlc_Backward, NULL);
181 forwarded_event.type = libvlc_MediaPlayerBackward;
184 libvlc_media_set_state( p_mi->p_md, libvlc_Ended, NULL);
185 forwarded_event.type = libvlc_MediaPlayerEndReached;
188 libvlc_media_set_state( p_mi->p_md, libvlc_Error, NULL);
189 forwarded_event.type = libvlc_MediaPlayerEncounteredError;
196 libvlc_event_send( p_mi->p_event_manager, &forwarded_event );
201 input_seekable_changed( vlc_object_t * p_this, char const * psz_cmd,
202 vlc_value_t oldval, vlc_value_t newval,
208 libvlc_media_player_t * p_mi = p_userdata;
209 libvlc_event_t event;
211 libvlc_media_set_state( p_mi->p_md, libvlc_NothingSpecial, NULL);
212 event.type = libvlc_MediaPlayerSeekableChanged;
213 event.u.media_player_seekable_changed.new_seekable = newval.b_bool;
215 libvlc_event_send( p_mi->p_event_manager, &event );
220 input_pausable_changed( vlc_object_t * p_this, char const * psz_cmd,
221 vlc_value_t oldval, vlc_value_t newval,
227 libvlc_media_player_t * p_mi = p_userdata;
228 libvlc_event_t event;
230 libvlc_media_set_state( p_mi->p_md, libvlc_NothingSpecial, NULL);
231 event.type = libvlc_MediaPlayerPausableChanged;
232 event.u.media_player_pausable_changed.new_pausable = newval.b_bool;
234 libvlc_event_send( p_mi->p_event_manager, &event );
239 * input_position_changed (Private) (input var "intf-change" Callback)
242 input_position_changed( vlc_object_t * p_this, char const * psz_cmd,
243 vlc_value_t oldval, vlc_value_t newval,
247 libvlc_media_player_t * p_mi = p_userdata;
250 if (!strncmp(psz_cmd, "intf", 4 /* "-change" no need to go further */))
252 input_thread_t * p_input = (input_thread_t *)p_this;
254 var_Get( p_input, "state", &val );
255 if( val.i_int != PLAYING_S )
256 return VLC_SUCCESS; /* Don't send the position while stopped */
258 var_Get( p_input, "position", &val );
261 val.i_time = newval.i_time;
263 libvlc_event_t event;
264 event.type = libvlc_MediaPlayerPositionChanged;
265 event.u.media_player_position_changed.new_position = val.f_float;
267 libvlc_event_send( p_mi->p_event_manager, &event );
272 * input_time_changed (Private) (input var "intf-change" Callback)
275 input_time_changed( vlc_object_t * p_this, char const * psz_cmd,
276 vlc_value_t oldval, vlc_value_t newval,
280 libvlc_media_player_t * p_mi = p_userdata;
283 if (!strncmp(psz_cmd, "intf", 4 /* "-change" no need to go further */))
285 input_thread_t * p_input = (input_thread_t *)p_this;
287 var_Get( p_input, "state", &val );
288 if( val.i_int != PLAYING_S )
289 return VLC_SUCCESS; /* Don't send the position while stopped */
291 var_Get( p_input, "time", &val );
294 val.i_time = newval.i_time;
296 libvlc_event_t event;
297 event.type = libvlc_MediaPlayerTimeChanged;
298 event.u.media_player_time_changed.new_time = val.i_time;
299 libvlc_event_send( p_mi->p_event_manager, &event );
303 /**************************************************************************
304 * Create a Media Instance object
305 **************************************************************************/
306 libvlc_media_player_t *
307 libvlc_media_player_new( libvlc_instance_t * p_libvlc_instance,
308 libvlc_exception_t * p_e )
310 libvlc_media_player_t * p_mi;
312 if( !p_libvlc_instance )
314 libvlc_exception_raise( p_e, "invalid libvlc instance" );
318 p_mi = malloc( sizeof(libvlc_media_player_t) );
321 libvlc_exception_raise( p_e, "Not enough memory" );
326 p_mi->p_libvlc_instance = p_libvlc_instance;
327 p_mi->p_input_thread = NULL;
328 /* refcount strategy:
329 * - All items created by _new start with a refcount set to 1
330 * - Accessor _release decrease the refcount by 1, if after that
331 * operation the refcount is 0, the object is destroyed.
332 * - Accessor _retain increase the refcount by 1 (XXX: to implement) */
333 p_mi->i_refcount = 1;
334 p_mi->b_own_its_input_thread = true;
335 /* object_lock strategy:
336 * - No lock held in constructor
337 * - Lock when accessing all variable this lock is held
338 * - Lock when attempting to destroy the object the lock is also held */
339 vlc_mutex_init( &p_mi->object_lock );
340 p_mi->p_event_manager = libvlc_event_manager_new( p_mi,
341 p_libvlc_instance, p_e );
342 if( libvlc_exception_raised( p_e ) )
348 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
349 libvlc_MediaPlayerNothingSpecial, p_e );
350 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
351 libvlc_MediaPlayerOpening, p_e );
352 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
353 libvlc_MediaPlayerBuffering, p_e );
354 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
355 libvlc_MediaPlayerPlaying, p_e );
356 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
357 libvlc_MediaPlayerPaused, p_e );
358 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
359 libvlc_MediaPlayerStopped, p_e );
360 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
361 libvlc_MediaPlayerForward, p_e );
362 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
363 libvlc_MediaPlayerBackward, p_e );
364 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
365 libvlc_MediaPlayerEndReached, p_e );
366 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
367 libvlc_MediaPlayerEncounteredError, p_e );
369 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
370 libvlc_MediaPlayerPositionChanged, p_e );
371 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
372 libvlc_MediaPlayerTimeChanged, p_e );
373 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
374 libvlc_MediaPlayerSeekableChanged, p_e );
375 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
376 libvlc_MediaPlayerPausableChanged, p_e );
381 /**************************************************************************
382 * Create a Media Instance object with a media descriptor
383 **************************************************************************/
384 libvlc_media_player_t *
385 libvlc_media_player_new_from_media(
386 libvlc_media_t * p_md,
387 libvlc_exception_t *p_e )
389 libvlc_media_player_t * p_mi;
390 p_mi = libvlc_media_player_new( p_md->p_libvlc_instance, p_e );
395 libvlc_media_retain( p_md );
401 /**************************************************************************
402 * Create a new media instance object from an input_thread (Libvlc Internal)
403 **************************************************************************/
404 libvlc_media_player_t * libvlc_media_player_new_from_input_thread(
405 struct libvlc_instance_t *p_libvlc_instance,
406 input_thread_t *p_input,
407 libvlc_exception_t *p_e )
409 libvlc_media_player_t * p_mi;
413 libvlc_exception_raise( p_e, "invalid input thread" );
417 p_mi = libvlc_media_player_new( p_libvlc_instance, p_e );
422 p_mi->p_md = libvlc_media_new_from_input_item(
424 input_GetItem( p_input ), p_e );
428 libvlc_media_player_destroy( p_mi );
432 /* will be released in media_player_release() */
433 vlc_object_hold( p_input );
435 p_mi->p_input_thread = p_input;
436 p_mi->b_own_its_input_thread = false;
441 /**************************************************************************
442 * Destroy a Media Instance object (libvlc internal)
444 * Warning: No lock held here, but hey, this is internal.
445 **************************************************************************/
446 void libvlc_media_player_destroy( libvlc_media_player_t *p_mi )
448 input_thread_t *p_input_thread;
449 libvlc_exception_t p_e;
451 libvlc_exception_init( &p_e );
456 p_input_thread = libvlc_get_input_thread( p_mi, &p_e );
458 if( libvlc_exception_raised( &p_e ) )
460 libvlc_event_manager_release( p_mi->p_event_manager );
461 libvlc_exception_clear( &p_e );
463 return; /* no need to worry about no input thread */
465 vlc_mutex_destroy( &p_mi->object_lock );
467 vlc_object_release( p_input_thread );
469 libvlc_media_release( p_mi->p_md );
474 /**************************************************************************
475 * Release a Media Instance object
476 **************************************************************************/
477 void libvlc_media_player_release( libvlc_media_player_t *p_mi )
482 vlc_mutex_lock( &p_mi->object_lock );
486 if( p_mi->i_refcount > 0 )
488 vlc_mutex_unlock( &p_mi->object_lock );
491 vlc_mutex_unlock( &p_mi->object_lock );
492 vlc_mutex_destroy( &p_mi->object_lock );
494 release_input_thread( p_mi );
496 libvlc_event_manager_release( p_mi->p_event_manager );
498 libvlc_media_release( p_mi->p_md );
503 /**************************************************************************
504 * Retain a Media Instance object
505 **************************************************************************/
506 void libvlc_media_player_retain( libvlc_media_player_t *p_mi )
514 /**************************************************************************
515 * Set the Media descriptor associated with the instance
516 **************************************************************************/
517 void libvlc_media_player_set_media(
518 libvlc_media_player_t *p_mi,
519 libvlc_media_t *p_md,
520 libvlc_exception_t *p_e )
527 vlc_mutex_lock( &p_mi->object_lock );
529 release_input_thread( p_mi );
532 libvlc_media_set_state( p_mi->p_md, libvlc_NothingSpecial, p_e );
534 libvlc_media_release( p_mi->p_md );
539 vlc_mutex_unlock( &p_mi->object_lock );
540 return; /* It is ok to pass a NULL md */
543 libvlc_media_retain( p_md );
546 /* The policy here is to ignore that we were created using a different
547 * libvlc_instance, because we don't really care */
548 p_mi->p_libvlc_instance = p_md->p_libvlc_instance;
550 vlc_mutex_unlock( &p_mi->object_lock );
553 /**************************************************************************
554 * Get the Media descriptor associated with the instance
555 **************************************************************************/
557 libvlc_media_player_get_media(
558 libvlc_media_player_t *p_mi,
559 libvlc_exception_t *p_e )
566 libvlc_media_retain( p_mi->p_md );
570 /**************************************************************************
571 * Get the event Manager
572 **************************************************************************/
573 libvlc_event_manager_t *
574 libvlc_media_player_event_manager(
575 libvlc_media_player_t *p_mi,
576 libvlc_exception_t *p_e )
580 return p_mi->p_event_manager;
583 /**************************************************************************
585 **************************************************************************/
586 void libvlc_media_player_play( libvlc_media_player_t *p_mi,
587 libvlc_exception_t *p_e )
589 input_thread_t * p_input_thread;
591 if( (p_input_thread = libvlc_get_input_thread( p_mi, p_e )) )
593 /* A thread already exists, send it a play message */
594 input_Control( p_input_thread, INPUT_SET_STATE, PLAYING_S );
595 vlc_object_release( p_input_thread );
599 /* Ignore previous exception */
600 libvlc_exception_clear( p_e );
602 vlc_mutex_lock( &p_mi->object_lock );
606 libvlc_exception_raise( p_e, "no associated media descriptor" );
607 vlc_mutex_unlock( &p_mi->object_lock );
611 p_mi->p_input_thread = input_CreateThread( p_mi->p_libvlc_instance->p_libvlc_int,
612 p_mi->p_md->p_input_item );
615 if( !p_mi->p_input_thread )
617 vlc_mutex_unlock( &p_mi->object_lock );
621 p_input_thread = p_mi->p_input_thread;
626 val.i_int = p_mi->drawable;
627 var_Create( p_input_thread, "drawable", VLC_VAR_DOINHERIT );
628 var_Set( p_input_thread, "drawable", val );
631 vlc_event_manager_t * p_em = input_get_event_manager( p_input_thread );
632 vlc_event_attach( p_em, vlc_InputStateChanged, input_state_changed, p_mi );
634 var_AddCallback( p_input_thread, "seekable", input_seekable_changed, p_mi );
635 var_AddCallback( p_input_thread, "pausable", input_pausable_changed, p_mi );
636 var_AddCallback( p_input_thread, "intf-change", input_position_changed, p_mi );
637 var_AddCallback( p_input_thread, "intf-change", input_time_changed, p_mi );
639 vlc_mutex_unlock( &p_mi->object_lock );
642 /**************************************************************************
644 **************************************************************************/
645 void libvlc_media_player_pause( libvlc_media_player_t *p_mi,
646 libvlc_exception_t *p_e )
648 input_thread_t * p_input_thread = libvlc_get_input_thread( p_mi, p_e );
650 if( !p_input_thread )
653 libvlc_state_t state = libvlc_media_player_get_state( p_mi, p_e );
655 if( state == libvlc_Playing )
657 if( libvlc_media_player_can_pause( p_mi, p_e ) )
658 input_Control( p_input_thread, INPUT_SET_STATE, PAUSE_S );
660 libvlc_media_player_stop( p_mi, p_e );
663 input_Control( p_input_thread, INPUT_SET_STATE, PLAYING_S );
665 vlc_object_release( p_input_thread );
668 /**************************************************************************
670 **************************************************************************/
671 void libvlc_media_player_stop( libvlc_media_player_t *p_mi,
672 libvlc_exception_t *p_e )
674 libvlc_state_t state = libvlc_media_player_get_state( p_mi, p_e );
676 if( state == libvlc_Playing || state == libvlc_Paused )
678 /* Send a stop notification event only of we are in playing or paused states */
679 libvlc_media_set_state( p_mi->p_md, libvlc_Ended, p_e );
681 /* Construct and send the event */
682 libvlc_event_t event;
683 event.type = libvlc_MediaPlayerEndReached;
684 libvlc_event_send( p_mi->p_event_manager, &event );
687 if( p_mi->b_own_its_input_thread )
689 vlc_mutex_lock( &p_mi->object_lock );
690 release_input_thread( p_mi ); /* This will stop the input thread */
691 vlc_mutex_unlock( &p_mi->object_lock );
695 input_thread_t * p_input_thread = libvlc_get_input_thread( p_mi, p_e );
697 if( !p_input_thread )
700 input_StopThread( p_input_thread );
701 vlc_object_release( p_input_thread );
705 /**************************************************************************
707 **************************************************************************/
708 void libvlc_media_player_set_drawable( libvlc_media_player_t *p_mi,
709 libvlc_drawable_t drawable,
710 libvlc_exception_t *p_e )
712 input_thread_t *p_input_thread;
713 vout_thread_t *p_vout = NULL;
715 p_mi->drawable = drawable;
717 /* Allow on the fly drawable changing. This is tricky has this may
718 * not be supported by every vout. We though can't disable it
719 * because of some creepy drawable type that are not flexible enough
720 * (Win32 HWND for instance) */
721 p_input_thread = libvlc_get_input_thread( p_mi, p_e );
722 if( !p_input_thread ) {
723 /* No input, nothing more to do, we are fine */
724 libvlc_exception_clear( p_e );
728 p_vout = vlc_object_find( p_input_thread, VLC_OBJECT_VOUT, FIND_CHILD );
731 vout_Control( p_vout , VOUT_REPARENT, drawable);
732 vlc_object_release( p_vout );
734 vlc_object_release( p_input_thread );
737 /**************************************************************************
739 **************************************************************************/
741 libvlc_media_player_get_drawable ( libvlc_media_player_t *p_mi, libvlc_exception_t *p_e )
744 return p_mi->drawable;
747 /**************************************************************************
748 * Getters for stream information
749 **************************************************************************/
750 libvlc_time_t libvlc_media_player_get_length(
751 libvlc_media_player_t *p_mi,
752 libvlc_exception_t *p_e )
754 input_thread_t *p_input_thread;
757 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
758 if( !p_input_thread )
761 var_Get( p_input_thread, "length", &val );
762 vlc_object_release( p_input_thread );
764 return (val.i_time+500LL)/1000LL;
767 libvlc_time_t libvlc_media_player_get_time(
768 libvlc_media_player_t *p_mi,
769 libvlc_exception_t *p_e )
771 input_thread_t *p_input_thread;
774 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
775 if( !p_input_thread )
778 var_Get( p_input_thread , "time", &val );
779 vlc_object_release( p_input_thread );
780 return (val.i_time+500LL)/1000LL;
783 void libvlc_media_player_set_time(
784 libvlc_media_player_t *p_mi,
786 libvlc_exception_t *p_e )
788 input_thread_t *p_input_thread;
791 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
792 if( !p_input_thread )
795 value.i_time = time*1000LL;
796 var_Set( p_input_thread, "time", value );
797 vlc_object_release( p_input_thread );
800 void libvlc_media_player_set_position(
801 libvlc_media_player_t *p_mi,
803 libvlc_exception_t *p_e )
805 input_thread_t *p_input_thread;
807 val.f_float = position;
809 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
810 if( !p_input_thread )
813 var_Set( p_input_thread, "position", val );
814 vlc_object_release( p_input_thread );
817 float libvlc_media_player_get_position(
818 libvlc_media_player_t *p_mi,
819 libvlc_exception_t *p_e )
821 input_thread_t *p_input_thread;
824 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
825 if( !p_input_thread )
828 var_Get( p_input_thread, "position", &val );
829 vlc_object_release( p_input_thread );
834 void libvlc_media_player_set_chapter(
835 libvlc_media_player_t *p_mi,
837 libvlc_exception_t *p_e )
839 input_thread_t *p_input_thread;
843 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
844 if( !p_input_thread )
847 var_Set( p_input_thread, "chapter", val );
848 vlc_object_release( p_input_thread );
851 int libvlc_media_player_get_chapter(
852 libvlc_media_player_t *p_mi,
853 libvlc_exception_t *p_e )
855 input_thread_t *p_input_thread;
858 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
859 if( !p_input_thread )
862 var_Get( p_input_thread, "chapter", &val );
863 vlc_object_release( p_input_thread );
868 int libvlc_media_player_get_chapter_count(
869 libvlc_media_player_t *p_mi,
870 libvlc_exception_t *p_e )
872 input_thread_t *p_input_thread;
875 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
876 if( !p_input_thread )
879 var_Change( p_input_thread, "chapter", VLC_VAR_CHOICESCOUNT, &val, NULL );
880 vlc_object_release( p_input_thread );
885 float libvlc_media_player_get_fps(
886 libvlc_media_player_t *p_mi,
887 libvlc_exception_t *p_e)
889 input_thread_t *p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
894 if( input_Control( p_input_thread, INPUT_GET_VIDEO_FPS, &f_fps ) )
896 vlc_object_release( p_input_thread );
901 int libvlc_media_player_will_play( libvlc_media_player_t *p_mi,
902 libvlc_exception_t *p_e)
904 input_thread_t *p_input_thread =
905 libvlc_get_input_thread ( p_mi, p_e);
906 if ( !p_input_thread )
909 if ( !p_input_thread->b_die && !p_input_thread->b_dead )
911 vlc_object_release( p_input_thread );
914 vlc_object_release( p_input_thread );
918 void libvlc_media_player_set_rate(
919 libvlc_media_player_t *p_mi,
921 libvlc_exception_t *p_e )
923 input_thread_t *p_input_thread;
927 RAISEVOID( "Rate value is invalid" );
929 val.i_int = 1000.0f/rate;
931 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
932 if ( !p_input_thread )
935 var_Set( p_input_thread, "rate", val );
936 vlc_object_release( p_input_thread );
939 float libvlc_media_player_get_rate(
940 libvlc_media_player_t *p_mi,
941 libvlc_exception_t *p_e )
943 input_thread_t *p_input_thread;
946 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
947 if ( !p_input_thread )
950 var_Get( p_input_thread, "rate", &val );
951 vlc_object_release( p_input_thread );
953 return (float)1000.0f/val.i_int;
956 libvlc_state_t libvlc_media_player_get_state(
957 libvlc_media_player_t *p_mi,
958 libvlc_exception_t *p_e )
960 input_thread_t *p_input_thread;
963 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
964 if ( !p_input_thread )
966 /* We do return the right value, no need to throw an exception */
967 if( libvlc_exception_raised( p_e ) )
968 libvlc_exception_clear( p_e );
972 var_Get( p_input_thread, "state", &val );
973 vlc_object_release( p_input_thread );
975 return vlc_to_libvlc_state(val.i_int);
978 int libvlc_media_player_is_seekable( libvlc_media_player_t *p_mi,
979 libvlc_exception_t *p_e )
981 input_thread_t *p_input_thread;
984 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
985 if ( !p_input_thread )
987 /* We do return the right value, no need to throw an exception */
988 if( libvlc_exception_raised( p_e ) )
989 libvlc_exception_clear( p_e );
992 var_Get( p_input_thread, "seekable", &val );
993 vlc_object_release( p_input_thread );
998 int libvlc_media_player_can_pause( libvlc_media_player_t *p_mi,
999 libvlc_exception_t *p_e )
1001 input_thread_t *p_input_thread;
1004 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
1005 if ( !p_input_thread )
1007 /* We do return the right value, no need to throw an exception */
1008 if( libvlc_exception_raised( p_e ) )
1009 libvlc_exception_clear( p_e );
1012 var_Get( p_input_thread, "can-pause", &val );
1013 vlc_object_release( p_input_thread );