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_yield( 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;
187 libvlc_media_set_state( p_mi->p_md, libvlc_Error, NULL);
188 forwarded_event.type = libvlc_MediaPlayerEncounteredError;
195 libvlc_event_send( p_mi->p_event_manager, &forwarded_event );
200 input_seekable_changed( vlc_object_t * p_this, char const * psz_cmd,
201 vlc_value_t oldval, vlc_value_t newval,
207 libvlc_media_player_t * p_mi = p_userdata;
208 libvlc_event_t event;
210 libvlc_media_set_state( p_mi->p_md, libvlc_NothingSpecial, NULL);
211 event.type = libvlc_MediaPlayerSeekableChanged;
212 event.u.media_player_seekable_changed.new_seekable = newval.b_bool;
214 libvlc_event_send( p_mi->p_event_manager, &event );
219 input_pausable_changed( vlc_object_t * p_this, char const * psz_cmd,
220 vlc_value_t oldval, vlc_value_t newval,
226 libvlc_media_player_t * p_mi = p_userdata;
227 libvlc_event_t event;
229 libvlc_media_set_state( p_mi->p_md, libvlc_NothingSpecial, NULL);
230 event.type = libvlc_MediaPlayerPausableChanged;
231 event.u.media_player_pausable_changed.new_pausable = newval.b_bool;
233 libvlc_event_send( p_mi->p_event_manager, &event );
238 * input_position_changed (Private) (input var "intf-change" Callback)
241 input_position_changed( vlc_object_t * p_this, char const * psz_cmd,
242 vlc_value_t oldval, vlc_value_t newval,
246 libvlc_media_player_t * p_mi = p_userdata;
249 if (!strncmp(psz_cmd, "intf", 4 /* "-change" no need to go further */))
251 input_thread_t * p_input = (input_thread_t *)p_this;
253 var_Get( p_input, "state", &val );
254 if( val.i_int != PLAYING_S )
255 return VLC_SUCCESS; /* Don't send the position while stopped */
257 var_Get( p_input, "position", &val );
260 val.i_time = newval.i_time;
262 libvlc_event_t event;
263 event.type = libvlc_MediaPlayerPositionChanged;
264 event.u.media_player_position_changed.new_position = val.f_float;
266 libvlc_event_send( p_mi->p_event_manager, &event );
271 * input_time_changed (Private) (input var "intf-change" Callback)
274 input_time_changed( vlc_object_t * p_this, char const * psz_cmd,
275 vlc_value_t oldval, vlc_value_t newval,
279 libvlc_media_player_t * p_mi = p_userdata;
282 if (!strncmp(psz_cmd, "intf", 4 /* "-change" no need to go further */))
284 input_thread_t * p_input = (input_thread_t *)p_this;
286 var_Get( p_input, "state", &val );
287 if( val.i_int != PLAYING_S )
288 return VLC_SUCCESS; /* Don't send the position while stopped */
290 var_Get( p_input, "time", &val );
293 val.i_time = newval.i_time;
295 libvlc_event_t event;
296 event.type = libvlc_MediaPlayerTimeChanged;
297 event.u.media_player_time_changed.new_time = val.i_time;
298 libvlc_event_send( p_mi->p_event_manager, &event );
302 /**************************************************************************
303 * Create a Media Instance object
304 **************************************************************************/
305 libvlc_media_player_t *
306 libvlc_media_player_new( libvlc_instance_t * p_libvlc_instance,
307 libvlc_exception_t * p_e )
309 libvlc_media_player_t * p_mi;
311 if( !p_libvlc_instance )
313 libvlc_exception_raise( p_e, "invalid libvlc instance" );
317 p_mi = malloc( sizeof(libvlc_media_player_t) );
320 libvlc_exception_raise( p_e, "Not enough memory" );
325 p_mi->p_libvlc_instance = p_libvlc_instance;
326 p_mi->p_input_thread = NULL;
327 /* refcount strategy:
328 * - All items created by _new start with a refcount set to 1
329 * - Accessor _release decrease the refcount by 1, if after that
330 * operation the refcount is 0, the object is destroyed.
331 * - Accessor _retain increase the refcount by 1 (XXX: to implement) */
332 p_mi->i_refcount = 1;
333 p_mi->b_own_its_input_thread = true;
334 /* object_lock strategy:
335 * - No lock held in constructor
336 * - Lock when accessing all variable this lock is held
337 * - Lock when attempting to destroy the object the lock is also held */
338 vlc_mutex_init( &p_mi->object_lock );
339 p_mi->p_event_manager = libvlc_event_manager_new( p_mi,
340 p_libvlc_instance, p_e );
341 if( libvlc_exception_raised( p_e ) )
347 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
348 libvlc_MediaPlayerNothingSpecial, p_e );
349 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
350 libvlc_MediaPlayerOpening, p_e );
351 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
352 libvlc_MediaPlayerBuffering, p_e );
353 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
354 libvlc_MediaPlayerPlaying, p_e );
355 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
356 libvlc_MediaPlayerPaused, p_e );
357 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
358 libvlc_MediaPlayerStopped, p_e );
359 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
360 libvlc_MediaPlayerForward, p_e );
361 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
362 libvlc_MediaPlayerBackward, p_e );
363 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
364 libvlc_MediaPlayerEndReached, p_e );
365 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
366 libvlc_MediaPlayerEncounteredError, p_e );
368 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
369 libvlc_MediaPlayerPositionChanged, p_e );
370 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
371 libvlc_MediaPlayerTimeChanged, p_e );
372 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
373 libvlc_MediaPlayerSeekableChanged, p_e );
374 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
375 libvlc_MediaPlayerPausableChanged, p_e );
380 /**************************************************************************
381 * Create a Media Instance object with a media descriptor
382 **************************************************************************/
383 libvlc_media_player_t *
384 libvlc_media_player_new_from_media(
385 libvlc_media_t * p_md,
386 libvlc_exception_t *p_e )
388 libvlc_media_player_t * p_mi;
389 p_mi = libvlc_media_player_new( p_md->p_libvlc_instance, p_e );
394 libvlc_media_retain( p_md );
400 /**************************************************************************
401 * Create a new media instance object from an input_thread (Libvlc Internal)
402 **************************************************************************/
403 libvlc_media_player_t * libvlc_media_player_new_from_input_thread(
404 struct libvlc_instance_t *p_libvlc_instance,
405 input_thread_t *p_input,
406 libvlc_exception_t *p_e )
408 libvlc_media_player_t * p_mi;
412 libvlc_exception_raise( p_e, "invalid input thread" );
416 p_mi = libvlc_media_player_new( p_libvlc_instance, p_e );
421 p_mi->p_md = libvlc_media_new_from_input_item(
423 input_GetItem( p_input ), p_e );
427 libvlc_media_player_destroy( p_mi );
431 /* will be released in media_player_release() */
432 vlc_object_yield( p_input );
434 p_mi->p_input_thread = p_input;
435 p_mi->b_own_its_input_thread = false;
440 /**************************************************************************
441 * Destroy a Media Instance object (libvlc internal)
443 * Warning: No lock held here, but hey, this is internal.
444 **************************************************************************/
445 void libvlc_media_player_destroy( libvlc_media_player_t *p_mi )
447 input_thread_t *p_input_thread;
448 libvlc_exception_t p_e;
450 libvlc_exception_init( &p_e );
455 p_input_thread = libvlc_get_input_thread( p_mi, &p_e );
457 if( libvlc_exception_raised( &p_e ) )
459 libvlc_event_manager_release( p_mi->p_event_manager );
460 libvlc_exception_clear( &p_e );
462 return; /* no need to worry about no input thread */
464 vlc_mutex_destroy( &p_mi->object_lock );
466 vlc_object_release( p_input_thread );
468 libvlc_media_release( p_mi->p_md );
473 /**************************************************************************
474 * Release a Media Instance object
475 **************************************************************************/
476 void libvlc_media_player_release( libvlc_media_player_t *p_mi )
481 vlc_mutex_lock( &p_mi->object_lock );
485 if( p_mi->i_refcount > 0 )
487 vlc_mutex_unlock( &p_mi->object_lock );
490 vlc_mutex_unlock( &p_mi->object_lock );
491 vlc_mutex_destroy( &p_mi->object_lock );
493 release_input_thread( p_mi );
495 libvlc_event_manager_release( p_mi->p_event_manager );
497 libvlc_media_release( p_mi->p_md );
502 /**************************************************************************
503 * Retain a Media Instance object
504 **************************************************************************/
505 void libvlc_media_player_retain( libvlc_media_player_t *p_mi )
513 /**************************************************************************
514 * Set the Media descriptor associated with the instance
515 **************************************************************************/
516 void libvlc_media_player_set_media(
517 libvlc_media_player_t *p_mi,
518 libvlc_media_t *p_md,
519 libvlc_exception_t *p_e )
526 vlc_mutex_lock( &p_mi->object_lock );
528 release_input_thread( p_mi );
531 libvlc_media_set_state( p_mi->p_md, libvlc_NothingSpecial, p_e );
533 libvlc_media_release( p_mi->p_md );
538 vlc_mutex_unlock( &p_mi->object_lock );
539 return; /* It is ok to pass a NULL md */
542 libvlc_media_retain( p_md );
545 /* The policy here is to ignore that we were created using a different
546 * libvlc_instance, because we don't really care */
547 p_mi->p_libvlc_instance = p_md->p_libvlc_instance;
549 vlc_mutex_unlock( &p_mi->object_lock );
552 /**************************************************************************
553 * Get the Media descriptor associated with the instance
554 **************************************************************************/
556 libvlc_media_player_get_media(
557 libvlc_media_player_t *p_mi,
558 libvlc_exception_t *p_e )
565 libvlc_media_retain( p_mi->p_md );
569 /**************************************************************************
570 * Get the event Manager
571 **************************************************************************/
572 libvlc_event_manager_t *
573 libvlc_media_player_event_manager(
574 libvlc_media_player_t *p_mi,
575 libvlc_exception_t *p_e )
579 return p_mi->p_event_manager;
582 /**************************************************************************
584 **************************************************************************/
585 void libvlc_media_player_play( libvlc_media_player_t *p_mi,
586 libvlc_exception_t *p_e )
588 input_thread_t * p_input_thread;
590 if( (p_input_thread = libvlc_get_input_thread( p_mi, p_e )) )
592 /* A thread already exists, send it a play message */
593 input_Control( p_input_thread, INPUT_SET_STATE, PLAYING_S );
594 vlc_object_release( p_input_thread );
598 /* Ignore previous exception */
599 libvlc_exception_clear( p_e );
601 vlc_mutex_lock( &p_mi->object_lock );
605 libvlc_exception_raise( p_e, "no associated media descriptor" );
606 vlc_mutex_unlock( &p_mi->object_lock );
610 p_mi->p_input_thread = input_CreateThread( p_mi->p_libvlc_instance->p_libvlc_int,
611 p_mi->p_md->p_input_item );
614 if( !p_mi->p_input_thread )
616 vlc_mutex_unlock( &p_mi->object_lock );
620 p_input_thread = p_mi->p_input_thread;
625 val.i_int = p_mi->drawable;
626 var_Create( p_input_thread, "drawable", VLC_VAR_DOINHERIT );
627 var_Set( p_input_thread, "drawable", val );
630 vlc_event_manager_t * p_em = input_get_event_manager( p_input_thread );
631 vlc_event_attach( p_em, vlc_InputStateChanged, input_state_changed, p_mi );
633 var_AddCallback( p_input_thread, "seekable", input_seekable_changed, p_mi );
634 var_AddCallback( p_input_thread, "pausable", input_pausable_changed, p_mi );
635 var_AddCallback( p_input_thread, "intf-change", input_position_changed, p_mi );
636 var_AddCallback( p_input_thread, "intf-change", input_time_changed, p_mi );
638 vlc_mutex_unlock( &p_mi->object_lock );
641 /**************************************************************************
643 **************************************************************************/
644 void libvlc_media_player_pause( libvlc_media_player_t *p_mi,
645 libvlc_exception_t *p_e )
647 input_thread_t * p_input_thread = libvlc_get_input_thread( p_mi, p_e );
649 if( !p_input_thread )
652 libvlc_state_t state = libvlc_media_player_get_state( p_mi, p_e );
654 if( state == libvlc_Playing )
656 if( libvlc_media_player_can_pause( p_mi, p_e ) )
657 input_Control( p_input_thread, INPUT_SET_STATE, PAUSE_S );
659 libvlc_media_player_stop( p_mi, p_e );
662 input_Control( p_input_thread, INPUT_SET_STATE, PLAYING_S );
664 vlc_object_release( p_input_thread );
667 /**************************************************************************
669 **************************************************************************/
670 void libvlc_media_player_stop( libvlc_media_player_t *p_mi,
671 libvlc_exception_t *p_e )
673 libvlc_state_t state = libvlc_media_player_get_state( p_mi, p_e );
675 if( state == libvlc_Playing || state == libvlc_Paused )
677 /* Send a stop notification event only of we are in playing or paused states */
678 libvlc_media_set_state( p_mi->p_md, libvlc_Ended, p_e );
680 /* Construct and send the event */
681 libvlc_event_t event;
682 event.type = libvlc_MediaPlayerEndReached;
683 libvlc_event_send( p_mi->p_event_manager, &event );
686 if( p_mi->b_own_its_input_thread )
688 vlc_mutex_lock( &p_mi->object_lock );
689 release_input_thread( p_mi ); /* This will stop the input thread */
690 vlc_mutex_unlock( &p_mi->object_lock );
694 input_thread_t * p_input_thread = libvlc_get_input_thread( p_mi, p_e );
696 if( !p_input_thread )
699 input_StopThread( p_input_thread );
700 vlc_object_release( p_input_thread );
704 /**************************************************************************
706 **************************************************************************/
707 void libvlc_media_player_set_drawable( libvlc_media_player_t *p_mi,
708 libvlc_drawable_t drawable,
709 libvlc_exception_t *p_e )
711 input_thread_t *p_input_thread;
712 vout_thread_t *p_vout = NULL;
714 p_mi->drawable = drawable;
716 /* Allow on the fly drawable changing. This is tricky has this may
717 * not be supported by every vout. We though can't disable it
718 * because of some creepy drawable type that are not flexible enough
719 * (Win32 HWND for instance) */
720 p_input_thread = libvlc_get_input_thread( p_mi, p_e );
721 if( !p_input_thread ) {
722 /* No input, nothing more to do, we are fine */
723 libvlc_exception_clear( p_e );
727 p_vout = vlc_object_find( p_input_thread, VLC_OBJECT_VOUT, FIND_CHILD );
730 vout_Control( p_vout , VOUT_REPARENT, drawable);
731 vlc_object_release( p_vout );
733 vlc_object_release( p_input_thread );
736 /**************************************************************************
738 **************************************************************************/
740 libvlc_media_player_get_drawable ( libvlc_media_player_t *p_mi, libvlc_exception_t *p_e )
743 return p_mi->drawable;
746 /**************************************************************************
747 * Getters for stream information
748 **************************************************************************/
749 libvlc_time_t libvlc_media_player_get_length(
750 libvlc_media_player_t *p_mi,
751 libvlc_exception_t *p_e )
753 input_thread_t *p_input_thread;
756 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
757 if( !p_input_thread )
760 var_Get( p_input_thread, "length", &val );
761 vlc_object_release( p_input_thread );
763 return (val.i_time+500LL)/1000LL;
766 libvlc_time_t libvlc_media_player_get_time(
767 libvlc_media_player_t *p_mi,
768 libvlc_exception_t *p_e )
770 input_thread_t *p_input_thread;
773 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
774 if( !p_input_thread )
777 var_Get( p_input_thread , "time", &val );
778 vlc_object_release( p_input_thread );
779 return (val.i_time+500LL)/1000LL;
782 void libvlc_media_player_set_time(
783 libvlc_media_player_t *p_mi,
785 libvlc_exception_t *p_e )
787 input_thread_t *p_input_thread;
790 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
791 if( !p_input_thread )
794 value.i_time = time*1000LL;
795 var_Set( p_input_thread, "time", value );
796 vlc_object_release( p_input_thread );
799 void libvlc_media_player_set_position(
800 libvlc_media_player_t *p_mi,
802 libvlc_exception_t *p_e )
804 input_thread_t *p_input_thread;
806 val.f_float = position;
808 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
809 if( !p_input_thread )
812 var_Set( p_input_thread, "position", val );
813 vlc_object_release( p_input_thread );
816 float libvlc_media_player_get_position(
817 libvlc_media_player_t *p_mi,
818 libvlc_exception_t *p_e )
820 input_thread_t *p_input_thread;
823 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
824 if( !p_input_thread )
827 var_Get( p_input_thread, "position", &val );
828 vlc_object_release( p_input_thread );
833 void libvlc_media_player_set_chapter(
834 libvlc_media_player_t *p_mi,
836 libvlc_exception_t *p_e )
838 input_thread_t *p_input_thread;
842 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
843 if( !p_input_thread )
846 var_Set( p_input_thread, "chapter", val );
847 vlc_object_release( p_input_thread );
850 int libvlc_media_player_get_chapter(
851 libvlc_media_player_t *p_mi,
852 libvlc_exception_t *p_e )
854 input_thread_t *p_input_thread;
857 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
858 if( !p_input_thread )
861 var_Get( p_input_thread, "chapter", &val );
862 vlc_object_release( p_input_thread );
867 int libvlc_media_player_get_chapter_count(
868 libvlc_media_player_t *p_mi,
869 libvlc_exception_t *p_e )
871 input_thread_t *p_input_thread;
874 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
875 if( !p_input_thread )
878 var_Change( p_input_thread, "chapter", VLC_VAR_CHOICESCOUNT, &val, NULL );
879 vlc_object_release( p_input_thread );
884 float libvlc_media_player_get_fps(
885 libvlc_media_player_t *p_mi,
886 libvlc_exception_t *p_e)
888 input_thread_t *p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
893 if( input_Control( p_input_thread, INPUT_GET_VIDEO_FPS, &f_fps ) )
895 vlc_object_release( p_input_thread );
900 int libvlc_media_player_will_play( libvlc_media_player_t *p_mi,
901 libvlc_exception_t *p_e)
903 input_thread_t *p_input_thread =
904 libvlc_get_input_thread ( p_mi, p_e);
905 if ( !p_input_thread )
908 if ( !p_input_thread->b_die && !p_input_thread->b_dead )
910 vlc_object_release( p_input_thread );
913 vlc_object_release( p_input_thread );
917 void libvlc_media_player_set_rate(
918 libvlc_media_player_t *p_mi,
920 libvlc_exception_t *p_e )
922 input_thread_t *p_input_thread;
926 RAISEVOID( "Rate value is invalid" );
928 val.i_int = 1000.0f/rate;
930 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
931 if ( !p_input_thread )
934 var_Set( p_input_thread, "rate", val );
935 vlc_object_release( p_input_thread );
938 float libvlc_media_player_get_rate(
939 libvlc_media_player_t *p_mi,
940 libvlc_exception_t *p_e )
942 input_thread_t *p_input_thread;
945 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
946 if ( !p_input_thread )
949 var_Get( p_input_thread, "rate", &val );
950 vlc_object_release( p_input_thread );
952 return (float)1000.0f/val.i_int;
955 libvlc_state_t libvlc_media_player_get_state(
956 libvlc_media_player_t *p_mi,
957 libvlc_exception_t *p_e )
959 input_thread_t *p_input_thread;
962 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
963 if ( !p_input_thread )
965 /* We do return the right value, no need to throw an exception */
966 if( libvlc_exception_raised( p_e ) )
967 libvlc_exception_clear( p_e );
971 var_Get( p_input_thread, "state", &val );
972 vlc_object_release( p_input_thread );
974 return vlc_to_libvlc_state(val.i_int);
977 int libvlc_media_player_is_seekable( libvlc_media_player_t *p_mi,
978 libvlc_exception_t *p_e )
980 input_thread_t *p_input_thread;
983 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
984 if ( !p_input_thread )
986 /* We do return the right value, no need to throw an exception */
987 if( libvlc_exception_raised( p_e ) )
988 libvlc_exception_clear( p_e );
991 var_Get( p_input_thread, "seekable", &val );
992 vlc_object_release( p_input_thread );
997 int libvlc_media_player_can_pause( libvlc_media_player_t *p_mi,
998 libvlc_exception_t *p_e )
1000 input_thread_t *p_input_thread;
1003 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
1004 if ( !p_input_thread )
1006 /* We do return the right value, no need to throw an exception */
1007 if( libvlc_exception_raised( p_e ) )
1008 libvlc_exception_clear( p_e );
1011 var_Get( p_input_thread, "can-pause", &val );
1012 vlc_object_release( p_input_thread );