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 [END_S] = libvlc_Ended,
60 [FORWARD_S] = libvlc_Forward,
61 [BACKWARD_S] = libvlc_Backward,
62 [ERROR_S] = libvlc_Error,
65 static inline libvlc_state_t vlc_to_libvlc_state( int vlc_state )
67 if( vlc_state < 0 || vlc_state > 6 )
70 return vlc_to_libvlc_state_array[vlc_state];
74 * Release the associated input thread
76 * Object lock is NOT held.
78 static void release_input_thread( libvlc_media_player_t *p_mi )
80 input_thread_t * p_input_thread;
82 if( !p_mi || !p_mi->p_input_thread )
85 p_input_thread = p_mi->p_input_thread;
87 /* No one is tracking this input_thread appart us. Destroy it */
88 if( p_mi->b_own_its_input_thread )
90 vlc_event_manager_t * p_em = input_get_event_manager( p_input_thread );
91 vlc_event_detach( p_em, vlc_InputStateChanged, input_state_changed, p_mi );
92 var_DelCallback( p_input_thread, "seekable", input_seekable_changed, p_mi );
93 var_DelCallback( p_input_thread, "pausable", input_pausable_changed, p_mi );
94 var_DelCallback( p_input_thread, "intf-change", input_position_changed, p_mi );
95 var_DelCallback( p_input_thread, "intf-change", input_time_changed, p_mi );
97 /* We owned this one */
98 input_StopThread( p_input_thread );
100 var_Destroy( p_input_thread, "drawable" );
103 vlc_object_release( p_input_thread );
105 p_mi->p_input_thread = NULL;
109 * Retrieve the input thread. Be sure to release the object
110 * once you are done with it. (libvlc Internal)
112 * Object lock is held.
114 input_thread_t *libvlc_get_input_thread( libvlc_media_player_t *p_mi,
115 libvlc_exception_t *p_e )
117 input_thread_t *p_input_thread;
119 if( !p_mi ) RAISENULL( "Media Instance is NULL" );
121 vlc_mutex_lock( &p_mi->object_lock );
123 if( !p_mi->p_input_thread )
125 vlc_mutex_unlock( &p_mi->object_lock );
126 RAISENULL( "Input is NULL" );
129 p_input_thread = p_mi->p_input_thread;
130 vlc_object_yield( p_input_thread );
132 vlc_mutex_unlock( &p_mi->object_lock );
134 return p_input_thread;
138 * input_state_changed (Private) (vlc_InputStateChanged callback)
141 input_state_changed( const vlc_event_t * event, void * p_userdata )
143 libvlc_media_player_t * p_mi = p_userdata;
144 libvlc_event_t forwarded_event;
145 libvlc_event_type_t type = event->u.input_state_changed.new_state;
150 libvlc_media_set_state( p_mi->p_md, libvlc_NothingSpecial, NULL);
151 forwarded_event.type = libvlc_MediaPlayerNothingSpecial;
154 libvlc_media_set_state( p_mi->p_md, libvlc_Opening, NULL);
155 forwarded_event.type = libvlc_MediaPlayerOpening;
158 libvlc_media_set_state( p_mi->p_md, libvlc_Buffering, NULL);
159 forwarded_event.type = libvlc_MediaPlayerBuffering;
162 libvlc_media_set_state( p_mi->p_md, libvlc_Playing, NULL);
163 forwarded_event.type = libvlc_MediaPlayerPlaying;
166 libvlc_media_set_state( p_mi->p_md, libvlc_Paused, NULL);
167 forwarded_event.type = libvlc_MediaPlayerPaused;
170 libvlc_media_set_state( p_mi->p_md, libvlc_Ended, NULL);
171 forwarded_event.type = libvlc_MediaPlayerEndReached;
174 libvlc_media_set_state( p_mi->p_md, libvlc_Forward, NULL);
175 forwarded_event.type = libvlc_MediaPlayerForward;
178 libvlc_media_set_state( p_mi->p_md, libvlc_Backward, NULL);
179 forwarded_event.type = libvlc_MediaPlayerBackward;
182 libvlc_media_set_state( p_mi->p_md, libvlc_Error, NULL);
183 forwarded_event.type = libvlc_MediaPlayerEncounteredError;
190 libvlc_event_send( p_mi->p_event_manager, &forwarded_event );
195 input_seekable_changed( vlc_object_t * p_this, char const * psz_cmd,
196 vlc_value_t oldval, vlc_value_t newval,
202 libvlc_media_player_t * p_mi = p_userdata;
203 libvlc_event_t event;
205 libvlc_media_set_state( p_mi->p_md, libvlc_NothingSpecial, NULL);
206 event.type = libvlc_MediaPlayerSeekableChanged;
207 event.u.media_player_seekable_changed.new_seekable = newval.b_bool;
209 libvlc_event_send( p_mi->p_event_manager, &event );
214 input_pausable_changed( vlc_object_t * p_this, char const * psz_cmd,
215 vlc_value_t oldval, vlc_value_t newval,
221 libvlc_media_player_t * p_mi = p_userdata;
222 libvlc_event_t event;
224 libvlc_media_set_state( p_mi->p_md, libvlc_NothingSpecial, NULL);
225 event.type = libvlc_MediaPlayerPausableChanged;
226 event.u.media_player_pausable_changed.new_pausable = newval.b_bool;
228 libvlc_event_send( p_mi->p_event_manager, &event );
233 * input_position_changed (Private) (input var "intf-change" Callback)
236 input_position_changed( vlc_object_t * p_this, char const * psz_cmd,
237 vlc_value_t oldval, vlc_value_t newval,
241 libvlc_media_player_t * p_mi = p_userdata;
244 if (!strncmp(psz_cmd, "intf", 4 /* "-change" no need to go further */))
246 input_thread_t * p_input = (input_thread_t *)p_this;
248 var_Get( p_input, "state", &val );
249 if( val.i_int != PLAYING_S )
250 return VLC_SUCCESS; /* Don't send the position while stopped */
252 var_Get( p_input, "position", &val );
255 val.i_time = newval.i_time;
257 libvlc_event_t event;
258 event.type = libvlc_MediaPlayerPositionChanged;
259 event.u.media_player_position_changed.new_position = val.f_float;
261 libvlc_event_send( p_mi->p_event_manager, &event );
266 * input_time_changed (Private) (input var "intf-change" Callback)
269 input_time_changed( vlc_object_t * p_this, char const * psz_cmd,
270 vlc_value_t oldval, vlc_value_t newval,
274 libvlc_media_player_t * p_mi = p_userdata;
277 if (!strncmp(psz_cmd, "intf", 4 /* "-change" no need to go further */))
279 input_thread_t * p_input = (input_thread_t *)p_this;
281 var_Get( p_input, "state", &val );
282 if( val.i_int != PLAYING_S )
283 return VLC_SUCCESS; /* Don't send the position while stopped */
285 var_Get( p_input, "time", &val );
288 val.i_time = newval.i_time;
290 libvlc_event_t event;
291 event.type = libvlc_MediaPlayerTimeChanged;
292 event.u.media_player_time_changed.new_time = val.i_time;
293 libvlc_event_send( p_mi->p_event_manager, &event );
297 /**************************************************************************
298 * Create a Media Instance object
299 **************************************************************************/
300 libvlc_media_player_t *
301 libvlc_media_player_new( libvlc_instance_t * p_libvlc_instance,
302 libvlc_exception_t * p_e )
304 libvlc_media_player_t * p_mi;
306 if( !p_libvlc_instance )
308 libvlc_exception_raise( p_e, "invalid libvlc instance" );
312 p_mi = malloc( sizeof(libvlc_media_player_t) );
315 libvlc_exception_raise( p_e, "Not enough memory" );
320 p_mi->p_libvlc_instance = p_libvlc_instance;
321 p_mi->p_input_thread = NULL;
322 /* refcount strategy:
323 * - All items created by _new start with a refcount set to 1
324 * - Accessor _release decrease the refcount by 1, if after that
325 * operation the refcount is 0, the object is destroyed.
326 * - Accessor _retain increase the refcount by 1 (XXX: to implement) */
327 p_mi->i_refcount = 1;
328 p_mi->b_own_its_input_thread = true;
329 /* object_lock strategy:
330 * - No lock held in constructor
331 * - Lock when accessing all variable this lock is held
332 * - Lock when attempting to destroy the object the lock is also held */
333 vlc_mutex_init( &p_mi->object_lock );
334 p_mi->p_event_manager = libvlc_event_manager_new( p_mi,
335 p_libvlc_instance, p_e );
336 if( libvlc_exception_raised( p_e ) )
342 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
343 libvlc_MediaPlayerNothingSpecial, p_e );
344 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
345 libvlc_MediaPlayerOpening, p_e );
346 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
347 libvlc_MediaPlayerBuffering, p_e );
348 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
349 libvlc_MediaPlayerPlaying, p_e );
350 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
351 libvlc_MediaPlayerPaused, p_e );
352 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
353 libvlc_MediaPlayerEndReached, p_e );
354 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
355 libvlc_MediaPlayerForward, p_e );
356 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
357 libvlc_MediaPlayerBackward, p_e );
358 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
359 libvlc_MediaPlayerEncounteredError, p_e );
361 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
362 libvlc_MediaPlayerPositionChanged, p_e );
363 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
364 libvlc_MediaPlayerTimeChanged, p_e );
365 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
366 libvlc_MediaPlayerSeekableChanged, p_e );
367 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
368 libvlc_MediaPlayerPausableChanged, p_e );
373 /**************************************************************************
374 * Create a Media Instance object with a media descriptor
375 **************************************************************************/
376 libvlc_media_player_t *
377 libvlc_media_player_new_from_media(
378 libvlc_media_t * p_md,
379 libvlc_exception_t *p_e )
381 libvlc_media_player_t * p_mi;
382 p_mi = libvlc_media_player_new( p_md->p_libvlc_instance, p_e );
387 libvlc_media_retain( p_md );
393 /**************************************************************************
394 * Create a new media instance object from an input_thread (Libvlc Internal)
395 **************************************************************************/
396 libvlc_media_player_t * libvlc_media_player_new_from_input_thread(
397 struct libvlc_instance_t *p_libvlc_instance,
398 input_thread_t *p_input,
399 libvlc_exception_t *p_e )
401 libvlc_media_player_t * p_mi;
405 libvlc_exception_raise( p_e, "invalid input thread" );
409 p_mi = libvlc_media_player_new( p_libvlc_instance, p_e );
414 p_mi->p_md = libvlc_media_new_from_input_item(
416 input_GetItem( p_input ), p_e );
420 libvlc_media_player_destroy( p_mi );
424 /* will be released in media_player_release() */
425 vlc_object_yield( p_input );
427 p_mi->p_input_thread = p_input;
428 p_mi->b_own_its_input_thread = false;
433 /**************************************************************************
434 * Destroy a Media Instance object (libvlc internal)
436 * Warning: No lock held here, but hey, this is internal.
437 **************************************************************************/
438 void libvlc_media_player_destroy( libvlc_media_player_t *p_mi )
440 input_thread_t *p_input_thread;
441 libvlc_exception_t p_e;
443 libvlc_exception_init( &p_e );
448 p_input_thread = libvlc_get_input_thread( p_mi, &p_e );
450 if( libvlc_exception_raised( &p_e ) )
452 libvlc_event_manager_release( p_mi->p_event_manager );
453 libvlc_exception_clear( &p_e );
455 return; /* no need to worry about no input thread */
457 vlc_mutex_destroy( &p_mi->object_lock );
459 vlc_object_release( p_input_thread );
461 libvlc_media_release( p_mi->p_md );
466 /**************************************************************************
467 * Release a Media Instance object
468 **************************************************************************/
469 void libvlc_media_player_release( libvlc_media_player_t *p_mi )
474 vlc_mutex_lock( &p_mi->object_lock );
478 if( p_mi->i_refcount > 0 )
480 vlc_mutex_unlock( &p_mi->object_lock );
483 vlc_mutex_unlock( &p_mi->object_lock );
484 vlc_mutex_destroy( &p_mi->object_lock );
486 release_input_thread( p_mi );
488 libvlc_event_manager_release( p_mi->p_event_manager );
490 libvlc_media_release( p_mi->p_md );
495 /**************************************************************************
496 * Retain a Media Instance object
497 **************************************************************************/
498 void libvlc_media_player_retain( libvlc_media_player_t *p_mi )
506 /**************************************************************************
507 * Set the Media descriptor associated with the instance
508 **************************************************************************/
509 void libvlc_media_player_set_media(
510 libvlc_media_player_t *p_mi,
511 libvlc_media_t *p_md,
512 libvlc_exception_t *p_e )
519 vlc_mutex_lock( &p_mi->object_lock );
521 release_input_thread( p_mi );
524 libvlc_media_set_state( p_mi->p_md, libvlc_NothingSpecial, p_e );
526 libvlc_media_release( p_mi->p_md );
531 vlc_mutex_unlock( &p_mi->object_lock );
532 return; /* It is ok to pass a NULL md */
535 libvlc_media_retain( p_md );
538 /* The policy here is to ignore that we were created using a different
539 * libvlc_instance, because we don't really care */
540 p_mi->p_libvlc_instance = p_md->p_libvlc_instance;
542 vlc_mutex_unlock( &p_mi->object_lock );
545 /**************************************************************************
546 * Get the Media descriptor associated with the instance
547 **************************************************************************/
549 libvlc_media_player_get_media(
550 libvlc_media_player_t *p_mi,
551 libvlc_exception_t *p_e )
558 libvlc_media_retain( p_mi->p_md );
562 /**************************************************************************
563 * Get the event Manager
564 **************************************************************************/
565 libvlc_event_manager_t *
566 libvlc_media_player_event_manager(
567 libvlc_media_player_t *p_mi,
568 libvlc_exception_t *p_e )
572 return p_mi->p_event_manager;
575 /**************************************************************************
577 **************************************************************************/
578 void libvlc_media_player_play( libvlc_media_player_t *p_mi,
579 libvlc_exception_t *p_e )
581 input_thread_t * p_input_thread;
583 if( (p_input_thread = libvlc_get_input_thread( p_mi, p_e )) )
585 /* A thread already exists, send it a play message */
586 input_Control( p_input_thread, INPUT_SET_STATE, PLAYING_S );
587 vlc_object_release( p_input_thread );
591 /* Ignore previous exception */
592 libvlc_exception_clear( p_e );
594 vlc_mutex_lock( &p_mi->object_lock );
598 libvlc_exception_raise( p_e, "no associated media descriptor" );
599 vlc_mutex_unlock( &p_mi->object_lock );
603 p_mi->p_input_thread = input_CreateThread( p_mi->p_libvlc_instance->p_libvlc_int,
604 p_mi->p_md->p_input_item );
607 if( !p_mi->p_input_thread )
609 vlc_mutex_unlock( &p_mi->object_lock );
613 p_input_thread = p_mi->p_input_thread;
618 val.i_int = p_mi->drawable;
619 var_Create( p_input_thread, "drawable", VLC_VAR_DOINHERIT );
620 var_Set( p_input_thread, "drawable", val );
623 vlc_event_manager_t * p_em = input_get_event_manager( p_input_thread );
624 vlc_event_attach( p_em, vlc_InputStateChanged, input_state_changed, p_mi );
626 var_AddCallback( p_input_thread, "seekable", input_seekable_changed, p_mi );
627 var_AddCallback( p_input_thread, "pausable", input_pausable_changed, p_mi );
628 var_AddCallback( p_input_thread, "intf-change", input_position_changed, p_mi );
629 var_AddCallback( p_input_thread, "intf-change", input_time_changed, p_mi );
631 vlc_mutex_unlock( &p_mi->object_lock );
634 /**************************************************************************
636 **************************************************************************/
637 void libvlc_media_player_pause( libvlc_media_player_t *p_mi,
638 libvlc_exception_t *p_e )
640 input_thread_t * p_input_thread = libvlc_get_input_thread( p_mi, p_e );
642 if( !p_input_thread )
645 libvlc_state_t state = libvlc_media_player_get_state( p_mi, p_e );
647 if( state == libvlc_Playing )
649 if( libvlc_media_player_can_pause( p_mi, p_e ) )
650 input_Control( p_input_thread, INPUT_SET_STATE, PAUSE_S );
652 libvlc_media_player_stop( p_mi, p_e );
655 input_Control( p_input_thread, INPUT_SET_STATE, PLAYING_S );
657 vlc_object_release( p_input_thread );
660 /**************************************************************************
662 **************************************************************************/
663 void libvlc_media_player_stop( libvlc_media_player_t *p_mi,
664 libvlc_exception_t *p_e )
666 libvlc_state_t state = libvlc_media_player_get_state( p_mi, p_e );
668 if( state == libvlc_Playing || state == libvlc_Paused )
670 /* Send a stop notification event only of we are in playing or paused states */
671 libvlc_media_set_state( p_mi->p_md, libvlc_Ended, p_e );
673 /* Construct and send the event */
674 libvlc_event_t event;
675 event.type = libvlc_MediaPlayerEndReached;
676 libvlc_event_send( p_mi->p_event_manager, &event );
679 if( p_mi->b_own_its_input_thread )
681 vlc_mutex_lock( &p_mi->object_lock );
682 release_input_thread( p_mi ); /* This will stop the input thread */
683 vlc_mutex_unlock( &p_mi->object_lock );
687 input_thread_t * p_input_thread = libvlc_get_input_thread( p_mi, p_e );
689 if( !p_input_thread )
692 input_StopThread( p_input_thread );
693 vlc_object_release( p_input_thread );
697 /**************************************************************************
699 **************************************************************************/
700 void libvlc_media_player_set_drawable( libvlc_media_player_t *p_mi,
701 libvlc_drawable_t drawable,
702 libvlc_exception_t *p_e )
704 input_thread_t *p_input_thread;
705 vout_thread_t *p_vout = NULL;
707 p_mi->drawable = drawable;
709 /* Allow on the fly drawable changing. This is tricky has this may
710 * not be supported by every vout. We though can't disable it
711 * because of some creepy drawable type that are not flexible enough
712 * (Win32 HWND for instance) */
713 p_input_thread = libvlc_get_input_thread( p_mi, p_e );
714 if( !p_input_thread ) return;
716 p_vout = vlc_object_find( p_input_thread, VLC_OBJECT_VOUT, FIND_CHILD );
718 libvlc_exception_raise( p_e, "No active video output" );
721 vout_Control( p_vout , VOUT_REPARENT, drawable);
722 vlc_object_release( p_vout );
724 vlc_object_release( p_input_thread );
727 /**************************************************************************
729 **************************************************************************/
731 libvlc_media_player_get_drawable ( libvlc_media_player_t *p_mi, libvlc_exception_t *p_e )
734 return p_mi->drawable;
737 /**************************************************************************
738 * Getters for stream information
739 **************************************************************************/
740 libvlc_time_t libvlc_media_player_get_length(
741 libvlc_media_player_t *p_mi,
742 libvlc_exception_t *p_e )
744 input_thread_t *p_input_thread;
747 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
748 if( !p_input_thread )
751 var_Get( p_input_thread, "length", &val );
752 vlc_object_release( p_input_thread );
754 return (val.i_time+500LL)/1000LL;
757 libvlc_time_t libvlc_media_player_get_time(
758 libvlc_media_player_t *p_mi,
759 libvlc_exception_t *p_e )
761 input_thread_t *p_input_thread;
764 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
765 if( !p_input_thread )
768 var_Get( p_input_thread , "time", &val );
769 vlc_object_release( p_input_thread );
770 return (val.i_time+500LL)/1000LL;
773 void libvlc_media_player_set_time(
774 libvlc_media_player_t *p_mi,
776 libvlc_exception_t *p_e )
778 input_thread_t *p_input_thread;
781 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
782 if( !p_input_thread )
785 value.i_time = time*1000LL;
786 var_Set( p_input_thread, "time", value );
787 vlc_object_release( p_input_thread );
790 void libvlc_media_player_set_position(
791 libvlc_media_player_t *p_mi,
793 libvlc_exception_t *p_e )
795 input_thread_t *p_input_thread;
797 val.f_float = position;
799 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
800 if( !p_input_thread )
803 var_Set( p_input_thread, "position", val );
804 vlc_object_release( p_input_thread );
807 float libvlc_media_player_get_position(
808 libvlc_media_player_t *p_mi,
809 libvlc_exception_t *p_e )
811 input_thread_t *p_input_thread;
814 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
815 if( !p_input_thread )
818 var_Get( p_input_thread, "position", &val );
819 vlc_object_release( p_input_thread );
824 void libvlc_media_player_set_chapter(
825 libvlc_media_player_t *p_mi,
827 libvlc_exception_t *p_e )
829 input_thread_t *p_input_thread;
833 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
834 if( !p_input_thread )
837 var_Set( p_input_thread, "chapter", val );
838 vlc_object_release( p_input_thread );
841 int libvlc_media_player_get_chapter(
842 libvlc_media_player_t *p_mi,
843 libvlc_exception_t *p_e )
845 input_thread_t *p_input_thread;
848 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
849 if( !p_input_thread )
852 var_Get( p_input_thread, "chapter", &val );
853 vlc_object_release( p_input_thread );
858 int libvlc_media_player_get_chapter_count(
859 libvlc_media_player_t *p_mi,
860 libvlc_exception_t *p_e )
862 input_thread_t *p_input_thread;
865 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
866 if( !p_input_thread )
869 var_Change( p_input_thread, "chapter", VLC_VAR_CHOICESCOUNT, &val, NULL );
870 vlc_object_release( p_input_thread );
875 float libvlc_media_player_get_fps(
876 libvlc_media_player_t *p_mi,
877 libvlc_exception_t *p_e)
879 input_thread_t *p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
884 if( input_Control( p_input_thread, INPUT_GET_VIDEO_FPS, &f_fps ) )
886 vlc_object_release( p_input_thread );
891 int libvlc_media_player_will_play( libvlc_media_player_t *p_mi,
892 libvlc_exception_t *p_e)
894 input_thread_t *p_input_thread =
895 libvlc_get_input_thread ( p_mi, p_e);
896 if ( !p_input_thread )
899 if ( !p_input_thread->b_die && !p_input_thread->b_dead )
901 vlc_object_release( p_input_thread );
904 vlc_object_release( p_input_thread );
908 void libvlc_media_player_set_rate(
909 libvlc_media_player_t *p_mi,
911 libvlc_exception_t *p_e )
913 input_thread_t *p_input_thread;
917 RAISEVOID( "Rate value is invalid" );
919 val.i_int = 1000.0f/rate;
921 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
922 if ( !p_input_thread )
925 var_Set( p_input_thread, "rate", val );
926 vlc_object_release( p_input_thread );
929 float libvlc_media_player_get_rate(
930 libvlc_media_player_t *p_mi,
931 libvlc_exception_t *p_e )
933 input_thread_t *p_input_thread;
936 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
937 if ( !p_input_thread )
940 var_Get( p_input_thread, "rate", &val );
941 vlc_object_release( p_input_thread );
943 return (float)1000.0f/val.i_int;
946 libvlc_state_t libvlc_media_player_get_state(
947 libvlc_media_player_t *p_mi,
948 libvlc_exception_t *p_e )
950 input_thread_t *p_input_thread;
953 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
954 if ( !p_input_thread )
956 /* We do return the right value, no need to throw an exception */
957 if( libvlc_exception_raised( p_e ) )
958 libvlc_exception_clear( p_e );
962 var_Get( p_input_thread, "state", &val );
963 vlc_object_release( p_input_thread );
965 return vlc_to_libvlc_state(val.i_int);
968 int libvlc_media_player_is_seekable( libvlc_media_player_t *p_mi,
969 libvlc_exception_t *p_e )
971 input_thread_t *p_input_thread;
974 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
975 if ( !p_input_thread )
977 /* We do return the right value, no need to throw an exception */
978 if( libvlc_exception_raised( p_e ) )
979 libvlc_exception_clear( p_e );
982 var_Get( p_input_thread, "seekable", &val );
983 vlc_object_release( p_input_thread );
988 int libvlc_media_player_can_pause( libvlc_media_player_t *p_mi,
989 libvlc_exception_t *p_e )
991 input_thread_t *p_input_thread;
994 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
995 if ( !p_input_thread )
997 /* We do return the right value, no need to throw an exception */
998 if( libvlc_exception_raised( p_e ) )
999 libvlc_exception_clear( p_e );
1002 var_Get( p_input_thread, "can-pause", &val );
1003 vlc_object_release( p_input_thread );