1 /*****************************************************************************
2 * media_player.c: Libvlc API Media Instance management functions
3 *****************************************************************************
4 * Copyright (C) 2005-2015 VLC authors and VideoLAN
6 * Authors: Clément Stenac <zorglub@videolan.org>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 2.1 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
29 #include <vlc/libvlc.h>
30 #include <vlc/libvlc_renderer_discoverer.h>
31 #include <vlc/libvlc_picture.h>
32 #include <vlc/libvlc_media.h>
33 #include <vlc/libvlc_events.h>
35 #include <vlc_demux.h>
38 #include <vlc_actions.h>
41 #include "libvlc_internal.h"
42 #include "media_internal.h" // libvlc_media_set_state()
43 #include "media_player_internal.h"
44 #include "renderer_discoverer_internal.h"
46 #define ES_INIT (-2) /* -1 is reserved for ES deselect */
49 snapshot_was_taken( vlc_object_t
*p_this
, char const *psz_cmd
,
50 vlc_value_t oldval
, vlc_value_t newval
, void *p_data
);
52 static void media_attach_preparsed_event(libvlc_media_t
*);
53 static void media_detach_preparsed_event(libvlc_media_t
*);
55 static void libvlc_media_player_destroy( libvlc_media_player_t
*p_mi
);
60 on_current_media_changed(vlc_player_t
*player
, input_item_t
*new_media
,
65 libvlc_media_player_t
*mp
= data
;
67 libvlc_media_t
*md
= mp
->p_md
;
69 input_item_t
*media
= md
? md
->p_input_item
: NULL
;
70 if (new_media
== media
)
75 media_detach_preparsed_event(md
);
79 mp
->p_md
= libvlc_media_new_from_input_item(mp
->p_libvlc_instance
,
82 /* error already printed by the function call */
85 media_attach_preparsed_event(mp
->p_md
);
90 libvlc_media_release(md
);
93 event
.type
= libvlc_MediaPlayerMediaChanged
;
94 event
.u
.media_player_media_changed
.new_media
= mp
->p_md
;
95 libvlc_event_send(&mp
->event_manager
, &event
);
99 on_state_changed(vlc_player_t
*player
, enum vlc_player_state new_state
,
104 libvlc_media_player_t
*mp
= data
;
106 libvlc_event_t event
;
108 case VLC_PLAYER_STATE_STOPPED
:
109 event
.type
= libvlc_MediaPlayerStopped
;
111 case VLC_PLAYER_STATE_STOPPING
:
112 event
.type
= libvlc_MediaPlayerEndReached
;
114 case VLC_PLAYER_STATE_STARTED
:
115 event
.type
= libvlc_MediaPlayerOpening
;
117 case VLC_PLAYER_STATE_PLAYING
:
118 event
.type
= libvlc_MediaPlayerPlaying
;
120 case VLC_PLAYER_STATE_PAUSED
:
121 event
.type
= libvlc_MediaPlayerPaused
;
124 vlc_assert_unreachable();
127 libvlc_event_send(&mp
->event_manager
, &event
);
131 on_error_changed(vlc_player_t
*player
, enum vlc_player_error error
, void *data
)
135 libvlc_media_player_t
*mp
= data
;
137 libvlc_event_t event
;
139 case VLC_PLAYER_ERROR_NONE
:
140 event
.type
= libvlc_MediaPlayerNothingSpecial
;
142 case VLC_PLAYER_ERROR_GENERIC
:
143 event
.type
= libvlc_MediaPlayerEncounteredError
;
146 vlc_assert_unreachable();
149 libvlc_event_send(&mp
->event_manager
, &event
);
153 on_buffering_changed(vlc_player_t
*player
, float new_buffering
, void *data
)
157 libvlc_media_player_t
*mp
= data
;
159 libvlc_event_t event
;
160 event
.type
= libvlc_MediaPlayerBuffering
;
161 event
.u
.media_player_buffering
.new_cache
= 100 * new_buffering
;
163 libvlc_event_send(&mp
->event_manager
, &event
);
167 on_capabilities_changed(vlc_player_t
*player
, int old_caps
, int new_caps
, void *data
)
171 libvlc_media_player_t
*mp
= data
;
173 libvlc_event_t event
;
175 bool old_seekable
= old_caps
& VLC_PLAYER_CAP_SEEK
;
176 bool new_seekable
= new_caps
& VLC_PLAYER_CAP_SEEK
;
177 if (new_seekable
!= old_seekable
)
179 event
.type
= libvlc_MediaPlayerSeekableChanged
;
180 event
.u
.media_player_seekable_changed
.new_seekable
= new_seekable
;
181 libvlc_event_send(&mp
->event_manager
, &event
);
184 bool old_pauseable
= old_caps
& VLC_PLAYER_CAP_PAUSE
;
185 bool new_pauseable
= new_caps
& VLC_PLAYER_CAP_PAUSE
;
186 if (new_pauseable
!= old_pauseable
)
188 event
.type
= libvlc_MediaPlayerPausableChanged
;
189 event
.u
.media_player_pausable_changed
.new_pausable
= new_pauseable
;
190 libvlc_event_send(&mp
->event_manager
, &event
);
195 on_position_changed(vlc_player_t
*player
, vlc_tick_t new_time
, float new_pos
,
200 libvlc_media_player_t
*mp
= data
;
202 libvlc_event_t event
;
204 event
.type
= libvlc_MediaPlayerPositionChanged
;
205 event
.u
.media_player_position_changed
.new_position
= new_pos
;
206 libvlc_event_send(&mp
->event_manager
, &event
);
208 event
.type
= libvlc_MediaPlayerTimeChanged
;
209 event
.u
.media_player_time_changed
.new_time
= MS_FROM_VLC_TICK(new_time
);
210 libvlc_event_send(&mp
->event_manager
, &event
);
214 on_length_changed(vlc_player_t
*player
, vlc_tick_t new_length
, void *data
)
218 libvlc_media_player_t
*mp
= data
;
220 libvlc_event_t event
;
222 event
.type
= libvlc_MediaPlayerLengthChanged
;
223 event
.u
.media_player_length_changed
.new_length
=
224 MS_FROM_VLC_TICK(new_length
);
226 libvlc_event_send(&mp
->event_manager
, &event
);
230 track_type_from_cat(enum es_format_category_e cat
)
235 return libvlc_track_video
;
237 return libvlc_track_audio
;
239 return libvlc_track_text
;
241 return libvlc_track_unknown
;
246 on_track_list_changed(vlc_player_t
*player
, enum vlc_player_list_action action
,
247 const struct vlc_player_track
*track
, void *data
)
251 libvlc_media_player_t
*mp
= data
;
253 libvlc_event_t event
;
256 case VLC_PLAYER_LIST_ADDED
:
257 event
.type
= libvlc_MediaPlayerESAdded
; break;
258 case VLC_PLAYER_LIST_REMOVED
:
259 event
.type
= libvlc_MediaPlayerESDeleted
; break;
260 case VLC_PLAYER_LIST_UPDATED
:
261 event
.type
= libvlc_MediaPlayerESUpdated
; break;
264 event
.u
.media_player_es_changed
.i_type
=
265 track_type_from_cat(track
->fmt
.i_cat
);
266 event
.u
.media_player_es_changed
.i_id
= vlc_es_id_GetInputId(track
->es_id
);
267 event
.u
.media_player_es_changed
.psz_id
= vlc_es_id_GetStrId(track
->es_id
);
269 libvlc_event_send(&mp
->event_manager
, &event
);
273 on_track_selection_changed(vlc_player_t
*player
, vlc_es_id_t
*unselected_id
,
274 vlc_es_id_t
*selected_id
, void *data
)
277 (void) unselected_id
;
279 libvlc_media_player_t
*mp
= data
;
281 libvlc_event_t event
;
282 event
.type
= libvlc_MediaPlayerESSelected
;
286 enum es_format_category_e cat
= vlc_es_id_GetCat(unselected_id
);
287 event
.u
.media_player_es_selection_changed
.i_type
= track_type_from_cat(cat
);
291 enum es_format_category_e cat
= vlc_es_id_GetCat(selected_id
);
292 event
.u
.media_player_es_selection_changed
.i_type
= track_type_from_cat(cat
);
295 event
.u
.media_player_es_selection_changed
.psz_unselected_id
=
296 unselected_id
? vlc_es_id_GetStrId(unselected_id
) : NULL
;
298 event
.u
.media_player_es_selection_changed
.psz_selected_id
=
299 selected_id
? vlc_es_id_GetStrId(selected_id
) : NULL
;
301 libvlc_event_send(&mp
->event_manager
, &event
);
305 on_program_list_changed(vlc_player_t
*player
,
306 enum vlc_player_list_action action
,
307 const struct vlc_player_program
*prgm
, void* data
)
312 libvlc_media_player_t
*mp
= data
;
314 const struct vlc_player_program
*selected
=
315 vlc_player_GetSelectedProgram(player
);
319 libvlc_event_t event
;
320 event
.type
= libvlc_MediaPlayerScrambledChanged
;
321 event
.u
.media_player_scrambled_changed
.new_scrambled
= selected
->scrambled
;
323 libvlc_event_send(&mp
->event_manager
, &event
);
327 on_program_selection_changed(vlc_player_t
*player
, int unselected_id
,
328 int selected_id
, void *data
)
330 (void) unselected_id
;
332 libvlc_media_player_t
*mp
= data
;
334 if (selected_id
== -1)
337 const struct vlc_player_program
*program
=
338 vlc_player_GetSelectedProgram(player
);
340 if (unlikely(program
== NULL
)) /* can happen when the player is stopping */
343 libvlc_event_t event
;
344 event
.type
= libvlc_MediaPlayerScrambledChanged
;
345 event
.u
.media_player_scrambled_changed
.new_scrambled
= program
->scrambled
;
347 libvlc_event_send(&mp
->event_manager
, &event
);
351 on_titles_changed(vlc_player_t
*player
,
352 vlc_player_title_list
*titles
, void *data
)
357 libvlc_media_player_t
*mp
= data
;
359 libvlc_event_t event
;
360 event
.type
= libvlc_MediaPlayerTitleListChanged
;
362 libvlc_event_send(&mp
->event_manager
, &event
);
366 on_title_selection_changed(vlc_player_t
*player
,
367 const struct vlc_player_title
*new_title
,
368 size_t new_idx
, void *data
)
373 libvlc_media_player_t
*mp
= data
;
375 const libvlc_title_description_t libtitle
= {
376 .i_duration
= MS_FROM_VLC_TICK(new_title
->length
),
377 .psz_name
= (char *) new_title
->name
,
378 .i_flags
= new_title
->flags
,
381 libvlc_event_t event
;
382 event
.type
= libvlc_MediaPlayerTitleSelectionChanged
;
383 event
.u
.media_player_title_selection_changed
.title
= &libtitle
;
384 event
.u
.media_player_title_selection_changed
.index
= new_idx
;
386 libvlc_event_send(&mp
->event_manager
, &event
);
390 on_chapter_selection_changed(vlc_player_t
*player
,
391 const struct vlc_player_title
*title
,
393 const struct vlc_player_chapter
*new_chapter
,
394 size_t new_chapter_idx
,
402 libvlc_media_player_t
*mp
= data
;
404 libvlc_event_t event
;
405 event
.type
= libvlc_MediaPlayerChapterChanged
;
406 event
.u
.media_player_chapter_changed
.new_chapter
= new_chapter_idx
;
408 libvlc_event_send(&mp
->event_manager
, &event
);
412 on_media_subitems_changed(vlc_player_t
*player
, input_item_t
*media
,
413 input_item_node_t
*new_subitems
, void *data
)
417 libvlc_media_player_t
*mp
= data
;
419 input_item_t
*current
= mp
->p_md
? mp
->p_md
->p_input_item
: NULL
;
420 if (media
== current
)
421 libvlc_media_add_subtree(mp
->p_md
, new_subitems
);
425 on_cork_changed(vlc_player_t
*player
, unsigned cork_count
, void *data
)
429 libvlc_media_player_t
*mp
= data
;
431 libvlc_event_t event
;
432 event
.type
= cork_count
? libvlc_MediaPlayerCorked
433 : libvlc_MediaPlayerUncorked
;
435 libvlc_event_send(&mp
->event_manager
, &event
);
439 on_vout_changed(vlc_player_t
*player
, enum vlc_player_vout_action action
,
440 vout_thread_t
*vout
, enum vlc_vout_order order
,
441 vlc_es_id_t
*es_id
, void *data
)
447 if (vlc_es_id_GetCat(es_id
) != VIDEO_ES
)
450 libvlc_media_player_t
*mp
= data
;
453 vout_thread_t
**vouts
= vlc_player_vout_HoldAll(player
, &count
);
456 for (size_t i
= 0; i
< count
; ++i
)
457 vout_Release(vouts
[i
]);
460 libvlc_event_t event
;
461 event
.type
= libvlc_MediaPlayerVout
;
462 event
.u
.media_player_vout
.new_count
= count
;
464 libvlc_event_send(&mp
->event_manager
, &event
);
467 // player aout callbacks
470 on_volume_changed(audio_output_t
*aout
, float new_volume
, void *data
)
474 libvlc_media_player_t
*mp
= data
;
476 libvlc_event_t event
;
477 event
.type
= libvlc_MediaPlayerAudioVolume
;
478 event
.u
.media_player_audio_volume
.volume
= new_volume
;
480 libvlc_event_send(&mp
->event_manager
, &event
);
484 on_mute_changed(audio_output_t
*aout
, bool new_muted
, void *data
)
488 libvlc_media_player_t
*mp
= data
;
490 libvlc_event_t event
;
491 event
.type
= new_muted
? libvlc_MediaPlayerMuted
492 : libvlc_MediaPlayerUnmuted
;
494 libvlc_event_send(&mp
->event_manager
, &event
);
498 on_audio_device_changed(audio_output_t
*aout
, const char *device
, void *data
)
502 libvlc_media_player_t
*mp
= data
;
504 libvlc_event_t event
;
505 event
.type
= libvlc_MediaPlayerAudioDevice
;
506 event
.u
.media_player_audio_device
.device
= device
;
508 libvlc_event_send(&mp
->event_manager
, &event
);
511 static const struct vlc_player_cbs vlc_player_cbs
= {
512 .on_current_media_changed
= on_current_media_changed
,
513 .on_state_changed
= on_state_changed
,
514 .on_error_changed
= on_error_changed
,
515 .on_buffering_changed
= on_buffering_changed
,
516 .on_capabilities_changed
= on_capabilities_changed
,
517 .on_position_changed
= on_position_changed
,
518 .on_length_changed
= on_length_changed
,
519 .on_track_list_changed
= on_track_list_changed
,
520 .on_track_selection_changed
= on_track_selection_changed
,
521 .on_program_list_changed
= on_program_list_changed
,
522 .on_program_selection_changed
= on_program_selection_changed
,
523 .on_titles_changed
= on_titles_changed
,
524 .on_title_selection_changed
= on_title_selection_changed
,
525 .on_chapter_selection_changed
= on_chapter_selection_changed
,
526 .on_media_subitems_changed
= on_media_subitems_changed
,
527 .on_cork_changed
= on_cork_changed
,
528 .on_vout_changed
= on_vout_changed
,
531 static const struct vlc_player_aout_cbs vlc_player_aout_cbs
= {
532 .on_volume_changed
= on_volume_changed
,
533 .on_mute_changed
= on_mute_changed
,
534 .on_device_changed
= on_audio_device_changed
,
537 /**************************************************************************
538 * Snapshot Taken Event.
540 * FIXME: This snapshot API interface makes no sense in media_player.
541 *************************************************************************/
542 static int snapshot_was_taken(vlc_object_t
*p_this
, char const *psz_cmd
,
543 vlc_value_t oldval
, vlc_value_t newval
, void *p_data
)
545 VLC_UNUSED(psz_cmd
); VLC_UNUSED(oldval
); VLC_UNUSED(p_this
);
547 libvlc_media_player_t
*mp
= p_data
;
548 libvlc_event_t event
;
549 event
.type
= libvlc_MediaPlayerSnapshotTaken
;
550 event
.u
.media_player_snapshot_taken
.psz_filename
= newval
.psz_string
;
551 libvlc_event_send(&mp
->event_manager
, &event
);
556 static void input_item_preparsed_changed( const vlc_event_t
*p_event
,
559 libvlc_media_t
*p_md
= user_data
;
560 if( p_event
->u
.input_item_preparsed_changed
.new_status
& ITEM_PREPARSED
)
563 libvlc_event_t event
;
564 event
.type
= libvlc_MediaParsedChanged
;
565 event
.u
.media_parsed_changed
.new_status
= libvlc_media_parsed_status_done
;
566 libvlc_event_send( &p_md
->event_manager
, &event
);
570 static void media_attach_preparsed_event( libvlc_media_t
*p_md
)
572 vlc_event_attach( &p_md
->p_input_item
->event_manager
,
573 vlc_InputItemPreparsedChanged
,
574 input_item_preparsed_changed
, p_md
);
577 static void media_detach_preparsed_event( libvlc_media_t
*p_md
)
579 vlc_event_detach( &p_md
->p_input_item
->event_manager
,
580 vlc_InputItemPreparsedChanged
,
581 input_item_preparsed_changed
,
585 /**************************************************************************
586 * Create a Media Instance object.
589 * - All items created by _new start with a refcount set to 1.
590 * - Accessor _release decrease the refcount by 1, if after that
591 * operation the refcount is 0, the object is destroyed.
592 * - Accessor _retain increase the refcount by 1 (XXX: to implement)
594 * Object locking strategy:
595 * - No lock held while in constructor.
596 * - When accessing any member variable this lock is held. (XXX who locks?)
597 * - When attempting to destroy the object the lock is also held.
598 **************************************************************************/
599 libvlc_media_player_t
*
600 libvlc_media_player_new( libvlc_instance_t
*instance
)
602 libvlc_media_player_t
* mp
;
606 mp
= vlc_object_create (instance
->p_libvlc_int
, sizeof(*mp
));
607 if (unlikely(mp
== NULL
))
609 libvlc_printerr("Not enough memory");
614 var_Create (mp
, "rate", VLC_VAR_FLOAT
|VLC_VAR_DOINHERIT
);
615 var_Create (mp
, "sout", VLC_VAR_STRING
);
616 var_Create (mp
, "demux-filter", VLC_VAR_STRING
);
619 var_Create (mp
, "vout", VLC_VAR_STRING
|VLC_VAR_DOINHERIT
);
620 var_Create (mp
, "window", VLC_VAR_STRING
);
621 var_Create (mp
, "gl", VLC_VAR_STRING
);
622 var_Create (mp
, "gles2", VLC_VAR_STRING
);
623 var_Create (mp
, "vmem-lock", VLC_VAR_ADDRESS
);
624 var_Create (mp
, "vmem-unlock", VLC_VAR_ADDRESS
);
625 var_Create (mp
, "vmem-display", VLC_VAR_ADDRESS
);
626 var_Create (mp
, "vmem-data", VLC_VAR_ADDRESS
);
627 var_Create (mp
, "vmem-setup", VLC_VAR_ADDRESS
);
628 var_Create (mp
, "vmem-cleanup", VLC_VAR_ADDRESS
);
629 var_Create (mp
, "vmem-chroma", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
630 var_Create (mp
, "vmem-width", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
631 var_Create (mp
, "vmem-height", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
632 var_Create (mp
, "vmem-pitch", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
634 var_Create (mp
, "vout-cb-type", VLC_VAR_INTEGER
);
635 var_Create( mp
, "vout-cb-opaque", VLC_VAR_ADDRESS
);
636 var_Create( mp
, "vout-cb-setup", VLC_VAR_ADDRESS
);
637 var_Create( mp
, "vout-cb-cleanup", VLC_VAR_ADDRESS
);
638 var_Create( mp
, "vout-cb-resize-cb", VLC_VAR_ADDRESS
);
639 var_Create( mp
, "vout-cb-update-output", VLC_VAR_ADDRESS
);
640 var_Create( mp
, "vout-cb-swap", VLC_VAR_ADDRESS
);
641 var_Create( mp
, "vout-cb-get-proc-address", VLC_VAR_ADDRESS
);
642 var_Create( mp
, "vout-cb-make-current", VLC_VAR_ADDRESS
);
643 var_Create( mp
, "vout-cb-metadata", VLC_VAR_ADDRESS
);
644 var_Create( mp
, "vout-cb-select-plane", VLC_VAR_ADDRESS
);
646 var_Create (mp
, "dec-dev", VLC_VAR_STRING
);
647 var_Create (mp
, "drawable-xid", VLC_VAR_INTEGER
);
648 #if defined (_WIN32) || defined (__OS2__)
649 var_Create (mp
, "drawable-hwnd", VLC_VAR_INTEGER
);
652 var_Create (mp
, "drawable-nsobject", VLC_VAR_ADDRESS
);
655 var_Create (mp
, "drawable-androidwindow", VLC_VAR_ADDRESS
);
658 var_Create (mp
, "keyboard-events", VLC_VAR_BOOL
);
659 var_SetBool (mp
, "keyboard-events", true);
660 var_Create (mp
, "mouse-events", VLC_VAR_BOOL
);
661 var_SetBool (mp
, "mouse-events", true);
663 var_Create (mp
, "fullscreen", VLC_VAR_BOOL
);
664 var_Create (mp
, "autoscale", VLC_VAR_BOOL
| VLC_VAR_DOINHERIT
);
665 var_Create (mp
, "zoom", VLC_VAR_FLOAT
| VLC_VAR_DOINHERIT
);
666 var_Create (mp
, "aspect-ratio", VLC_VAR_STRING
);
667 var_Create (mp
, "crop", VLC_VAR_STRING
);
668 var_Create (mp
, "deinterlace", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
669 var_Create (mp
, "deinterlace-mode", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
671 var_Create (mp
, "vbi-page", VLC_VAR_INTEGER
);
672 var_SetInteger (mp
, "vbi-page", 100);
674 var_Create (mp
, "video-filter", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
675 var_Create (mp
, "sub-source", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
676 var_Create (mp
, "sub-filter", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
678 var_Create (mp
, "marq-marquee", VLC_VAR_STRING
);
679 var_Create (mp
, "marq-color", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
680 var_Create (mp
, "marq-opacity", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
681 var_Create (mp
, "marq-position", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
682 var_Create (mp
, "marq-refresh", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
683 var_Create (mp
, "marq-size", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
684 var_Create (mp
, "marq-timeout", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
685 var_Create (mp
, "marq-x", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
686 var_Create (mp
, "marq-y", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
688 var_Create (mp
, "logo-file", VLC_VAR_STRING
);
689 var_Create (mp
, "logo-x", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
690 var_Create (mp
, "logo-y", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
691 var_Create (mp
, "logo-delay", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
692 var_Create (mp
, "logo-repeat", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
693 var_Create (mp
, "logo-opacity", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
694 var_Create (mp
, "logo-position", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
696 var_Create (mp
, "contrast", VLC_VAR_FLOAT
| VLC_VAR_DOINHERIT
);
697 var_Create (mp
, "brightness", VLC_VAR_FLOAT
| VLC_VAR_DOINHERIT
);
698 var_Create (mp
, "hue", VLC_VAR_FLOAT
| VLC_VAR_DOINHERIT
);
699 var_Create (mp
, "saturation", VLC_VAR_FLOAT
| VLC_VAR_DOINHERIT
);
700 var_Create (mp
, "gamma", VLC_VAR_FLOAT
| VLC_VAR_DOINHERIT
);
703 var_Create (mp
, "aout", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
704 var_Create (mp
, "audio-device", VLC_VAR_STRING
);
705 var_Create (mp
, "mute", VLC_VAR_BOOL
);
706 var_Create (mp
, "volume", VLC_VAR_FLOAT
);
707 var_Create (mp
, "corks", VLC_VAR_INTEGER
);
708 var_Create (mp
, "audio-filter", VLC_VAR_STRING
);
709 var_Create (mp
, "role", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
710 var_Create (mp
, "amem-data", VLC_VAR_ADDRESS
);
711 var_Create (mp
, "amem-setup", VLC_VAR_ADDRESS
);
712 var_Create (mp
, "amem-cleanup", VLC_VAR_ADDRESS
);
713 var_Create (mp
, "amem-play", VLC_VAR_ADDRESS
);
714 var_Create (mp
, "amem-pause", VLC_VAR_ADDRESS
);
715 var_Create (mp
, "amem-resume", VLC_VAR_ADDRESS
);
716 var_Create (mp
, "amem-flush", VLC_VAR_ADDRESS
);
717 var_Create (mp
, "amem-drain", VLC_VAR_ADDRESS
);
718 var_Create (mp
, "amem-set-volume", VLC_VAR_ADDRESS
);
719 var_Create (mp
, "amem-format", VLC_VAR_STRING
| VLC_VAR_DOINHERIT
);
720 var_Create (mp
, "amem-rate", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
721 var_Create (mp
, "amem-channels", VLC_VAR_INTEGER
| VLC_VAR_DOINHERIT
);
724 var_Create (mp
, "video-title-show", VLC_VAR_BOOL
);
725 var_Create (mp
, "video-title-position", VLC_VAR_INTEGER
);
726 var_Create (mp
, "video-title-timeout", VLC_VAR_INTEGER
);
729 var_Create (mp
, "equalizer-preamp", VLC_VAR_FLOAT
);
730 var_Create (mp
, "equalizer-vlcfreqs", VLC_VAR_BOOL
);
731 var_Create (mp
, "equalizer-bands", VLC_VAR_STRING
);
733 /* Initialize the shared HTTP cookie jar */
735 cookies
.p_address
= vlc_http_cookies_new();
736 if ( likely(cookies
.p_address
) )
738 var_Create(mp
, "http-cookies", VLC_VAR_ADDRESS
);
739 var_SetChecked(mp
, "http-cookies", VLC_VAR_ADDRESS
, cookies
);
743 mp
->p_libvlc_instance
= instance
;
744 /* use a reentrant lock to allow calling libvlc functions from callbacks */
745 mp
->player
= vlc_player_New(VLC_OBJECT(mp
), VLC_PLAYER_LOCK_REENTRANT
,
747 if (unlikely(!mp
->player
))
750 vlc_player_Lock(mp
->player
);
752 mp
->listener
= vlc_player_AddListener(mp
->player
, &vlc_player_cbs
, mp
);
753 if (unlikely(!mp
->listener
))
757 vlc_player_aout_AddListener(mp
->player
, &vlc_player_aout_cbs
, mp
);
758 if (unlikely(!mp
->aout_listener
))
761 vlc_player_Unlock(mp
->player
);
764 libvlc_event_manager_init(&mp
->event_manager
, mp
);
766 /* Snapshot initialization */
767 /* Attach a var callback to the global object to provide the glue between
768 * vout_thread that generates the event and media_player that re-emits it
769 * with its own event manager
771 * FIXME: It's unclear why we want to put this in public API, and why we
772 * want to expose it in such a limiting and ugly way.
774 var_AddCallback(vlc_object_instance(mp
),
775 "snapshot-file", snapshot_was_taken
, mp
);
777 libvlc_retain(instance
);
781 vlc_player_RemoveListener(mp
->player
, mp
->listener
);
783 vlc_player_Unlock(mp
->player
);
784 vlc_player_Delete(mp
->player
);
786 vlc_object_delete(mp
);
790 /**************************************************************************
791 * Create a Media Instance object with a media descriptor.
792 **************************************************************************/
793 libvlc_media_player_t
*
794 libvlc_media_player_new_from_media( libvlc_media_t
* p_md
)
796 libvlc_media_player_t
* p_mi
;
798 p_mi
= libvlc_media_player_new( p_md
->p_libvlc_instance
);
802 libvlc_media_retain( p_md
);
804 media_attach_preparsed_event(p_md
);
806 vlc_player_Lock(p_mi
->player
);
807 int ret
= vlc_player_SetCurrentMedia(p_mi
->player
, p_md
->p_input_item
);
808 vlc_player_Unlock(p_mi
->player
);
810 if (ret
!= VLC_SUCCESS
)
812 media_detach_preparsed_event(p_md
);
813 libvlc_media_release(p_md
);
821 /**************************************************************************
822 * Destroy a Media Instance object (libvlc internal)
824 * Warning: No lock held here, but hey, this is internal. Caller must lock.
825 **************************************************************************/
826 static void libvlc_media_player_destroy( libvlc_media_player_t
*p_mi
)
830 /* Detach Callback from the main libvlc object */
831 var_DelCallback( vlc_object_instance(p_mi
),
832 "snapshot-file", snapshot_was_taken
, p_mi
);
834 vlc_player_Lock(p_mi
->player
);
835 vlc_player_aout_RemoveListener(p_mi
->player
, p_mi
->aout_listener
);
836 vlc_player_RemoveListener(p_mi
->player
, p_mi
->listener
);
837 vlc_player_Unlock(p_mi
->player
);
839 vlc_player_Delete(p_mi
->player
);
842 media_detach_preparsed_event(p_mi
->p_md
);
843 libvlc_event_manager_destroy(&p_mi
->event_manager
);
844 libvlc_media_release( p_mi
->p_md
);
846 vlc_http_cookie_jar_t
*cookies
= var_GetAddress( p_mi
, "http-cookies" );
849 var_Destroy( p_mi
, "http-cookies" );
850 vlc_http_cookies_destroy( cookies
);
853 libvlc_instance_t
*instance
= p_mi
->p_libvlc_instance
;
854 vlc_object_delete(p_mi
);
855 libvlc_release(instance
);
858 /**************************************************************************
859 * Release a Media Instance object.
861 * Function does the locking.
862 **************************************************************************/
863 void libvlc_media_player_release( libvlc_media_player_t
*p_mi
)
868 vlc_player_Lock(p_mi
->player
);
869 destroy
= !--p_mi
->i_refcount
;
870 vlc_player_Unlock(p_mi
->player
);
873 libvlc_media_player_destroy( p_mi
);
876 /**************************************************************************
877 * Retain a Media Instance object.
879 * Caller must hold the lock.
880 **************************************************************************/
881 void libvlc_media_player_retain( libvlc_media_player_t
*p_mi
)
885 vlc_player_Lock(p_mi
->player
);
887 vlc_player_Unlock(p_mi
->player
);
890 /**************************************************************************
891 * Set the Media descriptor associated with the instance.
893 * Enter without lock -- function will lock the object.
894 **************************************************************************/
895 void libvlc_media_player_set_media(
896 libvlc_media_player_t
*p_mi
,
897 libvlc_media_t
*p_md
)
899 vlc_player_Lock(p_mi
->player
);
902 media_detach_preparsed_event(p_mi
->p_md
);
904 libvlc_media_release( p_mi
->p_md
);
908 libvlc_media_retain( p_md
);
909 media_attach_preparsed_event(p_md
);
913 vlc_player_SetCurrentMedia(p_mi
->player
, p_md
->p_input_item
);
915 vlc_player_Unlock(p_mi
->player
);
918 /**************************************************************************
919 * Get the Media descriptor associated with the instance.
920 **************************************************************************/
922 libvlc_media_player_get_media( libvlc_media_player_t
*p_mi
)
926 vlc_player_Lock(p_mi
->player
);
929 libvlc_media_retain( p_m
);
930 vlc_player_Unlock(p_mi
->player
);
935 /**************************************************************************
936 * Get the event Manager.
937 **************************************************************************/
938 libvlc_event_manager_t
*
939 libvlc_media_player_event_manager( libvlc_media_player_t
*p_mi
)
941 return &p_mi
->event_manager
;
944 /**************************************************************************
945 * Tell media player to start playing.
946 **************************************************************************/
947 int libvlc_media_player_play( libvlc_media_player_t
*p_mi
)
949 vlc_player_t
*player
= p_mi
->player
;
950 vlc_player_Lock(player
);
952 int ret
= vlc_player_Start(player
);
953 if (ret
== VLC_SUCCESS
)
955 if (vlc_player_IsPaused(player
))
956 vlc_player_Resume(player
);
959 vlc_player_Unlock(player
);
963 void libvlc_media_player_set_pause( libvlc_media_player_t
*p_mi
, int paused
)
965 vlc_player_t
*player
= p_mi
->player
;
966 vlc_player_Lock(player
);
970 if (vlc_player_CanPause(player
))
971 vlc_player_Pause(player
);
973 vlc_player_Stop(player
);
977 vlc_player_Resume(player
);
980 vlc_player_Unlock(player
);
983 /**************************************************************************
985 **************************************************************************/
986 void libvlc_media_player_pause( libvlc_media_player_t
*p_mi
)
988 vlc_player_t
*player
= p_mi
->player
;
989 vlc_player_Lock(player
);
991 vlc_player_TogglePause(player
);
993 vlc_player_Unlock(player
);
996 /**************************************************************************
997 * Tells whether the media player is currently playing.
998 **************************************************************************/
999 bool libvlc_media_player_is_playing(libvlc_media_player_t
*p_mi
)
1001 vlc_player_t
*player
= p_mi
->player
;
1002 vlc_player_Lock(player
);
1004 bool ret
= vlc_player_IsStarted(player
) && !vlc_player_IsPaused(player
);
1006 vlc_player_Unlock(player
);
1010 /**************************************************************************
1012 **************************************************************************/
1013 int libvlc_media_player_stop_async( libvlc_media_player_t
*p_mi
)
1015 vlc_player_t
*player
= p_mi
->player
;
1016 vlc_player_Lock(player
);
1018 int ret
= vlc_player_Stop(player
);
1020 vlc_player_Unlock(player
);
1025 int libvlc_media_player_set_renderer( libvlc_media_player_t
*p_mi
,
1026 libvlc_renderer_item_t
*p_litem
)
1028 vlc_player_t
*player
= p_mi
->player
;
1029 vlc_player_Lock(player
);
1031 vlc_renderer_item_t
*renderer
= libvlc_renderer_item_to_vlc(p_litem
);
1032 vlc_player_SetRenderer(player
, renderer
);
1034 vlc_player_Unlock(player
);
1038 void libvlc_video_set_callbacks( libvlc_media_player_t
*mp
,
1039 void *(*lock_cb
) (void *, void **),
1040 void (*unlock_cb
) (void *, void *, void *const *),
1041 void (*display_cb
) (void *, void *),
1044 var_SetAddress( mp
, "vmem-lock", lock_cb
);
1045 var_SetAddress( mp
, "vmem-unlock", unlock_cb
);
1046 var_SetAddress( mp
, "vmem-display", display_cb
);
1047 var_SetAddress( mp
, "vmem-data", opaque
);
1048 var_SetString( mp
, "dec-dev", "none" );
1049 var_SetString( mp
, "vout", "vmem" );
1050 var_SetString( mp
, "window", "dummy" );
1053 void libvlc_video_set_format_callbacks( libvlc_media_player_t
*mp
,
1054 libvlc_video_format_cb setup
,
1055 libvlc_video_cleanup_cb cleanup
)
1057 var_SetAddress( mp
, "vmem-setup", setup
);
1058 var_SetAddress( mp
, "vmem-cleanup", cleanup
);
1061 void libvlc_video_set_format( libvlc_media_player_t
*mp
, const char *chroma
,
1062 unsigned width
, unsigned height
, unsigned pitch
)
1064 var_SetString( mp
, "vmem-chroma", chroma
);
1065 var_SetInteger( mp
, "vmem-width", width
);
1066 var_SetInteger( mp
, "vmem-height", height
);
1067 var_SetInteger( mp
, "vmem-pitch", pitch
);
1070 bool libvlc_video_set_output_callbacks(libvlc_media_player_t
*mp
,
1071 libvlc_video_engine_t engine
,
1072 libvlc_video_output_setup_cb setup_cb
,
1073 libvlc_video_output_cleanup_cb cleanup_cb
,
1074 libvlc_video_output_set_resize_cb resize_cb
,
1075 libvlc_video_update_output_cb update_output_cb
,
1076 libvlc_video_swap_cb swap_cb
,
1077 libvlc_video_makeCurrent_cb makeCurrent_cb
,
1078 libvlc_video_getProcAddress_cb getProcAddress_cb
,
1079 libvlc_video_frameMetadata_cb metadata_cb
,
1080 libvlc_video_output_select_plane_cb select_plane_cb
,
1083 static_assert(libvlc_video_engine_disable
== 0, "No engine set must default to 0");
1085 //use the default android window
1086 var_SetString( mp
, "window", "");
1088 var_SetString( mp
, "window", "wextern");
1091 if( engine
== libvlc_video_engine_gles2
)
1093 var_SetString ( mp
, "vout", "gles2" );
1094 var_SetString ( mp
, "gles2", "vgl" );
1096 else if( engine
== libvlc_video_engine_opengl
)
1098 var_SetString ( mp
, "vout", "gl" );
1099 var_SetString ( mp
, "gl", "vgl");
1101 else if ( engine
== libvlc_video_engine_d3d11
)
1103 var_SetString ( mp
, "vout", "direct3d11" );
1104 var_SetString ( mp
, "dec-dev", "d3d11" );
1106 else if ( engine
== libvlc_video_engine_d3d9
)
1108 var_SetString ( mp
, "vout", "direct3d9" );
1109 var_SetString ( mp
, "dec-dev", "d3d9" );
1111 else if ( engine
== libvlc_video_engine_disable
)
1113 // use the default display module
1114 var_SetString ( mp
, "vout", "" );
1115 // use the default window
1116 var_SetString( mp
, "window", "");
1121 var_SetInteger( mp
, "vout-cb-type", engine
);
1122 var_SetAddress( mp
, "vout-cb-opaque", opaque
);
1123 var_SetAddress( mp
, "vout-cb-setup", setup_cb
);
1124 var_SetAddress( mp
, "vout-cb-cleanup", cleanup_cb
);
1125 var_SetAddress( mp
, "vout-cb-resize-cb", resize_cb
);
1126 var_SetAddress( mp
, "vout-cb-update-output", update_output_cb
);
1127 var_SetAddress( mp
, "vout-cb-swap", swap_cb
);
1128 var_SetAddress( mp
, "vout-cb-get-proc-address", getProcAddress_cb
);
1129 var_SetAddress( mp
, "vout-cb-make-current", makeCurrent_cb
);
1130 var_SetAddress( mp
, "vout-cb-metadata", metadata_cb
);
1131 var_SetAddress( mp
, "vout-cb-select-plane", select_plane_cb
);
1135 /**************************************************************************
1137 **************************************************************************/
1138 void libvlc_media_player_set_nsobject( libvlc_media_player_t
*p_mi
,
1141 assert (p_mi
!= NULL
);
1143 var_SetString (p_mi
, "dec-dev", "");
1144 var_SetString (p_mi
, "vout", "");
1145 var_SetString (p_mi
, "window", "");
1146 var_SetAddress (p_mi
, "drawable-nsobject", drawable
);
1149 libvlc_printerr ("can't set nsobject: APPLE build required");
1151 var_SetString (p_mi
, "vout", "none");
1152 var_SetString (p_mi
, "window", "none");
1156 /**************************************************************************
1158 **************************************************************************/
1159 void * libvlc_media_player_get_nsobject( libvlc_media_player_t
*p_mi
)
1161 assert (p_mi
!= NULL
);
1163 return var_GetAddress (p_mi
, "drawable-nsobject");
1170 /**************************************************************************
1172 **************************************************************************/
1173 void libvlc_media_player_set_xwindow( libvlc_media_player_t
*p_mi
,
1176 assert (p_mi
!= NULL
);
1178 var_SetString (p_mi
, "dec-dev", "");
1179 var_SetString (p_mi
, "vout", "");
1180 var_SetString (p_mi
, "window", drawable
? "embed-xid,any" : "");
1181 var_SetInteger (p_mi
, "drawable-xid", drawable
);
1184 /**************************************************************************
1186 **************************************************************************/
1187 uint32_t libvlc_media_player_get_xwindow( libvlc_media_player_t
*p_mi
)
1189 return var_GetInteger (p_mi
, "drawable-xid");
1192 /**************************************************************************
1194 **************************************************************************/
1195 void libvlc_media_player_set_hwnd( libvlc_media_player_t
*p_mi
,
1198 assert (p_mi
!= NULL
);
1199 #if defined (_WIN32) || defined (__OS2__)
1200 var_SetString (p_mi
, "dec-dev", "");
1201 var_SetString (p_mi
, "vout", "");
1202 var_SetString (p_mi
, "window",
1203 (drawable
!= NULL
) ? "embed-hwnd,any" : "");
1204 var_SetInteger (p_mi
, "drawable-hwnd", (uintptr_t)drawable
);
1207 libvlc_printerr ("can't set hwnd: WIN32 build required");
1209 var_SetString (p_mi
, "vout", "none");
1210 var_SetString (p_mi
, "window", "none");
1214 /**************************************************************************
1216 **************************************************************************/
1217 void *libvlc_media_player_get_hwnd( libvlc_media_player_t
*p_mi
)
1219 assert (p_mi
!= NULL
);
1220 #if defined (_WIN32) || defined (__OS2__)
1221 return (void *)(uintptr_t)var_GetInteger (p_mi
, "drawable-hwnd");
1228 /**************************************************************************
1229 * set_android_context
1230 **************************************************************************/
1231 void libvlc_media_player_set_android_context( libvlc_media_player_t
*p_mi
,
1232 void *p_awindow_handler
)
1234 assert (p_mi
!= NULL
);
1236 var_SetAddress (p_mi
, "drawable-androidwindow", p_awindow_handler
);
1238 (void) p_awindow_handler
;
1239 libvlc_printerr ("can't set android context: ANDROID build required");
1241 var_SetString (p_mi
, "vout", "none");
1242 var_SetString (p_mi
, "window", "none");
1246 void libvlc_audio_set_callbacks( libvlc_media_player_t
*mp
,
1247 libvlc_audio_play_cb play_cb
,
1248 libvlc_audio_pause_cb pause_cb
,
1249 libvlc_audio_resume_cb resume_cb
,
1250 libvlc_audio_flush_cb flush_cb
,
1251 libvlc_audio_drain_cb drain_cb
,
1254 var_SetAddress( mp
, "amem-play", play_cb
);
1255 var_SetAddress( mp
, "amem-pause", pause_cb
);
1256 var_SetAddress( mp
, "amem-resume", resume_cb
);
1257 var_SetAddress( mp
, "amem-flush", flush_cb
);
1258 var_SetAddress( mp
, "amem-drain", drain_cb
);
1259 var_SetAddress( mp
, "amem-data", opaque
);
1260 var_SetString( mp
, "aout", "amem,none" );
1262 vlc_player_aout_Reset( mp
->player
);
1265 void libvlc_audio_set_volume_callback( libvlc_media_player_t
*mp
,
1266 libvlc_audio_set_volume_cb cb
)
1268 var_SetAddress( mp
, "amem-set-volume", cb
);
1270 vlc_player_aout_Reset( mp
->player
);
1273 void libvlc_audio_set_format_callbacks( libvlc_media_player_t
*mp
,
1274 libvlc_audio_setup_cb setup
,
1275 libvlc_audio_cleanup_cb cleanup
)
1277 var_SetAddress( mp
, "amem-setup", setup
);
1278 var_SetAddress( mp
, "amem-cleanup", cleanup
);
1280 vlc_player_aout_Reset( mp
->player
);
1283 void libvlc_audio_set_format( libvlc_media_player_t
*mp
, const char *format
,
1284 unsigned rate
, unsigned channels
)
1286 var_SetString( mp
, "amem-format", format
);
1287 var_SetInteger( mp
, "amem-rate", rate
);
1288 var_SetInteger( mp
, "amem-channels", channels
);
1290 vlc_player_aout_Reset( mp
->player
);
1294 /**************************************************************************
1295 * Getters for stream information
1296 **************************************************************************/
1297 libvlc_time_t
libvlc_media_player_get_length(
1298 libvlc_media_player_t
*p_mi
)
1300 vlc_player_t
*player
= p_mi
->player
;
1301 vlc_player_Lock(player
);
1303 vlc_tick_t length
= vlc_player_GetLength(player
);
1304 libvlc_time_t i_time
= from_mtime(length
);
1306 vlc_player_Unlock(player
);
1310 libvlc_time_t
libvlc_media_player_get_time( libvlc_media_player_t
*p_mi
)
1312 vlc_player_t
*player
= p_mi
->player
;
1313 vlc_player_Lock(player
);
1315 vlc_tick_t tick
= vlc_player_GetTime(player
);
1316 libvlc_time_t i_time
= from_mtime(tick
);
1318 vlc_player_Unlock(player
);
1322 int libvlc_media_player_set_time( libvlc_media_player_t
*p_mi
,
1323 libvlc_time_t i_time
, bool b_fast
)
1325 vlc_tick_t tick
= to_mtime(i_time
);
1327 vlc_player_t
*player
= p_mi
->player
;
1328 vlc_player_Lock(player
);
1330 enum vlc_player_seek_speed speed
= b_fast
? VLC_PLAYER_SEEK_FAST
1331 : VLC_PLAYER_SEEK_PRECISE
;
1332 vlc_player_SeekByTime(player
, tick
, speed
, VLC_PLAYER_WHENCE_ABSOLUTE
);
1334 vlc_player_Unlock(player
);
1336 /* may not fail anymore, keep int not to break the API */
1340 int libvlc_media_player_set_position( libvlc_media_player_t
*p_mi
,
1341 float position
, bool b_fast
)
1343 vlc_player_t
*player
= p_mi
->player
;
1344 vlc_player_Lock(player
);
1346 enum vlc_player_seek_speed speed
= b_fast
? VLC_PLAYER_SEEK_FAST
1347 : VLC_PLAYER_SEEK_PRECISE
;
1348 vlc_player_SeekByPos(player
, position
, speed
, VLC_PLAYER_WHENCE_ABSOLUTE
);
1350 vlc_player_Unlock(player
);
1352 /* may not fail anymore, keep int not to break the API */
1356 float libvlc_media_player_get_position( libvlc_media_player_t
*p_mi
)
1358 vlc_player_t
*player
= p_mi
->player
;
1359 vlc_player_Lock(player
);
1361 float f_position
= vlc_player_GetPosition(player
);
1363 vlc_player_Unlock(player
);
1367 void libvlc_media_player_set_chapter( libvlc_media_player_t
*p_mi
,
1370 vlc_player_t
*player
= p_mi
->player
;
1371 vlc_player_Lock(player
);
1373 vlc_player_SelectChapterIdx(player
, chapter
);
1375 vlc_player_Unlock(player
);
1378 int libvlc_media_player_get_chapter( libvlc_media_player_t
*p_mi
)
1380 vlc_player_t
*player
= p_mi
->player
;
1381 vlc_player_Lock(player
);
1383 ssize_t i_chapter
= vlc_player_GetSelectedChapterIdx(player
);
1385 vlc_player_Unlock(player
);
1389 int libvlc_media_player_get_chapter_count( libvlc_media_player_t
*p_mi
)
1391 vlc_player_t
*player
= p_mi
->player
;
1392 vlc_player_Lock(player
);
1394 const struct vlc_player_title
*title
= vlc_player_GetSelectedTitle(player
);
1395 int ret
= title
? (int) title
->chapter_count
: -1;
1397 vlc_player_Unlock(player
);
1401 int libvlc_media_player_get_chapter_count_for_title(
1402 libvlc_media_player_t
*p_mi
,
1405 assert(i_title
>= 0);
1406 size_t idx
= i_title
;
1409 vlc_player_t
*player
= p_mi
->player
;
1410 vlc_player_Lock(player
);
1412 vlc_player_title_list
*titles
= vlc_player_GetTitleList(player
);
1416 size_t titles_count
= vlc_player_title_list_GetCount(titles
);
1417 if (idx
< titles_count
)
1420 const struct vlc_player_title
*title
=
1421 vlc_player_title_list_GetAt(titles
, idx
);
1424 ret
= title
->chapter_count
;
1427 vlc_player_Unlock(player
);
1431 void libvlc_media_player_set_title( libvlc_media_player_t
*p_mi
,
1434 vlc_player_t
*player
= p_mi
->player
;
1435 vlc_player_Lock(player
);
1437 vlc_player_SelectTitleIdx(player
, i_title
);
1439 vlc_player_Unlock(player
);
1442 int libvlc_media_player_get_title( libvlc_media_player_t
*p_mi
)
1444 vlc_player_t
*player
= p_mi
->player
;
1445 vlc_player_Lock(player
);
1447 ssize_t i_title
= vlc_player_GetSelectedTitleIdx(player
);
1449 vlc_player_Unlock(player
);
1453 int libvlc_media_player_get_title_count( libvlc_media_player_t
*p_mi
)
1455 vlc_player_t
*player
= p_mi
->player
;
1456 vlc_player_Lock(player
);
1458 vlc_player_title_list
*titles
= vlc_player_GetTitleList(player
);
1459 int ret
= titles
? (int) vlc_player_title_list_GetCount(titles
) : -1;
1461 vlc_player_Unlock(player
);
1465 int libvlc_media_player_get_full_title_descriptions( libvlc_media_player_t
*p_mi
,
1466 libvlc_title_description_t
*** pp_titles
)
1472 vlc_player_t
*player
= p_mi
->player
;
1473 vlc_player_Lock(player
);
1475 vlc_player_title_list
*titles
= vlc_player_GetTitleList(player
);
1479 size_t count
= vlc_player_title_list_GetCount(titles
);
1481 libvlc_title_description_t
**descs
= vlc_alloc(count
, sizeof(*descs
));
1482 if (count
> 0 && !descs
)
1485 for (size_t i
= 0; i
< count
; i
++)
1487 const struct vlc_player_title
*title
=
1488 vlc_player_title_list_GetAt(titles
, i
);
1489 libvlc_title_description_t
*desc
= malloc(sizeof(*desc
));
1492 libvlc_title_descriptions_release(descs
, i
);
1498 /* we want to return milliseconds to match the rest of the API */
1499 desc
->i_duration
= MS_FROM_VLC_TICK(title
->length
);
1500 desc
->i_flags
= title
->flags
;
1501 desc
->psz_name
= title
->name
? strdup(title
->name
) : NULL
;
1508 vlc_player_Unlock(player
);
1512 void libvlc_title_descriptions_release( libvlc_title_description_t
**p_titles
,
1515 for (unsigned i
= 0; i
< i_count
; i
++ )
1520 free( p_titles
[i
]->psz_name
);
1521 free( p_titles
[i
] );
1526 int libvlc_media_player_get_full_chapter_descriptions( libvlc_media_player_t
*p_mi
,
1527 int i_chapters_of_title
,
1528 libvlc_chapter_description_t
*** pp_chapters
)
1534 vlc_player_t
*player
= p_mi
->player
;
1535 vlc_player_Lock(player
);
1537 vlc_player_title_list
*titles
= vlc_player_GetTitleList(player
);
1541 size_t titles_count
= vlc_player_title_list_GetCount(titles
);
1542 if (i_chapters_of_title
< (int) titles_count
)
1545 const struct vlc_player_title
*title
=
1546 vlc_player_title_list_GetAt(titles
, i_chapters_of_title
);
1549 size_t i_chapter_count
= title
->chapter_count
;
1551 libvlc_chapter_description_t
**descs
=
1552 vlc_alloc(i_chapter_count
, sizeof(*descs
));
1553 if (i_chapter_count
> 0 && !descs
)
1556 for (size_t i
= 0; i
< i_chapter_count
; i
++)
1558 const struct vlc_player_chapter
*chapter
= &title
->chapters
[i
];
1559 libvlc_chapter_description_t
*desc
= malloc(sizeof(*desc
));
1562 libvlc_chapter_descriptions_release(descs
, i
);
1568 vlc_tick_t chapter_end
= i
< i_chapter_count
- 1
1569 ? title
->chapters
[i
+ 1].time
1571 desc
->i_time_offset
= MS_FROM_VLC_TICK(chapter
->time
);
1572 desc
->psz_name
= chapter
->name
? strdup(chapter
->name
) : NULL
;
1573 desc
->i_duration
= MS_FROM_VLC_TICK(chapter_end
) - desc
->i_time_offset
;
1576 ret
= i_chapter_count
;
1577 *pp_chapters
= descs
;
1580 vlc_player_Unlock(player
);
1584 void libvlc_chapter_descriptions_release( libvlc_chapter_description_t
**p_chapters
,
1587 for (unsigned i
= 0; i
< i_count
; i
++ )
1589 if ( !p_chapters
[i
] )
1592 free( p_chapters
[i
]->psz_name
);
1593 free( p_chapters
[i
] );
1598 void libvlc_media_player_next_chapter( libvlc_media_player_t
*p_mi
)
1600 vlc_player_t
*player
= p_mi
->player
;
1601 vlc_player_Lock(player
);
1603 vlc_player_SelectNextChapter(player
);
1605 vlc_player_Unlock(player
);
1608 void libvlc_media_player_previous_chapter( libvlc_media_player_t
*p_mi
)
1610 vlc_player_t
*player
= p_mi
->player
;
1611 vlc_player_Lock(player
);
1613 vlc_player_SelectPrevChapter(player
);
1615 vlc_player_Unlock(player
);
1618 int libvlc_media_player_set_rate( libvlc_media_player_t
*p_mi
, float rate
)
1620 vlc_player_t
*player
= p_mi
->player
;
1621 vlc_player_Lock(player
);
1623 vlc_player_ChangeRate(player
, rate
);
1625 vlc_player_Unlock(player
);
1629 float libvlc_media_player_get_rate( libvlc_media_player_t
*p_mi
)
1631 vlc_player_t
*player
= p_mi
->player
;
1632 vlc_player_Lock(player
);
1634 float rate
= vlc_player_GetRate(player
);
1636 vlc_player_Unlock(player
);
1640 libvlc_state_t
libvlc_media_player_get_state( libvlc_media_player_t
*p_mi
)
1642 vlc_player_t
*player
= p_mi
->player
;
1643 vlc_player_Lock(player
);
1645 enum vlc_player_error error
= vlc_player_GetError(player
);
1646 enum vlc_player_state state
= vlc_player_GetState(player
);
1648 vlc_player_Unlock(player
);
1650 if (error
!= VLC_PLAYER_ERROR_NONE
)
1651 return libvlc_Error
;
1653 case VLC_PLAYER_STATE_STOPPED
:
1654 return libvlc_Stopped
;
1655 case VLC_PLAYER_STATE_STOPPING
:
1656 return libvlc_Ended
;
1657 case VLC_PLAYER_STATE_STARTED
:
1658 return libvlc_Opening
;
1659 case VLC_PLAYER_STATE_PLAYING
:
1660 return libvlc_Playing
;
1661 case VLC_PLAYER_STATE_PAUSED
:
1662 return libvlc_Paused
;
1664 vlc_assert_unreachable();
1668 bool libvlc_media_player_is_seekable(libvlc_media_player_t
*p_mi
)
1670 vlc_player_t
*player
= p_mi
->player
;
1671 vlc_player_Lock(player
);
1673 bool b_seekable
= vlc_player_CanSeek(player
);
1675 vlc_player_Unlock(player
);
1679 void libvlc_media_player_navigate( libvlc_media_player_t
* p_mi
,
1682 static const enum vlc_player_nav map
[] =
1684 VLC_PLAYER_NAV_ACTIVATE
, VLC_PLAYER_NAV_UP
, VLC_PLAYER_NAV_DOWN
,
1685 VLC_PLAYER_NAV_LEFT
, VLC_PLAYER_NAV_RIGHT
, VLC_PLAYER_NAV_POPUP
,
1688 if( navigate
>= sizeof(map
) / sizeof(map
[0]) )
1691 vlc_player_t
*player
= p_mi
->player
;
1692 vlc_player_Lock(player
);
1694 vlc_player_Navigate(player
, map
[navigate
]);
1696 vlc_player_Unlock(player
);
1699 /* internal function, used by audio, video */
1700 libvlc_track_description_t
*
1701 libvlc_get_track_description( libvlc_media_player_t
*p_mi
,
1702 enum es_format_category_e cat
)
1704 vlc_player_t
*player
= p_mi
->player
;
1705 vlc_player_Lock(player
);
1707 libvlc_track_description_t
*ret
, **pp
= &ret
;
1709 size_t count
= vlc_player_GetTrackCount(player
, cat
);
1710 for (size_t i
= 0; i
< count
; i
++)
1712 libvlc_track_description_t
*tr
= malloc(sizeof (*tr
));
1713 if (unlikely(tr
== NULL
))
1715 libvlc_printerr("Not enough memory");
1719 const struct vlc_player_track
*track
=
1720 vlc_player_GetTrackAt(player
, cat
, i
);
1723 tr
->i_id
= vlc_es_id_GetInputId(track
->es_id
);
1724 tr
->psz_name
= strdup(track
->name
);
1725 if (unlikely(!tr
->psz_name
))
1735 vlc_player_Unlock(player
);
1739 void libvlc_track_description_list_release( libvlc_track_description_t
*p_td
)
1741 libvlc_track_description_t
*p_actual
, *p_before
;
1746 free( p_actual
->psz_name
);
1747 p_before
= p_actual
;
1748 p_actual
= p_before
->p_next
;
1753 bool libvlc_media_player_can_pause(libvlc_media_player_t
*p_mi
)
1755 vlc_player_t
*player
= p_mi
->player
;
1756 vlc_player_Lock(player
);
1758 bool b_can_pause
= vlc_player_CanPause(player
);
1760 vlc_player_Unlock(player
);
1764 bool libvlc_media_player_program_scrambled(libvlc_media_player_t
*p_mi
)
1766 bool b_program_scrambled
= false;
1768 vlc_player_t
*player
= p_mi
->player
;
1769 vlc_player_Lock(player
);
1771 const struct vlc_player_program
*program
=
1772 vlc_player_GetSelectedProgram(player
);
1776 b_program_scrambled
= program
->scrambled
;
1778 vlc_player_Unlock(player
);
1780 return b_program_scrambled
;
1783 void libvlc_media_player_next_frame( libvlc_media_player_t
*p_mi
)
1785 vlc_player_t
*player
= p_mi
->player
;
1786 vlc_player_Lock(player
);
1788 vlc_player_NextVideoFrame(player
);
1790 vlc_player_Unlock(player
);
1794 * Private lookup table to get subpicture alignment flag values corresponding
1795 * to a libvlc_position_t enumerated value.
1797 static const unsigned char position_subpicture_alignment
[] = {
1798 [libvlc_position_center
] = 0,
1799 [libvlc_position_left
] = SUBPICTURE_ALIGN_LEFT
,
1800 [libvlc_position_right
] = SUBPICTURE_ALIGN_RIGHT
,
1801 [libvlc_position_top
] = SUBPICTURE_ALIGN_TOP
,
1802 [libvlc_position_top_left
] = SUBPICTURE_ALIGN_TOP
| SUBPICTURE_ALIGN_LEFT
,
1803 [libvlc_position_top_right
] = SUBPICTURE_ALIGN_TOP
| SUBPICTURE_ALIGN_RIGHT
,
1804 [libvlc_position_bottom
] = SUBPICTURE_ALIGN_BOTTOM
,
1805 [libvlc_position_bottom_left
] = SUBPICTURE_ALIGN_BOTTOM
| SUBPICTURE_ALIGN_LEFT
,
1806 [libvlc_position_bottom_right
] = SUBPICTURE_ALIGN_BOTTOM
| SUBPICTURE_ALIGN_RIGHT
1809 void libvlc_media_player_set_video_title_display( libvlc_media_player_t
*p_mi
, libvlc_position_t position
, unsigned timeout
)
1811 assert( position
>= libvlc_position_disable
&& position
<= libvlc_position_bottom_right
);
1813 if ( position
!= libvlc_position_disable
)
1815 var_SetBool( p_mi
, "video-title-show", true );
1816 var_SetInteger( p_mi
, "video-title-position", position_subpicture_alignment
[position
] );
1817 var_SetInteger( p_mi
, "video-title-timeout", timeout
);
1821 var_SetBool( p_mi
, "video-title-show", false );
1825 libvlc_media_tracklist_t
*
1826 libvlc_media_player_get_tracklist(libvlc_media_player_t
*p_mi
,
1827 libvlc_track_type_t type
)
1829 vlc_player_t
*player
= p_mi
->player
;
1831 vlc_player_Lock(player
);
1833 libvlc_media_tracklist_t
*list
=
1834 libvlc_media_tracklist_from_player(player
, type
);
1836 vlc_player_Unlock(player
);
1841 libvlc_media_track_t
*
1842 libvlc_media_player_get_selected_track(libvlc_media_player_t
*p_mi
,
1843 libvlc_track_type_t type
)
1845 vlc_player_t
*player
= p_mi
->player
;
1847 vlc_player_Lock(player
);
1849 const enum es_format_category_e cat
= libvlc_track_type_to_escat(type
);
1850 const struct vlc_player_track
*track
=
1851 vlc_player_GetSelectedTrack(player
, cat
);
1855 vlc_player_Unlock(player
);
1859 libvlc_media_track_t
*libtrack
=
1860 libvlc_media_track_create_from_player_track(track
);
1861 vlc_player_Unlock(player
);
1866 libvlc_media_track_t
*
1867 libvlc_media_player_get_track_from_id( libvlc_media_player_t
*p_mi
,
1868 const char *psz_id
)
1870 vlc_player_t
*player
= p_mi
->player
;
1872 vlc_player_Lock(player
);
1874 enum es_format_category_e cats
[] = { VIDEO_ES
, AUDIO_ES
, SPU_ES
};
1875 for (size_t i
= 0; i
< ARRAY_SIZE(cats
); ++i
)
1877 enum es_format_category_e cat
= cats
[i
];
1878 size_t count
= vlc_player_GetTrackCount(player
, cat
);
1880 for (size_t j
= 0; j
< count
; ++j
)
1882 const struct vlc_player_track
*track
=
1883 vlc_player_GetTrackAt(player
, cat
, j
);
1884 if (strcmp(psz_id
, vlc_es_id_GetStrId(track
->es_id
)) == 0)
1886 libvlc_media_track_t
*libtrack
=
1887 libvlc_media_track_create_from_player_track(track
);
1888 vlc_player_Unlock(player
);
1895 vlc_player_Unlock(player
);
1900 libvlc_media_player_select_track(libvlc_media_player_t
*p_mi
,
1901 libvlc_track_type_t type
,
1902 const libvlc_media_track_t
*track
)
1904 assert( track
== NULL
|| type
== track
->i_type
);
1905 vlc_player_t
*player
= p_mi
->player
;
1907 vlc_player_Lock(player
);
1911 const libvlc_media_trackpriv_t
*trackpriv
=
1912 libvlc_media_track_to_priv(track
);
1913 vlc_player_SelectEsId(player
, trackpriv
->es_id
,
1914 VLC_PLAYER_SELECT_EXCLUSIVE
);
1918 const enum es_format_category_e cat
= libvlc_track_type_to_escat(type
);
1919 vlc_player_UnselectTrackCategory(player
, cat
);
1922 vlc_player_Unlock(player
);
1926 libvlc_media_player_select_tracks(libvlc_media_player_t
*p_mi
,
1927 libvlc_track_type_t type
,
1928 const libvlc_media_track_t
**tracks
,
1931 vlc_player_t
*player
= p_mi
->player
;
1933 vlc_es_id_t
**es_id_list
= vlc_alloc(track_count
+ 1, sizeof(vlc_es_id_t
*));
1934 size_t es_id_idx
= 0;
1936 if (es_id_list
== NULL
)
1939 const enum es_format_category_e cat
= libvlc_track_type_to_escat(type
);
1941 vlc_player_Lock(player
);
1943 for (size_t i
= 0; i
< track_count
; ++i
)
1945 const libvlc_media_track_t
*track
= tracks
[i
];
1946 const libvlc_media_trackpriv_t
*trackpriv
=
1947 libvlc_media_track_to_priv(track
);
1949 es_id_list
[es_id_idx
++] = trackpriv
->es_id
;
1951 es_id_list
[es_id_idx
++] = NULL
;
1952 vlc_player_SelectEsIdList(player
, cat
, es_id_list
);
1954 vlc_player_Unlock(player
);
1960 libvlc_media_player_select_tracks_by_ids( libvlc_media_player_t
*p_mi
,
1961 libvlc_track_type_t type
,
1962 const char *psz_ids
)
1964 const enum es_format_category_e cat
= libvlc_track_type_to_escat(type
);
1966 vlc_player_t
*player
= p_mi
->player
;
1968 vlc_player_Lock(player
);
1970 vlc_player_SelectTracksByStringIds(player
, cat
, psz_ids
);
1972 vlc_player_Unlock(player
);
1975 int libvlc_media_player_add_slave( libvlc_media_player_t
*p_mi
,
1976 libvlc_media_slave_type_t i_type
,
1977 const char *psz_uri
, bool b_select
)
1979 vlc_player_t
*player
= p_mi
->player
;
1980 vlc_player_Lock(player
);
1982 enum es_format_category_e cat
= i_type
== libvlc_media_slave_type_subtitle
1986 int ret
= vlc_player_AddAssociatedMedia(player
, cat
, psz_uri
, b_select
,
1989 vlc_player_Unlock(player
);
1994 * Maximum size of a formatted equalizer amplification band frequency value.
1996 * The allowed value range is supposed to be constrained from -20.0 to 20.0.
1998 * The format string " %.07f" with a minimum value of "-20" gives a maximum
1999 * string length of e.g. " -19.1234567", i.e. 12 bytes (not including the null
2002 #define EQZ_BAND_VALUE_SIZE 12
2004 int libvlc_media_player_set_equalizer( libvlc_media_player_t
*p_mi
, libvlc_equalizer_t
*p_equalizer
)
2006 char bands
[EQZ_BANDS_MAX
* EQZ_BAND_VALUE_SIZE
+ 1];
2008 if( p_equalizer
!= NULL
)
2010 for( unsigned i
= 0, c
= 0; i
< EQZ_BANDS_MAX
; i
++ )
2012 c
+= snprintf( bands
+ c
, sizeof(bands
) - c
, " %.07f",
2013 p_equalizer
->f_amp
[i
] );
2014 if( unlikely(c
>= sizeof(bands
)) )
2018 var_SetFloat( p_mi
, "equalizer-preamp", p_equalizer
->f_preamp
);
2019 var_SetString( p_mi
, "equalizer-bands", bands
);
2021 var_SetString( p_mi
, "audio-filter", p_equalizer
? "equalizer" : "" );
2023 audio_output_t
*p_aout
= vlc_player_aout_Hold( p_mi
->player
);
2024 if( p_aout
!= NULL
)
2026 if( p_equalizer
!= NULL
)
2028 var_SetFloat( p_aout
, "equalizer-preamp", p_equalizer
->f_preamp
);
2029 var_SetString( p_aout
, "equalizer-bands", bands
);
2032 var_SetString( p_aout
, "audio-filter", p_equalizer
? "equalizer" : "" );
2033 aout_Release(p_aout
);
2039 static const char roles
[][16] =
2041 [libvlc_role_Music
] = "music",
2042 [libvlc_role_Video
] = "video",
2043 [libvlc_role_Communication
] = "communication",
2044 [libvlc_role_Game
] = "game",
2045 [libvlc_role_Notification
] = "notification",
2046 [libvlc_role_Animation
] = "animation",
2047 [libvlc_role_Production
] = "production",
2048 [libvlc_role_Accessibility
] = "accessibility",
2049 [libvlc_role_Test
] = "test",
2052 int libvlc_media_player_set_role(libvlc_media_player_t
*mp
, unsigned role
)
2054 if (role
>= ARRAY_SIZE(roles
)
2055 || var_SetString(mp
, "role", roles
[role
]) != VLC_SUCCESS
)
2060 int libvlc_media_player_get_role(libvlc_media_player_t
*mp
)
2063 char *str
= var_GetString(mp
, "role");
2067 for (size_t i
= 0; i
< ARRAY_SIZE(roles
); i
++)
2068 if (!strcmp(roles
[i
], str
))
2078 #include <vlc_vout_display.h>
2080 /* make sure surface structures from libvlc can be passed as such to vlc
2081 otherwise we will need wrappers between what libvlc understands and what vlc uses */
2082 #define cast_ libvlc_video_color_space_t
2083 static_assert(libvlc_video_colorspace_BT601
== (cast_
)COLOR_SPACE_BT601
&&
2084 libvlc_video_colorspace_BT709
== (cast_
)COLOR_SPACE_BT709
&&
2085 libvlc_video_colorspace_BT2020
== (cast_
)COLOR_SPACE_BT2020
2086 , "libvlc video colorspace mismatch");
2089 #define cast_ libvlc_video_transfer_func_t
2090 static_assert(libvlc_video_transfer_func_LINEAR
== (cast_
)TRANSFER_FUNC_LINEAR
&&
2091 libvlc_video_transfer_func_SRGB
== (cast_
)TRANSFER_FUNC_SRGB
&&
2092 libvlc_video_transfer_func_BT470_BG
== (cast_
)TRANSFER_FUNC_BT470_BG
&&
2093 libvlc_video_transfer_func_BT470_M
== (cast_
)TRANSFER_FUNC_BT470_M
&&
2094 libvlc_video_transfer_func_BT709
== (cast_
)TRANSFER_FUNC_BT709
&&
2095 libvlc_video_transfer_func_PQ
== (cast_
)TRANSFER_FUNC_SMPTE_ST2084
&&
2096 libvlc_video_transfer_func_SMPTE_240
== (cast_
)TRANSFER_FUNC_SMPTE_240
&&
2097 libvlc_video_transfer_func_HLG
== (cast_
)TRANSFER_FUNC_HLG
2098 , "libvlc video transfer function mismatch");
2101 #define cast_ libvlc_video_color_primaries_t
2102 static_assert(libvlc_video_primaries_BT601_525
== (cast_
)COLOR_PRIMARIES_BT601_525
&&
2103 libvlc_video_primaries_BT601_625
== (cast_
)COLOR_PRIMARIES_BT601_625
&&
2104 libvlc_video_primaries_BT709
== (cast_
)COLOR_PRIMARIES_BT709
&&
2105 libvlc_video_primaries_BT2020
== (cast_
)COLOR_PRIMARIES_BT2020
&&
2106 libvlc_video_primaries_DCI_P3
== (cast_
)COLOR_PRIMARIES_DCI_P3
&&
2107 libvlc_video_primaries_BT470_M
== (cast_
)COLOR_PRIMARIES_BT470_M
2108 , "libvlc video color primaries mismatch");