1 /*****************************************************************************
2 * media_instance.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>
32 input_state_changed( vlc_object_t * p_this, char const * psz_cmd,
33 vlc_value_t oldval, vlc_value_t newval,
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_Opening,
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 [ERROR_S] = libvlc_Error,
62 static inline libvlc_state_t vlc_to_libvlc_state( int vlc_state )
64 if( vlc_state < 0 || vlc_state > 6 )
65 return libvlc_Stopped;
67 return vlc_to_libvlc_state_array[vlc_state];
71 * Release the associated input thread
73 * Object lock is NOT held.
75 static void release_input_thread( libvlc_media_instance_t *p_mi )
77 input_thread_t *p_input_thread;
79 if( !p_mi || p_mi->i_input_id == -1 )
82 p_input_thread = (input_thread_t*)vlc_object_get( p_mi->i_input_id );
84 p_mi->i_input_id = -1;
90 /* No one is tracking this input_thread appart us. Destroy it */
91 if( p_mi->b_own_its_input_thread )
93 var_DelCallback( p_input_thread, "state", input_state_changed, p_mi );
94 var_DelCallback( p_input_thread, "seekable", input_seekable_changed, p_mi );
95 var_DelCallback( p_input_thread, "pausable", input_pausable_changed, p_mi );
96 var_DelCallback( p_input_thread, "intf-change", input_position_changed, p_mi );
97 var_DelCallback( p_input_thread, "intf-change", input_time_changed, p_mi );
99 /* We owned this one */
100 input_StopThread( p_input_thread );
102 var_Destroy( p_input_thread, "drawable" );
106 /* XXX: hack the playlist doesn't retain the input thread,
107 * so we did it for the playlist (see _new_from_input_thread),
108 * revert that here. This will be deleted with the playlist API */
109 vlc_object_release( p_input_thread );
112 /* release for previous vlc_object_get */
113 vlc_object_release( p_input_thread );
117 * Retrieve the input thread. Be sure to release the object
118 * once you are done with it. (libvlc Internal)
120 * Object lock is held.
122 input_thread_t *libvlc_get_input_thread( libvlc_media_instance_t *p_mi,
123 libvlc_exception_t *p_e )
125 input_thread_t *p_input_thread;
129 RAISENULL( "Input is NULL" );
132 vlc_mutex_lock( &p_mi->object_lock );
134 if( !p_mi || p_mi->i_input_id == -1 )
136 vlc_mutex_unlock( &p_mi->object_lock );
137 RAISENULL( "Input is NULL" );
140 p_input_thread = (input_thread_t*)vlc_object_get( p_mi->i_input_id );
141 if( !p_input_thread )
143 vlc_mutex_unlock( &p_mi->object_lock );
144 RAISENULL( "Input does not exist" );
147 vlc_mutex_unlock( &p_mi->object_lock );
148 return p_input_thread;
152 * input_state_changed (Private) (input var "state" Callback)
155 input_state_changed( vlc_object_t * p_this, char const * psz_cmd,
156 vlc_value_t oldval, vlc_value_t newval,
162 libvlc_media_instance_t * p_mi = p_userdata;
163 libvlc_event_t event;
164 libvlc_event_type_t type = newval.i_int;
169 libvlc_media_descriptor_set_state( p_mi->p_md, libvlc_NothingSpecial, NULL);
170 event.type = libvlc_MediaInstanceReachedEnd;
173 libvlc_media_descriptor_set_state( p_mi->p_md, libvlc_Playing, NULL);
174 event.type = libvlc_MediaInstancePaused;
177 libvlc_media_descriptor_set_state( p_mi->p_md, libvlc_Playing, NULL);
178 event.type = libvlc_MediaInstancePlayed;
181 libvlc_media_descriptor_set_state( p_mi->p_md, libvlc_Error, NULL);
182 event.type = libvlc_MediaInstanceEncounteredError;
188 libvlc_event_send( p_mi->p_event_manager, &event );
193 input_seekable_changed( vlc_object_t * p_this, char const * psz_cmd,
194 vlc_value_t oldval, vlc_value_t newval,
200 libvlc_media_instance_t * p_mi = p_userdata;
201 libvlc_event_t event;
203 libvlc_media_descriptor_set_state( p_mi->p_md, libvlc_NothingSpecial, NULL);
204 event.type = libvlc_MediaInstanceSeekableChanged;
205 event.u.media_instance_seekable_changed.new_seekable = newval.b_bool;
207 libvlc_event_send( p_mi->p_event_manager, &event );
212 input_pausable_changed( vlc_object_t * p_this, char const * psz_cmd,
213 vlc_value_t oldval, vlc_value_t newval,
219 libvlc_media_instance_t * p_mi = p_userdata;
220 libvlc_event_t event;
222 libvlc_media_descriptor_set_state( p_mi->p_md, libvlc_NothingSpecial, NULL);
223 event.type = libvlc_MediaInstancePausableChanged;
224 event.u.media_instance_pausable_changed.new_pausable = newval.b_bool;
226 libvlc_event_send( p_mi->p_event_manager, &event );
231 * input_position_changed (Private) (input var "intf-change" Callback)
234 input_position_changed( vlc_object_t * p_this, char const * psz_cmd,
235 vlc_value_t oldval, vlc_value_t newval,
239 libvlc_media_instance_t * p_mi = p_userdata;
242 if (!strncmp(psz_cmd, "intf", 4 /* "-change" no need to go further */))
244 input_thread_t * p_input = (input_thread_t *)p_this;
246 var_Get( p_input, "state", &val );
247 if( val.i_int != PLAYING_S )
248 return VLC_SUCCESS; /* Don't send the position while stopped */
250 var_Get( p_input, "position", &val );
253 val.i_time = newval.i_time;
255 libvlc_event_t event;
256 event.type = libvlc_MediaInstancePositionChanged;
257 event.u.media_instance_position_changed.new_position = val.f_float;
259 libvlc_event_send( p_mi->p_event_manager, &event );
264 * input_time_changed (Private) (input var "intf-change" Callback)
267 input_time_changed( vlc_object_t * p_this, char const * psz_cmd,
268 vlc_value_t oldval, vlc_value_t newval,
272 libvlc_media_instance_t * p_mi = p_userdata;
275 if (!strncmp(psz_cmd, "intf", 4 /* "-change" no need to go further */))
277 input_thread_t * p_input = (input_thread_t *)p_this;
279 var_Get( p_input, "state", &val );
280 if( val.i_int != PLAYING_S )
281 return VLC_SUCCESS; /* Don't send the position while stopped */
283 var_Get( p_input, "time", &val );
286 val.i_time = newval.i_time;
288 libvlc_event_t event;
289 event.type = libvlc_MediaInstanceTimeChanged;
290 event.u.media_instance_time_changed.new_time = val.i_time;
291 libvlc_event_send( p_mi->p_event_manager, &event );
295 /**************************************************************************
296 * Create a Media Instance object
297 **************************************************************************/
298 libvlc_media_instance_t *
299 libvlc_media_instance_new( libvlc_instance_t * p_libvlc_instance,
300 libvlc_exception_t * p_e )
302 libvlc_media_instance_t * p_mi;
304 if( !p_libvlc_instance )
306 libvlc_exception_raise( p_e, "invalid libvlc instance" );
310 p_mi = malloc( sizeof(libvlc_media_instance_t) );
313 p_mi->p_libvlc_instance = p_libvlc_instance;
314 p_mi->i_input_id = -1;
315 /* refcount strategy:
316 * - All items created by _new start with a refcount set to 1
317 * - Accessor _release decrease the refcount by 1, if after that
318 * operation the refcount is 0, the object is destroyed.
319 * - Accessor _retain increase the refcount by 1 (XXX: to implement) */
320 p_mi->i_refcount = 1;
321 p_mi->b_own_its_input_thread = VLC_TRUE;
322 /* object_lock strategy:
323 * - No lock held in constructor
324 * - Lock when accessing all variable this lock is held
325 * - Lock when attempting to destroy the object the lock is also held */
326 vlc_mutex_init( p_mi->p_libvlc_instance->p_libvlc_int,
327 &p_mi->object_lock );
328 p_mi->p_event_manager = libvlc_event_manager_new( p_mi,
329 p_libvlc_instance, p_e );
330 if( libvlc_exception_raised( p_e ) )
336 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
337 libvlc_MediaInstanceReachedEnd, p_e );
338 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
339 libvlc_MediaInstanceEncounteredError, p_e );
340 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
341 libvlc_MediaInstancePaused, p_e );
342 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
343 libvlc_MediaInstancePlayed, p_e );
344 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
345 libvlc_MediaInstancePositionChanged, p_e );
346 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
347 libvlc_MediaInstanceTimeChanged, p_e );
348 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
349 libvlc_MediaInstanceSeekableChanged, p_e );
350 libvlc_event_manager_register_event_type( p_mi->p_event_manager,
351 libvlc_MediaInstancePausableChanged, p_e );
356 /**************************************************************************
357 * Create a Media Instance object with a media descriptor
358 **************************************************************************/
359 libvlc_media_instance_t *
360 libvlc_media_instance_new_from_media_descriptor(
361 libvlc_media_descriptor_t * p_md,
362 libvlc_exception_t *p_e )
364 libvlc_media_instance_t * p_mi;
365 p_mi = libvlc_media_instance_new( p_md->p_libvlc_instance, p_e );
370 libvlc_media_descriptor_retain( p_md );
376 /**************************************************************************
377 * Create a new media instance object from an input_thread (Libvlc Internal)
378 **************************************************************************/
379 libvlc_media_instance_t * libvlc_media_instance_new_from_input_thread(
380 struct libvlc_instance_t *p_libvlc_instance,
381 input_thread_t *p_input,
382 libvlc_exception_t *p_e )
384 libvlc_media_instance_t * p_mi;
388 libvlc_exception_raise( p_e, "invalid input thread" );
392 p_mi = libvlc_media_instance_new( p_libvlc_instance, p_e );
397 p_mi->p_md = libvlc_media_descriptor_new_from_input_item(
399 input_GetItem( p_input ), p_e );
403 libvlc_media_instance_destroy( p_mi );
407 p_mi->i_input_id = p_input->i_object_id;
408 p_mi->b_own_its_input_thread = VLC_FALSE;
410 /* will be released in media_instance_release() */
411 vlc_object_yield( p_input );
413 /* XXX: Hack as the playlist doesn't yield the input thread we retain
414 * the input for the playlist. (see corresponding hack in _release) */
415 vlc_object_yield( p_input );
420 /**************************************************************************
421 * Destroy a Media Instance object (libvlc internal)
423 * Warning: No lock held here, but hey, this is internal.
424 **************************************************************************/
425 void libvlc_media_instance_destroy( libvlc_media_instance_t *p_mi )
427 input_thread_t *p_input_thread;
428 libvlc_exception_t p_e;
430 libvlc_exception_init( &p_e );
435 p_input_thread = libvlc_get_input_thread( p_mi, &p_e );
437 if( libvlc_exception_raised( &p_e ) )
439 libvlc_event_manager_release( p_mi->p_event_manager );
440 libvlc_exception_clear( &p_e );
442 return; /* no need to worry about no input thread */
444 vlc_mutex_destroy( &p_mi->object_lock );
446 input_DestroyThread( p_input_thread );
448 libvlc_media_descriptor_release( p_mi->p_md );
453 /**************************************************************************
454 * Release a Media Instance object
455 **************************************************************************/
456 void libvlc_media_instance_release( libvlc_media_instance_t *p_mi )
461 vlc_mutex_lock( &p_mi->object_lock );
465 if( p_mi->i_refcount > 0 )
467 vlc_mutex_unlock( &p_mi->object_lock );
470 vlc_mutex_unlock( &p_mi->object_lock );
471 vlc_mutex_destroy( &p_mi->object_lock );
473 release_input_thread( p_mi );
475 libvlc_event_manager_release( p_mi->p_event_manager );
477 libvlc_media_descriptor_release( p_mi->p_md );
482 /**************************************************************************
483 * Retain a Media Instance object
484 **************************************************************************/
485 void libvlc_media_instance_retain( libvlc_media_instance_t *p_mi )
493 /**************************************************************************
494 * Set the Media descriptor associated with the instance
495 **************************************************************************/
496 void libvlc_media_instance_set_media_descriptor(
497 libvlc_media_instance_t *p_mi,
498 libvlc_media_descriptor_t *p_md,
499 libvlc_exception_t *p_e )
506 vlc_mutex_lock( &p_mi->object_lock );
508 release_input_thread( p_mi );
511 libvlc_media_descriptor_set_state( p_mi->p_md, libvlc_NothingSpecial, NULL );
513 libvlc_media_descriptor_release( p_mi->p_md );
518 vlc_mutex_unlock( &p_mi->object_lock );
519 return; /* It is ok to pass a NULL md */
522 libvlc_media_descriptor_retain( p_md );
525 /* The policy here is to ignore that we were created using a different
526 * libvlc_instance, because we don't really care */
527 p_mi->p_libvlc_instance = p_md->p_libvlc_instance;
529 vlc_mutex_unlock( &p_mi->object_lock );
532 /**************************************************************************
533 * Get the Media descriptor associated with the instance
534 **************************************************************************/
535 libvlc_media_descriptor_t *
536 libvlc_media_instance_get_media_descriptor(
537 libvlc_media_instance_t *p_mi,
538 libvlc_exception_t *p_e )
545 libvlc_media_descriptor_retain( p_mi->p_md );
549 /**************************************************************************
550 * Get the event Manager
551 **************************************************************************/
552 libvlc_event_manager_t *
553 libvlc_media_instance_event_manager(
554 libvlc_media_instance_t *p_mi,
555 libvlc_exception_t *p_e )
559 return p_mi->p_event_manager;
562 /**************************************************************************
564 **************************************************************************/
565 void libvlc_media_instance_play( libvlc_media_instance_t *p_mi,
566 libvlc_exception_t *p_e )
568 input_thread_t * p_input_thread;
570 if( (p_input_thread = libvlc_get_input_thread( p_mi, p_e )) )
572 /* A thread alread exists, send it a play message */
573 input_Control( p_input_thread, INPUT_SET_STATE, PLAYING_S );
574 vlc_object_release( p_input_thread );
578 /* Ignore previous exception */
579 libvlc_exception_clear( p_e );
581 vlc_mutex_lock( &p_mi->object_lock );
585 libvlc_exception_raise( p_e, "no associated media descriptor" );
586 vlc_mutex_unlock( &p_mi->object_lock );
590 p_mi->i_input_id = input_Read( p_mi->p_libvlc_instance->p_libvlc_int,
591 p_mi->p_md->p_input_item, VLC_FALSE );
593 p_input_thread = (input_thread_t*)vlc_object_get( p_mi->i_input_id );
595 if( !p_input_thread )
598 vlc_mutex_unlock( &p_mi->object_lock );
604 val.i_int = p_mi->drawable;
605 var_Create( p_input_thread, "drawable", VLC_VAR_DOINHERIT );
606 var_Set( p_input_thread, "drawable", val );
608 var_AddCallback( p_input_thread, "state", input_state_changed, p_mi );
609 var_AddCallback( p_input_thread, "seekable", input_seekable_changed, p_mi );
610 var_AddCallback( p_input_thread, "pausable", input_pausable_changed, p_mi );
611 var_AddCallback( p_input_thread, "intf-change", input_position_changed, p_mi );
612 var_AddCallback( p_input_thread, "intf-change", input_time_changed, p_mi );
614 vlc_object_release( p_input_thread );
615 vlc_mutex_unlock( &p_mi->object_lock );
618 /**************************************************************************
620 **************************************************************************/
621 void libvlc_media_instance_pause( libvlc_media_instance_t *p_mi,
622 libvlc_exception_t *p_e )
624 input_thread_t * p_input_thread = libvlc_get_input_thread( p_mi, p_e );
626 if( !p_input_thread )
629 int state = var_GetInteger( p_input_thread, "state" );
631 if( state == PLAYING_S )
633 if( libvlc_media_instance_can_pause( p_mi, p_e ) )
634 input_Control( p_input_thread, INPUT_SET_STATE, PAUSE_S );
636 libvlc_media_instance_stop( p_mi, p_e );
639 input_Control( p_input_thread, INPUT_SET_STATE, PLAYING_S );
641 vlc_object_release( p_input_thread );
644 /**************************************************************************
646 **************************************************************************/
647 void libvlc_media_instance_stop( libvlc_media_instance_t *p_mi,
648 libvlc_exception_t *p_e )
650 if( p_mi->b_own_its_input_thread )
651 release_input_thread( p_mi ); /* This will stop the input thread */
654 input_thread_t * p_input_thread = libvlc_get_input_thread( p_mi, p_e );
656 if( !p_input_thread )
659 input_StopThread( p_input_thread );
660 vlc_object_release( p_input_thread );
664 /**************************************************************************
666 **************************************************************************/
667 void libvlc_media_instance_set_drawable( libvlc_media_instance_t *p_mi,
668 libvlc_drawable_t drawable,
669 libvlc_exception_t *p_e )
672 p_mi->drawable = drawable;
675 /**************************************************************************
677 **************************************************************************/
679 libvlc_media_instance_get_drawable ( libvlc_media_instance_t *p_mi, libvlc_exception_t *p_e )
682 return p_mi->drawable;
685 /**************************************************************************
686 * Getters for stream information
687 **************************************************************************/
688 libvlc_time_t libvlc_media_instance_get_length(
689 libvlc_media_instance_t *p_mi,
690 libvlc_exception_t *p_e )
692 input_thread_t *p_input_thread;
695 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
696 if( !p_input_thread )
699 var_Get( p_input_thread, "length", &val );
700 vlc_object_release( p_input_thread );
702 return (val.i_time+500LL)/1000LL;
705 libvlc_time_t libvlc_media_instance_get_time(
706 libvlc_media_instance_t *p_mi,
707 libvlc_exception_t *p_e )
709 input_thread_t *p_input_thread;
712 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
713 if( !p_input_thread )
716 var_Get( p_input_thread , "time", &val );
717 vlc_object_release( p_input_thread );
718 return (val.i_time+500LL)/1000LL;
721 void libvlc_media_instance_set_time(
722 libvlc_media_instance_t *p_mi,
724 libvlc_exception_t *p_e )
726 input_thread_t *p_input_thread;
729 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
730 if( !p_input_thread )
733 value.i_time = time*1000LL;
734 var_Set( p_input_thread, "time", value );
735 vlc_object_release( p_input_thread );
738 void libvlc_media_instance_set_position(
739 libvlc_media_instance_t *p_mi,
741 libvlc_exception_t *p_e )
743 input_thread_t *p_input_thread;
745 val.f_float = position;
747 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
748 if( !p_input_thread )
751 var_Set( p_input_thread, "position", val );
752 vlc_object_release( p_input_thread );
755 float libvlc_media_instance_get_position(
756 libvlc_media_instance_t *p_mi,
757 libvlc_exception_t *p_e )
759 input_thread_t *p_input_thread;
762 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
763 if( !p_input_thread )
766 var_Get( p_input_thread, "position", &val );
767 vlc_object_release( p_input_thread );
772 void libvlc_media_instance_set_chapter(
773 libvlc_media_instance_t *p_mi,
775 libvlc_exception_t *p_e )
777 input_thread_t *p_input_thread;
781 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
782 if( !p_input_thread )
785 var_Set( p_input_thread, "chapter", val );
786 vlc_object_release( p_input_thread );
789 int libvlc_media_instance_get_chapter(
790 libvlc_media_instance_t *p_mi,
791 libvlc_exception_t *p_e )
793 input_thread_t *p_input_thread;
796 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
797 if( !p_input_thread )
800 var_Get( p_input_thread, "chapter", &val );
801 vlc_object_release( p_input_thread );
806 int libvlc_media_instance_get_chapter_count(
807 libvlc_media_instance_t *p_mi,
808 libvlc_exception_t *p_e )
810 input_thread_t *p_input_thread;
813 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
814 if( !p_input_thread )
817 var_Change( p_input_thread, "chapter", VLC_VAR_CHOICESCOUNT, &val, NULL );
818 vlc_object_release( p_input_thread );
823 float libvlc_media_instance_get_fps(
824 libvlc_media_instance_t *p_mi,
825 libvlc_exception_t *p_e)
827 input_thread_t *p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
832 if( input_Control( p_input_thread, INPUT_GET_VIDEO_FPS, &f_fps ) )
834 vlc_object_release( p_input_thread );
839 vlc_bool_t libvlc_media_instance_will_play(
840 libvlc_media_instance_t *p_mi,
841 libvlc_exception_t *p_e)
843 input_thread_t *p_input_thread =
844 libvlc_get_input_thread ( p_mi, p_e);
845 if ( !p_input_thread )
848 if ( !p_input_thread->b_die && !p_input_thread->b_dead )
850 vlc_object_release( p_input_thread );
853 vlc_object_release( p_input_thread );
857 void libvlc_media_instance_set_rate(
858 libvlc_media_instance_t *p_mi,
860 libvlc_exception_t *p_e )
862 input_thread_t *p_input_thread;
866 RAISEVOID( "Rate value is invalid" );
868 val.i_int = 1000.0f/rate;
870 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
871 if ( !p_input_thread )
874 var_Set( p_input_thread, "rate", val );
875 vlc_object_release( p_input_thread );
878 float libvlc_media_instance_get_rate(
879 libvlc_media_instance_t *p_mi,
880 libvlc_exception_t *p_e )
882 input_thread_t *p_input_thread;
885 p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
886 if ( !p_input_thread )
889 var_Get( p_input_thread, "rate", &val );
890 vlc_object_release( p_input_thread );
892 return (float)1000.0f/val.i_int;
895 libvlc_state_t libvlc_media_instance_get_state(
896 libvlc_media_instance_t *p_mi,
897 libvlc_exception_t *p_e )
899 input_thread_t *p_input_thread;
902 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
903 if ( !p_input_thread )
905 /* We do return the right value, no need to throw an exception */
906 if( libvlc_exception_raised( p_e ) )
907 libvlc_exception_clear( p_e );
908 return libvlc_Stopped;
911 var_Get( p_input_thread, "state", &val );
912 vlc_object_release( p_input_thread );
914 return vlc_to_libvlc_state(val.i_int);
917 vlc_bool_t libvlc_media_instance_is_seekable(
918 libvlc_media_instance_t *p_mi,
919 libvlc_exception_t *p_e )
921 input_thread_t *p_input_thread;
924 p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
925 if ( !p_input_thread )
927 /* We do return the right value, no need to throw an exception */
928 if( libvlc_exception_raised( p_e ) )
929 libvlc_exception_clear( p_e );
932 var_Get( p_input_thread, "seekable", &val );
933 vlc_object_release( p_input_thread );
938 vlc_bool_t libvlc_media_instance_can_pause(
939 libvlc_media_instance_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 )
948 /* We do return the right value, no need to throw an exception */
949 if( libvlc_exception_raised( p_e ) )
950 libvlc_exception_clear( p_e );
953 var_Get( p_input_thread, "can-pause", &val );
954 vlc_object_release( p_input_thread );