1 /*****************************************************************************
2 * media_player.c: Libvlc API Media Instance management functions
3 *****************************************************************************
4 * Copyright (C) 2005-2009 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 *****************************************************************************/
30 #include <vlc/libvlc.h>
31 #include <vlc/libvlc_media.h>
32 #include <vlc/libvlc_events.h>
34 #include <vlc_demux.h>
35 #include <vlc_input.h>
40 #include "libvlc_internal.h"
41 #include "media_internal.h" // libvlc_media_set_state()
42 #include "media_player_internal.h"
45 input_seekable_changed( vlc_object_t
* p_this
, char const * psz_cmd
,
46 vlc_value_t oldval
, vlc_value_t newval
,
49 input_pausable_changed( vlc_object_t
* p_this
, char const * psz_cmd
,
50 vlc_value_t oldval
, vlc_value_t newval
,
53 input_event_changed( vlc_object_t
* p_this
, char const * psz_cmd
,
54 vlc_value_t oldval
, vlc_value_t newval
,
58 snapshot_was_taken( vlc_object_t
*p_this
, char const *psz_cmd
,
59 vlc_value_t oldval
, vlc_value_t newval
, void *p_data
);
61 static void libvlc_media_player_destroy( libvlc_media_player_t
*p_mi
);
67 #define register_event(a, b) __register_event(a, libvlc_MediaPlayer ## b)
68 static inline void __register_event(libvlc_media_player_t
*mp
, libvlc_event_type_t type
)
70 libvlc_event_manager_register_event_type(mp
->p_event_manager
, type
);
74 * The input lock protects the input and input resource pointer.
75 * It MUST NOT be used from callbacks.
77 * The object lock protects the reset, namely the media and the player state.
78 * It can, and usually needs to be taken from callbacks.
79 * The object lock can be acquired under the input lock... and consequently
80 * the opposite order is STRICTLY PROHIBITED.
82 static inline void lock(libvlc_media_player_t
*mp
)
84 vlc_mutex_lock(&mp
->object_lock
);
87 static inline void unlock(libvlc_media_player_t
*mp
)
89 vlc_mutex_unlock(&mp
->object_lock
);
92 static inline void lock_input(libvlc_media_player_t
*mp
)
94 vlc_mutex_lock(&mp
->input
.lock
);
97 static inline void unlock_input(libvlc_media_player_t
*mp
)
99 vlc_mutex_unlock(&mp
->input
.lock
);
103 * Release the associated input thread.
105 * Object lock is NOT held.
106 * Input lock is held or instance is being destroyed.
108 static void release_input_thread( libvlc_media_player_t
*p_mi
, bool b_input_abort
)
112 input_thread_t
*p_input_thread
= p_mi
->input
.p_thread
;
113 if( !p_input_thread
)
116 var_DelCallback( p_input_thread
, "can-seek",
117 input_seekable_changed
, p_mi
);
118 var_DelCallback( p_input_thread
, "can-pause",
119 input_pausable_changed
, p_mi
);
120 var_DelCallback( p_input_thread
, "intf-event",
121 input_event_changed
, p_mi
);
123 /* We owned this one */
124 input_Stop( p_input_thread
, b_input_abort
);
126 vlc_thread_join( p_input_thread
);
128 assert( p_input_thread
->b_dead
);
130 /* Store the input resource for future use. */
131 assert( p_mi
->input
.p_resource
== NULL
);
132 p_mi
->input
.p_resource
= input_DetachResource( p_input_thread
);
134 p_mi
->input
.p_thread
= NULL
;
135 vlc_object_release( p_input_thread
);
139 * Retrieve the input thread. Be sure to release the object
140 * once you are done with it. (libvlc Internal)
142 input_thread_t
*libvlc_get_input_thread( libvlc_media_player_t
*p_mi
)
144 input_thread_t
*p_input_thread
;
149 p_input_thread
= p_mi
->input
.p_thread
;
151 vlc_object_hold( p_input_thread
);
153 libvlc_printerr( "No active input" );
156 return p_input_thread
;
160 * Set the internal state of the media_player. (media player Internal)
162 * Function will lock the media_player.
164 static void set_state( libvlc_media_player_t
*p_mi
, libvlc_state_t state
,
171 libvlc_media_t
*media
= p_mi
->p_md
;
173 libvlc_media_retain(media
);
180 // Also set the state of the corresponding media
181 // This is strictly for convenience.
182 libvlc_media_set_state(media
, state
);
184 libvlc_media_release(media
);
189 input_seekable_changed( vlc_object_t
* p_this
, char const * psz_cmd
,
190 vlc_value_t oldval
, vlc_value_t newval
,
196 libvlc_media_player_t
* p_mi
= p_userdata
;
197 libvlc_event_t event
;
199 event
.type
= libvlc_MediaPlayerSeekableChanged
;
200 event
.u
.media_player_seekable_changed
.new_seekable
= newval
.b_bool
;
202 libvlc_event_send( p_mi
->p_event_manager
, &event
);
207 input_pausable_changed( vlc_object_t
* p_this
, char const * psz_cmd
,
208 vlc_value_t oldval
, vlc_value_t newval
,
214 libvlc_media_player_t
* p_mi
= p_userdata
;
215 libvlc_event_t event
;
217 event
.type
= libvlc_MediaPlayerPausableChanged
;
218 event
.u
.media_player_pausable_changed
.new_pausable
= newval
.b_bool
;
220 libvlc_event_send( p_mi
->p_event_manager
, &event
);
225 input_event_changed( vlc_object_t
* p_this
, char const * psz_cmd
,
226 vlc_value_t oldval
, vlc_value_t newval
,
230 input_thread_t
* p_input
= (input_thread_t
*)p_this
;
231 libvlc_media_player_t
* p_mi
= p_userdata
;
232 libvlc_event_t event
;
234 assert( !strcmp( psz_cmd
, "intf-event" ) );
236 if( newval
.i_int
== INPUT_EVENT_STATE
)
238 libvlc_state_t libvlc_state
;
240 switch ( var_GetInteger( p_input
, "state" ) )
243 libvlc_state
= libvlc_NothingSpecial
;
244 event
.type
= libvlc_MediaPlayerNothingSpecial
;
247 libvlc_state
= libvlc_Opening
;
248 event
.type
= libvlc_MediaPlayerOpening
;
251 libvlc_state
= libvlc_Playing
;
252 event
.type
= libvlc_MediaPlayerPlaying
;
255 libvlc_state
= libvlc_Paused
;
256 event
.type
= libvlc_MediaPlayerPaused
;
259 libvlc_state
= libvlc_Ended
;
260 event
.type
= libvlc_MediaPlayerEndReached
;
263 libvlc_state
= libvlc_Error
;
264 event
.type
= libvlc_MediaPlayerEncounteredError
;
271 set_state( p_mi
, libvlc_state
, false );
272 libvlc_event_send( p_mi
->p_event_manager
, &event
);
274 else if( newval
.i_int
== INPUT_EVENT_ABORT
)
276 libvlc_state_t libvlc_state
= libvlc_Stopped
;
277 event
.type
= libvlc_MediaPlayerStopped
;
279 set_state( p_mi
, libvlc_state
, false );
280 libvlc_event_send( p_mi
->p_event_manager
, &event
);
282 else if( newval
.i_int
== INPUT_EVENT_POSITION
)
284 if( var_GetInteger( p_input
, "state" ) != PLAYING_S
)
285 return VLC_SUCCESS
; /* Don't send the position while stopped */
288 event
.type
= libvlc_MediaPlayerPositionChanged
;
289 event
.u
.media_player_position_changed
.new_position
=
290 var_GetFloat( p_input
, "position" );
291 libvlc_event_send( p_mi
->p_event_manager
, &event
);
294 event
.type
= libvlc_MediaPlayerTimeChanged
;
295 event
.u
.media_player_time_changed
.new_time
=
296 from_mtime(var_GetTime( p_input
, "time" ));
297 libvlc_event_send( p_mi
->p_event_manager
, &event
);
299 else if( newval
.i_int
== INPUT_EVENT_LENGTH
)
301 event
.type
= libvlc_MediaPlayerLengthChanged
;
302 event
.u
.media_player_length_changed
.new_length
=
303 from_mtime(var_GetTime( p_input
, "length" ));
304 libvlc_event_send( p_mi
->p_event_manager
, &event
);
311 /**************************************************************************
312 * Snapshot Taken Event.
314 * FIXME: This snapshot API interface makes no sense in media_player.
315 *************************************************************************/
316 static int snapshot_was_taken(vlc_object_t
*p_this
, char const *psz_cmd
,
317 vlc_value_t oldval
, vlc_value_t newval
, void *p_data
)
319 VLC_UNUSED(psz_cmd
); VLC_UNUSED(oldval
); VLC_UNUSED(p_this
);
321 libvlc_media_player_t
*mp
= p_data
;
322 libvlc_event_t event
;
323 event
.type
= libvlc_MediaPlayerSnapshotTaken
;
324 event
.u
.media_player_snapshot_taken
.psz_filename
= newval
.psz_string
;
325 libvlc_event_send(mp
->p_event_manager
, &event
);
330 static input_thread_t
*find_input (vlc_object_t
*obj
)
332 libvlc_media_player_t
*mp
= (libvlc_media_player_t
*)obj
;
334 return libvlc_get_input_thread (mp
);
338 static void libvlc_media_player_destroy( libvlc_media_player_t
* );
341 /**************************************************************************
342 * Create a Media Instance object.
345 * - All items created by _new start with a refcount set to 1.
346 * - Accessor _release decrease the refcount by 1, if after that
347 * operation the refcount is 0, the object is destroyed.
348 * - Accessor _retain increase the refcount by 1 (XXX: to implement)
350 * Object locking strategy:
351 * - No lock held while in constructor.
352 * - When accessing any member variable this lock is held. (XXX who locks?)
353 * - When attempting to destroy the object the lock is also held.
354 **************************************************************************/
355 libvlc_media_player_t
*
356 libvlc_media_player_new( libvlc_instance_t
*instance
)
358 libvlc_media_player_t
* mp
;
362 mp
= vlc_object_create (instance
->p_libvlc_int
, sizeof(*mp
));
363 if (unlikely(mp
== NULL
))
365 libvlc_printerr("Not enough memory");
368 vlc_object_attach (mp
, mp
->p_libvlc
);
371 var_Create (mp
, "rate", VLC_VAR_FLOAT
|VLC_VAR_DOINHERIT
);
374 var_Create (mp
, "drawable-xid", VLC_VAR_INTEGER
);
376 var_Create (mp
, "drawable-hwnd", VLC_VAR_ADDRESS
);
379 var_Create (mp
, "drawable-agl", VLC_VAR_INTEGER
);
380 var_Create (mp
, "drawable-nsobject", VLC_VAR_ADDRESS
);
383 var_Create (mp
, "keyboard-events", VLC_VAR_BOOL
);
384 var_SetBool (mp
, "keyboard-events", true);
385 var_Create (mp
, "mouse-events", VLC_VAR_BOOL
);
386 var_SetBool (mp
, "mouse-events", true);
388 var_Create (mp
, "fullscreen", VLC_VAR_BOOL
);
389 var_Create (mp
, "autoscale", VLC_VAR_BOOL
);
390 var_SetBool (mp
, "autoscale", true);
391 var_Create (mp
, "scale", VLC_VAR_FLOAT
);
392 var_SetFloat (mp
, "scale", 1.);
393 var_Create (mp
, "aspect-ratio", VLC_VAR_STRING
);
394 var_Create (mp
, "crop", VLC_VAR_STRING
);
395 var_Create (mp
, "deinterlace", VLC_VAR_INTEGER
);
396 var_Create (mp
, "deinterlace-mode", VLC_VAR_STRING
);
398 var_Create (mp
, "vbi-page", VLC_VAR_INTEGER
);
400 var_Create (mp
, "marq-marquee", VLC_VAR_STRING
);
401 var_Create (mp
, "marq-color", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
402 var_Create (mp
, "marq-opacity", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
403 var_Create (mp
, "marq-position", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
404 var_Create (mp
, "marq-refresh", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
405 var_Create (mp
, "marq-size", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
406 var_Create (mp
, "marq-timeout", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
407 var_Create (mp
, "marq-x", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
408 var_Create (mp
, "marq-y", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
410 var_Create (mp
, "logo-file", VLC_VAR_STRING
);
411 var_Create (mp
, "logo-x", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
412 var_Create (mp
, "logo-y", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
413 var_Create (mp
, "logo-delay", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
414 var_Create (mp
, "logo-repeat", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
415 var_Create (mp
, "logo-opacity", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
416 var_Create (mp
, "logo-position", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
418 var_Create (mp
, "contrast", VLC_VAR_FLOAT
| VLC_VAR_DOINHERIT
);
419 var_Create (mp
, "brightness", VLC_VAR_FLOAT
| VLC_VAR_DOINHERIT
);
420 var_Create (mp
, "hue", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
421 var_Create (mp
, "saturation", VLC_VAR_FLOAT
| VLC_VAR_DOINHERIT
);
422 var_Create (mp
, "gamma", VLC_VAR_FLOAT
| VLC_VAR_DOINHERIT
);
425 var_Create (mp
, "aout", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
426 var_Create (mp
, "volume-muted", VLC_VAR_BOOL
);
427 var_Create (mp
, "saved-volume", VLC_VAR_INTEGER
);
428 var_Create (mp
, "volume-change", VLC_VAR_VOID
);
429 var_Create (mp
, "find-input-callback", VLC_VAR_ADDRESS
);
430 var_SetAddress (mp
, "find-input-callback", find_input
);
433 mp
->state
= libvlc_NothingSpecial
;
434 mp
->p_libvlc_instance
= instance
;
435 mp
->input
.p_thread
= NULL
;
436 mp
->input
.p_resource
= NULL
;
437 vlc_mutex_init (&mp
->input
.lock
);
439 mp
->p_event_manager
= libvlc_event_manager_new(mp
, instance
);
440 if (unlikely(mp
->p_event_manager
== NULL
))
442 vlc_object_release(mp
);
445 vlc_mutex_init(&mp
->object_lock
);
447 register_event(mp
, NothingSpecial
);
448 register_event(mp
, Opening
);
449 register_event(mp
, Buffering
);
450 register_event(mp
, Playing
);
451 register_event(mp
, Paused
);
452 register_event(mp
, Stopped
);
453 register_event(mp
, Forward
);
454 register_event(mp
, Backward
);
455 register_event(mp
, EndReached
);
456 register_event(mp
, EncounteredError
);
457 register_event(mp
, SeekableChanged
);
459 register_event(mp
, PositionChanged
);
460 register_event(mp
, TimeChanged
);
461 register_event(mp
, LengthChanged
);
462 register_event(mp
, TitleChanged
);
463 register_event(mp
, PausableChanged
);
465 /* Snapshot initialization */
466 register_event(mp
, SnapshotTaken
);
468 register_event(mp
, MediaChanged
);
470 /* Attach a var callback to the global object to provide the glue between
471 * vout_thread that generates the event and media_player that re-emits it
472 * with its own event manager
474 * FIXME: It's unclear why we want to put this in public API, and why we
475 * want to expose it in such a limiting and ugly way.
477 var_AddCallback(mp
->p_libvlc
, "snapshot-file", snapshot_was_taken
, mp
);
479 libvlc_retain(instance
);
483 /**************************************************************************
484 * Create a Media Instance object with a media descriptor.
485 **************************************************************************/
486 libvlc_media_player_t
*
487 libvlc_media_player_new_from_media( libvlc_media_t
* p_md
)
489 libvlc_media_player_t
* p_mi
;
491 p_mi
= libvlc_media_player_new( p_md
->p_libvlc_instance
);
495 libvlc_media_retain( p_md
);
501 /**************************************************************************
502 * Destroy a Media Instance object (libvlc internal)
504 * Warning: No lock held here, but hey, this is internal. Caller must lock.
505 **************************************************************************/
506 static void libvlc_media_player_destroy( libvlc_media_player_t
*p_mi
)
510 /* Detach Callback from the main libvlc object */
511 var_DelCallback( p_mi
->p_libvlc
,
512 "snapshot-file", snapshot_was_taken
, p_mi
);
514 /* No need for lock_input() because no other threads knows us anymore */
515 if( p_mi
->input
.p_thread
)
516 release_input_thread(p_mi
, true);
517 if( p_mi
->input
.p_resource
)
519 input_resource_Delete( p_mi
->input
.p_resource
);
520 p_mi
->input
.p_resource
= NULL
;
522 vlc_mutex_destroy( &p_mi
->input
.lock
);
524 libvlc_event_manager_release( p_mi
->p_event_manager
);
525 libvlc_media_release( p_mi
->p_md
);
526 vlc_mutex_destroy( &p_mi
->object_lock
);
528 libvlc_instance_t
*instance
= p_mi
->p_libvlc_instance
;
529 vlc_object_release( p_mi
);
530 libvlc_release(instance
);
533 /**************************************************************************
534 * Release a Media Instance object.
536 * Function does the locking.
537 **************************************************************************/
538 void libvlc_media_player_release( libvlc_media_player_t
*p_mi
)
544 destroy
= !--p_mi
->i_refcount
;
548 libvlc_media_player_destroy( p_mi
);
551 /**************************************************************************
552 * Retain a Media Instance object.
554 * Caller must hold the lock.
555 **************************************************************************/
556 void libvlc_media_player_retain( libvlc_media_player_t
*p_mi
)
565 /**************************************************************************
566 * Set the Media descriptor associated with the instance.
568 * Enter without lock -- function will lock the object.
569 **************************************************************************/
570 void libvlc_media_player_set_media(
571 libvlc_media_player_t
*p_mi
,
572 libvlc_media_t
*p_md
)
576 /* FIXME I am not sure if it is a user request or on die(eof/error)
578 release_input_thread( p_mi
,
579 p_mi
->input
.p_thread
&&
580 !p_mi
->input
.p_thread
->b_eof
&&
581 !p_mi
->input
.p_thread
->b_error
);
584 set_state( p_mi
, libvlc_NothingSpecial
, true );
585 unlock_input( p_mi
);
587 libvlc_media_release( p_mi
->p_md
);
593 return; /* It is ok to pass a NULL md */
596 libvlc_media_retain( p_md
);
599 /* The policy here is to ignore that we were created using a different
600 * libvlc_instance, because we don't really care */
601 p_mi
->p_libvlc_instance
= p_md
->p_libvlc_instance
;
605 /* Send an event for the newly available media */
606 libvlc_event_t event
;
607 event
.type
= libvlc_MediaPlayerMediaChanged
;
608 event
.u
.media_player_media_changed
.new_media
= p_md
;
609 libvlc_event_send( p_mi
->p_event_manager
, &event
);
613 /**************************************************************************
614 * Get the Media descriptor associated with the instance.
615 **************************************************************************/
617 libvlc_media_player_get_media( libvlc_media_player_t
*p_mi
)
624 libvlc_media_retain( p_mi
->p_md
);
629 /**************************************************************************
630 * Get the event Manager.
631 **************************************************************************/
632 libvlc_event_manager_t
*
633 libvlc_media_player_event_manager( libvlc_media_player_t
*p_mi
)
635 return p_mi
->p_event_manager
;
638 /**************************************************************************
639 * Tell media player to start playing.
640 **************************************************************************/
641 int libvlc_media_player_play( libvlc_media_player_t
*p_mi
)
645 input_thread_t
*p_input_thread
= p_mi
->input
.p_thread
;
648 /* A thread already exists, send it a play message */
649 input_Control( p_input_thread
, INPUT_SET_STATE
, PLAYING_S
);
650 unlock_input( p_mi
);
654 /* Ignore previous exception */
660 unlock_input( p_mi
);
661 libvlc_printerr( "No associated media descriptor" );
665 p_input_thread
= input_Create( p_mi
, p_mi
->p_md
->p_input_item
, NULL
,
666 p_mi
->input
.p_resource
);
668 if( !p_input_thread
)
671 libvlc_printerr( "Not enough memory" );
675 p_mi
->input
.p_resource
= NULL
;
677 var_AddCallback( p_input_thread
, "can-seek", input_seekable_changed
, p_mi
);
678 var_AddCallback( p_input_thread
, "can-pause", input_pausable_changed
, p_mi
);
679 var_AddCallback( p_input_thread
, "intf-event", input_event_changed
, p_mi
);
681 if( input_Start( p_input_thread
) )
684 var_DelCallback( p_input_thread
, "intf-event", input_event_changed
, p_mi
);
685 var_DelCallback( p_input_thread
, "can-pause", input_pausable_changed
, p_mi
);
686 var_DelCallback( p_input_thread
, "can-seek", input_seekable_changed
, p_mi
);
687 vlc_object_release( p_input_thread
);
688 libvlc_printerr( "Input initialization failure" );
691 p_mi
->input
.p_thread
= p_input_thread
;
696 /**************************************************************************
698 **************************************************************************/
699 void libvlc_media_player_pause( libvlc_media_player_t
*p_mi
)
701 input_thread_t
* p_input_thread
= libvlc_get_input_thread( p_mi
);
702 if( !p_input_thread
)
705 libvlc_state_t state
= libvlc_media_player_get_state( p_mi
);
706 if( state
== libvlc_Playing
|| state
== libvlc_Buffering
)
708 if( libvlc_media_player_can_pause( p_mi
) )
709 input_Control( p_input_thread
, INPUT_SET_STATE
, PAUSE_S
);
711 libvlc_media_player_stop( p_mi
);
714 input_Control( p_input_thread
, INPUT_SET_STATE
, PLAYING_S
);
716 vlc_object_release( p_input_thread
);
719 /**************************************************************************
720 * Tells whether the media player is currently playing.
722 * Enter with lock held.
723 **************************************************************************/
724 int libvlc_media_player_is_playing( libvlc_media_player_t
*p_mi
)
726 libvlc_state_t state
= libvlc_media_player_get_state( p_mi
);
727 return (libvlc_Playing
== state
) || (libvlc_Buffering
== state
);
730 /**************************************************************************
732 **************************************************************************/
733 void libvlc_media_player_stop( libvlc_media_player_t
*p_mi
)
735 libvlc_state_t state
= libvlc_media_player_get_state( p_mi
);
738 release_input_thread( p_mi
, true ); /* This will stop the input thread */
740 /* Force to go to stopped state, in case we were in Ended, or Error
742 if( state
!= libvlc_Stopped
)
744 set_state( p_mi
, libvlc_Stopped
, false );
746 /* Construct and send the event */
747 libvlc_event_t event
;
748 event
.type
= libvlc_MediaPlayerStopped
;
749 libvlc_event_send( p_mi
->p_event_manager
, &event
);
752 if( p_mi
->input
.p_resource
!= NULL
)
753 input_resource_TerminateVout( p_mi
->input
.p_resource
);
757 /**************************************************************************
759 **************************************************************************/
760 void libvlc_media_player_set_nsobject( libvlc_media_player_t
*p_mi
,
763 assert (p_mi
!= NULL
);
765 var_SetAddress (p_mi
, "drawable-nsobject", drawable
);
767 (void) p_mi
; (void)drawable
;
771 /**************************************************************************
773 **************************************************************************/
774 void * libvlc_media_player_get_nsobject( libvlc_media_player_t
*p_mi
)
776 assert (p_mi
!= NULL
);
778 return var_GetAddress (p_mi
, "drawable-nsobject");
784 /**************************************************************************
786 **************************************************************************/
787 void libvlc_media_player_set_agl( libvlc_media_player_t
*p_mi
,
791 var_SetInteger (p_mi
, "drawable-agl", drawable
);
793 (void) p_mi
; (void)drawable
;
797 /**************************************************************************
799 **************************************************************************/
800 uint32_t libvlc_media_player_get_agl( libvlc_media_player_t
*p_mi
)
802 assert (p_mi
!= NULL
);
804 return var_GetInteger (p_mi
, "drawable-agl");
810 /**************************************************************************
812 **************************************************************************/
813 void libvlc_media_player_set_xwindow( libvlc_media_player_t
*p_mi
,
816 assert (p_mi
!= NULL
);
817 var_SetInteger (p_mi
, "drawable-xid", drawable
);
820 /**************************************************************************
822 **************************************************************************/
823 uint32_t libvlc_media_player_get_xwindow( libvlc_media_player_t
*p_mi
)
825 return var_GetInteger (p_mi
, "drawable-xid");
828 /**************************************************************************
830 **************************************************************************/
831 void libvlc_media_player_set_hwnd( libvlc_media_player_t
*p_mi
,
834 assert (p_mi
!= NULL
);
836 var_SetAddress (p_mi
, "drawable-hwnd", drawable
);
838 (void) p_mi
; (void) drawable
;
842 /**************************************************************************
844 **************************************************************************/
845 void *libvlc_media_player_get_hwnd( libvlc_media_player_t
*p_mi
)
847 assert (p_mi
!= NULL
);
849 return var_GetAddress (p_mi
, "drawable-hwnd");
855 /**************************************************************************
856 * Getters for stream information
857 **************************************************************************/
858 libvlc_time_t
libvlc_media_player_get_length(
859 libvlc_media_player_t
*p_mi
)
861 input_thread_t
*p_input_thread
;
862 libvlc_time_t i_time
;
864 p_input_thread
= libvlc_get_input_thread ( p_mi
);
865 if( !p_input_thread
)
868 i_time
= from_mtime(var_GetTime( p_input_thread
, "length" ));
869 vlc_object_release( p_input_thread
);
874 libvlc_time_t
libvlc_media_player_get_time( libvlc_media_player_t
*p_mi
)
876 input_thread_t
*p_input_thread
;
877 libvlc_time_t i_time
;
879 p_input_thread
= libvlc_get_input_thread ( p_mi
);
880 if( !p_input_thread
)
883 i_time
= from_mtime(var_GetTime( p_input_thread
, "time" ));
884 vlc_object_release( p_input_thread
);
888 void libvlc_media_player_set_time( libvlc_media_player_t
*p_mi
,
889 libvlc_time_t i_time
)
891 input_thread_t
*p_input_thread
;
893 p_input_thread
= libvlc_get_input_thread ( p_mi
);
894 if( !p_input_thread
)
897 var_SetTime( p_input_thread
, "time", to_mtime(i_time
) );
898 vlc_object_release( p_input_thread
);
901 void libvlc_media_player_set_position( libvlc_media_player_t
*p_mi
,
904 input_thread_t
*p_input_thread
;
906 p_input_thread
= libvlc_get_input_thread ( p_mi
);
907 if( !p_input_thread
)
910 var_SetFloat( p_input_thread
, "position", position
);
911 vlc_object_release( p_input_thread
);
914 float libvlc_media_player_get_position( libvlc_media_player_t
*p_mi
)
916 input_thread_t
*p_input_thread
;
919 p_input_thread
= libvlc_get_input_thread ( p_mi
);
920 if( !p_input_thread
)
923 f_position
= var_GetFloat( p_input_thread
, "position" );
924 vlc_object_release( p_input_thread
);
929 void libvlc_media_player_set_chapter( libvlc_media_player_t
*p_mi
,
932 input_thread_t
*p_input_thread
;
934 p_input_thread
= libvlc_get_input_thread ( p_mi
);
935 if( !p_input_thread
)
938 var_SetInteger( p_input_thread
, "chapter", chapter
);
939 vlc_object_release( p_input_thread
);
942 int libvlc_media_player_get_chapter( libvlc_media_player_t
*p_mi
)
944 input_thread_t
*p_input_thread
;
947 p_input_thread
= libvlc_get_input_thread ( p_mi
);
948 if( !p_input_thread
)
951 i_chapter
= var_GetInteger( p_input_thread
, "chapter" );
952 vlc_object_release( p_input_thread
);
957 int libvlc_media_player_get_chapter_count( libvlc_media_player_t
*p_mi
)
959 input_thread_t
*p_input_thread
;
962 p_input_thread
= libvlc_get_input_thread ( p_mi
);
963 if( !p_input_thread
)
966 var_Change( p_input_thread
, "chapter", VLC_VAR_CHOICESCOUNT
, &val
, NULL
);
967 vlc_object_release( p_input_thread
);
972 int libvlc_media_player_get_chapter_count_for_title(
973 libvlc_media_player_t
*p_mi
,
976 input_thread_t
*p_input_thread
;
979 p_input_thread
= libvlc_get_input_thread ( p_mi
);
980 if( !p_input_thread
)
984 if( asprintf( &psz_name
, "title %2i", i_title
) == -1 )
986 vlc_object_release( p_input_thread
);
989 var_Change( p_input_thread
, psz_name
, VLC_VAR_CHOICESCOUNT
, &val
, NULL
);
990 vlc_object_release( p_input_thread
);
996 void libvlc_media_player_set_title( libvlc_media_player_t
*p_mi
,
999 input_thread_t
*p_input_thread
;
1001 p_input_thread
= libvlc_get_input_thread ( p_mi
);
1002 if( !p_input_thread
)
1005 var_SetInteger( p_input_thread
, "title", i_title
);
1006 vlc_object_release( p_input_thread
);
1009 libvlc_event_t event
;
1010 event
.type
= libvlc_MediaPlayerTitleChanged
;
1011 event
.u
.media_player_title_changed
.new_title
= i_title
;
1012 libvlc_event_send( p_mi
->p_event_manager
, &event
);
1015 int libvlc_media_player_get_title( libvlc_media_player_t
*p_mi
)
1017 input_thread_t
*p_input_thread
;
1020 p_input_thread
= libvlc_get_input_thread ( p_mi
);
1021 if( !p_input_thread
)
1024 i_title
= var_GetInteger( p_input_thread
, "title" );
1025 vlc_object_release( p_input_thread
);
1030 int libvlc_media_player_get_title_count( libvlc_media_player_t
*p_mi
)
1032 input_thread_t
*p_input_thread
;
1035 p_input_thread
= libvlc_get_input_thread ( p_mi
);
1036 if( !p_input_thread
)
1039 var_Change( p_input_thread
, "title", VLC_VAR_CHOICESCOUNT
, &val
, NULL
);
1040 vlc_object_release( p_input_thread
);
1045 void libvlc_media_player_next_chapter( libvlc_media_player_t
*p_mi
)
1047 input_thread_t
*p_input_thread
;
1049 p_input_thread
= libvlc_get_input_thread ( p_mi
);
1050 if( !p_input_thread
)
1053 int i_type
= var_Type( p_input_thread
, "next-chapter" );
1054 var_SetBool( p_input_thread
, (i_type
& VLC_VAR_TYPE
) != 0 ?
1055 "next-chapter":"next-title", true );
1057 vlc_object_release( p_input_thread
);
1060 void libvlc_media_player_previous_chapter( libvlc_media_player_t
*p_mi
)
1062 input_thread_t
*p_input_thread
;
1064 p_input_thread
= libvlc_get_input_thread ( p_mi
);
1065 if( !p_input_thread
)
1068 int i_type
= var_Type( p_input_thread
, "next-chapter" );
1069 var_SetBool( p_input_thread
, (i_type
& VLC_VAR_TYPE
) != 0 ?
1070 "prev-chapter":"prev-title", true );
1072 vlc_object_release( p_input_thread
);
1075 float libvlc_media_player_get_fps( libvlc_media_player_t
*p_mi
)
1077 input_thread_t
*p_input_thread
= libvlc_get_input_thread ( p_mi
);
1080 if( p_input_thread
)
1082 if( input_Control( p_input_thread
, INPUT_GET_VIDEO_FPS
, &f_fps
) )
1084 vlc_object_release( p_input_thread
);
1089 int libvlc_media_player_will_play( libvlc_media_player_t
*p_mi
)
1092 input_thread_t
*p_input_thread
=
1093 libvlc_get_input_thread ( p_mi
);
1094 if ( !p_input_thread
)
1097 b_will_play
= !p_input_thread
->b_die
&& !p_input_thread
->b_dead
;
1098 vlc_object_release( p_input_thread
);
1103 int libvlc_media_player_set_rate( libvlc_media_player_t
*p_mi
, float rate
)
1107 libvlc_printerr ("Playing backward not supported");
1111 var_SetFloat (p_mi
, "rate", rate
);
1113 input_thread_t
*p_input_thread
= libvlc_get_input_thread ( p_mi
);
1114 if( !p_input_thread
)
1116 var_SetFloat( p_input_thread
, "rate", rate
);
1117 vlc_object_release( p_input_thread
);
1121 float libvlc_media_player_get_rate( libvlc_media_player_t
*p_mi
)
1123 return var_GetFloat (p_mi
, "rate");
1126 libvlc_state_t
libvlc_media_player_get_state( libvlc_media_player_t
*p_mi
)
1129 libvlc_state_t state
= p_mi
->state
;
1134 int libvlc_media_player_is_seekable( libvlc_media_player_t
*p_mi
)
1136 input_thread_t
*p_input_thread
;
1139 p_input_thread
= libvlc_get_input_thread ( p_mi
);
1140 if ( !p_input_thread
)
1142 b_seekable
= var_GetBool( p_input_thread
, "can-seek" );
1143 vlc_object_release( p_input_thread
);
1148 /* internal function, used by audio, video */
1149 libvlc_track_description_t
*
1150 libvlc_get_track_description( libvlc_media_player_t
*p_mi
,
1151 const char *psz_variable
)
1153 input_thread_t
*p_input
= libvlc_get_input_thread( p_mi
);
1154 libvlc_track_description_t
*p_track_description
= NULL
,
1155 *p_actual
, *p_previous
;
1160 vlc_value_t val_list
, text_list
;
1161 var_Change( p_input
, psz_variable
, VLC_VAR_GETLIST
, &val_list
, &text_list
);
1164 if( val_list
.p_list
->i_count
<= 0 )
1167 p_track_description
= ( libvlc_track_description_t
* )
1168 malloc( sizeof( libvlc_track_description_t
) );
1169 if ( !p_track_description
)
1171 libvlc_printerr( "Not enough memory" );
1174 p_actual
= p_track_description
;
1176 for( int i
= 0; i
< val_list
.p_list
->i_count
; i
++ )
1180 p_actual
= ( libvlc_track_description_t
* )
1181 malloc( sizeof( libvlc_track_description_t
) );
1184 libvlc_track_description_release( p_track_description
);
1185 libvlc_printerr( "Not enough memory" );
1189 p_actual
->i_id
= val_list
.p_list
->p_values
[i
].i_int
;
1190 p_actual
->psz_name
= strdup( text_list
.p_list
->p_values
[i
].psz_string
);
1191 p_actual
->p_next
= NULL
;
1193 p_previous
->p_next
= p_actual
;
1194 p_previous
= p_actual
;
1199 var_FreeList( &val_list
, &text_list
);
1200 vlc_object_release( p_input
);
1202 return p_track_description
;
1205 void libvlc_track_description_release( libvlc_track_description_t
*p_td
)
1207 libvlc_track_description_t
*p_actual
, *p_before
;
1212 free( p_actual
->psz_name
);
1213 p_before
= p_actual
;
1214 p_actual
= p_before
->p_next
;
1219 int libvlc_media_player_can_pause( libvlc_media_player_t
*p_mi
)
1221 input_thread_t
*p_input_thread
;
1224 p_input_thread
= libvlc_get_input_thread ( p_mi
);
1225 if ( !p_input_thread
)
1227 b_can_pause
= var_GetBool( p_input_thread
, "can-pause" );
1228 vlc_object_release( p_input_thread
);
1233 void libvlc_media_player_next_frame( libvlc_media_player_t
*p_mi
)
1235 input_thread_t
*p_input_thread
= libvlc_get_input_thread ( p_mi
);
1236 if( p_input_thread
!= NULL
)
1238 var_TriggerCallback( p_input_thread
, "frame-next" );
1239 vlc_object_release( p_input_thread
);