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_MediaPlayerTitleChanged, p_e );
375 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
376 libvlc_MediaPlayerSeekableChanged, p_e );
377 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
378 libvlc_MediaPlayerPausableChanged, p_e );
383 /**************************************************************************
384 * Create a Media Instance object with a media descriptor
385 **************************************************************************/
386 libvlc_media_player_t *
387 libvlc_media_player_new_from_media(
388 libvlc_media_t * p_md,
389 libvlc_exception_t *p_e )
391 libvlc_media_player_t * p_mi;
392 p_mi = libvlc_media_player_new( p_md->p_libvlc_instance, p_e );
397 libvlc_media_retain( p_md );
403 /**************************************************************************
404 * Create a new media instance object from an input_thread (Libvlc Internal)
405 **************************************************************************/
406 libvlc_media_player_t * libvlc_media_player_new_from_input_thread(
407 struct libvlc_instance_t *p_libvlc_instance,
408 input_thread_t *p_input,
409 libvlc_exception_t *p_e )
411 libvlc_media_player_t * p_mi;
415 libvlc_exception_raise( p_e, "invalid input thread" );
419 p_mi = libvlc_media_player_new( p_libvlc_instance, p_e );
424 p_mi->p_md = libvlc_media_new_from_input_item(
426 input_GetItem( p_input ), p_e );
430 libvlc_media_player_destroy( p_mi );
434 /* will be released in media_player_release() */
435 vlc_object_hold( p_input );
437 p_mi->p_input_thread = p_input;
438 p_mi->b_own_its_input_thread = false;
443 /**************************************************************************
444 * Destroy a Media Instance object (libvlc internal)
446 * Warning: No lock held here, but hey, this is internal.
447 **************************************************************************/
448 void libvlc_media_player_destroy( libvlc_media_player_t *p_mi )
450 input_thread_t *p_input_thread;
451 libvlc_exception_t p_e;
453 libvlc_exception_init( &p_e );
458 p_input_thread = libvlc_get_input_thread( p_mi, &p_e );
460 if( libvlc_exception_raised( &p_e ) )
462 libvlc_event_manager_release( p_mi->p_event_manager );
463 libvlc_exception_clear( &p_e );
465 return; /* no need to worry about no input thread */
467 vlc_mutex_destroy( &p_mi->object_lock );
469 vlc_object_release( p_input_thread );
471 libvlc_media_release( p_mi->p_md );
476 /**************************************************************************
477 * Release a Media Instance object
478 **************************************************************************/
479 void libvlc_media_player_release( libvlc_media_player_t *p_mi )
484 vlc_mutex_lock( &p_mi->object_lock );
488 if( p_mi->i_refcount > 0 )
490 vlc_mutex_unlock( &p_mi->object_lock );
493 vlc_mutex_unlock( &p_mi->object_lock );
494 vlc_mutex_destroy( &p_mi->object_lock );
496 release_input_thread( p_mi );
498 libvlc_event_manager_release( p_mi->p_event_manager );
500 libvlc_media_release( p_mi->p_md );
505 /**************************************************************************
506 * Retain a Media Instance object
507 **************************************************************************/
508 void libvlc_media_player_retain( libvlc_media_player_t *p_mi )
516 /**************************************************************************
517 * Set the Media descriptor associated with the instance
518 **************************************************************************/
519 void libvlc_media_player_set_media(
520 libvlc_media_player_t *p_mi,
521 libvlc_media_t *p_md,
522 libvlc_exception_t *p_e )
529 vlc_mutex_lock( &p_mi->object_lock );
531 release_input_thread( p_mi );
534 libvlc_media_set_state( p_mi->p_md, libvlc_NothingSpecial, p_e );
536 libvlc_media_release( p_mi->p_md );
541 vlc_mutex_unlock( &p_mi->object_lock );
542 return; /* It is ok to pass a NULL md */
545 libvlc_media_retain( p_md );
548 /* The policy here is to ignore that we were created using a different
549 * libvlc_instance, because we don't really care */
550 p_mi->p_libvlc_instance = p_md->p_libvlc_instance;
552 vlc_mutex_unlock( &p_mi->object_lock );
555 /**************************************************************************
556 * Get the Media descriptor associated with the instance
557 **************************************************************************/
559 libvlc_media_player_get_media(
560 libvlc_media_player_t *p_mi,
561 libvlc_exception_t *p_e )
568 libvlc_media_retain( p_mi->p_md );
572 /**************************************************************************
573 * Get the event Manager
574 **************************************************************************/
575 libvlc_event_manager_t *
576 libvlc_media_player_event_manager(
577 libvlc_media_player_t *p_mi,
578 libvlc_exception_t *p_e )
582 return p_mi->p_event_manager;
585 /**************************************************************************
587 **************************************************************************/
588 void libvlc_media_player_play( libvlc_media_player_t *p_mi,
589 libvlc_exception_t *p_e )
591 input_thread_t * p_input_thread;
593 if( (p_input_thread = libvlc_get_input_thread( p_mi, p_e )) )
595 /* A thread already exists, send it a play message */
596 input_Control( p_input_thread, INPUT_SET_STATE, PLAYING_S );
597 vlc_object_release( p_input_thread );
601 /* Ignore previous exception */
602 libvlc_exception_clear( p_e );
604 vlc_mutex_lock( &p_mi->object_lock );
608 libvlc_exception_raise( p_e, "no associated media descriptor" );
609 vlc_mutex_unlock( &p_mi->object_lock );
613 p_mi->p_input_thread = input_CreateThread( p_mi->p_libvlc_instance->p_libvlc_int,
614 p_mi->p_md->p_input_item );
617 if( !p_mi->p_input_thread )
619 vlc_mutex_unlock( &p_mi->object_lock );
623 p_input_thread = p_mi->p_input_thread;
628 val.i_int = p_mi->drawable;
629 var_Create( p_input_thread, "drawable", VLC_VAR_DOINHERIT );
630 var_Set( p_input_thread, "drawable", val );
633 vlc_event_manager_t * p_em = input_get_event_manager( p_input_thread );
634 vlc_event_attach( p_em, vlc_InputStateChanged, input_state_changed, p_mi );
636 var_AddCallback( p_input_thread, "seekable", input_seekable_changed, p_mi );
637 var_AddCallback( p_input_thread, "pausable", input_pausable_changed, p_mi );
638 var_AddCallback( p_input_thread, "intf-change", input_position_changed, p_mi );
639 var_AddCallback( p_input_thread, "intf-change", input_time_changed, p_mi );
641 vlc_mutex_unlock( &p_mi->object_lock );
644 /**************************************************************************
646 **************************************************************************/
647 void libvlc_media_player_pause( libvlc_media_player_t *p_mi,
648 libvlc_exception_t *p_e )
650 input_thread_t * p_input_thread = libvlc_get_input_thread( p_mi, p_e );
652 if( !p_input_thread )
655 libvlc_state_t state = libvlc_media_player_get_state( p_mi, p_e );
657 if( state == libvlc_Playing )
659 if( libvlc_media_player_can_pause( p_mi, p_e ) )
660 input_Control( p_input_thread, INPUT_SET_STATE, PAUSE_S );
662 libvlc_media_player_stop( p_mi, p_e );
665 input_Control( p_input_thread, INPUT_SET_STATE, PLAYING_S );
667 vlc_object_release( p_input_thread );
670 /**************************************************************************
672 **************************************************************************/
673 void libvlc_media_player_stop( libvlc_media_player_t *p_mi,
674 libvlc_exception_t *p_e )
676 libvlc_state_t state = libvlc_media_player_get_state( p_mi, p_e );
678 if( state == libvlc_Playing || state == libvlc_Paused )
680 /* Send a stop notification event only of we are in playing or paused states */
681 libvlc_media_set_state( p_mi->p_md, libvlc_Ended, p_e );
683 /* Construct and send the event */
684 libvlc_event_t event;
685 event.type = libvlc_MediaPlayerEndReached;
686 libvlc_event_send( p_mi->p_event_manager, &event );
689 if( p_mi->b_own_its_input_thread )
691 vlc_mutex_lock( &p_mi->object_lock );
692 release_input_thread( p_mi ); /* This will stop the input thread */
693 vlc_mutex_unlock( &p_mi->object_lock );
697 input_thread_t * p_input_thread = libvlc_get_input_thread( p_mi, p_e );
699 if( !p_input_thread )
702 input_StopThread( p_input_thread );
703 vlc_object_release( p_input_thread );
707 /**************************************************************************
709 **************************************************************************/
710 void libvlc_media_player_set_drawable( libvlc_media_player_t *p_mi,
711 libvlc_drawable_t drawable,
712 libvlc_exception_t *p_e )
714 input_thread_t *p_input_thread;
715 vout_thread_t *p_vout = NULL;
717 p_mi->drawable = drawable;
719 /* Allow on the fly drawable changing. This is tricky has this may
720 * not be supported by every vout. We though can't disable it
721 * because of some creepy drawable type that are not flexible enough
722 * (Win32 HWND for instance) */
723 p_input_thread = libvlc_get_input_thread( p_mi, p_e );
724 if( !p_input_thread ) {
725 /* No input, nothing more to do, we are fine */
726 libvlc_exception_clear( p_e );
730 p_vout = vlc_object_find( p_input_thread, VLC_OBJECT_VOUT, FIND_CHILD );
733 vout_Control( p_vout , VOUT_REPARENT, drawable);
734 vlc_object_release( p_vout );
736 vlc_object_release( p_input_thread );
739 /**************************************************************************
741 **************************************************************************/
743 libvlc_media_player_get_drawable ( libvlc_media_player_t *p_mi, libvlc_exception_t *p_e )
746 return p_mi->drawable;
749 /**************************************************************************
750 * Getters for stream information
751 **************************************************************************/
752 libvlc_time_t libvlc_media_player_get_length(
753 libvlc_media_player_t *p_mi,
754 libvlc_exception_t *p_e )
756 input_thread_t *p_input_thread;
759 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
760 if( !p_input_thread )
763 var_Get( p_input_thread, "length", &val );
764 vlc_object_release( p_input_thread );
766 return (val.i_time+500LL)/1000LL;
769 libvlc_time_t libvlc_media_player_get_time(
770 libvlc_media_player_t *p_mi,
771 libvlc_exception_t *p_e )
773 input_thread_t *p_input_thread;
776 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
777 if( !p_input_thread )
780 var_Get( p_input_thread , "time", &val );
781 vlc_object_release( p_input_thread );
782 return (val.i_time+500LL)/1000LL;
785 void libvlc_media_player_set_time(
786 libvlc_media_player_t *p_mi,
788 libvlc_exception_t *p_e )
790 input_thread_t *p_input_thread;
793 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
794 if( !p_input_thread )
797 value.i_time = time*1000LL;
798 var_Set( p_input_thread, "time", value );
799 vlc_object_release( p_input_thread );
802 void libvlc_media_player_set_position(
803 libvlc_media_player_t *p_mi,
805 libvlc_exception_t *p_e )
807 input_thread_t *p_input_thread;
809 val.f_float = position;
811 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
812 if( !p_input_thread )
815 var_Set( p_input_thread, "position", val );
816 vlc_object_release( p_input_thread );
819 float libvlc_media_player_get_position(
820 libvlc_media_player_t *p_mi,
821 libvlc_exception_t *p_e )
823 input_thread_t *p_input_thread;
826 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
827 if( !p_input_thread )
830 var_Get( p_input_thread, "position", &val );
831 vlc_object_release( p_input_thread );
836 void libvlc_media_player_set_chapter(
837 libvlc_media_player_t *p_mi,
839 libvlc_exception_t *p_e )
841 input_thread_t *p_input_thread;
845 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
846 if( !p_input_thread )
849 var_Set( p_input_thread, "chapter", val );
850 vlc_object_release( p_input_thread );
853 int libvlc_media_player_get_chapter(
854 libvlc_media_player_t *p_mi,
855 libvlc_exception_t *p_e )
857 input_thread_t *p_input_thread;
860 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
861 if( !p_input_thread )
864 var_Get( p_input_thread, "chapter", &val );
865 vlc_object_release( p_input_thread );
870 int libvlc_media_player_get_chapter_count(
871 libvlc_media_player_t *p_mi,
872 libvlc_exception_t *p_e )
874 input_thread_t *p_input_thread;
877 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
878 if( !p_input_thread )
881 var_Change( p_input_thread, "chapter", VLC_VAR_CHOICESCOUNT, &val, NULL );
882 vlc_object_release( p_input_thread );
887 int libvlc_media_player_get_chapter_count_for_title(
888 libvlc_media_player_t *p_mi,
890 libvlc_exception_t *p_e )
892 input_thread_t *p_input_thread;
895 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
896 if( !p_input_thread )
900 if( asprintf( &psz_name, "title %2i", i_title ) == -1 )
902 vlc_object_release( p_input_thread );
905 var_Change( p_input_thread, psz_name, VLC_VAR_CHOICESCOUNT, &val, NULL );
906 vlc_object_release( p_input_thread );
912 void libvlc_media_player_set_title(
913 libvlc_media_player_t *p_mi,
915 libvlc_exception_t *p_e )
917 input_thread_t *p_input_thread;
921 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
922 if( !p_input_thread )
925 var_Set( p_input_thread, "title", val );
926 vlc_object_release( p_input_thread );
929 libvlc_event_t event;
930 event.type = libvlc_MediaPlayerTitleChanged;
931 event.u.media_player_title_changed.new_title = i_title;
932 libvlc_event_send( p_mi->p_event_manager, &event );
935 int libvlc_media_player_get_title(
936 libvlc_media_player_t *p_mi,
937 libvlc_exception_t *p_e )
939 input_thread_t *p_input_thread;
942 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
943 if( !p_input_thread )
946 var_Get( p_input_thread, "title", &val );
947 vlc_object_release( p_input_thread );
952 int libvlc_media_player_get_title_count(
953 libvlc_media_player_t *p_mi,
954 libvlc_exception_t *p_e )
956 input_thread_t *p_input_thread;
959 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
960 if( !p_input_thread )
963 var_Change( p_input_thread, "title", VLC_VAR_CHOICESCOUNT, &val, NULL );
964 vlc_object_release( p_input_thread );
969 void libvlc_media_player_next_chapter(
970 libvlc_media_player_t *p_mi,
971 libvlc_exception_t *p_e )
973 input_thread_t *p_input_thread;
975 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
976 if( !p_input_thread )
979 int i_type = var_Type( p_input_thread, "next-chapter" );
982 var_Set( p_input_thread, (i_type & VLC_VAR_TYPE) != 0 ?
983 "next-chapter":"next-title", val );
985 vlc_object_release( p_input_thread );
988 void libvlc_media_player_previous_chapter(
989 libvlc_media_player_t *p_mi,
990 libvlc_exception_t *p_e )
992 input_thread_t *p_input_thread;
994 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
995 if( !p_input_thread )
998 int i_type = var_Type( p_input_thread, "next-chapter" );
1001 var_Set( p_input_thread, (i_type & VLC_VAR_TYPE) != 0 ?
1002 "prev-chapter":"prev-title", val );
1004 vlc_object_release( p_input_thread );
1007 float libvlc_media_player_get_fps(
1008 libvlc_media_player_t *p_mi,
1009 libvlc_exception_t *p_e)
1011 input_thread_t *p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
1014 if( p_input_thread )
1016 if( input_Control( p_input_thread, INPUT_GET_VIDEO_FPS, &f_fps ) )
1018 vlc_object_release( p_input_thread );
1023 int libvlc_media_player_will_play( libvlc_media_player_t *p_mi,
1024 libvlc_exception_t *p_e)
1026 input_thread_t *p_input_thread =
1027 libvlc_get_input_thread ( p_mi, p_e);
1028 if ( !p_input_thread )
1031 if ( !p_input_thread->b_die && !p_input_thread->b_dead )
1033 vlc_object_release( p_input_thread );
1036 vlc_object_release( p_input_thread );
1040 void libvlc_media_player_set_rate(
1041 libvlc_media_player_t *p_mi,
1043 libvlc_exception_t *p_e )
1045 input_thread_t *p_input_thread;
1049 RAISEVOID( "Rate value is invalid" );
1051 val.i_int = 1000.0f/rate;
1053 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
1054 if ( !p_input_thread )
1057 var_Set( p_input_thread, "rate", val );
1058 vlc_object_release( p_input_thread );
1061 float libvlc_media_player_get_rate(
1062 libvlc_media_player_t *p_mi,
1063 libvlc_exception_t *p_e )
1065 input_thread_t *p_input_thread;
1068 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
1069 if ( !p_input_thread )
1072 var_Get( p_input_thread, "rate", &val );
1073 vlc_object_release( p_input_thread );
1075 return (float)1000.0f/val.i_int;
1078 libvlc_state_t libvlc_media_player_get_state(
1079 libvlc_media_player_t *p_mi,
1080 libvlc_exception_t *p_e )
1082 input_thread_t *p_input_thread;
1085 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
1086 if ( !p_input_thread )
1088 /* We do return the right value, no need to throw an exception */
1089 if( libvlc_exception_raised( p_e ) )
1090 libvlc_exception_clear( p_e );
1091 return libvlc_Ended;
1094 var_Get( p_input_thread, "state", &val );
1095 vlc_object_release( p_input_thread );
1097 return vlc_to_libvlc_state(val.i_int);
1100 int libvlc_media_player_is_seekable( libvlc_media_player_t *p_mi,
1101 libvlc_exception_t *p_e )
1103 input_thread_t *p_input_thread;
1106 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
1107 if ( !p_input_thread )
1109 /* We do return the right value, no need to throw an exception */
1110 if( libvlc_exception_raised( p_e ) )
1111 libvlc_exception_clear( p_e );
1114 var_Get( p_input_thread, "seekable", &val );
1115 vlc_object_release( p_input_thread );
1120 int libvlc_media_player_can_pause( libvlc_media_player_t *p_mi,
1121 libvlc_exception_t *p_e )
1123 input_thread_t *p_input_thread;
1126 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
1127 if ( !p_input_thread )
1129 /* We do return the right value, no need to throw an exception */
1130 if( libvlc_exception_raised( p_e ) )
1131 libvlc_exception_clear( p_e );
1134 var_Get( p_input_thread, "can-pause", &val );
1135 vlc_object_release( p_input_thread );