From cb23823e64f6b6f000a35c2847374f8c6ed3e98c Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Sun, 20 Apr 2025 22:06:07 +0300
Subject: [PATCH] Video playback (#1625)
* Work
* Work
* Update Video.cpp
* Update Video.cpp
* Update Video.cpp
* Update Video.cpp
* Update Video.cpp
* Working playback
* Update Video.cpp
* Cleanups
* Additions
* Update Video.cpp
* Formatting
* Correct pausing/resuming
* Remove .mov extension, as it's not supported
* Use vector instead of array
* Implement SetIntroVideoPath
* Swap intro image and intro video to better reflect original legal sequence
* Update Gameflow.lua
* Simplify synchronization with VLC thread
* Use Vector2i for sizes, only fetch video dimensions once
* Rename callbacks, move logging callback to a class
* Update Video.cpp
* Update CHANGELOG.md
* Removed empty OnDisplayFrame event
* Rename
* Stop video player if user pressed Alt+F4
* Allow background video playback
* Update Video.cpp
* Update Video.cpp
* Fixed init errors
* Restore .mov default extension for video playback
* Update RendererDraw2D.cpp
* Add video streaming for rectangular faces of room geometry
* Remove magic and use normalized UVs instead
* Use VIDEO_SPRITE_ID instead of NO_VALUE
* Added more scripting API functions for video playback
* Correct variable names
* Shorten notification
* Add GetVideoDominantColor
* Do proper cleanup when alt+F4ing during video playback
* Change game loop deinit to avoid several issues with cleaning up
* Organise `VideoHandler` class
* Randomize glow angle
* Update comment
* Update Video.cpp
* Update Video.cpp
* Fix issues with frame drops in exclusive mode
* Optimize CPU usage in exclusive mode
---------
Co-authored-by: Sezz
---
CHANGELOG.md | 5 +
Documentation/doc/1 modules/Flow.html | 27 +
Documentation/doc/1 modules/Sound.html | 2 +-
Documentation/doc/1 modules/View.html | 174 +-
.../doc/2 classes/View.DisplaySprite.html | 50 +-
Libs/vlc/libvlc.h | 546 +++
Libs/vlc/libvlc_dialog.h | 260 ++
Libs/vlc/libvlc_events.h | 457 +++
Libs/vlc/libvlc_media.h | 917 +++++
Libs/vlc/libvlc_media_discoverer.h | 188 +
Libs/vlc/libvlc_media_list.h | 200 +
Libs/vlc/libvlc_media_list_player.h | 249 ++
Libs/vlc/libvlc_media_player.h | 3304 +++++++++++++++++
Libs/vlc/libvlc_media_track.h | 212 ++
Libs/vlc/libvlc_picture.h | 151 +
Libs/vlc/libvlc_renderer_discoverer.h | 255 ++
Libs/vlc/libvlc_version.h | 79 +
Libs/vlc/libvlc_video.h | 67 +
Libs/vlc/vlc.h | 55 +
Libs/vlc/x64/libvlc.dll | Bin 0 -> 170496 bytes
Libs/vlc/x64/libvlc.lib | Bin 0 -> 59026 bytes
Libs/vlc/x64/libvlccore.dll | Bin 0 -> 4082688 bytes
Libs/vlc/x64/libvlccore.lib | Bin 0 -> 181442 bytes
Libs/vlc/x86/libvlc.dll | Bin 0 -> 153088 bytes
Libs/vlc/x86/libvlc.lib | Bin 0 -> 59898 bytes
Libs/vlc/x86/libvlccore.dll | Bin 0 -> 3806720 bytes
Libs/vlc/x86/libvlccore.lib | Bin 0 -> 184644 bytes
Scripts/Gameflow.lua | 5 +
TombEngine/Game/control/control.cpp | 55 +-
TombEngine/Game/control/control.h | 1 +
TombEngine/Game/debug/debug.cpp | 4 +
TombEngine/Game/gui.cpp | 12 +-
TombEngine/Game/savegame.cpp | 25 +-
.../Renderer/ConstantBuffers/AnimatedBuffer.h | 2 +-
TombEngine/Renderer/Renderer.cpp | 14 +-
TombEngine/Renderer/Renderer.h | 7 +-
TombEngine/Renderer/RendererCompatibility.cpp | 27 +-
TombEngine/Renderer/RendererDraw.cpp | 85 +-
TombEngine/Renderer/RendererDraw2D.cpp | 10 +-
TombEngine/Renderer/RendererDrawEffect.cpp | 8 +-
TombEngine/Renderer/RendererDrawMenu.cpp | 2 +-
TombEngine/Renderer/RendererInit.cpp | 8 +-
.../Structures/RendererAnimatedTexture.h | 1 +
.../Structures/RendererAnimatedTextureSet.h | 12 +-
.../Renderer/Structures/RendererSprite.h | 2 +
.../Include/Flow/ScriptInterfaceFlowHandler.h | 1 +
.../Scripting/Internal/ReservedScriptNames.h | 7 +
.../Internal/TEN/Flow/FlowHandler.cpp | 13 +
.../Scripting/Internal/TEN/Flow/FlowHandler.h | 1 +
.../Internal/TEN/Sound/SoundHandler.cpp | 2 +-
.../DisplaySprite/ScriptDisplaySprite.cpp | 37 +-
.../View/DisplaySprite/ScriptDisplaySprite.h | 2 +
.../Internal/TEN/View/ViewHandler.cpp | 96 +-
TombEngine/Sound/sound.cpp | 3 +
TombEngine/Specific/Input/Input.cpp | 6 +-
TombEngine/Specific/Input/Input.h | 2 +-
TombEngine/Specific/Video/Video.cpp | 622 ++++
TombEngine/Specific/Video/Video.h | 107 +
TombEngine/Specific/level.cpp | 12 +-
TombEngine/Specific/level.h | 7 +-
.../flatbuffers/ten_savegame_generated.h | 229 +-
.../Specific/savegame/schema/ten_savegame.fbs | 10 +-
TombEngine/Specific/winmain.cpp | 33 +-
TombEngine/TombEngine.vcxproj | 30 +-
TombEngine/framework.h | 1 +
65 files changed, 8551 insertions(+), 148 deletions(-)
create mode 100644 Libs/vlc/libvlc.h
create mode 100644 Libs/vlc/libvlc_dialog.h
create mode 100644 Libs/vlc/libvlc_events.h
create mode 100644 Libs/vlc/libvlc_media.h
create mode 100644 Libs/vlc/libvlc_media_discoverer.h
create mode 100644 Libs/vlc/libvlc_media_list.h
create mode 100644 Libs/vlc/libvlc_media_list_player.h
create mode 100644 Libs/vlc/libvlc_media_player.h
create mode 100644 Libs/vlc/libvlc_media_track.h
create mode 100644 Libs/vlc/libvlc_picture.h
create mode 100644 Libs/vlc/libvlc_renderer_discoverer.h
create mode 100644 Libs/vlc/libvlc_version.h
create mode 100644 Libs/vlc/libvlc_video.h
create mode 100644 Libs/vlc/vlc.h
create mode 100644 Libs/vlc/x64/libvlc.dll
create mode 100644 Libs/vlc/x64/libvlc.lib
create mode 100644 Libs/vlc/x64/libvlccore.dll
create mode 100644 Libs/vlc/x64/libvlccore.lib
create mode 100644 Libs/vlc/x86/libvlc.dll
create mode 100644 Libs/vlc/x86/libvlc.lib
create mode 100644 Libs/vlc/x86/libvlccore.dll
create mode 100644 Libs/vlc/x86/libvlccore.lib
create mode 100644 TombEngine/Specific/Video/Video.cpp
create mode 100644 TombEngine/Specific/Video/Video.h
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 273123e04..4973d3ee7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,9 @@ TombEngine releases are located in this repository (alongside with Tomb Editor):
## [Version 1.8.2]
+## New features
+* Added video playback support.
+
### Bug fixes
* Fixed crashes when shooting, if gunflash or gunshell objects are not present in a level.
* Fixed Teleporter object.
@@ -20,6 +23,8 @@ TombEngine releases are located in this repository (alongside with Tomb Editor):
* Added muzzle glow effect for firearms.
### Lua API changes
+* Added `View.PlayVideoFile` function to play videos.
+* Added `Flow.SetIntroVideoPath` function to specify intro video.
* Added `muzzleGlow` and `muzzleOffset` parameters to weapon settings.
* Added ability to use gunflash parameters for all weapons in weapon settings.
* Fixed `Moveable.GetJointPosition` not returning correct results if moveable is invisible or not rendered.
diff --git a/Documentation/doc/1 modules/Flow.html b/Documentation/doc/1 modules/Flow.html
index 4a680cba5..998af2ca6 100644
--- a/Documentation/doc/1 modules/Flow.html
+++ b/Documentation/doc/1 modules/Flow.html
@@ -132,6 +132,10 @@ scripts too.
Image to show when loading the game. |
+ SetIntroVideoPath(path) |
+ Video to show when loading the game. |
+
+
SetTitleScreenImagePath(path) |
Image to show in the background of the title screen. |
@@ -330,6 +334,29 @@ Must be a .jpg or .png image.
+
+
+
+ SetIntroVideoPath(path)
+
+
+ Video to show when loading the game.
+Must be a common video format, such as .mp4, .mkv or .avi.
+
+
+
+ Parameters:
+
+ - path
+ string
+ the path to the video, relative to the TombEngine exe
+
+
+
+
+
+
+
diff --git a/Documentation/doc/1 modules/Sound.html b/Documentation/doc/1 modules/Sound.html
index be07997d5..d15b22848 100644
--- a/Documentation/doc/1 modules/Sound.html
+++ b/Documentation/doc/1 modules/Sound.html
@@ -177,7 +177,7 @@
PlayAudioTrack(filename, type)
- Play an audio track. Supported formats are wav, mp3 and ogg.
+ Play an audio track. Should be placed in the Audio
folder. Supported formats are wav, mp3 and ogg.
diff --git a/Documentation/doc/1 modules/View.html b/Documentation/doc/1 modules/View.html
index 51c5b824e..3e55ab4e5 100644
--- a/Documentation/doc/1 modules/View.html
+++ b/Documentation/doc/1 modules/View.html
@@ -172,6 +172,30 @@
Sets the post-process tint. |
+ PlayVideo(fileName[, background][, silent][, loop]) |
+ Play a video file. |
+
+
+ StopVideo() |
+ Stop the currently playing video. |
+
+
+ GetVideoPosition() |
+ Gets the currently playing video position. |
+
+
+ SetVideoPosition(position) |
+ Sets the currently playing video position. |
+
+
+ GetVideoDominantColor() |
+ Gets the dominant color for the current video frame. |
+
+
+ IsVideoPlaying([name]) |
+ Checks if video is currently playing. |
+
+
PlayFlyby(seqID) |
Play a flyby sequence. |
@@ -261,11 +285,11 @@
- height
float
- (default 30) Percentage of the screen to be covered
+ (default 30). Percentage of the screen to be covered
- speed
float
- (default 30) Coverage percent per second
+ (default 30). Coverage percent per second
@@ -474,6 +498,152 @@
+
+
+
+ PlayVideo(fileName[, background][, silent][, loop])
+
+
+ Play a video file. File should be placed in the FMV
folder.
+
+
+
+ Parameters:
+
+ - fileName
+ string
+ Video file name. Can be provided without extension, if type is mp4, mkv or avi.
+
+ - background
+ bool
+ (default: false). Play video in the background mode.
+ In such case, video won't play in fullscreen, but must be shown using special animated texture type in Tomb Editor, or using View.DisplaySprite.
+ (optional)
+
+ - silent
+ bool
+ (default: false). Play video without sound.
+ (optional)
+
+ - loop
+ bool
+ (default: false). Play video in a loop.
+ (optional)
+
+
+
+
+
+
+
+
+
+
+ StopVideo()
+
+
+ Stop the currently playing video. Only possible if video is playing in the background mode.
+
+
+
+
+
+
+
+
+
+
+
+ GetVideoPosition()
+
+
+ Gets the currently playing video position.
+
+
+
+
+ Returns:
+
+
+ Time
+ Current video position.
+
+
+
+
+
+
+
+
+ SetVideoPosition(position)
+
+
+ Sets the currently playing video position.
+
+
+
+ Parameters:
+
+ - position
+ Time
+ New video position.
+
+
+
+
+
+
+
+
+
+
+ GetVideoDominantColor()
+
+
+ Gets the dominant color for the current video frame. If no video is playing, returns black.
+
+
+
+
+ Returns:
+
+
+ Color
+ Dominant video color.
+
+
+
+
+
+
+
+
+ IsVideoPlaying([name])
+
+
+ Checks if video is currently playing.
+
+
+
+ Parameters:
+
+ - name
+ string
+ Video file name. If provided, checks if the currently playing video file name is the same as the provided one.
+ (optional)
+
+
+
+ Returns:
+
+
+ bool
+ True if video is currently playing.
+
+
+
+
+
diff --git a/Documentation/doc/2 classes/View.DisplaySprite.html b/Documentation/doc/2 classes/View.DisplaySprite.html
index 2b097a9bb..e46055254 100644
--- a/Documentation/doc/2 classes/View.DisplaySprite.html
+++ b/Documentation/doc/2 classes/View.DisplaySprite.html
@@ -128,6 +128,10 @@
Create a DisplaySprite object. |
+ DisplaySprite(pos, rot, scale[, color]) |
+ Create a DisplaySprite object with a video image. |
+
+
DisplaySprite:GetObjectID() |
Get the object ID of the sprite sequence object used by the display sprite. |
@@ -193,7 +197,7 @@
DisplaySprite(ID, int, pos, rot, scale, [color])
- Create a DisplaySprite object. ()
+ Create a DisplaySprite object.
@@ -236,6 +240,48 @@
+
+
+
+ DisplaySprite(pos, rot, scale[, color])
+
+
+ Create a DisplaySprite object with a video image.
+ Video should be played using View.PlayVideo function in a background mode. If no video is played, sprite will not show.
+
+
+
+ Parameters:
+
+ - pos
+ Vec2
+ Display position in percent.
+
+ - rot
+ float
+ Rotation in degrees.
+
+ - scale
+ Vec2
+ Horizontal and vertical scale in percent. Scaling is interpreted by the DisplaySpriteEnum.ScaleMode passed to the Draw() function call.
+
+ - color
+ Color
+ Color. Default: Color(255, 255, 255, 255)
+ (optional)
+
+
+
+ Returns:
+
+
+ DisplaySprite
+ A new DisplaySprite object with attached video image.
+
+
+
+
+
@@ -272,7 +318,7 @@
int
- Sprite ID in the sprite sequence object.
+ Sprite ID in the sprite sequence object. Value -1 means that it is a background video, played using View.PlayVideo.
diff --git a/Libs/vlc/libvlc.h b/Libs/vlc/libvlc.h
new file mode 100644
index 000000000..0970dc294
--- /dev/null
+++ b/Libs/vlc/libvlc.h
@@ -0,0 +1,546 @@
+/*****************************************************************************
+ * libvlc.h: libvlc external API
+ *****************************************************************************
+ * Copyright (C) 1998-2009 VLC authors and VideoLAN
+ *
+ * Authors: Clément Stenac
+ * Jean-Paul Saman
+ * Pierre d'Herbemont
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+/**
+ * \defgroup libvlc LibVLC
+ * LibVLC is the external programming interface of the VLC media player.
+ * It is used to embed VLC into other applications or frameworks.
+ * @{
+ * \file
+ * LibVLC core external API
+ */
+
+#ifndef VLC_LIBVLC_H
+#define VLC_LIBVLC_H 1
+
+#if defined (_WIN32) && defined (LIBVLC_DLL_EXPORT)
+# define LIBVLC_API __declspec(dllexport)
+#elif defined (__GNUC__) && (__GNUC__ >= 4)
+# define LIBVLC_API __attribute__((visibility("default")))
+#else
+# define LIBVLC_API
+#endif
+
+#ifdef LIBVLC_INTERNAL_
+/* Avoid unhelpful warnings from libvlc with our deprecated APIs */
+# define LIBVLC_DEPRECATED
+#elif defined(__GNUC__) && \
+ (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0)
+# define LIBVLC_DEPRECATED __attribute__((deprecated))
+#else
+# define LIBVLC_DEPRECATED
+#endif
+
+#include
+#include
+#include
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+/** \defgroup libvlc_core LibVLC core
+ * \ingroup libvlc
+ * Before it can do anything useful, LibVLC must be initialized.
+ * You can create one (or more) instance(s) of LibVLC in a given process,
+ * with libvlc_new() and destroy them with libvlc_release().
+ *
+ * \version Unless otherwise stated, these functions are available
+ * from LibVLC versions numbered 1.1.0 or more.
+ * Earlier versions (0.9.x and 1.0.x) are not compatible.
+ * @{
+ */
+
+/** This structure is opaque. It represents a libvlc instance */
+typedef struct libvlc_instance_t libvlc_instance_t;
+
+typedef int64_t libvlc_time_t;
+
+/** \defgroup libvlc_error LibVLC error handling
+ * @{
+ */
+
+/**
+ * A human-readable error message for the last LibVLC error in the calling
+ * thread. The resulting string is valid until another error occurs (at least
+ * until the next LibVLC call).
+ *
+ * @warning
+ * This will be NULL if there was no error.
+ */
+LIBVLC_API const char *libvlc_errmsg (void);
+
+/**
+ * Clears the LibVLC error status for the current thread. This is optional.
+ * By default, the error status is automatically overridden when a new error
+ * occurs, and destroyed when the thread exits.
+ */
+LIBVLC_API void libvlc_clearerr (void);
+
+/**
+ * Sets the LibVLC error status and message for the current thread.
+ * Any previous error is overridden.
+ * \param fmt the format string
+ * \param ... the arguments for the format string
+ * \return a nul terminated string in any case
+ */
+const char *libvlc_printerr (const char *fmt, ...);
+
+/**@} */
+
+/**
+ * Create and initialize a libvlc instance.
+ * This functions accept a list of "command line" arguments similar to the
+ * main(). These arguments affect the LibVLC instance default configuration.
+ *
+ * \note
+ * LibVLC may create threads. Therefore, any thread-unsafe process
+ * initialization must be performed before calling libvlc_new(). In particular
+ * and where applicable:
+ * - setlocale() and textdomain(),
+ * - setenv(), unsetenv() and putenv(),
+ * - with the X11 display system, XInitThreads()
+ * (see also libvlc_media_player_set_xwindow()) and
+ * - on Microsoft Windows, SetErrorMode().
+ * - sigprocmask() shall never be invoked; pthread_sigmask() can be used.
+ *
+ * On POSIX systems, the SIGCHLD signal must not be ignored, i.e. the
+ * signal handler must set to SIG_DFL or a function pointer, not SIG_IGN.
+ * Also while LibVLC is active, the wait() function shall not be called, and
+ * any call to waitpid() shall use a strictly positive value for the first
+ * parameter (i.e. the PID). Failure to follow those rules may lead to a
+ * deadlock or a busy loop.
+ * Also on POSIX systems, it is recommended that the SIGPIPE signal be blocked,
+ * even if it is not, in principles, necessary, e.g.:
+ * @code
+ sigset_t set;
+
+ signal(SIGCHLD, SIG_DFL);
+ sigemptyset(&set);
+ sigaddset(&set, SIGPIPE);
+ pthread_sigmask(SIG_BLOCK, &set, NULL);
+ * @endcode
+ *
+ * On Microsoft Windows, setting the default DLL directories to SYSTEM32
+ * exclusively is strongly recommended for security reasons:
+ * @code
+ SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32);
+ * @endcode
+ *
+ * \version
+ * Arguments are meant to be passed from the command line to LibVLC, just like
+ * VLC media player does. The list of valid arguments depends on the LibVLC
+ * version, the operating system and platform, and set of available LibVLC
+ * plugins. Invalid or unsupported arguments will cause the function to fail
+ * (i.e. return NULL). Also, some arguments may alter the behaviour or
+ * otherwise interfere with other LibVLC functions.
+ *
+ * \warning
+ * There is absolutely no warranty or promise of forward, backward and
+ * cross-platform compatibility with regards to libvlc_new() arguments.
+ * We recommend that you do not use them, other than when debugging.
+ *
+ * \param argc the number of arguments (should be 0)
+ * \param argv list of arguments (should be NULL)
+ * \return the libvlc instance or NULL in case of error
+ */
+LIBVLC_API libvlc_instance_t *
+libvlc_new( int argc , const char *const *argv );
+
+/**
+ * Decrement the reference count of a libvlc instance, and destroy it
+ * if it reaches zero.
+ *
+ * \param p_instance the instance to destroy
+ */
+LIBVLC_API void libvlc_release( libvlc_instance_t *p_instance );
+
+/**
+ * Increments the reference count of a libvlc instance.
+ * The initial reference count is 1 after libvlc_new() returns.
+ *
+ * \param p_instance the instance to reference
+ * \return the same object
+ */
+LIBVLC_API libvlc_instance_t *libvlc_retain( libvlc_instance_t *p_instance );
+
+/**
+ * Get the ABI version of the libvlc library.
+ *
+ * This is different than the VLC version, which is the version of the whole
+ * VLC package. The value is the same as LIBVLC_ABI_VERSION_INT used when
+ * compiling.
+ *
+ * \return a value with the following mask in hexadecimal
+ * 0xFF000000: major VLC version, similar to VLC major version,
+ * 0x00FF0000: major ABI version, incremented incompatible changes are added,
+ * 0x0000FF00: minor ABI version, incremented when new functions are added
+ * 0x000000FF: micro ABI version, incremented with new release/builds
+ *
+ * \note This the same value as the .so version but cross platform.
+ */
+LIBVLC_API int libvlc_abi_version(void);
+
+/**
+ * Sets the application name. LibVLC passes this as the user agent string
+ * when a protocol requires it.
+ *
+ * \param p_instance LibVLC instance
+ * \param name human-readable application name, e.g. "FooBar player 1.2.3"
+ * \param http HTTP User Agent, e.g. "FooBar/1.2.3 Python/2.6.0"
+ * \version LibVLC 1.1.1 or later
+ */
+LIBVLC_API
+void libvlc_set_user_agent( libvlc_instance_t *p_instance,
+ const char *name, const char *http );
+
+/**
+ * Sets some meta-information about the application.
+ * See also libvlc_set_user_agent().
+ *
+ * \param p_instance LibVLC instance
+ * \param id Java-style application identifier, e.g. "com.acme.foobar"
+ * \param version application version numbers, e.g. "1.2.3"
+ * \param icon application icon name, e.g. "foobar"
+ * \version LibVLC 2.1.0 or later.
+ */
+LIBVLC_API
+void libvlc_set_app_id( libvlc_instance_t *p_instance, const char *id,
+ const char *version, const char *icon );
+
+/**
+ * Retrieve libvlc version.
+ *
+ * Example: "1.1.0-git The Luggage"
+ *
+ * \return a string containing the libvlc version
+ */
+LIBVLC_API const char * libvlc_get_version(void);
+
+/**
+ * Retrieve libvlc compiler version.
+ *
+ * Example: "gcc version 4.2.3 (Ubuntu 4.2.3-2ubuntu6)"
+ *
+ * \return a string containing the libvlc compiler version
+ */
+LIBVLC_API const char * libvlc_get_compiler(void);
+
+/**
+ * Retrieve libvlc changeset.
+ *
+ * Example: "aa9bce0bc4"
+ *
+ * \return a string containing the libvlc changeset
+ */
+LIBVLC_API const char * libvlc_get_changeset(void);
+
+/**
+ * Frees an heap allocation returned by a LibVLC function.
+ * If you know you're using the same underlying C run-time as the LibVLC
+ * implementation, then you can call ANSI C free() directly instead.
+ *
+ * \param ptr the pointer
+ */
+LIBVLC_API void libvlc_free( void *ptr );
+
+/** \defgroup libvlc_event LibVLC asynchronous events
+ * LibVLC emits asynchronous events.
+ *
+ * Several LibVLC objects (such @ref libvlc_instance_t as
+ * @ref libvlc_media_player_t) generate events asynchronously. Each of them
+ * provides @ref libvlc_event_manager_t event manager. You can subscribe to
+ * events with libvlc_event_attach() and unsubscribe with
+ * libvlc_event_detach().
+ * @{
+ */
+
+/**
+ * Event manager that belongs to a libvlc object, and from whom events can
+ * be received.
+ */
+typedef struct libvlc_event_manager_t libvlc_event_manager_t;
+
+struct libvlc_event_t;
+
+/**
+ * Type of a LibVLC event.
+ */
+typedef int libvlc_event_type_t;
+
+/**
+ * Callback function notification
+ * \param p_event the event triggering the callback
+ */
+typedef void ( *libvlc_callback_t )( const struct libvlc_event_t *p_event, void *p_data );
+
+/**
+ * Register for an event notification.
+ *
+ * \param p_event_manager the event manager to which you want to attach to.
+ * Generally it is obtained by vlc_my_object_event_manager() where
+ * my_object is the object you want to listen to.
+ * \param i_event_type the desired event to which we want to listen
+ * \param f_callback the function to call when i_event_type occurs
+ * \param user_data user provided data to carry with the event
+ * \return 0 on success, ENOMEM on error
+ */
+LIBVLC_API int libvlc_event_attach( libvlc_event_manager_t *p_event_manager,
+ libvlc_event_type_t i_event_type,
+ libvlc_callback_t f_callback,
+ void *user_data );
+
+/**
+ * Unregister an event notification.
+ *
+ * \param p_event_manager the event manager
+ * \param i_event_type the desired event to which we want to unregister
+ * \param f_callback the function to call when i_event_type occurs
+ * \param p_user_data user provided data to carry with the event
+ */
+LIBVLC_API void libvlc_event_detach( libvlc_event_manager_t *p_event_manager,
+ libvlc_event_type_t i_event_type,
+ libvlc_callback_t f_callback,
+ void *p_user_data );
+
+/** @} */
+
+/** \defgroup libvlc_log LibVLC logging
+ * libvlc_log_* functions provide access to the LibVLC messages log.
+ * This is used for logging and debugging.
+ * @{
+ */
+
+/**
+ * Logging messages level.
+ * \note Future LibVLC versions may define new levels.
+ */
+enum libvlc_log_level
+{
+ LIBVLC_DEBUG=0, /**< Debug message */
+ LIBVLC_NOTICE=2, /**< Important informational message */
+ LIBVLC_WARNING=3, /**< Warning (potential error) message */
+ LIBVLC_ERROR=4 /**< Error message */
+};
+
+typedef struct vlc_log_t libvlc_log_t;
+
+/**
+ * Gets log message debug infos.
+ *
+ * This function retrieves self-debug information about a log message:
+ * - the name of the VLC module emitting the message,
+ * - the name of the source code module (i.e. file) and
+ * - the line number within the source code module.
+ *
+ * The returned module name and file name will be NULL if unknown.
+ * The returned line number will similarly be zero if unknown.
+ *
+ * \param ctx message context (as passed to the @ref libvlc_log_cb callback)
+ * \param module module name storage (or NULL) [OUT]
+ * \param file source code file name storage (or NULL) [OUT]
+ * \param line source code file line number storage (or NULL) [OUT]
+ * \warning The returned module name and source code file name, if non-NULL,
+ * are only valid until the logging callback returns.
+ *
+ * \version LibVLC 2.1.0 or later
+ */
+LIBVLC_API void libvlc_log_get_context(const libvlc_log_t *ctx,
+ const char **module, const char **file, unsigned *line);
+
+/**
+ * Gets log message info.
+ *
+ * This function retrieves meta-information about a log message:
+ * - the type name of the VLC object emitting the message,
+ * - the object header if any, and
+ * - a temporaly-unique object identifier.
+ *
+ * This information is mainly meant for manual troubleshooting.
+ *
+ * The returned type name may be "generic" if unknown, but it cannot be NULL.
+ * The returned header will be NULL if unset; in current versions, the header
+ * is used to distinguish for VLM inputs.
+ * The returned object ID will be zero if the message is not associated with
+ * any VLC object.
+ *
+ * \param ctx message context (as passed to the @ref libvlc_log_cb callback)
+ * \param name object name storage (or NULL) [OUT]
+ * \param header object header (or NULL) [OUT]
+ * \param id temporarily-unique object identifier (or 0) [OUT]
+ * \warning The returned module name and source code file name, if non-NULL,
+ * are only valid until the logging callback returns.
+ *
+ * \version LibVLC 2.1.0 or later
+ */
+LIBVLC_API void libvlc_log_get_object(const libvlc_log_t *ctx,
+ const char **name, const char **header, uintptr_t *id);
+
+/**
+ * Callback prototype for LibVLC log message handler.
+ *
+ * \param data data pointer as given to libvlc_log_set()
+ * \param level message level (@ref libvlc_log_level)
+ * \param ctx message context (meta-information about the message)
+ * \param fmt printf() format string (as defined by ISO C11)
+ * \param args variable argument list for the format
+ * \note Log message handlers must be thread-safe.
+ * \warning The message context pointer, the format string parameters and the
+ * variable arguments are only valid until the callback returns.
+ */
+typedef void (*libvlc_log_cb)(void *data, int level, const libvlc_log_t *ctx,
+ const char *fmt, va_list args);
+
+/**
+ * Unsets the logging callback.
+ *
+ * This function deregisters the logging callback for a LibVLC instance.
+ * This is rarely needed as the callback is implicitly unset when the instance
+ * is destroyed.
+ *
+ * \note This function will wait for any pending callbacks invocation to
+ * complete (causing a deadlock if called from within the callback).
+ *
+ * \param p_instance libvlc instance
+ * \version LibVLC 2.1.0 or later
+ */
+LIBVLC_API void libvlc_log_unset( libvlc_instance_t *p_instance );
+
+/**
+ * Sets the logging callback for a LibVLC instance.
+ *
+ * This function is thread-safe: it will wait for any pending callbacks
+ * invocation to complete.
+ *
+ * \param cb callback function pointer
+ * \param data opaque data pointer for the callback function
+ *
+ * \note Some log messages (especially debug) are emitted by LibVLC while
+ * is being initialized. These messages cannot be captured with this interface.
+ *
+ * \warning A deadlock may occur if this function is called from the callback.
+ *
+ * \param p_instance libvlc instance
+ * \version LibVLC 2.1.0 or later
+ */
+LIBVLC_API void libvlc_log_set( libvlc_instance_t *p_instance,
+ libvlc_log_cb cb, void *data );
+
+
+/**
+ * Sets up logging to a file.
+ * \param p_instance libvlc instance
+ * \param stream FILE pointer opened for writing
+ * (the FILE pointer must remain valid until libvlc_log_unset())
+ * \version LibVLC 2.1.0 or later
+ */
+LIBVLC_API void libvlc_log_set_file( libvlc_instance_t *p_instance, FILE *stream );
+
+/** @} */
+
+/**
+ * Description of a module.
+ */
+typedef struct libvlc_module_description_t
+{
+ char *psz_name;
+ char *psz_shortname;
+ char *psz_longname;
+ char *psz_help;
+ char *psz_help_html;
+ struct libvlc_module_description_t *p_next;
+} libvlc_module_description_t;
+
+/**
+ * Release a list of module descriptions.
+ *
+ * \param p_list the list to be released
+ */
+LIBVLC_API
+void libvlc_module_description_list_release( libvlc_module_description_t *p_list );
+
+/**
+ * Returns a list of audio filters that are available.
+ *
+ * \param p_instance libvlc instance
+ *
+ * \return a list of module descriptions. It should be freed with libvlc_module_description_list_release().
+ * In case of an error, NULL is returned.
+ *
+ * \see libvlc_module_description_t
+ * \see libvlc_module_description_list_release
+ */
+LIBVLC_API
+libvlc_module_description_t *libvlc_audio_filter_list_get( libvlc_instance_t *p_instance );
+
+/**
+ * Returns a list of video filters that are available.
+ *
+ * \param p_instance libvlc instance
+ *
+ * \return a list of module descriptions. It should be freed with libvlc_module_description_list_release().
+ * In case of an error, NULL is returned.
+ *
+ * \see libvlc_module_description_t
+ * \see libvlc_module_description_list_release
+ */
+LIBVLC_API
+libvlc_module_description_t *libvlc_video_filter_list_get( libvlc_instance_t *p_instance );
+
+/** @} */
+
+/** \defgroup libvlc_clock LibVLC time
+ * These functions provide access to the LibVLC time/clock.
+ * @{
+ */
+
+/**
+ * Return the current time as defined by LibVLC. The unit is the microsecond.
+ * Time increases monotonically (regardless of time zone changes and RTC
+ * adjustments).
+ * The origin is arbitrary but consistent across the whole system
+ * (e.g. the system uptime, the time since the system was booted).
+ * \note On systems that support it, the POSIX monotonic clock is used.
+ */
+LIBVLC_API
+int64_t libvlc_clock(void);
+
+/**
+ * Return the delay (in microseconds) until a certain timestamp.
+ * \param pts timestamp
+ * \return negative if timestamp is in the past,
+ * positive if it is in the future
+ */
+static inline int64_t libvlc_delay(int64_t pts)
+{
+ return pts - libvlc_clock();
+}
+
+/** @} */
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif /** @} */
diff --git a/Libs/vlc/libvlc_dialog.h b/Libs/vlc/libvlc_dialog.h
new file mode 100644
index 000000000..e87d8464c
--- /dev/null
+++ b/Libs/vlc/libvlc_dialog.h
@@ -0,0 +1,260 @@
+/*****************************************************************************
+ * libvlc_dialog.h: libvlc dialog API
+ *****************************************************************************
+ * Copyright © 2016 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef LIBVLC_DIALOG_H
+#define LIBVLC_DIALOG_H 1
+
+#include
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+typedef struct libvlc_dialog_id libvlc_dialog_id;
+
+/**
+ * @defgroup libvlc_dialog LibVLC dialog
+ * @ingroup libvlc
+ * @{
+ * @file
+ * LibVLC dialog external API
+ */
+
+typedef enum libvlc_dialog_question_type
+{
+ LIBVLC_DIALOG_QUESTION_NORMAL,
+ LIBVLC_DIALOG_QUESTION_WARNING,
+ LIBVLC_DIALOG_QUESTION_CRITICAL,
+} libvlc_dialog_question_type;
+
+/**
+ * Dialog callbacks to be implemented
+ *
+ * @attention starting with vlc 4.0.0 the error callback (pf_display_error) is
+ * no longer part of this struct and need to be registered separately
+ * using @a libvlc_dialog_set_error_callback
+ *
+ * @see libvlc_dialog_set_error_callback
+ */
+typedef struct libvlc_dialog_cbs
+{
+ /**
+ * Called when a login dialog needs to be displayed
+ *
+ * You can interact with this dialog by calling libvlc_dialog_post_login()
+ * to post an answer or libvlc_dialog_dismiss() to cancel this dialog.
+ *
+ * @note to receive this callback, libvlc_dialog_cbs.pf_cancel should not be
+ * NULL.
+ *
+ * @param p_data opaque pointer for the callback
+ * @param p_id id used to interact with the dialog
+ * @param psz_title title of the dialog
+ * @param psz_text text of the dialog
+ * @param psz_default_username user name that should be set on the user form
+ * @param b_ask_store if true, ask the user if he wants to save the
+ * credentials
+ */
+ void (*pf_display_login)(void *p_data, libvlc_dialog_id *p_id,
+ const char *psz_title, const char *psz_text,
+ const char *psz_default_username,
+ bool b_ask_store);
+
+ /**
+ * Called when a question dialog needs to be displayed
+ *
+ * You can interact with this dialog by calling libvlc_dialog_post_action()
+ * to post an answer or libvlc_dialog_dismiss() to cancel this dialog.
+ *
+ * @note to receive this callback, libvlc_dialog_cbs.pf_cancel should not be
+ * NULL.
+ *
+ * @param p_data opaque pointer for the callback
+ * @param p_id id used to interact with the dialog
+ * @param psz_title title of the dialog
+ * @param psz_text text of the dialog
+ * @param i_type question type (or severity) of the dialog
+ * @param psz_cancel text of the cancel button
+ * @param psz_action1 text of the first button, if NULL, don't display this
+ * button
+ * @param psz_action2 text of the second button, if NULL, don't display
+ * this button
+ */
+ void (*pf_display_question)(void *p_data, libvlc_dialog_id *p_id,
+ const char *psz_title, const char *psz_text,
+ libvlc_dialog_question_type i_type,
+ const char *psz_cancel, const char *psz_action1,
+ const char *psz_action2);
+
+ /**
+ * Called when a progress dialog needs to be displayed
+ *
+ * If cancellable (psz_cancel != NULL), you can cancel this dialog by
+ * calling libvlc_dialog_dismiss()
+ *
+ * @note to receive this callback, libvlc_dialog_cbs.pf_cancel and
+ * libvlc_dialog_cbs.pf_update_progress should not be NULL.
+ *
+ * @param p_data opaque pointer for the callback
+ * @param p_id id used to interact with the dialog
+ * @param psz_title title of the dialog
+ * @param psz_text text of the dialog
+ * @param b_indeterminate true if the progress dialog is indeterminate
+ * @param f_position initial position of the progress bar (between 0.0 and
+ * 1.0)
+ * @param psz_cancel text of the cancel button, if NULL the dialog is not
+ * cancellable
+ */
+ void (*pf_display_progress)(void *p_data, libvlc_dialog_id *p_id,
+ const char *psz_title, const char *psz_text,
+ bool b_indeterminate, float f_position,
+ const char *psz_cancel);
+
+ /**
+ * Called when a displayed dialog needs to be cancelled
+ *
+ * The implementation must call libvlc_dialog_dismiss() to really release
+ * the dialog.
+ *
+ * @param p_data opaque pointer for the callback
+ * @param p_id id of the dialog
+ */
+ void (*pf_cancel)(void *p_data, libvlc_dialog_id *p_id);
+
+ /**
+ * Called when a progress dialog needs to be updated
+ *
+ * @param p_data opaque pointer for the callback
+ * @param p_id id of the dialog
+ * @param f_position osition of the progress bar (between 0.0 and 1.0)
+ * @param psz_text new text of the progress dialog
+ */
+ void (*pf_update_progress)(void *p_data, libvlc_dialog_id *p_id,
+ float f_position, const char *psz_text);
+} libvlc_dialog_cbs;
+
+
+/**
+ * Called when an error message needs to be displayed
+ *
+ * @param p_data opaque pointer for the callback
+ * @param psz_title title of the dialog
+ * @param psz_text text of the dialog
+ */
+typedef void (*libvlc_dialog_error_cbs)(void *p_data, const char *psz_title, const char *psz_text);
+
+/**
+ * Register callbacks in order to handle VLC dialogs
+ *
+ * @version LibVLC 3.0.0 and later.
+ *
+ * @param p_instance the libvlc instance to attach the dialog callbacks to
+ * @param p_cbs a pointer to callbacks, or NULL to unregister callbacks.
+ * @param p_data opaque pointer for the callback
+ */
+LIBVLC_API void
+libvlc_dialog_set_callbacks(libvlc_instance_t *p_instance,
+ const libvlc_dialog_cbs *p_cbs, void *p_data);
+
+/*
+* Register callback in order to handle VLC error messages
+*
+* @version LibVLC 4.0.0 and later.
+*
+* @param p_cbs a pointer to callback, or NULL to unregister callback.
+* @param p_data opaque pointer for the callback
+*/
+LIBVLC_API void
+libvlc_dialog_set_error_callback(libvlc_instance_t *p_instance,
+ libvlc_dialog_error_cbs p_cbs, void *p_data);
+
+/**
+ * Associate an opaque pointer with the dialog id
+ *
+ * @version LibVLC 3.0.0 and later.
+ */
+LIBVLC_API void
+libvlc_dialog_set_context(libvlc_dialog_id *p_id, void *p_context);
+
+/**
+ * Return the opaque pointer associated with the dialog id
+ * \see libvlc_dialog_set_context
+ * @version LibVLC 3.0.0 and later.
+ */
+LIBVLC_API void *
+libvlc_dialog_get_context(libvlc_dialog_id *p_id);
+
+/**
+ * Post a login answer
+ *
+ * After this call, p_id won't be valid anymore
+ *
+ * @see libvlc_dialog_cbs.pf_display_login
+ *
+ * @version LibVLC 3.0.0 and later.
+ *
+ * @param p_id id of the dialog
+ * @param psz_username valid and non empty string
+ * @param psz_password valid string (can be empty)
+ * @param b_store if true, store the credentials
+ * @return 0 on success, or -1 on error
+ */
+LIBVLC_API int
+libvlc_dialog_post_login(libvlc_dialog_id *p_id, const char *psz_username,
+ const char *psz_password, bool b_store);
+
+/**
+ * Post a question answer
+ *
+ * After this call, p_id won't be valid anymore
+ *
+ * @see libvlc_dialog_cbs.pf_display_question
+ *
+ * @version LibVLC 3.0.0 and later.
+ *
+ * @param p_id id of the dialog
+ * @param i_action 1 for action1, 2 for action2
+ * @return 0 on success, or -1 on error
+ */
+LIBVLC_API int
+libvlc_dialog_post_action(libvlc_dialog_id *p_id, int i_action);
+
+/**
+ * Dismiss a dialog
+ *
+ * After this call, p_id won't be valid anymore
+ *
+ * @see libvlc_dialog_cbs.pf_cancel
+ *
+ * @version LibVLC 3.0.0 and later.
+ *
+ * @param p_id id of the dialog
+ * @return 0 on success, or -1 on error
+ */
+LIBVLC_API int
+libvlc_dialog_dismiss(libvlc_dialog_id *p_id);
+
+/** @} */
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif /* LIBVLC_DIALOG_H */
diff --git a/Libs/vlc/libvlc_events.h b/Libs/vlc/libvlc_events.h
new file mode 100644
index 000000000..3e4de7e46
--- /dev/null
+++ b/Libs/vlc/libvlc_events.h
@@ -0,0 +1,457 @@
+/*****************************************************************************
+ * libvlc_events.h: libvlc_events external API structure
+ *****************************************************************************
+ * Copyright (C) 1998-2010 VLC authors and VideoLAN
+ *
+ * Authors: Filippo Carone
+ * Pierre d'Herbemont
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef LIBVLC_EVENTS_H
+#define LIBVLC_EVENTS_H 1
+
+# include
+# include
+# include
+# include
+
+/**
+ * \file
+ * This file defines libvlc_event external API
+ */
+
+# ifdef __cplusplus
+extern "C" {
+# else
+# include
+# endif
+
+typedef struct libvlc_renderer_item_t libvlc_renderer_item_t;
+typedef struct libvlc_title_description_t libvlc_title_description_t;
+typedef struct libvlc_picture_t libvlc_picture_t;
+typedef struct libvlc_picture_list_t libvlc_picture_list_t;
+typedef struct libvlc_media_t libvlc_media_t;
+typedef struct libvlc_media_list_t libvlc_media_list_t;
+
+/**
+ * \ingroup libvlc_event
+ * @{
+ */
+
+/**
+ * Event types
+ */
+enum libvlc_event_e {
+ /* Append new event types at the end of a category.
+ * Do not remove, insert or re-order any entry.
+ */
+
+ /**
+ * 1 or several Metadata of a \link #libvlc_media_t media item\endlink changed
+ */
+ libvlc_MediaMetaChanged=0,
+ /**
+ * Subitem was added to a \link #libvlc_media_t media item\endlink
+ * \see libvlc_media_subitems()
+ */
+ libvlc_MediaSubItemAdded,
+ /**
+ * Deprecated, use libvlc_MediaParsedChanged or libvlc_MediaPlayerLengthChanged.
+ */
+ libvlc_MediaDurationChanged,
+ /**
+ * Parsing state of a \link #libvlc_media_t media item\endlink changed
+ * \see libvlc_media_parse_request(),
+ * libvlc_media_get_parsed_status(),
+ * libvlc_media_parse_stop()
+ */
+ libvlc_MediaParsedChanged,
+
+ /* Removed: libvlc_MediaFreed, */
+ /* Removed: libvlc_MediaStateChanged */
+
+ /**
+ * Subitem tree was added to a \link #libvlc_media_t media item\endlink
+ */
+ libvlc_MediaSubItemTreeAdded = libvlc_MediaParsedChanged + 3,
+ /**
+ * A thumbnail generation for this \link #libvlc_media_t media \endlink completed.
+ * \see libvlc_media_thumbnail_request_by_time()
+ * \see libvlc_media_thumbnail_request_by_pos()
+ */
+ libvlc_MediaThumbnailGenerated,
+ /**
+ * One or more embedded thumbnails were found during the media preparsing
+ * The user can hold these picture(s) using libvlc_picture_retain if they
+ * wish to use them
+ */
+ libvlc_MediaAttachedThumbnailsFound,
+
+ libvlc_MediaPlayerMediaChanged=0x100,
+ libvlc_MediaPlayerNothingSpecial,
+ libvlc_MediaPlayerOpening,
+ libvlc_MediaPlayerBuffering,
+ libvlc_MediaPlayerPlaying,
+ libvlc_MediaPlayerPaused,
+ libvlc_MediaPlayerStopped,
+ libvlc_MediaPlayerForward,
+ libvlc_MediaPlayerBackward,
+ libvlc_MediaPlayerStopping,
+ libvlc_MediaPlayerEncounteredError,
+ libvlc_MediaPlayerTimeChanged,
+ libvlc_MediaPlayerPositionChanged,
+ libvlc_MediaPlayerSeekableChanged,
+ libvlc_MediaPlayerPausableChanged,
+ /* libvlc_MediaPlayerTitleChanged, */
+ libvlc_MediaPlayerSnapshotTaken = libvlc_MediaPlayerPausableChanged + 2,
+ libvlc_MediaPlayerLengthChanged,
+ libvlc_MediaPlayerVout,
+
+ /* libvlc_MediaPlayerScrambledChanged, use libvlc_MediaPlayerProgramUpdated */
+
+ /** A track was added, cf. media_player_es_changed in \ref libvlc_event_t.u
+ * to get the id of the new track. */
+ libvlc_MediaPlayerESAdded = libvlc_MediaPlayerVout + 2,
+ /** A track was removed, cf. media_player_es_changed in \ref
+ * libvlc_event_t.u to get the id of the removed track. */
+ libvlc_MediaPlayerESDeleted,
+ /** Tracks were selected or unselected, cf.
+ * media_player_es_selection_changed in \ref libvlc_event_t.u to get the
+ * unselected and/or the selected track ids. */
+ libvlc_MediaPlayerESSelected,
+ libvlc_MediaPlayerCorked,
+ libvlc_MediaPlayerUncorked,
+ libvlc_MediaPlayerMuted,
+ libvlc_MediaPlayerUnmuted,
+ libvlc_MediaPlayerAudioVolume,
+ libvlc_MediaPlayerAudioDevice,
+ /** A track was updated, cf. media_player_es_changed in \ref
+ * libvlc_event_t.u to get the id of the updated track. */
+ libvlc_MediaPlayerESUpdated,
+ libvlc_MediaPlayerProgramAdded,
+ libvlc_MediaPlayerProgramDeleted,
+ libvlc_MediaPlayerProgramSelected,
+ libvlc_MediaPlayerProgramUpdated,
+ /**
+ * The title list changed, call
+ * libvlc_media_player_get_full_title_descriptions() to get the new list.
+ */
+ libvlc_MediaPlayerTitleListChanged,
+ /**
+ * The title selection changed, cf media_player_title_selection_changed in
+ * \ref libvlc_event_t.u
+ */
+ libvlc_MediaPlayerTitleSelectionChanged,
+ libvlc_MediaPlayerChapterChanged,
+ libvlc_MediaPlayerRecordChanged,
+
+ /**
+ * A \link #libvlc_media_t media item\endlink was added to a
+ * \link #libvlc_media_list_t media list\endlink.
+ */
+ libvlc_MediaListItemAdded=0x200,
+ /**
+ * A \link #libvlc_media_t media item\endlink is about to get
+ * added to a \link #libvlc_media_list_t media list\endlink.
+ */
+ libvlc_MediaListWillAddItem,
+ /**
+ * A \link #libvlc_media_t media item\endlink was deleted from
+ * a \link #libvlc_media_list_t media list\endlink.
+ */
+ libvlc_MediaListItemDeleted,
+ /**
+ * A \link #libvlc_media_t media item\endlink is about to get
+ * deleted from a \link #libvlc_media_list_t media list\endlink.
+ */
+ libvlc_MediaListWillDeleteItem,
+ /**
+ * A \link #libvlc_media_list_t media list\endlink has reached the
+ * end.
+ * All \link #libvlc_media_t items\endlink were either added (in
+ * case of a \ref libvlc_media_discoverer_t) or parsed (preparser).
+ */
+ libvlc_MediaListEndReached,
+
+ /**
+ * \deprecated No longer used.
+ * This belonged to the removed libvlc_media_list_view_t
+ */
+ libvlc_MediaListViewItemAdded LIBVLC_DEPRECATED =0x300,
+ /**
+ * \deprecated No longer used.
+ * This belonged to the removed libvlc_media_list_view_t
+ */
+ libvlc_MediaListViewWillAddItem LIBVLC_DEPRECATED,
+ /**
+ * \deprecated No longer used.
+ * This belonged to the removed libvlc_media_list_view_t
+ */
+ libvlc_MediaListViewItemDeleted LIBVLC_DEPRECATED,
+ /**
+ * \deprecated No longer used.
+ * This belonged to the removed libvlc_media_list_view_t
+ */
+ libvlc_MediaListViewWillDeleteItem LIBVLC_DEPRECATED,
+
+ /**
+ * Playback of a \link #libvlc_media_list_player_t media list
+ * player\endlink has started.
+ */
+ libvlc_MediaListPlayerPlayed=0x400,
+
+ /**
+ * The current \link #libvlc_media_t item\endlink of a
+ * \link #libvlc_media_list_player_t media list player\endlink
+ * has changed to a different item.
+ */
+ libvlc_MediaListPlayerNextItemSet,
+
+ /**
+ * Playback of a \link #libvlc_media_list_player_t media list
+ * player\endlink has stopped.
+ */
+ libvlc_MediaListPlayerStopped,
+
+ /**
+ * A new \link #libvlc_renderer_item_t renderer item\endlink was found by a
+ * \link #libvlc_renderer_discoverer_t renderer discoverer\endlink.
+ * The renderer item is valid until deleted.
+ */
+ libvlc_RendererDiscovererItemAdded=0x502,
+
+ /**
+ * A previously discovered \link #libvlc_renderer_item_t renderer item\endlink
+ * was deleted by a \link #libvlc_renderer_discoverer_t renderer discoverer\endlink.
+ * The renderer item is no longer valid.
+ */
+ libvlc_RendererDiscovererItemDeleted,
+
+ /**
+ * The current media set into the \ref libvlc_media_player_t is stopping.
+ *
+ * This event can be used to notify when the media callbacks, initialized
+ * from \ref libvlc_media_new_callbacks, should be interrupted, and in
+ * particular the \ref libvlc_media_read_cb. It can also be used to signal
+ * the application state that any input resource (webserver, file mounting,
+ * etc) can be discarded. Output resources still need to be active until
+ * the player switches to the \ref libvlc_Stopped state.
+ */
+ libvlc_MediaPlayerMediaStopping,
+};
+
+/**
+ * A LibVLC event
+ */
+typedef struct libvlc_event_t
+{
+ int type; /**< Event type (see @ref libvlc_event_e) */
+ void *p_obj; /**< Object emitting the event */
+ union
+ {
+ /* media descriptor */
+ struct
+ {
+ libvlc_meta_t meta_type; /**< Deprecated, any meta_type can change */
+ } media_meta_changed;
+ struct
+ {
+ libvlc_media_t * new_child;
+ } media_subitem_added;
+ struct
+ {
+ int64_t new_duration;
+ } media_duration_changed;
+ struct
+ {
+ int new_status; /**< see @ref libvlc_media_parsed_status_t */
+ } media_parsed_changed;
+ struct
+ {
+ int new_state; /**< see @ref libvlc_state_t */
+ } media_state_changed;
+ struct
+ {
+ libvlc_picture_t* p_thumbnail;
+ } media_thumbnail_generated;
+ struct
+ {
+ libvlc_media_t * item;
+ } media_subitemtree_added;
+ struct
+ {
+ libvlc_picture_list_t* thumbnails;
+ } media_attached_thumbnails_found;
+
+ /* media instance */
+ struct
+ {
+ float new_cache;
+ } media_player_buffering;
+ struct
+ {
+ int new_chapter;
+ } media_player_chapter_changed;
+ struct
+ {
+ double new_position;
+ } media_player_position_changed;
+ struct
+ {
+ libvlc_time_t new_time;
+ } media_player_time_changed;
+ struct
+ {
+ const libvlc_title_description_t *title;
+ int index;
+ } media_player_title_selection_changed;
+ struct
+ {
+ int new_seekable;
+ } media_player_seekable_changed;
+ struct
+ {
+ int new_pausable;
+ } media_player_pausable_changed;
+ struct
+ {
+ int new_scrambled;
+ } media_player_scrambled_changed;
+ struct
+ {
+ int new_count;
+ } media_player_vout;
+
+ /* media list */
+ struct
+ {
+ libvlc_media_t * item;
+ int index;
+ } media_list_item_added;
+ struct
+ {
+ libvlc_media_t * item;
+ int index;
+ } media_list_will_add_item;
+ struct
+ {
+ libvlc_media_t * item;
+ int index;
+ } media_list_item_deleted;
+ struct
+ {
+ libvlc_media_t * item;
+ int index;
+ } media_list_will_delete_item;
+
+ /* media list player */
+ struct
+ {
+ libvlc_media_t * item;
+ } media_list_player_next_item_set;
+
+ /* snapshot taken */
+ struct
+ {
+ char* psz_filename ;
+ } media_player_snapshot_taken ;
+
+ /* Length changed */
+ struct
+ {
+ libvlc_time_t new_length;
+ } media_player_length_changed;
+
+ /* Extra MediaPlayer */
+ struct
+ {
+ libvlc_media_t * new_media;
+ } media_player_media_changed;
+
+ struct
+ {
+ libvlc_media_t * media;
+ } media_player_media_stopping;
+
+
+ /* ESAdded, ESDeleted, ESUpdated */
+ struct
+ {
+ libvlc_track_type_t i_type;
+ int i_id; /**< Deprecated, use psz_id */
+ /** Call libvlc_media_player_get_track_from_id() to get the track
+ * description. */
+ const char *psz_id;
+ } media_player_es_changed;
+
+ /* ESSelected */
+ struct
+ {
+ libvlc_track_type_t i_type;
+ const char *psz_unselected_id;
+ const char *psz_selected_id;
+ } media_player_es_selection_changed;
+
+ /* ProgramAdded, ProgramDeleted, ProgramUpdated */
+ struct
+ {
+ int i_id;
+ } media_player_program_changed;
+
+ /* ProgramSelected */
+ struct
+ {
+ int i_unselected_id;
+ int i_selected_id;
+ } media_player_program_selection_changed;
+
+ struct
+ {
+ float volume;
+ } media_player_audio_volume;
+
+ struct
+ {
+ const char *device;
+ } media_player_audio_device;
+
+ struct
+ {
+ bool recording;
+ /** Only valid when recording ends (recording == false) */
+ const char *recorded_file_path;
+ } media_player_record_changed;
+
+ struct
+ {
+ libvlc_renderer_item_t *item;
+ } renderer_discoverer_item_added;
+ struct
+ {
+ libvlc_renderer_item_t *item;
+ } renderer_discoverer_item_deleted;
+ } u; /**< Type-dependent event description */
+} libvlc_event_t;
+
+
+/**@} */
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif /* _LIBVLC_EVENTS_H */
diff --git a/Libs/vlc/libvlc_media.h b/Libs/vlc/libvlc_media.h
new file mode 100644
index 000000000..05ae45639
--- /dev/null
+++ b/Libs/vlc/libvlc_media.h
@@ -0,0 +1,917 @@
+/*****************************************************************************
+ * libvlc_media.h: libvlc external API
+ *****************************************************************************
+ * Copyright (C) 1998-2009 VLC authors and VideoLAN
+ *
+ * Authors: Clément Stenac
+ * Jean-Paul Saman
+ * Pierre d'Herbemont
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef VLC_LIBVLC_MEDIA_H
+#define VLC_LIBVLC_MEDIA_H 1
+
+#include
+#include
+
+# ifdef __cplusplus
+extern "C" {
+# else
+# include
+# endif
+#include
+
+/** \defgroup libvlc_media LibVLC media
+ * \ingroup libvlc
+ * @ref libvlc_media_t is an abstract representation of a playable media.
+ * It consists of a media location and various optional meta data.
+ * @{
+ * \file
+ * LibVLC media item/descriptor external API
+ */
+
+typedef struct libvlc_media_t libvlc_media_t;
+
+/** Meta data types */
+typedef enum libvlc_meta_t {
+ libvlc_meta_Title,
+ libvlc_meta_Artist,
+ libvlc_meta_Genre,
+ libvlc_meta_Copyright,
+ libvlc_meta_Album,
+ libvlc_meta_TrackNumber,
+ libvlc_meta_Description,
+ libvlc_meta_Rating,
+ libvlc_meta_Date,
+ libvlc_meta_Setting,
+ libvlc_meta_URL,
+ libvlc_meta_Language,
+ libvlc_meta_NowPlaying,
+ libvlc_meta_Publisher,
+ libvlc_meta_EncodedBy,
+ libvlc_meta_ArtworkURL,
+ libvlc_meta_TrackID,
+ libvlc_meta_TrackTotal,
+ libvlc_meta_Director,
+ libvlc_meta_Season,
+ libvlc_meta_Episode,
+ libvlc_meta_ShowName,
+ libvlc_meta_Actors,
+ libvlc_meta_AlbumArtist,
+ libvlc_meta_DiscNumber,
+ libvlc_meta_DiscTotal
+ /* Add new meta types HERE */
+} libvlc_meta_t;
+
+/**
+ * libvlc media or media_player state
+ */
+typedef enum libvlc_state_t
+{
+ libvlc_NothingSpecial=0,
+ libvlc_Opening,
+ libvlc_Buffering, /* XXX: Deprecated value. Check the
+ * libvlc_MediaPlayerBuffering event to know the
+ * buffering state of a libvlc_media_player */
+ libvlc_Playing,
+ libvlc_Paused,
+ libvlc_Stopped,
+ libvlc_Stopping,
+ libvlc_Error
+} libvlc_state_t;
+
+enum
+{
+ libvlc_media_option_trusted = 0x2,
+ libvlc_media_option_unique = 0x100
+};
+
+typedef struct libvlc_media_stats_t
+{
+ /* Input */
+ uint64_t i_read_bytes;
+ float f_input_bitrate;
+
+ /* Demux */
+ uint64_t i_demux_read_bytes;
+ float f_demux_bitrate;
+ uint64_t i_demux_corrupted;
+ uint64_t i_demux_discontinuity;
+
+ /* Decoders */
+ uint64_t i_decoded_video;
+ uint64_t i_decoded_audio;
+
+ /* Video Output */
+ uint64_t i_displayed_pictures;
+ uint64_t i_late_pictures;
+ uint64_t i_lost_pictures;
+
+ /* Audio output */
+ uint64_t i_played_abuffers;
+ uint64_t i_lost_abuffers;
+} libvlc_media_stats_t;
+
+/**
+ * Media type
+ *
+ * \see libvlc_media_get_type
+ */
+typedef enum libvlc_media_type_t {
+ libvlc_media_type_unknown,
+ libvlc_media_type_file,
+ libvlc_media_type_directory,
+ libvlc_media_type_disc,
+ libvlc_media_type_stream,
+ libvlc_media_type_playlist,
+} libvlc_media_type_t;
+
+/**
+ * Parse flags used by libvlc_media_parse_request()
+ */
+typedef enum libvlc_media_parse_flag_t
+{
+ /**
+ * Parse media if it's a local file
+ */
+ libvlc_media_parse_local = 0x01,
+ /**
+ * Parse media even if it's a network file
+ */
+ libvlc_media_parse_network = 0x02,
+ /**
+ * Force parsing the media even if it would be skipped.
+ */
+ libvlc_media_parse_forced = 0x04,
+ /**
+ * Fetch meta and cover art using local resources
+ */
+ libvlc_media_fetch_local = 0x08,
+ /**
+ * Fetch meta and cover art using network resources
+ */
+ libvlc_media_fetch_network = 0x10,
+ /**
+ * Interact with the user (via libvlc_dialog_cbs) when preparsing this item
+ * (and not its sub items). Set this flag in order to receive a callback
+ * when the input is asking for credentials.
+ */
+ libvlc_media_do_interact = 0x20,
+} libvlc_media_parse_flag_t;
+
+/**
+ * Parse status used sent by libvlc_media_parse_request() or returned by
+ * libvlc_media_get_parsed_status()
+ */
+typedef enum libvlc_media_parsed_status_t
+{
+ libvlc_media_parsed_status_none,
+ libvlc_media_parsed_status_pending,
+ libvlc_media_parsed_status_skipped,
+ libvlc_media_parsed_status_failed,
+ libvlc_media_parsed_status_timeout,
+ libvlc_media_parsed_status_cancelled,
+ libvlc_media_parsed_status_done,
+} libvlc_media_parsed_status_t;
+
+/**
+ * Type of a media slave: subtitle or audio.
+ */
+typedef enum libvlc_media_slave_type_t
+{
+ libvlc_media_slave_type_subtitle,
+ libvlc_media_slave_type_generic,
+ libvlc_media_slave_type_audio = libvlc_media_slave_type_generic,
+} libvlc_media_slave_type_t;
+
+/**
+ * A slave of a libvlc_media_t
+ * \see libvlc_media_slaves_get
+ */
+typedef struct libvlc_media_slave_t
+{
+ char * psz_uri;
+ libvlc_media_slave_type_t i_type;
+ unsigned int i_priority;
+} libvlc_media_slave_t;
+
+/**
+ * Type of stat that can be requested from libvlc_media_get_filestat()
+ */
+#define libvlc_media_filestat_mtime 0
+#define libvlc_media_filestat_size 1
+
+/**
+ * Callback prototype to open a custom bitstream input media.
+ *
+ * The same media item can be opened multiple times. Each time, this callback
+ * is invoked. It should allocate and initialize any instance-specific
+ * resources, then store them in *datap. The instance resources can be freed
+ * in the @ref libvlc_media_close_cb callback.
+ *
+ * \param opaque private pointer as passed to libvlc_media_new_callbacks()
+ * \param datap storage space for a private data pointer [OUT]
+ * \param sizep byte length of the bitstream or UINT64_MAX if unknown [OUT]
+ *
+ * \note For convenience, *datap is initially NULL and *sizep is initially 0.
+ *
+ * \return 0 on success, non-zero on error. In case of failure, the other
+ * callbacks will not be invoked and any value stored in *datap and *sizep is
+ * discarded.
+ */
+typedef int (*libvlc_media_open_cb)(void *opaque, void **datap,
+ uint64_t *sizep);
+
+/**
+ * Callback prototype to read data from a custom bitstream input media.
+ *
+ * \param opaque private pointer as set by the @ref libvlc_media_open_cb
+ * callback
+ * \param buf start address of the buffer to read data into
+ * \param len bytes length of the buffer
+ *
+ * \return strictly positive number of bytes read, 0 on end-of-stream,
+ * or -1 on non-recoverable error
+ *
+ * \note If no data is immediately available, then the callback should sleep.
+ * \warning The application is responsible for avoiding deadlock situations.
+ */
+typedef ptrdiff_t (*libvlc_media_read_cb)(void *opaque, unsigned char *buf,
+ size_t len);
+
+/**
+ * Callback prototype to seek a custom bitstream input media.
+ *
+ * \param opaque private pointer as set by the @ref libvlc_media_open_cb
+ * callback
+ * \param offset absolute byte offset to seek to
+ * \return 0 on success, -1 on error.
+ */
+typedef int (*libvlc_media_seek_cb)(void *opaque, uint64_t offset);
+
+/**
+ * Callback prototype to close a custom bitstream input media.
+ *
+ * \param opaque private pointer as set by the @ref libvlc_media_open_cb
+ * callback
+ */
+typedef void (*libvlc_media_close_cb)(void *opaque);
+
+/**
+ * Create a media with a certain given media resource location,
+ * for instance a valid URL.
+ *
+ * \note To refer to a local file with this function,
+ * the file://... URI syntax must be used (see IETF RFC3986).
+ * We recommend using libvlc_media_new_path() instead when dealing with
+ * local files.
+ *
+ * \see libvlc_media_release
+ *
+ * \param psz_mrl the media location
+ * \return the newly created media or NULL on error
+ */
+LIBVLC_API libvlc_media_t *libvlc_media_new_location(const char * psz_mrl);
+
+/**
+ * Create a media for a certain file path.
+ *
+ * \see libvlc_media_release
+ *
+ * \param path local filesystem path
+ * \return the newly created media or NULL on error
+ */
+LIBVLC_API libvlc_media_t *libvlc_media_new_path(const char *path);
+
+/**
+ * Create a media for an already open file descriptor.
+ * The file descriptor shall be open for reading (or reading and writing).
+ *
+ * Regular file descriptors, pipe read descriptors and character device
+ * descriptors (including TTYs) are supported on all platforms.
+ * Block device descriptors are supported where available.
+ * Directory descriptors are supported on systems that provide fdopendir().
+ * Sockets are supported on all platforms where they are file descriptors,
+ * i.e. all except Windows.
+ *
+ * \note This library will not automatically close the file descriptor
+ * under any circumstance. Nevertheless, a file descriptor can usually only be
+ * rendered once in a media player. To render it a second time, the file
+ * descriptor should probably be rewound to the beginning with lseek().
+ *
+ * \see libvlc_media_release
+ *
+ * \version LibVLC 1.1.5 and later.
+ *
+ * \param fd open file descriptor
+ * \return the newly created media or NULL on error
+ */
+LIBVLC_API libvlc_media_t *libvlc_media_new_fd(int fd);
+
+/**
+ * Create a media with custom callbacks to read the data from.
+ *
+ * \param open_cb callback to open the custom bitstream input media
+ * \param read_cb callback to read data (must not be NULL)
+ * \param seek_cb callback to seek, or NULL if seeking is not supported
+ * \param close_cb callback to close the media, or NULL if unnecessary
+ * \param opaque data pointer for the open callback
+ *
+ * \return the newly created media or NULL on error
+ *
+ * \note If open_cb is NULL, the opaque pointer will be passed to read_cb,
+ * seek_cb and close_cb, and the stream size will be treated as unknown.
+ *
+ * \note The callbacks may be called asynchronously (from another thread).
+ * A single stream instance need not be reentrant. However the open_cb needs to
+ * be reentrant if the media is used by multiple player instances.
+ *
+ * \warning The callbacks may be used until all or any player instances
+ * that were supplied the media item are stopped.
+ *
+ * \see libvlc_media_release
+ *
+ * \version LibVLC 3.0.0 and later.
+ */
+LIBVLC_API libvlc_media_t *libvlc_media_new_callbacks(
+ libvlc_media_open_cb open_cb,
+ libvlc_media_read_cb read_cb,
+ libvlc_media_seek_cb seek_cb,
+ libvlc_media_close_cb close_cb,
+ void *opaque );
+
+/**
+ * Create a media as an empty node with a given name.
+ *
+ * \see libvlc_media_release
+ *
+ * \param psz_name the name of the node
+ * \return the new empty media or NULL on error
+ */
+LIBVLC_API libvlc_media_t *libvlc_media_new_as_node(const char * psz_name);
+
+/**
+ * Add an option to the media.
+ *
+ * This option will be used to determine how the media_player will
+ * read the media. This allows to use VLC's advanced
+ * reading/streaming options on a per-media basis.
+ *
+ * \note The options are listed in 'vlc --longhelp' from the command line,
+ * e.g. "--sout-all". Keep in mind that available options and their semantics
+ * vary across LibVLC versions and builds.
+ * \warning Not all options affects libvlc_media_t objects:
+ * Specifically, due to architectural issues most audio and video options,
+ * such as text renderer options, have no effects on an individual media.
+ * These options must be set through libvlc_new() instead.
+ *
+ * \param p_md the media descriptor
+ * \param psz_options the options (as a string)
+ */
+LIBVLC_API void libvlc_media_add_option(
+ libvlc_media_t *p_md,
+ const char * psz_options );
+
+/**
+ * Add an option to the media with configurable flags.
+ *
+ * This option will be used to determine how the media_player will
+ * read the media. This allows to use VLC's advanced
+ * reading/streaming options on a per-media basis.
+ *
+ * The options are detailed in vlc --longhelp, for instance
+ * "--sout-all". Note that all options are not usable on medias:
+ * specifically, due to architectural issues, video-related options
+ * such as text renderer options cannot be set on a single media. They
+ * must be set on the whole libvlc instance instead.
+ *
+ * \param p_md the media descriptor
+ * \param psz_options the options (as a string)
+ * \param i_flags the flags for this option
+ */
+LIBVLC_API void libvlc_media_add_option_flag(
+ libvlc_media_t *p_md,
+ const char * psz_options,
+ unsigned i_flags );
+
+
+/**
+ * Retain a reference to a media descriptor object (libvlc_media_t). Use
+ * libvlc_media_release() to decrement the reference count of a
+ * media descriptor object.
+ *
+ * \param p_md the media descriptor
+ * \return the same object
+ */
+LIBVLC_API libvlc_media_t *libvlc_media_retain( libvlc_media_t *p_md );
+
+/**
+ * Decrement the reference count of a media descriptor object. If the
+ * reference count is 0, then libvlc_media_release() will release the
+ * media descriptor object. If the media descriptor object has been released it
+ * should not be used again.
+ *
+ * \param p_md the media descriptor
+ */
+LIBVLC_API void libvlc_media_release( libvlc_media_t *p_md );
+
+
+/**
+ * Get the media resource locator (mrl) from a media descriptor object
+ *
+ * \param p_md a media descriptor object
+ * \return string with mrl of media descriptor object
+ */
+LIBVLC_API char *libvlc_media_get_mrl( libvlc_media_t *p_md );
+
+/**
+ * Duplicate a media descriptor object.
+ *
+ * \warning the duplicated media won't share forthcoming updates from the
+ * original one.
+ *
+ * \param p_md a media descriptor object.
+ */
+LIBVLC_API libvlc_media_t *libvlc_media_duplicate( libvlc_media_t *p_md );
+
+/**
+ * Read the meta of the media.
+ *
+ * Note, you need to call libvlc_media_parse_request() or play the media
+ * at least once before calling this function.
+ * If the media has not yet been parsed this will return NULL.
+ *
+ * \see libvlc_MediaMetaChanged
+ *
+ * \param p_md the media descriptor
+ * \param e_meta the meta to read
+ * \return the media's meta
+ */
+LIBVLC_API char *libvlc_media_get_meta( libvlc_media_t *p_md,
+ libvlc_meta_t e_meta );
+
+/**
+ * Set the meta of the media (this function will not save the meta, call
+ * libvlc_media_save_meta in order to save the meta)
+ *
+ * \param p_md the media descriptor
+ * \param e_meta the meta to write
+ * \param psz_value the media's meta
+ */
+LIBVLC_API void libvlc_media_set_meta( libvlc_media_t *p_md,
+ libvlc_meta_t e_meta,
+ const char *psz_value );
+
+/**
+ * Read the meta extra of the media.
+ *
+ * If the media has not yet been parsed this will return NULL.
+ *
+ * \see libvlc_media_parse
+ * \see libvlc_media_parse_with_options
+ *
+ * \param p_md the media descriptor
+ * \param psz_name the meta extra to read (nonnullable)
+ * \return the media's meta extra or NULL
+ */
+LIBVLC_API char *libvlc_media_get_meta_extra( libvlc_media_t *p_md,
+ const char *psz_name );
+
+/**
+ * Set the meta of the media (this function will not save the meta, call
+ * libvlc_media_save_meta in order to save the meta)
+ *
+ * \param p_md the media descriptor
+ * \param psz_name the meta extra to write (nonnullable)
+ * \param psz_value the media's meta extra (nullable)
+ * Removed from meta extra if set to NULL
+ */
+LIBVLC_API void libvlc_media_set_meta_extra( libvlc_media_t *p_md,
+ const char *psz_name,
+ const char *psz_value );
+
+/**
+ * Read the meta extra names of the media.
+ *
+ * \param p_md the media descriptor
+ * \param pppsz_names the media's meta extra name array
+ * you can access the elements using the return value (count)
+ * must be released with libvlc_media_meta_extra_names_release()
+ * \return the meta extra count
+ */
+LIBVLC_API unsigned libvlc_media_get_meta_extra_names( libvlc_media_t *p_md,
+ char ***pppsz_names );
+
+/**
+ * Release a media meta extra names
+ *
+ * \param ppsz_names meta extra names array to release
+ * \param i_count number of elements in the array
+ */
+LIBVLC_API void libvlc_media_meta_extra_names_release( char **ppsz_names,
+ unsigned i_count );
+
+/**
+ * Save the meta previously set
+ *
+ * \param inst LibVLC instance
+ * \param p_md the media descriptor
+ * \return true if the write operation was successful
+ */
+LIBVLC_API int libvlc_media_save_meta( libvlc_instance_t *inst,
+ libvlc_media_t *p_md );
+
+/**
+ * Get the current statistics about the media
+ * \param p_md media descriptor object
+ * \param p_stats structure that contain the statistics about the media
+ * (this structure must be allocated by the caller)
+ * \retval true statistics are available
+ * \retval false otherwise
+ */
+LIBVLC_API bool libvlc_media_get_stats(libvlc_media_t *p_md,
+ libvlc_media_stats_t *p_stats);
+
+/* The following method uses libvlc_media_list_t, however, media_list usage is optional
+ * and this is here for convenience */
+#define VLC_FORWARD_DECLARE_OBJECT(a) struct a
+
+/**
+ * Get subitems of media descriptor object. This will increment
+ * the reference count of supplied media descriptor object. Use
+ * libvlc_media_list_release() to decrement the reference counting.
+ *
+ * \param p_md media descriptor object
+ * \return list of media descriptor subitems or NULL
+ */
+LIBVLC_API VLC_FORWARD_DECLARE_OBJECT(libvlc_media_list_t *)
+libvlc_media_subitems( libvlc_media_t *p_md );
+
+/**
+ * Get event manager from media descriptor object.
+ * NOTE: this function doesn't increment reference counting.
+ *
+ * \param p_md a media descriptor object
+ * \return event manager object
+ */
+LIBVLC_API libvlc_event_manager_t *
+ libvlc_media_event_manager( libvlc_media_t *p_md );
+
+/**
+ * Get duration (in ms) of media descriptor object item.
+ *
+ * Note, you need to call libvlc_media_parse_request() or play the media
+ * at least once before calling this function.
+ * Not doing this will result in an undefined result.
+ *
+ * \param p_md media descriptor object
+ * \return duration of media item or -1 on error
+ */
+LIBVLC_API libvlc_time_t
+ libvlc_media_get_duration( libvlc_media_t *p_md );
+
+/**
+ * Get a 'stat' value of media descriptor object item.
+ *
+ * \note 'stat' values are currently only parsed by directory accesses. This
+ * mean that only sub medias of a directory media, parsed with
+ * libvlc_media_parse_request() can have valid 'stat' properties.
+ * \version LibVLC 4.0.0 and later.
+ *
+ * \param p_md media descriptor object
+ * \param type a valid libvlc_media_stat_ define
+ * \param out field in which the value will be stored
+ * \return 1 on success, 0 if not found, -1 on error.
+ */
+LIBVLC_API int
+ libvlc_media_get_filestat( libvlc_media_t *p_md, unsigned type, uint64_t *out );
+
+/**
+ * Parse the media asynchronously with options.
+ *
+ * This fetches (local or network) art, meta data and/or tracks information.
+ *
+ * To track when this is over you can listen to libvlc_MediaParsedChanged
+ * event. However if this functions returns an error, you will not receive any
+ * events.
+ *
+ * It uses a flag to specify parse options (see libvlc_media_parse_flag_t). All
+ * these flags can be combined. By default, media is parsed if it's a local
+ * file.
+ *
+ * \note Parsing can be aborted with libvlc_media_parse_stop().
+ *
+ * \see libvlc_MediaParsedChanged
+ * \see libvlc_media_get_meta
+ * \see libvlc_media_get_tracklist
+ * \see libvlc_media_get_parsed_status
+ * \see libvlc_media_parse_flag_t
+ *
+ * \param inst LibVLC instance that is to parse the media
+ * \param p_md media descriptor object
+ * \param parse_flag parse options:
+ * \param timeout maximum time allowed to preparse the media. If -1, the
+ * default "preparse-timeout" option will be used as a timeout. If 0, it will
+ * wait indefinitely. If > 0, the timeout will be used (in milliseconds).
+ * \return -1 in case of error, 0 otherwise
+ * \version LibVLC 4.0.0 or later
+ */
+LIBVLC_API int
+libvlc_media_parse_request( libvlc_instance_t *inst, libvlc_media_t *p_md,
+ libvlc_media_parse_flag_t parse_flag,
+ int timeout );
+
+/**
+ * Stop the parsing of the media
+ *
+ * When the media parsing is stopped, the libvlc_MediaParsedChanged event will
+ * be sent with the libvlc_media_parsed_status_timeout status.
+ *
+ * \see libvlc_media_parse_request()
+ *
+ * \param inst LibVLC instance that is to cease or give up parsing the media
+ * \param p_md media descriptor object
+ * \version LibVLC 3.0.0 or later
+ */
+LIBVLC_API void
+libvlc_media_parse_stop( libvlc_instance_t *inst, libvlc_media_t *p_md );
+
+/**
+ * Get Parsed status for media descriptor object.
+ *
+ * \see libvlc_MediaParsedChanged
+ * \see libvlc_media_parsed_status_t
+ * \see libvlc_media_parse_request()
+ *
+ * \param p_md media descriptor object
+ * \return a value of the libvlc_media_parsed_status_t enum
+ * \version LibVLC 3.0.0 or later
+ */
+LIBVLC_API libvlc_media_parsed_status_t
+ libvlc_media_get_parsed_status( libvlc_media_t *p_md );
+
+/**
+ * Sets media descriptor's user_data. user_data is specialized data
+ * accessed by the host application, VLC.framework uses it as a pointer to
+ * an native object that references a libvlc_media_t pointer
+ *
+ * \param p_md media descriptor object
+ * \param p_new_user_data pointer to user data
+ */
+LIBVLC_API void
+ libvlc_media_set_user_data( libvlc_media_t *p_md, void *p_new_user_data );
+
+/**
+ * Get media descriptor's user_data. user_data is specialized data
+ * accessed by the host application, VLC.framework uses it as a pointer to
+ * an native object that references a libvlc_media_t pointer
+ *
+ * \see libvlc_media_set_user_data
+ *
+ * \param p_md media descriptor object
+ */
+LIBVLC_API void *libvlc_media_get_user_data( libvlc_media_t *p_md );
+
+/**
+ * Get the track list for one type
+ *
+ * \version LibVLC 4.0.0 and later.
+ *
+ * \note You need to call libvlc_media_parse_request() or play the media
+ * at least once before calling this function. Not doing this will result in
+ * an empty list.
+ *
+ * \see libvlc_media_tracklist_count
+ * \see libvlc_media_tracklist_at
+ *
+ * \param p_md media descriptor object
+ * \param type type of the track list to request
+ *
+ * \return a valid libvlc_media_tracklist_t or NULL in case of error, if there
+ * is no track for a category, the returned list will have a size of 0, delete
+ * with libvlc_media_tracklist_delete()
+ */
+LIBVLC_API libvlc_media_tracklist_t *
+libvlc_media_get_tracklist( libvlc_media_t *p_md, libvlc_track_type_t type );
+
+/**
+ * Get codec description from media elementary stream
+ *
+ * Note, you need to call libvlc_media_parse_request() or play the media
+ * at least once before calling this function.
+ *
+ * \version LibVLC 3.0.0 and later.
+ *
+ * \see libvlc_media_track_t
+ *
+ * \param i_type i_type from libvlc_media_track_t
+ * \param i_codec i_codec or i_original_fourcc from libvlc_media_track_t
+ *
+ * \return codec description
+ */
+LIBVLC_API
+const char *libvlc_media_get_codec_description( libvlc_track_type_t i_type,
+ uint32_t i_codec );
+
+/**
+ * Get the media type of the media descriptor object
+ *
+ * \version LibVLC 3.0.0 and later.
+ *
+ * \see libvlc_media_type_t
+ *
+ * \param p_md media descriptor object
+ *
+ * \return media type
+ */
+LIBVLC_API
+libvlc_media_type_t libvlc_media_get_type( libvlc_media_t *p_md );
+
+/**
+ * \brief libvlc_media_thumbnail_request_t An opaque thumbnail request object
+ */
+typedef struct libvlc_media_thumbnail_request_t libvlc_media_thumbnail_request_t;
+
+typedef enum libvlc_thumbnailer_seek_speed_t
+{
+ libvlc_media_thumbnail_seek_precise,
+ libvlc_media_thumbnail_seek_fast,
+} libvlc_thumbnailer_seek_speed_t;
+
+/**
+ * \brief libvlc_media_request_thumbnail_by_time Start an asynchronous thumbnail generation
+ *
+ * If the request is successfully queued, the libvlc_MediaThumbnailGenerated is
+ * guaranteed to be emitted (except if the request is destroyed early by the
+ * user).
+ * The resulting thumbnail size can either be:
+ * - Hardcoded by providing both width & height. In which case, the image will
+ * be stretched to match the provided aspect ratio, or cropped if crop is true.
+ * - Derived from the media aspect ratio if only width or height is provided and
+ * the other one is set to 0.
+ *
+ * \param inst LibVLC instance to generate the thumbnail with
+ * \param md media descriptor object
+ * \param time The time at which the thumbnail should be generated
+ * \param speed The seeking speed \sa{libvlc_thumbnailer_seek_speed_t}
+ * \param width The thumbnail width
+ * \param height the thumbnail height
+ * \param crop Should the picture be cropped to preserve source aspect ratio
+ * \param picture_type The thumbnail picture type \sa{libvlc_picture_type_t}
+ * \param timeout A timeout value in ms, or 0 to disable timeout
+ *
+ * \return A valid opaque request object, or NULL in case of failure.
+ * It must be released by libvlc_media_thumbnail_request_destroy() and
+ * can be cancelled by calling it early.
+ *
+ * \version libvlc 4.0 or later
+ *
+ * \see libvlc_picture_t
+ * \see libvlc_picture_type_t
+ */
+LIBVLC_API libvlc_media_thumbnail_request_t*
+libvlc_media_thumbnail_request_by_time( libvlc_instance_t *inst,
+ libvlc_media_t *md, libvlc_time_t time,
+ libvlc_thumbnailer_seek_speed_t speed,
+ unsigned int width, unsigned int height,
+ bool crop, libvlc_picture_type_t picture_type,
+ libvlc_time_t timeout );
+
+/**
+ * \brief libvlc_media_request_thumbnail_by_pos Start an asynchronous thumbnail generation
+ *
+ * If the request is successfully queued, the libvlc_MediaThumbnailGenerated is
+ * guaranteed to be emitted (except if the request is destroyed early by the
+ * user).
+ * The resulting thumbnail size can either be:
+ * - Hardcoded by providing both width & height. In which case, the image will
+ * be stretched to match the provided aspect ratio, or cropped if crop is true.
+ * - Derived from the media aspect ratio if only width or height is provided and
+ * the other one is set to 0.
+ *
+ * \param inst LibVLC instance to generate the thumbnail with
+ * \param md media descriptor object
+ * \param pos The position at which the thumbnail should be generated
+ * \param speed The seeking speed \sa{libvlc_thumbnailer_seek_speed_t}
+ * \param width The thumbnail width
+ * \param height the thumbnail height
+ * \param crop Should the picture be cropped to preserve source aspect ratio
+ * \param picture_type The thumbnail picture type \sa{libvlc_picture_type_t}
+ * \param timeout A timeout value in ms, or 0 to disable timeout
+ *
+ * \return A valid opaque request object, or NULL in case of failure.
+ * It must be released by libvlc_media_thumbnail_request_destroy().
+ *
+ * \version libvlc 4.0 or later
+ *
+ * \see libvlc_picture_t
+ * \see libvlc_picture_type_t
+ */
+LIBVLC_API libvlc_media_thumbnail_request_t*
+libvlc_media_thumbnail_request_by_pos( libvlc_instance_t *inst,
+ libvlc_media_t *md, double pos,
+ libvlc_thumbnailer_seek_speed_t speed,
+ unsigned int width, unsigned int height,
+ bool crop, libvlc_picture_type_t picture_type,
+ libvlc_time_t timeout );
+
+/**
+ * @brief libvlc_media_thumbnail_destroy destroys a thumbnail request
+ * @param p_req An opaque thumbnail request object.
+ *
+ * This will also cancel the thumbnail request, no events will be emitted after
+ * this call.
+ */
+LIBVLC_API void
+libvlc_media_thumbnail_request_destroy( libvlc_media_thumbnail_request_t *p_req );
+
+/**
+ * Add a slave to the current media.
+ *
+ * A slave is an external input source that may contains an additional subtitle
+ * track (like a .srt) or an additional audio track (like a .ac3).
+ *
+ * \note This function must be called before the media is parsed (via
+ * libvlc_media_parse_request()) or before the media is played (via
+ * libvlc_media_player_play())
+ *
+ * \version LibVLC 3.0.0 and later.
+ *
+ * \param p_md media descriptor object
+ * \param i_type subtitle or audio
+ * \param i_priority from 0 (low priority) to 4 (high priority)
+ * \param psz_uri Uri of the slave (should contain a valid scheme).
+ *
+ * \return 0 on success, -1 on error.
+ */
+LIBVLC_API
+int libvlc_media_slaves_add( libvlc_media_t *p_md,
+ libvlc_media_slave_type_t i_type,
+ unsigned int i_priority,
+ const char *psz_uri );
+
+/**
+ * Clear all slaves previously added by libvlc_media_slaves_add() or
+ * internally.
+ *
+ * \version LibVLC 3.0.0 and later.
+ *
+ * \param p_md media descriptor object
+ */
+LIBVLC_API
+void libvlc_media_slaves_clear( libvlc_media_t *p_md );
+
+/**
+ * Get a media descriptor's slave list
+ *
+ * The list will contain slaves parsed by VLC or previously added by
+ * libvlc_media_slaves_add(). The typical use case of this function is to save
+ * a list of slave in a database for a later use.
+ *
+ * \version LibVLC 3.0.0 and later.
+ *
+ * \see libvlc_media_slaves_add
+ *
+ * \param p_md media descriptor object
+ * \param ppp_slaves address to store an allocated array of slaves (must be
+ * freed with libvlc_media_slaves_release()) [OUT]
+ *
+ * \return the number of slaves (zero on error)
+ */
+LIBVLC_API
+unsigned int libvlc_media_slaves_get( libvlc_media_t *p_md,
+ libvlc_media_slave_t ***ppp_slaves );
+
+/**
+ * Release a media descriptor's slave list
+ *
+ * \version LibVLC 3.0.0 and later.
+ *
+ * \param pp_slaves slave array to release
+ * \param i_count number of elements in the array
+ */
+LIBVLC_API
+void libvlc_media_slaves_release( libvlc_media_slave_t **pp_slaves,
+ unsigned int i_count );
+
+/** @}*/
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif /* VLC_LIBVLC_MEDIA_H */
diff --git a/Libs/vlc/libvlc_media_discoverer.h b/Libs/vlc/libvlc_media_discoverer.h
new file mode 100644
index 000000000..9054c837b
--- /dev/null
+++ b/Libs/vlc/libvlc_media_discoverer.h
@@ -0,0 +1,188 @@
+/*****************************************************************************
+ * libvlc_media_discoverer.h: libvlc external API
+ *****************************************************************************
+ * Copyright (C) 1998-2009 VLC authors and VideoLAN
+ *
+ * Authors: Clément Stenac
+ * Jean-Paul Saman
+ * Pierre d'Herbemont
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef VLC_LIBVLC_MEDIA_DISCOVERER_H
+#define VLC_LIBVLC_MEDIA_DISCOVERER_H 1
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+typedef struct libvlc_media_list_t libvlc_media_list_t;
+
+/**
+ * Category of a media discoverer
+ * \see libvlc_media_discoverer_list_get()
+ */
+typedef enum libvlc_media_discoverer_category_t {
+ /** devices, like portable music player */
+ libvlc_media_discoverer_devices,
+ /** LAN/WAN services, like Upnp, SMB, or SAP */
+ libvlc_media_discoverer_lan,
+ /** Podcasts */
+ libvlc_media_discoverer_podcasts,
+ /** Local directories, like Video, Music or Pictures directories */
+ libvlc_media_discoverer_localdirs,
+} libvlc_media_discoverer_category_t;
+
+/**
+ * Media discoverer description
+ * \see libvlc_media_discoverer_list_get()
+ */
+typedef struct libvlc_media_discoverer_description_t {
+ char *psz_name;
+ char *psz_longname;
+ libvlc_media_discoverer_category_t i_cat;
+} libvlc_media_discoverer_description_t;
+
+/** \defgroup libvlc_media_discoverer LibVLC media discovery
+ * \ingroup libvlc
+ * LibVLC media discovery finds available media via various means.
+ * This corresponds to the service discovery functionality in VLC media player.
+ * Different plugins find potential medias locally (e.g. user media directory),
+ * from peripherals (e.g. video capture device), on the local network
+ * (e.g. SAP) or on the Internet (e.g. Internet radios).
+ * @{
+ * \file
+ * LibVLC media discovery external API
+ */
+
+typedef struct libvlc_media_discoverer_t libvlc_media_discoverer_t;
+
+/**
+ * Create a media discoverer object by name.
+ *
+ * After this object is created, you should attach to media_list events in
+ * order to be notified of new items discovered.
+ *
+ * You need to call libvlc_media_discoverer_start() in order to start the
+ * discovery.
+ *
+ * \see libvlc_media_discoverer_media_list
+ * \see libvlc_media_discoverer_start
+ *
+ * \param p_inst libvlc instance
+ * \param psz_name service name; use libvlc_media_discoverer_list_get() to get
+ * a list of the discoverer names available in this libVLC instance
+ * \return media discover object or NULL in case of error
+ * \version LibVLC 3.0.0 or later
+ */
+LIBVLC_API libvlc_media_discoverer_t *
+libvlc_media_discoverer_new( libvlc_instance_t * p_inst,
+ const char * psz_name );
+
+/**
+ * Start media discovery.
+ *
+ * To stop it, call libvlc_media_discoverer_stop() or
+ * libvlc_media_discoverer_list_release() directly.
+ *
+ * \see libvlc_media_discoverer_stop
+ *
+ * \param p_mdis media discover object
+ * \return -1 in case of error, 0 otherwise
+ * \version LibVLC 3.0.0 or later
+ */
+LIBVLC_API int
+libvlc_media_discoverer_start( libvlc_media_discoverer_t * p_mdis );
+
+/**
+ * Stop media discovery.
+ *
+ * \see libvlc_media_discoverer_start
+ *
+ * \param p_mdis media discover object
+ * \version LibVLC 3.0.0 or later
+ */
+LIBVLC_API void
+libvlc_media_discoverer_stop( libvlc_media_discoverer_t * p_mdis );
+
+/**
+ * Release media discover object. If the reference count reaches 0, then
+ * the object will be released.
+ *
+ * \param p_mdis media service discover object
+ */
+LIBVLC_API void
+libvlc_media_discoverer_release( libvlc_media_discoverer_t * p_mdis );
+
+/**
+ * Get media service discover media list.
+ *
+ * \param p_mdis media service discover object
+ * \return list of media items
+ */
+LIBVLC_API libvlc_media_list_t *
+libvlc_media_discoverer_media_list( libvlc_media_discoverer_t * p_mdis );
+
+/**
+ * Query if media service discover object is running.
+ *
+ * \param p_mdis media service discover object
+ *
+ * \retval true running
+ * \retval false not running
+ */
+LIBVLC_API bool
+libvlc_media_discoverer_is_running(libvlc_media_discoverer_t *p_mdis);
+
+/**
+ * Get media discoverer services by category
+ *
+ * \version LibVLC 3.0.0 and later.
+ *
+ * \param p_inst libvlc instance
+ * \param i_cat category of services to fetch
+ * \param ppp_services address to store an allocated array of media discoverer
+ * services (must be freed with libvlc_media_discoverer_list_release() by
+ * the caller) [OUT]
+ *
+ * \return the number of media discoverer services (0 on error)
+ */
+LIBVLC_API size_t
+libvlc_media_discoverer_list_get( libvlc_instance_t *p_inst,
+ libvlc_media_discoverer_category_t i_cat,
+ libvlc_media_discoverer_description_t ***ppp_services );
+
+/**
+ * Release an array of media discoverer services
+ *
+ * \version LibVLC 3.0.0 and later.
+ *
+ * \see libvlc_media_discoverer_list_get()
+ *
+ * \param pp_services array to release
+ * \param i_count number of elements in the array
+ */
+LIBVLC_API void
+libvlc_media_discoverer_list_release( libvlc_media_discoverer_description_t **pp_services,
+ size_t i_count );
+
+/**@} */
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif /* */
diff --git a/Libs/vlc/libvlc_media_list.h b/Libs/vlc/libvlc_media_list.h
new file mode 100644
index 000000000..ba2a340de
--- /dev/null
+++ b/Libs/vlc/libvlc_media_list.h
@@ -0,0 +1,200 @@
+/*****************************************************************************
+ * libvlc_media_list.h: libvlc_media_list API
+ *****************************************************************************
+ * Copyright (C) 1998-2008 VLC authors and VideoLAN
+ *
+ * Authors: Pierre d'Herbemont
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef LIBVLC_MEDIA_LIST_H
+#define LIBVLC_MEDIA_LIST_H 1
+
+typedef struct libvlc_media_t libvlc_media_t;
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+/** \defgroup libvlc_media_list LibVLC media list
+ * \ingroup libvlc
+ * A LibVLC media list holds multiple @ref libvlc_media_t media descriptors.
+ * @{
+ * \file
+ * LibVLC media list (playlist) external API
+ */
+
+typedef struct libvlc_media_list_t libvlc_media_list_t;
+
+/**
+ * Create an empty media list.
+ *
+ * \return empty media list, or NULL on error
+ */
+LIBVLC_API libvlc_media_list_t *libvlc_media_list_new(void);
+
+/**
+ * Release media list created with libvlc_media_list_new().
+ *
+ * \param p_ml a media list created with libvlc_media_list_new()
+ */
+LIBVLC_API void
+ libvlc_media_list_release( libvlc_media_list_t *p_ml );
+
+/**
+ * Retain reference to a media list
+ *
+ * \param p_ml a media list created with libvlc_media_list_new()
+ * \return the same object
+ */
+LIBVLC_API libvlc_media_list_t *
+ libvlc_media_list_retain( libvlc_media_list_t *p_ml );
+
+/**
+ * Associate media instance with this media list instance.
+ * If another media instance was present it will be released.
+ * The libvlc_media_list_lock should NOT be held upon entering this function.
+ *
+ * \param p_ml a media list instance
+ * \param p_md media instance to add
+ */
+LIBVLC_API void
+libvlc_media_list_set_media( libvlc_media_list_t *p_ml, libvlc_media_t *p_md );
+
+/**
+ * Get media instance from this media list instance. This action will increase
+ * the refcount on the media instance.
+ * The libvlc_media_list_lock should NOT be held upon entering this function.
+ *
+ * \param p_ml a media list instance
+ * \return media instance
+ */
+LIBVLC_API libvlc_media_t *
+ libvlc_media_list_media( libvlc_media_list_t *p_ml );
+
+/**
+ * Add media instance to media list
+ * The libvlc_media_list_lock should be held upon entering this function.
+ *
+ * \param p_ml a media list instance
+ * \param p_md a media instance
+ * \return 0 on success, -1 if the media list is read-only
+ */
+LIBVLC_API int
+libvlc_media_list_add_media( libvlc_media_list_t *p_ml, libvlc_media_t *p_md );
+
+/**
+ * Insert media instance in media list on a position
+ * The libvlc_media_list_lock should be held upon entering this function.
+ *
+ * \param p_ml a media list instance
+ * \param p_md a media instance
+ * \param i_pos position in array where to insert
+ * \return 0 on success, -1 if the media list is read-only
+ */
+LIBVLC_API int
+libvlc_media_list_insert_media( libvlc_media_list_t *p_ml,
+ libvlc_media_t *p_md, int i_pos );
+
+/**
+ * Remove media instance from media list on a position
+ * The libvlc_media_list_lock should be held upon entering this function.
+ *
+ * \param p_ml a media list instance
+ * \param i_pos position in array where to insert
+ * \return 0 on success, -1 if the list is read-only or the item was not found
+ */
+LIBVLC_API int
+libvlc_media_list_remove_index( libvlc_media_list_t *p_ml, int i_pos );
+
+/**
+ * Get count on media list items
+ * The libvlc_media_list_lock should be held upon entering this function.
+ *
+ * \param p_ml a media list instance
+ * \return number of items in media list
+ */
+LIBVLC_API int
+ libvlc_media_list_count( libvlc_media_list_t *p_ml );
+
+/**
+ * List media instance in media list at a position
+ * The libvlc_media_list_lock should be held upon entering this function.
+ *
+ * \param p_ml a media list instance
+ * \param i_pos position in array where to insert
+ * \return media instance at position i_pos, or NULL if not found.
+ * In case of success, libvlc_media_retain() is called to increase the refcount
+ * on the media.
+ */
+LIBVLC_API libvlc_media_t *
+ libvlc_media_list_item_at_index( libvlc_media_list_t *p_ml, int i_pos );
+/**
+ * Find index position of List media instance in media list.
+ * Warning: the function will return the first matched position.
+ * The libvlc_media_list_lock should be held upon entering this function.
+ *
+ * \param p_ml a media list instance
+ * \param p_md media instance
+ * \return position of media instance or -1 if media not found
+ */
+LIBVLC_API int
+ libvlc_media_list_index_of_item( libvlc_media_list_t *p_ml,
+ libvlc_media_t *p_md );
+
+/**
+ * This indicates if this media list is read-only from a user point of view
+ *
+ * \param p_ml media list instance
+ * \retval true read-only
+ * \retval false read/write
+ */
+LIBVLC_API bool libvlc_media_list_is_readonly(libvlc_media_list_t *p_ml);
+
+/**
+ * Get lock on media list items
+ *
+ * \param p_ml a media list instance
+ */
+LIBVLC_API void
+ libvlc_media_list_lock( libvlc_media_list_t *p_ml );
+
+/**
+ * Release lock on media list items
+ * The libvlc_media_list_lock should be held upon entering this function.
+ *
+ * \param p_ml a media list instance
+ */
+LIBVLC_API void
+ libvlc_media_list_unlock( libvlc_media_list_t *p_ml );
+
+/**
+ * Get libvlc_event_manager from this media list instance.
+ * The p_event_manager is immutable, so you don't have to hold the lock
+ *
+ * \param p_ml a media list instance
+ * \return libvlc_event_manager
+ */
+LIBVLC_API libvlc_event_manager_t *
+ libvlc_media_list_event_manager( libvlc_media_list_t *p_ml );
+
+/** @} media_list */
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif /* _LIBVLC_MEDIA_LIST_H */
diff --git a/Libs/vlc/libvlc_media_list_player.h b/Libs/vlc/libvlc_media_list_player.h
new file mode 100644
index 000000000..aa287b460
--- /dev/null
+++ b/Libs/vlc/libvlc_media_list_player.h
@@ -0,0 +1,249 @@
+/*****************************************************************************
+ * libvlc_media_list_player.h: libvlc_media_list API
+ *****************************************************************************
+ * Copyright (C) 1998-2008 VLC authors and VideoLAN
+ *
+ * Authors: Pierre d'Herbemont
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef LIBVLC_MEDIA_LIST_PLAYER_H
+#define LIBVLC_MEDIA_LIST_PLAYER_H 1
+
+#include
+#include
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+typedef struct libvlc_instance_t libvlc_instance_t;
+typedef struct libvlc_media_player_t libvlc_media_player_t;
+typedef struct libvlc_media_list_t libvlc_media_list_t;
+typedef struct libvlc_media_t libvlc_media_t;
+
+/** \defgroup libvlc_media_list_player LibVLC media list player
+ * \ingroup libvlc
+ * The LibVLC media list player plays a @ref libvlc_media_list_t list of media,
+ * in a certain order.
+ * This is required to especially support playlist files.
+ * The normal @ref libvlc_media_player_t LibVLC media player can only play a
+ * single media, and does not handle playlist files properly.
+ * @{
+ * \file
+ * LibVLC media list player external API
+ */
+
+typedef struct libvlc_media_list_player_t libvlc_media_list_player_t;
+
+/**
+ * Defines playback modes for playlist.
+ */
+typedef enum libvlc_playback_mode_t
+{
+ libvlc_playback_mode_default,
+ libvlc_playback_mode_loop,
+ libvlc_playback_mode_repeat
+} libvlc_playback_mode_t;
+
+/**
+ * Create new media_list_player.
+ *
+ * \param p_instance libvlc instance
+ * \return media list player instance or NULL on error
+ * (it must be released by libvlc_media_list_player_release())
+ */
+LIBVLC_API libvlc_media_list_player_t *
+ libvlc_media_list_player_new( libvlc_instance_t * p_instance );
+
+/**
+ * Release a media_list_player after use
+ * Decrement the reference count of a media player object. If the
+ * reference count is 0, then libvlc_media_list_player_release() will
+ * release the media player object. If the media player object
+ * has been released, then it should not be used again.
+ *
+ * \param p_mlp media list player instance
+ */
+LIBVLC_API void
+ libvlc_media_list_player_release( libvlc_media_list_player_t * p_mlp );
+
+/**
+ * Retain a reference to a media player list object. Use
+ * libvlc_media_list_player_release() to decrement reference count.
+ *
+ * \param p_mlp media player list object
+ * \return the same object
+ */
+LIBVLC_API libvlc_media_list_player_t *
+ libvlc_media_list_player_retain( libvlc_media_list_player_t *p_mlp );
+
+/**
+ * Return the event manager of this media_list_player.
+ *
+ * \param p_mlp media list player instance
+ * \return the event manager
+ */
+LIBVLC_API libvlc_event_manager_t *
+ libvlc_media_list_player_event_manager(libvlc_media_list_player_t * p_mlp);
+
+/**
+ * Replace media player in media_list_player with this instance.
+ *
+ * \param p_mlp media list player instance
+ * \param p_mi media player instance
+ */
+LIBVLC_API void
+ libvlc_media_list_player_set_media_player(
+ libvlc_media_list_player_t * p_mlp,
+ libvlc_media_player_t * p_mi );
+
+/**
+ * Get media player of the media_list_player instance.
+ *
+ * \param p_mlp media list player instance
+ * \return media player instance
+ * \note the caller is responsible for releasing the returned instance
+ with libvlc_media_list_player_set_media_player().
+ */
+LIBVLC_API libvlc_media_player_t *
+ libvlc_media_list_player_get_media_player(libvlc_media_list_player_t * p_mlp);
+
+/**
+ * Set the media list associated with the player
+ *
+ * \param p_mlp media list player instance
+ * \param p_mlist list of media
+ */
+LIBVLC_API void
+ libvlc_media_list_player_set_media_list(
+ libvlc_media_list_player_t * p_mlp,
+ libvlc_media_list_t * p_mlist );
+
+/**
+ * Play media list
+ *
+ * \param p_mlp media list player instance
+ */
+LIBVLC_API
+void libvlc_media_list_player_play(libvlc_media_list_player_t * p_mlp);
+
+/**
+ * Toggle pause (or resume) media list
+ *
+ * \param p_mlp media list player instance
+ */
+LIBVLC_API
+void libvlc_media_list_player_pause(libvlc_media_list_player_t * p_mlp);
+
+/**
+ * Pause or resume media list
+ *
+ * \param p_mlp media list player instance
+ * \param do_pause play/resume if zero, pause if non-zero
+ * \version LibVLC 3.0.0 or later
+ */
+LIBVLC_API
+void libvlc_media_list_player_set_pause(libvlc_media_list_player_t * p_mlp,
+ int do_pause);
+
+/**
+ * Is media list playing?
+ *
+ * \param p_mlp media list player instance
+ *
+ * \retval true playing
+ * \retval false not playing
+ */
+LIBVLC_API bool
+libvlc_media_list_player_is_playing(libvlc_media_list_player_t * p_mlp);
+
+/**
+ * Get current libvlc_state of media list player
+ *
+ * \param p_mlp media list player instance
+ * \return libvlc_state_t for media list player
+ */
+LIBVLC_API libvlc_state_t
+ libvlc_media_list_player_get_state( libvlc_media_list_player_t * p_mlp );
+
+/**
+ * Play media list item at position index
+ *
+ * \param p_mlp media list player instance
+ * \param i_index index in media list to play
+ * \return 0 upon success -1 if the item wasn't found
+ */
+LIBVLC_API
+int libvlc_media_list_player_play_item_at_index(libvlc_media_list_player_t * p_mlp,
+ int i_index);
+
+/**
+ * Play the given media item
+ *
+ * \param p_mlp media list player instance
+ * \param p_md the media instance
+ * \return 0 upon success, -1 if the media is not part of the media list
+ */
+LIBVLC_API
+int libvlc_media_list_player_play_item(libvlc_media_list_player_t * p_mlp,
+ libvlc_media_t * p_md);
+
+/**
+ * Stop playing media list
+ *
+ * \param p_mlp media list player instance
+ */
+LIBVLC_API void
+ libvlc_media_list_player_stop_async( libvlc_media_list_player_t * p_mlp);
+
+/**
+ * Play next item from media list
+ *
+ * \param p_mlp media list player instance
+ * \return 0 upon success -1 if there is no next item
+ */
+LIBVLC_API
+int libvlc_media_list_player_next(libvlc_media_list_player_t * p_mlp);
+
+/**
+ * Play previous item from media list
+ *
+ * \param p_mlp media list player instance
+ * \return 0 upon success -1 if there is no previous item
+ */
+LIBVLC_API
+int libvlc_media_list_player_previous(libvlc_media_list_player_t * p_mlp);
+
+
+
+/**
+ * Sets the playback mode for the playlist
+ *
+ * \param p_mlp media list player instance
+ * \param e_mode playback mode specification
+ */
+LIBVLC_API
+void libvlc_media_list_player_set_playback_mode(libvlc_media_list_player_t * p_mlp,
+ libvlc_playback_mode_t e_mode );
+
+/** @} media_list_player */
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif /* LIBVLC_MEDIA_LIST_PLAYER_H */
diff --git a/Libs/vlc/libvlc_media_player.h b/Libs/vlc/libvlc_media_player.h
new file mode 100644
index 000000000..982e70ad3
--- /dev/null
+++ b/Libs/vlc/libvlc_media_player.h
@@ -0,0 +1,3304 @@
+/*****************************************************************************
+ * libvlc_media_player.h: libvlc_media_player external API
+ *****************************************************************************
+ * Copyright (C) 1998-2024 VLC authors and VideoLAN
+ *
+ * Authors: Clément Stenac
+ * Jean-Paul Saman
+ * Pierre d'Herbemont
+ * Maxime Chapelet
+ * Alexandre Janniaux
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef VLC_LIBVLC_MEDIA_PLAYER_H
+#define VLC_LIBVLC_MEDIA_PLAYER_H 1
+
+/* Definitions of enum properties for video */
+#include "libvlc_video.h"
+
+# ifdef __cplusplus
+extern "C" {
+# else
+# include
+# endif
+
+typedef struct libvlc_video_viewpoint_t libvlc_video_viewpoint_t;
+typedef enum libvlc_media_slave_type_t libvlc_media_slave_type_t;
+typedef struct libvlc_media_t libvlc_media_t;
+typedef struct libvlc_media_track_t libvlc_media_track_t;
+typedef struct libvlc_media_tracklist_t libvlc_media_tracklist_t;
+typedef enum libvlc_track_type_t libvlc_track_type_t;
+typedef struct libvlc_renderer_item_t libvlc_renderer_item_t;
+typedef enum libvlc_state_t libvlc_state_t;
+
+/** \defgroup libvlc_media_player LibVLC media player
+ * \ingroup libvlc
+ * A LibVLC media player plays one media (usually in a custom drawable).
+ * @{
+ * \file
+ * LibVLC simple media player external API
+ */
+
+typedef struct libvlc_media_player_t libvlc_media_player_t;
+
+/**
+ * Description for titles
+ */
+enum
+{
+ libvlc_title_menu = 0x01,
+ libvlc_title_interactive = 0x02
+};
+
+typedef struct libvlc_title_description_t
+{
+ int64_t i_duration; /**< duration in milliseconds */
+ char *psz_name; /**< title name */
+ unsigned i_flags; /**< info if item was recognized as a menu, interactive or plain content by the demuxer */
+} libvlc_title_description_t;
+
+/**
+ * Description for chapters
+ */
+typedef struct libvlc_chapter_description_t
+{
+ int64_t i_time_offset; /**< time-offset of the chapter in milliseconds */
+ int64_t i_duration; /**< duration of the chapter in milliseconds */
+ char *psz_name; /**< chapter name */
+} libvlc_chapter_description_t;
+
+/**
+ * Description for audio output. It contains
+ * name, description and pointer to next record.
+ */
+typedef struct libvlc_audio_output_t
+{
+ char *psz_name;
+ char *psz_description;
+ struct libvlc_audio_output_t *p_next;
+
+} libvlc_audio_output_t;
+
+/**
+ * Description for audio output device.
+ */
+typedef struct libvlc_audio_output_device_t
+{
+ struct libvlc_audio_output_device_t *p_next; /**< Next entry in list */
+ char *psz_device; /**< Device identifier string */
+ char *psz_description; /**< User-friendly device description */
+ /* More fields may be added here in later versions */
+} libvlc_audio_output_device_t;
+
+/**
+ * Marq options definition
+ */
+typedef enum libvlc_video_marquee_option_t {
+ libvlc_marquee_Enable = 0,
+ libvlc_marquee_Text, /** string argument */
+ libvlc_marquee_Color,
+ libvlc_marquee_Opacity,
+ libvlc_marquee_Position,
+ libvlc_marquee_Refresh,
+ libvlc_marquee_Size,
+ libvlc_marquee_Timeout,
+ libvlc_marquee_X,
+ libvlc_marquee_Y
+} libvlc_video_marquee_option_t;
+
+/**
+ * Navigation mode
+ */
+typedef enum libvlc_navigate_mode_t
+{
+ libvlc_navigate_activate = 0,
+ libvlc_navigate_up,
+ libvlc_navigate_down,
+ libvlc_navigate_left,
+ libvlc_navigate_right,
+ libvlc_navigate_popup
+} libvlc_navigate_mode_t;
+
+/**
+ * Enumeration of values used to set position (e.g. of video title).
+ */
+typedef enum libvlc_position_t {
+ libvlc_position_disable=-1,
+ libvlc_position_center,
+ libvlc_position_left,
+ libvlc_position_right,
+ libvlc_position_top,
+ libvlc_position_top_left,
+ libvlc_position_top_right,
+ libvlc_position_bottom,
+ libvlc_position_bottom_left,
+ libvlc_position_bottom_right
+} libvlc_position_t;
+
+/**
+ * Enumeration of values used to set the video fitting inside the display area.
+ */
+typedef enum libvlc_video_fit_mode_t {
+ libvlc_video_fit_none = 0, /**< Explicit zoom set by \ref libvlc_video_set_scale */
+ libvlc_video_fit_smaller, /**< Fit inside / to smallest display dimension */
+ libvlc_video_fit_larger, /**< Fit outside / to largest display dimension */
+ libvlc_video_fit_width, /**< Fit to display width */
+ libvlc_video_fit_height, /**< Fit to display height */
+} libvlc_video_fit_mode_t;
+
+/**
+ * Enumeration of teletext keys than can be passed via
+ * libvlc_video_set_teletext()
+ */
+typedef enum libvlc_teletext_key_t {
+ libvlc_teletext_key_red = 'r' << 16,
+ libvlc_teletext_key_green = 'g' << 16,
+ libvlc_teletext_key_yellow = 'y' << 16,
+ libvlc_teletext_key_blue = 'b' << 16,
+ libvlc_teletext_key_index = 'i' << 16,
+} libvlc_teletext_key_t;
+
+/**
+ * A to B loop state
+ */
+typedef enum libvlc_abloop_t {
+ libvlc_abloop_none,
+ libvlc_abloop_a,
+ libvlc_abloop_b,
+} libvlc_abloop_t;
+
+/**
+ * Opaque equalizer handle.
+ *
+ * Equalizer settings can be applied to a media player.
+ */
+typedef struct libvlc_equalizer_t libvlc_equalizer_t;
+
+/**
+ * Create an empty Media Player object
+ *
+ * \param p_libvlc_instance the libvlc instance in which the Media Player
+ * should be created.
+ * \return a new media player object, or NULL on error.
+ * It must be released by libvlc_media_player_release().
+ */
+LIBVLC_API libvlc_media_player_t * libvlc_media_player_new( libvlc_instance_t *p_libvlc_instance );
+
+/**
+ * Create a Media Player object from a Media
+ *
+ * \param inst LibVLC instance to create a media player with
+ * \param p_md the media. Afterwards the p_md can be safely
+ * destroyed.
+ * \return a new media player object, or NULL on error.
+ * It must be released by libvlc_media_player_release().
+ */
+LIBVLC_API libvlc_media_player_t * libvlc_media_player_new_from_media( libvlc_instance_t *inst, libvlc_media_t *p_md );
+
+/**
+ * Release a media_player after use
+ * Decrement the reference count of a media player object. If the
+ * reference count is 0, then libvlc_media_player_release() will
+ * release the media player object. If the media player object
+ * has been released, then it should not be used again.
+ *
+ * \param p_mi the Media Player to free
+ */
+LIBVLC_API void libvlc_media_player_release( libvlc_media_player_t *p_mi );
+
+/**
+ * Retain a reference to a media player object. Use
+ * libvlc_media_player_release() to decrement reference count.
+ *
+ * \param p_mi media player object
+ * \return the same object
+ */
+LIBVLC_API libvlc_media_player_t *libvlc_media_player_retain( libvlc_media_player_t *p_mi );
+
+/**
+ * Set the media that will be used by the media_player. If any,
+ * previous md will be released.
+ *
+ * \note The user should listen to the libvlc_MediaPlayerMediaChanged event, to
+ * know when the new media is actually used by the player (or to known that the
+ * older media is no longer used).
+ *
+ * \param p_mi the Media Player
+ * \param p_md the Media. Afterwards the p_md can be safely
+ * destroyed.
+ */
+LIBVLC_API void libvlc_media_player_set_media( libvlc_media_player_t *p_mi,
+ libvlc_media_t *p_md );
+
+/**
+ * Get the media used by the media_player.
+ *
+ * \warning Calling this function just after libvlc_media_player_set_media()
+ * will return the media that was just set, but this media might not be
+ * currently used internally by the player. To detect such case, the user
+ * should listen to the libvlc_MediaPlayerMediaChanged event.
+ *
+ * \param p_mi the Media Player
+ * \return the media associated with p_mi, or NULL if no
+ * media is associated
+ */
+LIBVLC_API libvlc_media_t * libvlc_media_player_get_media( libvlc_media_player_t *p_mi );
+
+/**
+ * Get the Event Manager from which the media player send event.
+ *
+ * \param p_mi the Media Player
+ * \return the event manager associated with p_mi
+ */
+LIBVLC_API libvlc_event_manager_t * libvlc_media_player_event_manager ( libvlc_media_player_t *p_mi );
+
+/**
+ * is_playing
+ *
+ * \param p_mi the Media Player
+ * \retval true media player is playing
+ * \retval false media player is not playing
+ */
+LIBVLC_API bool libvlc_media_player_is_playing(libvlc_media_player_t *p_mi);
+
+/**
+ * Play
+ *
+ * \param p_mi the Media Player
+ * \return 0 if playback started (and was already started), or -1 on error.
+ */
+LIBVLC_API int libvlc_media_player_play ( libvlc_media_player_t *p_mi );
+
+/**
+ * Pause or resume (no effect if there is no media)
+ *
+ * \param mp the Media Player
+ * \param do_pause play/resume if zero, pause if non-zero
+ * \version LibVLC 1.1.1 or later
+ */
+LIBVLC_API void libvlc_media_player_set_pause ( libvlc_media_player_t *mp,
+ int do_pause );
+
+/**
+ * Toggle pause (no effect if there is no media)
+ *
+ * \param p_mi the Media Player
+ */
+LIBVLC_API void libvlc_media_player_pause ( libvlc_media_player_t *p_mi );
+
+/**
+ * Stop asynchronously
+ *
+ * \note This function is asynchronous. In case of success, the user should
+ * wait for the libvlc_MediaPlayerStopped event to know when the stop is
+ * finished.
+ *
+ * \param p_mi the Media Player
+ * \return 0 if the player is being stopped, -1 otherwise (no-op)
+ * \version LibVLC 4.0.0 or later
+ */
+LIBVLC_API int libvlc_media_player_stop_async ( libvlc_media_player_t *p_mi );
+
+/**
+ * Set a renderer to the media player
+ *
+ * \note must be called before the first call of libvlc_media_player_play() to
+ * take effect.
+ *
+ * \see libvlc_renderer_discoverer_new
+ *
+ * \param p_mi the Media Player
+ * \param p_item an item discovered by libvlc_renderer_discoverer_start()
+ * \return 0 on success, -1 on error.
+ * \version LibVLC 3.0.0 or later
+ */
+LIBVLC_API int libvlc_media_player_set_renderer( libvlc_media_player_t *p_mi,
+ libvlc_renderer_item_t *p_item );
+
+/**
+ * Enumeration of the Video color primaries.
+ */
+typedef enum libvlc_video_color_primaries_t {
+ libvlc_video_primaries_BT601_525 = 1,
+ libvlc_video_primaries_BT601_625 = 2,
+ libvlc_video_primaries_BT709 = 3,
+ libvlc_video_primaries_BT2020 = 4,
+ libvlc_video_primaries_DCI_P3 = 5,
+ libvlc_video_primaries_BT470_M = 6,
+} libvlc_video_color_primaries_t;
+
+/**
+ * Enumeration of the Video color spaces.
+ */
+typedef enum libvlc_video_color_space_t {
+ libvlc_video_colorspace_BT601 = 1,
+ libvlc_video_colorspace_BT709 = 2,
+ libvlc_video_colorspace_BT2020 = 3,
+} libvlc_video_color_space_t;
+
+/**
+ * Enumeration of the Video transfer functions.
+ */
+typedef enum libvlc_video_transfer_func_t {
+ libvlc_video_transfer_func_LINEAR = 1,
+ libvlc_video_transfer_func_SRGB = 2,
+ libvlc_video_transfer_func_BT470_BG = 3,
+ libvlc_video_transfer_func_BT470_M = 4,
+ libvlc_video_transfer_func_BT709 = 5,
+ libvlc_video_transfer_func_PQ = 6,
+ libvlc_video_transfer_func_SMPTE_240 = 7,
+ libvlc_video_transfer_func_HLG = 8,
+} libvlc_video_transfer_func_t;
+
+
+/**
+ * Callback prototype to allocate and lock a picture buffer.
+ *
+ * Whenever a new video frame needs to be decoded, the lock callback is
+ * invoked. Depending on the video chroma, one or three pixel planes of
+ * adequate dimensions must be returned via the second parameter. Those
+ * planes must be aligned on 32-bytes boundaries.
+ *
+ * \param[in] opaque private pointer as passed to libvlc_video_set_callbacks()
+ * \param[out] planes start address of the pixel planes (LibVLC allocates the array
+ * of void pointers, this callback must initialize the array)
+ * \return a private pointer for the display and unlock callbacks to identify
+ * the picture buffers
+ */
+typedef void *(*libvlc_video_lock_cb)(void *opaque, void **planes);
+
+/**
+ * Callback prototype to unlock a picture buffer.
+ *
+ * When the video frame decoding is complete, the unlock callback is invoked.
+ * This callback might not be needed at all. It is only an indication that the
+ * application can now read the pixel values if it needs to.
+ *
+ * \note A picture buffer is unlocked after the picture is decoded,
+ * but before the picture is displayed.
+ *
+ * \param[in] opaque private pointer as passed to libvlc_video_set_callbacks()
+ * \param[in] picture private pointer returned from the @ref libvlc_video_lock_cb
+ * callback
+ * \param[in] planes pixel planes as defined by the @ref libvlc_video_lock_cb
+ * callback (this parameter is only for convenience)
+ */
+typedef void (*libvlc_video_unlock_cb)(void *opaque, void *picture,
+ void *const *planes);
+
+/**
+ * Callback prototype to display a picture.
+ *
+ * When the video frame needs to be shown, as determined by the media playback
+ * clock, the display callback is invoked.
+ *
+ * \param[in] opaque private pointer as passed to libvlc_video_set_callbacks()
+ * \param[in] picture private pointer returned from the @ref libvlc_video_lock_cb
+ * callback
+ */
+typedef void (*libvlc_video_display_cb)(void *opaque, void *picture);
+
+/**
+ * Callback prototype to configure picture buffers format.
+ * This callback gets the format of the video as output by the video decoder
+ * and the chain of video filters (if any). It can opt to change any parameter
+ * as it needs. In that case, LibVLC will attempt to convert the video format
+ * (rescaling and chroma conversion) but these operations can be CPU intensive.
+ *
+ * \param[in,out] opaque pointer to the private pointer passed to
+ * libvlc_video_set_callbacks()
+ * \param[in,out] chroma pointer to the 4 bytes video format identifier
+ * \param[in,out] width pointer to the buffer width in pixels
+ * \param[in,out] height pointer to the buffer height in pixels
+ * \param[out] pitches table of scanline pitches in bytes for each pixel plane
+ * (the table is allocated by LibVLC)
+ * \param[out] lines table of scanlines count for each plane
+ * \return the number of picture buffers allocated, 0 indicates failure
+ *
+ * \version LibVLC 4.0.0 and later.
+ * \param[in] width pointer to display width - 1 in pixels
+ * \param[in] height pointer to display height - 1 in pixels
+ *
+ * \note
+ * For each pixels plane, the scanline pitch must be bigger than or equal to
+ * the number of bytes per pixel multiplied by the pixel width.
+ * Similarly, the number of scanlines must be bigger than of equal to
+ * the pixel height.
+ * Furthermore, we recommend that pitches and lines be multiple of 32
+ * to not break assumptions that might be held by optimized code
+ * in the video decoders, video filters and/or video converters.
+ */
+typedef unsigned (*libvlc_video_format_cb)(void **opaque, char *chroma,
+ unsigned *width, unsigned *height,
+ unsigned *pitches,
+ unsigned *lines);
+
+/**
+ * Callback prototype to configure picture buffers format.
+ *
+ * \param[in] opaque private pointer as passed to libvlc_video_set_format_callbacks()
+ * (and possibly modified by @ref libvlc_video_format_cb)
+ */
+typedef void (*libvlc_video_cleanup_cb)(void *opaque);
+
+
+/**
+ * Set callbacks and private data to render decoded video to a custom area
+ * in memory.
+ * Use libvlc_video_set_format() or libvlc_video_set_format_callbacks()
+ * to configure the decoded format.
+ *
+ * \warning Rendering video into custom memory buffers is considerably less
+ * efficient than rendering in a custom window as normal.
+ *
+ * For optimal performances, VLC media player renders into a custom window, and
+ * does not use this function and associated callbacks. It is highly
+ * recommended that other LibVLC-based application do likewise.
+ * To embed video in a window, use libvlc_media_player_set_xwindow() or
+ * equivalent depending on the operating system.
+ *
+ * If window embedding does not fit the application use case, then a custom
+ * LibVLC video output display plugin is required to maintain optimal video
+ * rendering performances.
+ *
+ * The following limitations affect performance:
+ * - Hardware video decoding acceleration will either be disabled completely,
+ * or require (relatively slow) copy from video/DSP memory to main memory.
+ * - Sub-pictures (subtitles, on-screen display, etc.) must be blent into the
+ * main picture by the CPU instead of the GPU.
+ * - Depending on the video format, pixel format conversion, picture scaling,
+ * cropping and/or picture re-orientation, must be performed by the CPU
+ * instead of the GPU.
+ * - Memory copying is required between LibVLC reference picture buffers and
+ * application buffers (between lock and unlock callbacks).
+ *
+ * \param mp the media player
+ * \param lock callback to lock video memory (must not be NULL)
+ * \param unlock callback to unlock video memory (or NULL if not needed)
+ * \param display callback to display video (or NULL if not needed)
+ * \param opaque private pointer for the three callbacks (as first parameter)
+ * \version LibVLC 1.1.1 or later
+ */
+LIBVLC_API
+void libvlc_video_set_callbacks( libvlc_media_player_t *mp,
+ libvlc_video_lock_cb lock,
+ libvlc_video_unlock_cb unlock,
+ libvlc_video_display_cb display,
+ void *opaque );
+
+/**
+ * Set decoded video chroma and dimensions.
+ * This only works in combination with libvlc_video_set_callbacks(),
+ * and is mutually exclusive with libvlc_video_set_format_callbacks().
+ *
+ * \param mp the media player
+ * \param chroma a four-characters string identifying the chroma
+ * (e.g. "RV32" or "YUYV")
+ * \param width pixel width
+ * \param height pixel height
+ * \param pitch line pitch (in bytes)
+ * \version LibVLC 1.1.1 or later
+ * \bug All pixel planes are expected to have the same pitch.
+ * To use the YCbCr color space with chrominance subsampling,
+ * consider using libvlc_video_set_format_callbacks() instead.
+ */
+LIBVLC_API
+void libvlc_video_set_format( libvlc_media_player_t *mp, const char *chroma,
+ unsigned width, unsigned height,
+ unsigned pitch );
+
+/**
+ * Set decoded video chroma and dimensions. This only works in combination with
+ * libvlc_video_set_callbacks().
+ *
+ * \param mp the media player
+ * \param setup callback to select the video format (cannot be NULL)
+ * \param cleanup callback to release any allocated resources (or NULL)
+ * \version LibVLC 2.0.0 or later
+ */
+LIBVLC_API
+void libvlc_video_set_format_callbacks( libvlc_media_player_t *mp,
+ libvlc_video_format_cb setup,
+ libvlc_video_cleanup_cb cleanup );
+
+
+typedef struct libvlc_video_setup_device_cfg_t
+{
+ bool hardware_decoding; /** set if D3D11_CREATE_DEVICE_VIDEO_SUPPORT is needed for D3D11 */
+} libvlc_video_setup_device_cfg_t;
+
+typedef struct libvlc_video_setup_device_info_t
+{
+ union {
+ struct {
+ void *device_context; /** ID3D11DeviceContext* */
+ void *context_mutex; /** Windows Mutex HANDLE to protect ID3D11DeviceContext usage */
+ } d3d11;
+ struct {
+ void *device; /** IDirect3D9* */
+ int adapter; /** Adapter to use with the IDirect3D9* */
+ } d3d9;
+ };
+} libvlc_video_setup_device_info_t;
+
+/**
+ * Callback prototype called to initialize user data.
+ * Setup the rendering environment.
+ *
+ * \param[in,out] opaque private pointer passed to the @a libvlc_video_set_output_callbacks()
+ * on input. The callback can change this value on output to be
+ * passed to all the other callbacks set on @a libvlc_video_set_output_callbacks().
+ * \param[in] cfg requested configuration of the video device
+ * \param[out] out libvlc_video_setup_device_info_t* to fill
+ * \return true on success
+ * \version LibVLC 4.0.0 or later
+ *
+ * For \ref libvlc_video_engine_d3d9 the output must be a IDirect3D9*.
+ * A reference to this object is held until the \ref libvlc_video_output_cleanup_cb is called.
+ * the device must be created with D3DPRESENT_PARAMETERS.hDeviceWindow set to 0.
+ *
+ * For \ref libvlc_video_engine_d3d11 the output must be a ID3D11DeviceContext*.
+ * A reference to this object is held until the \ref libvlc_video_output_cleanup_cb is called.
+ * The ID3D11Device used to create ID3D11DeviceContext must have multithreading enabled.
+ *
+ * If the ID3D11DeviceContext is used outside of the callbacks called by libvlc, the host
+ * MUST use a mutex to protect the access to the ID3D11DeviceContext of libvlc. This mutex
+ * value is set on d3d11.context_mutex. If the ID3D11DeviceContext is not used outside of
+ * the callbacks, the mutex d3d11.context_mutex may be NULL.
+ */
+typedef bool (*libvlc_video_output_setup_cb)(void **opaque,
+ const libvlc_video_setup_device_cfg_t *cfg,
+ libvlc_video_setup_device_info_t *out);
+
+
+/**
+ * Callback prototype called to release user data
+ *
+ * \param[in] opaque private pointer set on the opaque parameter of @a libvlc_video_output_setup_cb()
+ * \version LibVLC 4.0.0 or later
+ */
+typedef void (*libvlc_video_output_cleanup_cb)(void* opaque);
+
+typedef struct libvlc_video_render_cfg_t
+{
+ /** rendering video width in pixel */
+ unsigned width;
+ /** rendering video height in pixel */
+ unsigned height;
+ /** rendering video bit depth in bits per channel */
+ unsigned bitdepth;
+ /** video is full range or studio/limited range */
+ bool full_range;
+ /** video color space */
+ libvlc_video_color_space_t colorspace;
+ /** video color primaries */
+ libvlc_video_color_primaries_t primaries;
+ /** video transfer function */
+ libvlc_video_transfer_func_t transfer;
+ /** device used for rendering, IDirect3DDevice9* for D3D9 */
+ void *device;
+} libvlc_video_render_cfg_t;
+
+typedef struct libvlc_video_output_cfg_t
+{
+ union {
+ /** The rendering DXGI_FORMAT for \ref libvlc_video_engine_d3d11. */
+ int dxgi_format;
+ /** The rendering D3DFORMAT for \ref libvlc_video_engine_d3d9. */
+ uint32_t d3d9_format;
+ /** The rendering GLint GL_RGBA or GL_RGB for
+ * \ref libvlc_video_engine_opengl and for
+ * \ref libvlc_video_engine_gles2. */
+ int opengl_format;
+ /** currently unused */
+ void *p_surface;
+ struct {
+ /** Pointer to an ANativeWindow, used for video rendering */
+ void *video;
+ /** Pointer to an ANativeWindow, used for subtitles rendering, if
+ * blending subtitles into the video surface is not possible (when
+ * using MediaCodec with direct hw rendering) */
+ void *subtitle;
+ } anw;
+ };
+ /** Video is full range or studio/limited range. */
+ bool full_range;
+ /** video color space */
+ libvlc_video_color_space_t colorspace;
+ /** video color primaries */
+ libvlc_video_color_primaries_t primaries;
+ /** video transfer function */
+ libvlc_video_transfer_func_t transfer;
+ /** video surface orientation */
+ libvlc_video_orient_t orientation;
+} libvlc_video_output_cfg_t;
+
+/**
+ * Callback prototype called on video size changes.
+ * Update the rendering output setup.
+ *
+ * \param[in] opaque private pointer set on the opaque parameter of @a libvlc_video_output_setup_cb()
+ * \param[in] cfg configuration of the video that will be rendered
+ * \param[out] output configuration describing with how the rendering is setup
+ * \version LibVLC 4.0.0 or later
+ *
+ * \note the configuration device for Direct3D9 is the IDirect3DDevice9 that VLC
+ * uses to render. The host must set a Render target and call Present()
+ * when it needs the drawing from VLC to be done. This object is not valid
+ * anymore after Cleanup is called.
+ * Tone mapping, range and color conversion will be done depending on the
+ * values set in the output structure. It can be ignored in the \ref
+ * libvlc_video_engine_anw case.
+ */
+typedef bool (*libvlc_video_update_output_cb)(void* opaque, const libvlc_video_render_cfg_t *cfg,
+ libvlc_video_output_cfg_t *output );
+
+
+/**
+ * Callback prototype called after performing drawing calls.
+ *
+ * This callback is called outside of libvlc_video_makeCurrent_cb current/not-current
+ * calls.
+ *
+ * \param[in] opaque private pointer set on the opaque parameter of @a libvlc_video_output_setup_cb()
+ * \version LibVLC 4.0.0 or later
+ */
+typedef void (*libvlc_video_swap_cb)(void* opaque);
+
+/**
+ * Callback prototype to set up the OpenGL context for rendering.
+ * Tell the host the rendering is about to start/has finished.
+ *
+ * \param[in] opaque private pointer set on the opaque parameter of @a libvlc_video_output_setup_cb()
+ * \param[in] enter true to set the context as current, false to unset it
+ * \return true on success
+ * \version LibVLC 4.0.0 or later
+ *
+ * On Direct3D11 the following may change on the provided ID3D11DeviceContext*
+ * between \p enter being true and \p enter being false:
+ * - IASetPrimitiveTopology()
+ * - IASetInputLayout()
+ * - IASetVertexBuffers()
+ * - IASetIndexBuffer()
+ * - VSSetConstantBuffers()
+ * - VSSetShader()
+ * - PSSetSamplers()
+ * - PSSetConstantBuffers()
+ * - PSSetShaderResources()
+ * - PSSetShader()
+ * - RSSetViewports()
+ * - DrawIndexed()
+ */
+typedef bool (*libvlc_video_makeCurrent_cb)(void* opaque, bool enter);
+
+/**
+ * Callback prototype to load opengl functions
+ *
+ * \param[in] opaque private pointer set on the opaque parameter of @a libvlc_video_output_setup_cb()
+ * \param fct_name name of the opengl function to load
+ * \return a pointer to the named OpenGL function the NULL otherwise
+ * \version LibVLC 4.0.0 or later
+ */
+typedef void* (*libvlc_video_getProcAddress_cb)(void* opaque, const char* fct_name);
+
+typedef struct libvlc_video_frame_hdr10_metadata_t
+{
+ /* similar to SMPTE ST 2086 mastering display color volume */
+ uint16_t RedPrimary[2];
+ uint16_t GreenPrimary[2];
+ uint16_t BluePrimary[2];
+ uint16_t WhitePoint[2];
+ unsigned int MaxMasteringLuminance;
+ unsigned int MinMasteringLuminance;
+ uint16_t MaxContentLightLevel;
+ uint16_t MaxFrameAverageLightLevel;
+} libvlc_video_frame_hdr10_metadata_t;
+
+typedef enum libvlc_video_metadata_type_t {
+ libvlc_video_metadata_frame_hdr10, /**< libvlc_video_frame_hdr10_metadata_t */
+} libvlc_video_metadata_type_t;
+
+/**
+ * Callback prototype to receive metadata before rendering.
+ *
+ * \param[in] opaque private pointer passed to the @a libvlc_video_set_output_callbacks()
+ * \param[in] type type of data passed in metadata
+ * \param[in] metadata the type of metadata
+ * \version LibVLC 4.0.0 or later
+ */
+typedef void (*libvlc_video_frameMetadata_cb)(void* opaque, libvlc_video_metadata_type_t type, const void *metadata);
+
+/**
+ * Enumeration of the Video engine to be used on output.
+ * can be passed to @a libvlc_video_set_output_callbacks
+ */
+typedef enum libvlc_video_engine_t {
+ /** Disable rendering engine */
+ libvlc_video_engine_disable,
+ libvlc_video_engine_opengl,
+ libvlc_video_engine_gles2,
+ /** Direct3D11 rendering engine */
+ libvlc_video_engine_d3d11,
+ /** Direct3D9 rendering engine */
+ libvlc_video_engine_d3d9,
+
+ /**
+ * Android ANativeWindow. It can be set in \ref libvlc_video_output_cfg_t
+ * from the \ref libvlc_video_update_output_cb callback. The ANativeWindow
+ * can be created via:
+ * - 'ANativeWindow_fromSurface': from a JAVA SurfaceView
+ * - 'AImageReader_getWindow()': from an 'AImageReader' created with the
+ * following arguments: \verbatim
+ AImageReader_newWithUsage(1, 1 AIMAGE_FORMAT_PRIVATE,
+ AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE,
+ maxImages, &reader);
+ \endverbatim
+ * The width and height from \ref libvlc_video_render_cfg_t should be
+ * ignored as the video size is overridden by the producer (MediaCodec or
+ * EGL vout).
+ */
+ libvlc_video_engine_anw,
+} libvlc_video_engine_t;
+
+
+/** Callback type that can be called to request a render size changes.
+ *
+ * libvlc will provide a callback of this type when calling \ref libvlc_video_output_set_window_cb.
+ *
+ * \param report_opaque parameter passed to \ref libvlc_video_output_set_window_cb. [IN]
+ * \param width new rendering width requested. [IN]
+ * \param height new rendering height requested. [IN]
+ */
+typedef void( *libvlc_video_output_resize_cb )( void *report_opaque, unsigned width, unsigned height );
+
+
+/**
+ * Enumeration of the different mouse buttons that can be reported for user interaction
+ * can be passed to \ref libvlc_video_output_mouse_press_cb and \ref libvlc_video_output_mouse_release_cb.
+ */
+typedef enum libvlc_video_output_mouse_button_t {
+ libvlc_video_output_mouse_button_left = 0,
+ libvlc_video_output_mouse_button_middle = 1,
+ libvlc_video_output_mouse_button_right = 2
+} libvlc_video_output_mouse_button_t;
+
+
+/** Callback type that can be called to notify the mouse position when hovering the render surface.
+ *
+ * libvlc will provide a callback of this type when calling \ref libvlc_video_output_set_window_cb.
+ *
+ * The position (0,0) denotes the top left corner, bottom right corner position
+ * is (width,height) as reported by \ref libvlc_video_output_resize_cb.
+ *
+ * \param opaque parameter passed to \ref libvlc_video_output_set_window_cb. [IN]
+ * \param x horizontal mouse position in \ref libvlc_video_output_resize_cb coordinates. [IN]
+ * \param y vertical mouse position in \ref libvlc_video_output_resize_cb coordinates. [IN]
+ */
+typedef void (*libvlc_video_output_mouse_move_cb)(void *opaque, int x, int y);
+
+/** Callback type that can be called to notify when a mouse button is pressed in the rendering surface.
+ *
+ * libvlc will provide a callback of this type when calling \ref libvlc_video_output_set_window_cb.
+ *
+ * The button event will be reported at the last position provided by \ref libvlc_video_output_mouse_move_cb
+ *
+ * \param opaque parameter passed to \ref libvlc_video_output_set_window_cb. [IN]
+ * \param button represent the button pressed, see \ref libvlc_video_output_mouse_button_t for available buttons. [IN]
+ */
+typedef void (*libvlc_video_output_mouse_press_cb)(void *opaque, libvlc_video_output_mouse_button_t button);
+
+/** Callback type that can be called to notify when a mouse button is released in the rendering surface.
+ *
+ * libvlc will provide a callback of this type when calling \ref libvlc_video_output_set_window_cb.
+ *
+ * The button event will be reported at the last position provided by \ref libvlc_video_output_mouse_move_cb.
+ *
+ * \param opaque parameter passed to \ref libvlc_video_output_set_window_cb. [IN]
+ * \param button represent the button released, see \ref libvlc_video_output_mouse_button_t for available buttons. [IN]
+ */
+typedef void (*libvlc_video_output_mouse_release_cb)(void *opaque, libvlc_video_output_mouse_button_t button);
+
+/** Set the callback to call when the host app resizes the rendering area.
+ *
+ * This allows text rendering and aspect ratio to be handled properly when the host
+ * rendering size changes and to provide mouse.
+ *
+ * It may be called before the \ref libvlc_video_output_setup_cb callback.
+ *
+ * \warning These callbacks cannot be called concurrently, the caller is responsible for serialization
+ *
+ * \param[in] opaque private pointer set on the opaque parameter of @a libvlc_video_output_setup_cb()
+ * \param[in] report_size_change callback which must be called when the host size changes.
+ * The callback is valid until another call to \ref libvlc_video_output_set_window_cb
+ * is done. This may be called from any thread.
+ * \param[in] report_mouse_move callback which must be called when the mouse position change on the video surface.
+ * The coordinates are relative to the size reported through the \p report_size_change.
+ * This may be called from any thread.
+ * \param[in] report_mouse_pressed callback which must be called when a mouse button is pressed on the video surface,
+ * The position of the event is the last position reported by the report_mouse_move callback. This may be
+ * called from any thread.
+ * \param[in] report_mouse_released callback which must be called when a mouse button is released on the video surface,
+ * The position of the event is the last position reported by the report_mouse_move callback. This may be
+ * called from any thread.
+ * \param[in] report_opaque private pointer to pass to the \p report_size_change callback.
+ */
+typedef void( *libvlc_video_output_set_window_cb )( void *opaque,
+ libvlc_video_output_resize_cb report_size_change,
+ libvlc_video_output_mouse_move_cb report_mouse_move,
+ libvlc_video_output_mouse_press_cb report_mouse_pressed,
+ libvlc_video_output_mouse_release_cb report_mouse_released,
+ void *report_opaque );
+
+/** Tell the host the rendering for the given plane is about to start
+ *
+ * \param[in] opaque private pointer set on the opaque parameter of @a libvlc_video_output_setup_cb()
+ * \param plane number of the rendering plane to select
+ * \param output handle of the rendering output for the given plane
+ * \return true on success
+ * \version LibVLC 4.0.0 or later
+ *
+ * \note This is only used with \ref libvlc_video_engine_d3d11.
+ *
+ * The output parameter receives the ID3D11RenderTargetView* to use for rendering
+ * the plane.
+ *
+ * If this callback is not used (set to NULL in @a libvlc_video_set_output_callbacks())
+ * OMSetRenderTargets has to be set during the @a libvlc_video_makeCurrent_cb()
+ * entering call.
+ *
+ * The number of planes depend on the DXGI_FORMAT returned during the
+ * @a libvlc_video_update_output_cb() call. It's usually one plane except for
+ * semi-planar formats like DXGI_FORMAT_NV12 or DXGI_FORMAT_P010.
+ *
+ * This callback is called between libvlc_video_makeCurrent_cb current/not-current
+ * calls.
+ */
+typedef bool( *libvlc_video_output_select_plane_cb )( void *opaque, size_t plane, void *output );
+
+/**
+ * Set callbacks and data to render decoded video to a custom texture
+ *
+ * \warning VLC will perform video rendering in its own thread and at its own rate,
+ * You need to provide your own synchronisation mechanism.
+ *
+ * \param mp the media player
+ * \param engine the GPU engine to use
+ * \param setup_cb callback called to initialize user data
+ * \param cleanup_cb callback called to clean up user data
+ * \param window_cb callback called to setup the window
+ * \param update_output_cb callback to get the rendering format of the host (cannot be NULL)
+ * \param swap_cb callback called after rendering a video frame (can only be
+ * NULL when using \ref libvlc_video_engine_anw)
+ * \param makeCurrent_cb callback called to enter/leave the rendering context
+ * (can only be NULL when using \ref libvlc_video_engine_anw)
+ * \param getProcAddress_cb opengl function loading callback (cannot be NULL
+ * for \ref libvlc_video_engine_opengl and for \ref libvlc_video_engine_gles2)
+ * \param metadata_cb callback to provide frame metadata (D3D11 only)
+ * \param select_plane_cb callback to select different D3D11 rendering targets
+ * \param opaque private pointer passed to callbacks
+ *
+ * \note the \p setup_cb and \p cleanup_cb may be called more than once per
+ * playback.
+ *
+ * \retval true engine selected and callbacks set
+ * \retval false engine type unknown, callbacks not set
+ * \version LibVLC 4.0.0 or later
+ */
+LIBVLC_API
+bool libvlc_video_set_output_callbacks( libvlc_media_player_t *mp,
+ libvlc_video_engine_t engine,
+ libvlc_video_output_setup_cb setup_cb,
+ libvlc_video_output_cleanup_cb cleanup_cb,
+ libvlc_video_output_set_window_cb window_cb,
+ libvlc_video_update_output_cb update_output_cb,
+ libvlc_video_swap_cb swap_cb,
+ libvlc_video_makeCurrent_cb makeCurrent_cb,
+ libvlc_video_getProcAddress_cb getProcAddress_cb,
+ libvlc_video_frameMetadata_cb metadata_cb,
+ libvlc_video_output_select_plane_cb select_plane_cb,
+ void* opaque );
+
+/**
+ * Helper to setup output_callbacks for \ref libvlc_video_engine_anw
+ */
+static inline bool
+libvlc_video_set_anw_callbacks( libvlc_media_player_t *mp,
+ libvlc_video_output_setup_cb setup_cb,
+ libvlc_video_output_cleanup_cb cleanup_cb,
+ libvlc_video_update_output_cb update_output_cb,
+ void *opaque )
+{
+ return libvlc_video_set_output_callbacks( mp, libvlc_video_engine_anw,
+ setup_cb, cleanup_cb, NULL,
+ update_output_cb, NULL, NULL,
+ NULL, NULL, NULL, opaque );
+}
+
+/**
+ * Set the handler where the media player should display its video output.
+ *
+ * The drawable is an `NSObject` that require responding to two selectors
+ * like in this protocol:
+ *
+ * @code{.m}
+ * @protocol VLCDrawable
+ * - (void)addSubview:(VLCView *)view;
+ * - (CGRect)bounds;
+ * @end
+ * @endcode
+ *
+ * In this protocol `VLCView` type can either be a `UIView` or a `NSView` type
+ * class.
+ * VLCDrawable protocol conformance isn't mandatory but a drawable must respond
+ * to both `addSubview:` and `bounds` selectors.
+ *
+ * Additionally, a drawable can also conform to the `VLCPictureInPictureDrawable`
+ * protocol to allow picture in picture support :
+ *
+ * @code{.m}
+ * @protocol VLCPictureInPictureMediaControlling
+ * - (void)play;
+ * - (void)pause;
+ * - (void)seekBy:(int64_t)offset completion:(dispatch_block_t)completion;;
+ * - (int64_t)mediaLength;
+ * - (int64_t)mediaTime;
+ * - (BOOL)isMediaSeekable;
+ * - (BOOL)isMediaPlaying;
+ * @end
+ *
+ * @protocol VLCPictureInPictureWindowControlling
+ * - (void)startPictureInPicture;
+ * - (void)stopPictureInPicture;
+ * - (void)invalidatePlaybackState;
+ * @end
+ *
+ * @protocol VLCPictureInPictureDrawable
+ * - (id) mediaController;
+ * - (void (^)(id)) pictureInPictureReady;
+ * @end
+ * @endcode
+ *
+ * Be aware that full `VLCPictureInPictureDrawable` conformance is mandatory to
+ * enable picture in picture support and that time values in
+ * `VLCPictureInPictureMediaControlling` methods are expressed in milliseconds.
+ *
+ * If you want to use it along with Qt see the QMacCocoaViewContainer. Then
+ * the following code should work:
+ * @code{.mm}
+ * {
+ * NSView *video = [[NSView alloc] init];
+ * QMacCocoaViewContainer *container = new QMacCocoaViewContainer(video, parent);
+ * libvlc_media_player_set_nsobject(mp, video);
+ * [video release];
+ * }
+ * @endcode
+ *
+ * You can find a live example in VLCVideoView in VLCKit.framework.
+ *
+ * \param p_mi the Media Player
+ * \param drawable the drawable that is either an NSView, a UIView or any
+ * NSObject responding to `addSubview:` and `bounds` selectors
+ */
+LIBVLC_API void libvlc_media_player_set_nsobject ( libvlc_media_player_t *p_mi, void * drawable );
+
+/**
+ * Get the NSView handler previously set with libvlc_media_player_set_nsobject().
+ *
+ * \param p_mi the Media Player
+ * \return the NSView handler or 0 if none where set
+ */
+LIBVLC_API void * libvlc_media_player_get_nsobject ( libvlc_media_player_t *p_mi );
+
+/**
+ * Set an X Window System drawable where the media player should render its
+ * video output. The call takes effect when the playback starts. If it is
+ * already started, it might need to be stopped before changes apply.
+ * If LibVLC was built without X11 output support, then this function has no
+ * effects.
+ *
+ * By default, LibVLC will capture input events on the video rendering area.
+ * Use libvlc_video_set_mouse_input() and libvlc_video_set_key_input() to
+ * disable that and deliver events to the parent window / to the application
+ * instead. By design, the X11 protocol delivers input events to only one
+ * recipient.
+ *
+ * \warning
+ * The application must call the XInitThreads() function from Xlib before
+ * libvlc_new(), and before any call to XOpenDisplay() directly or via any
+ * other library. Failure to call XInitThreads() will seriously impede LibVLC
+ * performance. Calling XOpenDisplay() before XInitThreads() will eventually
+ * crash the process. That is a limitation of Xlib.
+ *
+ * \param p_mi media player
+ * \param drawable X11 window ID
+ *
+ * \note
+ * The specified identifier must correspond to an existing Input/Output class
+ * X11 window. Pixmaps are not currently supported. The default X11
+ * server is assumed, i.e. that specified in the DISPLAY environment variable.
+ *
+ * \warning
+ * LibVLC can deal with invalid X11 handle errors, however some display drivers
+ * (EGL, GLX, VA and/or VDPAU) can unfortunately not. Thus the window handle
+ * must remain valid until playback is stopped, otherwise the process may
+ * abort or crash.
+ *
+ * \bug
+ * No more than one window handle per media player instance can be specified.
+ * If the media has multiple simultaneously active video tracks, extra tracks
+ * will be rendered into external windows beyond the control of the
+ * application.
+ */
+LIBVLC_API void libvlc_media_player_set_xwindow(libvlc_media_player_t *p_mi,
+ uint32_t drawable);
+
+/**
+ * Get the X Window System window identifier previously set with
+ * libvlc_media_player_set_xwindow(). Note that this will return the identifier
+ * even if VLC is not currently using it (for instance if it is playing an
+ * audio-only input).
+ *
+ * \param p_mi the Media Player
+ * \return an X window ID, or 0 if none where set.
+ */
+LIBVLC_API uint32_t libvlc_media_player_get_xwindow ( libvlc_media_player_t *p_mi );
+
+/**
+ * Set a Win32/Win64 API window handle (HWND) where the media player should
+ * render its video output. If LibVLC was built without Win32/Win64 API output
+ * support, then this has no effects.
+ *
+ * \warning the HWND must have the WS_CLIPCHILDREN set in its style.
+ *
+ * \param p_mi the Media Player
+ * \param drawable windows handle of the drawable
+ */
+LIBVLC_API void libvlc_media_player_set_hwnd ( libvlc_media_player_t *p_mi, void *drawable );
+
+/**
+ * Get the Windows API window handle (HWND) previously set with
+ * libvlc_media_player_set_hwnd(). The handle will be returned even if LibVLC
+ * is not currently outputting any video to it.
+ *
+ * \param p_mi the Media Player
+ * \return a window handle or NULL if there are none.
+ */
+LIBVLC_API void *libvlc_media_player_get_hwnd ( libvlc_media_player_t *p_mi );
+
+/**
+ * Set the android context.
+ *
+ * \version LibVLC 3.0.0 and later.
+ *
+ * \param p_mi the media player
+ * \param p_awindow_handler org.videolan.libvlc.AWindow jobject owned by the
+ * org.videolan.libvlc.MediaPlayer class from the libvlc-android project.
+ */
+LIBVLC_API void libvlc_media_player_set_android_context( libvlc_media_player_t *p_mi,
+ void *p_awindow_handler );
+
+/**
+ * Callback prototype for audio playback.
+ *
+ * The LibVLC media player decodes and post-processes the audio signal
+ * asynchronously (in an internal thread). Whenever audio samples are ready
+ * to be queued to the output, this callback is invoked.
+ *
+ * The number of samples provided per invocation may depend on the file format,
+ * the audio coding algorithm, the decoder plug-in, the post-processing
+ * filters and timing. Application must not assume a certain number of samples.
+ *
+ * The exact format of audio samples is determined by libvlc_audio_set_format()
+ * or libvlc_audio_set_format_callbacks() as is the channels layout.
+ *
+ * Note that the number of samples is per channel. For instance, if the audio
+ * track sampling rate is 48000 Hz, then 1200 samples represent 25 milliseconds
+ * of audio signal - regardless of the number of audio channels.
+ *
+ * \param[in] data data pointer as passed to libvlc_audio_set_callbacks()
+ * \param[in] samples pointer to a table of audio samples to play back
+ * \param count number of audio samples to play back
+ * \param pts expected play time stamp (see libvlc_delay())
+ */
+typedef void (*libvlc_audio_play_cb)(void *data, const void *samples,
+ unsigned count, int64_t pts);
+
+/**
+ * Callback prototype for audio pause.
+ *
+ * LibVLC invokes this callback to pause audio playback.
+ *
+ * \note The pause callback is never called if the audio is already paused.
+ * \param[in] data data pointer as passed to libvlc_audio_set_callbacks()
+ * \param pts time stamp of the pause request (should be elapsed already)
+ */
+typedef void (*libvlc_audio_pause_cb)(void *data, int64_t pts);
+
+/**
+ * Callback prototype for audio resumption.
+ *
+ * LibVLC invokes this callback to resume audio playback after it was
+ * previously paused.
+ *
+ * \note The resume callback is never called if the audio is not paused.
+ * \param[in] data data pointer as passed to libvlc_audio_set_callbacks()
+ * \param pts time stamp of the resumption request (should be elapsed already)
+ */
+typedef void (*libvlc_audio_resume_cb)(void *data, int64_t pts);
+
+/**
+ * Callback prototype for audio buffer flush.
+ *
+ * LibVLC invokes this callback if it needs to discard all pending buffers and
+ * stop playback as soon as possible. This typically occurs when the media is
+ * stopped.
+ *
+ * \param[in] data data pointer as passed to libvlc_audio_set_callbacks()
+ */
+typedef void (*libvlc_audio_flush_cb)(void *data, int64_t pts);
+
+/**
+ * Callback prototype for audio buffer drain.
+ *
+ * LibVLC may invoke this callback when the decoded audio track is ending.
+ * There will be no further decoded samples for the track, but playback should
+ * nevertheless continue until all already pending buffers are rendered.
+ *
+ * \param[in] data data pointer as passed to libvlc_audio_set_callbacks()
+ */
+typedef void (*libvlc_audio_drain_cb)(void *data);
+
+/**
+ * Callback prototype for audio volume change.
+ * \param[in] data data pointer as passed to libvlc_audio_set_callbacks()
+ * \param volume software volume (1. = nominal, 0. = mute)
+ * \param mute muted flag
+ */
+typedef void (*libvlc_audio_set_volume_cb)(void *data,
+ float volume, bool mute);
+
+/**
+ * Sets callbacks and private data for decoded audio.
+ *
+ * Use libvlc_audio_set_format() or libvlc_audio_set_format_callbacks()
+ * to configure the decoded audio format.
+ *
+ * \note The audio callbacks override any other audio output mechanism.
+ * If the callbacks are set, LibVLC will not output audio in any way.
+ *
+ * \param mp the media player
+ * \param play callback to play audio samples (must not be NULL)
+ * \param pause callback to pause playback (or NULL to ignore)
+ * \param resume callback to resume playback (or NULL to ignore)
+ * \param flush callback to flush audio buffers (or NULL to ignore)
+ * \param drain callback to drain audio buffers (or NULL to ignore)
+ * \param opaque private pointer for the audio callbacks (as first parameter)
+ * \version LibVLC 2.0.0 or later
+ */
+LIBVLC_API
+void libvlc_audio_set_callbacks( libvlc_media_player_t *mp,
+ libvlc_audio_play_cb play,
+ libvlc_audio_pause_cb pause,
+ libvlc_audio_resume_cb resume,
+ libvlc_audio_flush_cb flush,
+ libvlc_audio_drain_cb drain,
+ void *opaque );
+
+/**
+ * Set callbacks and private data for decoded audio. This only works in
+ * combination with libvlc_audio_set_callbacks().
+ * Use libvlc_audio_set_format() or libvlc_audio_set_format_callbacks()
+ * to configure the decoded audio format.
+ *
+ * \param mp the media player
+ * \param set_volume callback to apply audio volume,
+ * or NULL to apply volume in software
+ * \version LibVLC 2.0.0 or later
+ */
+LIBVLC_API
+void libvlc_audio_set_volume_callback( libvlc_media_player_t *mp,
+ libvlc_audio_set_volume_cb set_volume );
+
+/**
+ * Callback prototype to setup the audio playback.
+ *
+ * This is called when the media player needs to create a new audio output.
+ * \param[in,out] opaque pointer to the data pointer passed to
+ * libvlc_audio_set_callbacks()
+ * \param[in,out] format 4 bytes sample format
+ * \param[in,out] rate sample rate
+ * \param[in,out] channels channels count
+ * \return 0 on success, anything else to skip audio playback
+ */
+typedef int (*libvlc_audio_setup_cb)(void **opaque, char *format, unsigned *rate,
+ unsigned *channels);
+
+/**
+ * Callback prototype for audio playback cleanup.
+ *
+ * This is called when the media player no longer needs an audio output.
+ * \param[in] opaque data pointer as passed to libvlc_audio_set_callbacks()
+ */
+typedef void (*libvlc_audio_cleanup_cb)(void *opaque);
+
+/**
+ * Sets decoded audio format via callbacks.
+ *
+ * This only works in combination with libvlc_audio_set_callbacks().
+ *
+ * \param mp the media player
+ * \param setup callback to select the audio format (cannot be NULL)
+ * \param cleanup callback to release any allocated resources (or NULL)
+ * \version LibVLC 2.0.0 or later
+ */
+LIBVLC_API
+void libvlc_audio_set_format_callbacks( libvlc_media_player_t *mp,
+ libvlc_audio_setup_cb setup,
+ libvlc_audio_cleanup_cb cleanup );
+
+/**
+ * Sets a fixed decoded audio format.
+ *
+ * This only works in combination with libvlc_audio_set_callbacks(),
+ * and is mutually exclusive with libvlc_audio_set_format_callbacks().
+ *
+ * The supported formats are:
+ * - "S16N" for signed 16-bit PCM
+ * - "S32N" for signed 32-bit PCM
+ * - "FL32" for single precision IEEE 754
+ *
+ * All supported formats use the native endianness.
+ * If there are more than one channel, samples are interleaved.
+ *
+ * \param mp the media player
+ * \param format a four-characters string identifying the sample format
+ * \param rate sample rate (expressed in Hz)
+ * \param channels channels count
+ * \version LibVLC 2.0.0 or later
+ */
+LIBVLC_API
+void libvlc_audio_set_format( libvlc_media_player_t *mp, const char *format,
+ unsigned rate, unsigned channels );
+
+/** \bug This might go away ... to be replaced by a broader system */
+
+/**
+ * Get the current movie length (in ms).
+ *
+ * \param p_mi the Media Player
+ * \return the movie length (in ms), or -1 if there is no media.
+ */
+LIBVLC_API libvlc_time_t libvlc_media_player_get_length( libvlc_media_player_t *p_mi );
+
+/**
+ * Get the current movie time (in ms).
+ *
+ * \param p_mi the Media Player
+ * \return the movie time (in ms), or -1 if there is no media.
+ */
+LIBVLC_API libvlc_time_t libvlc_media_player_get_time( libvlc_media_player_t *p_mi );
+
+/**
+ * Set the movie time (in ms).
+ *
+ * This has no effect if no media is being played.
+ * Not all formats and protocols support this.
+ *
+ * \param p_mi the Media Player
+ * \param i_time the movie time (in ms).
+ * \param b_fast prefer fast seeking or precise seeking
+ * \return 0 on success, -1 on error
+ */
+LIBVLC_API int libvlc_media_player_set_time( libvlc_media_player_t *p_mi,
+ libvlc_time_t i_time, bool b_fast );
+
+/**
+ * Jump the movie time (in ms).
+ *
+ * This will trigger a precise and relative seek (from the current time).
+ * This has no effect if no media is being played.
+ * Not all formats and protocols support this.
+ *
+ * \param p_mi the Media Player
+ * \param i_time the movie time (in ms).
+ * \return 0 on success, -1 on error
+ * \version LibVLC 4.0.0 and later.
+ */
+LIBVLC_API int libvlc_media_player_jump_time( libvlc_media_player_t *p_mi,
+ libvlc_time_t i_time );
+
+/**
+ * Get movie position as percentage between 0.0 and 1.0.
+ *
+ * \param p_mi the Media Player
+ * \return movie position, or -1. in case of error
+ */
+LIBVLC_API double libvlc_media_player_get_position( libvlc_media_player_t *p_mi );
+
+/**
+ * Set movie position as percentage between 0.0 and 1.0.
+ * This has no effect if playback is not enabled.
+ * This might not work depending on the underlying input format and protocol.
+ *
+ * \param p_mi the Media Player
+ * \param b_fast prefer fast seeking or precise seeking
+ * \param f_pos the position
+ * \return 0 on success, -1 on error
+ */
+LIBVLC_API int libvlc_media_player_set_position( libvlc_media_player_t *p_mi,
+ double f_pos, bool b_fast );
+
+/**
+ * Enable A to B loop for the current media by setting the start time and end
+ * time
+ *
+ * The B time must be higher than the A time.
+ *
+ * \param p_mi the Media Player
+ * \param a_time start time for the loop (in ms)
+ * \param b_time end time for the loop (in ms)
+ * \return 0 on success, -1 on error
+ * \version LibVLC 4.0.0 and later.
+ */
+LIBVLC_API int
+libvlc_media_player_set_abloop_time( libvlc_media_player_t *p_mi,
+ libvlc_time_t a_time, libvlc_time_t b_time );
+
+/**
+ * Enable A to B loop for the current media by setting the start position and
+ * end position
+ *
+ * The B position must be higher than the A position.
+ *
+ * \param p_mi the Media Player
+ * \param a_pos start position for the loop
+ * \param b_pos end position for the loop
+ * \return 0 on success, -1 on error
+ * \version LibVLC 4.0.0 and later.
+ */
+LIBVLC_API int
+libvlc_media_player_set_abloop_position( libvlc_media_player_t *p_mi,
+ double a_pos, double b_pos );
+
+/**
+ * Reset/remove the A to B loop for the current media
+ *
+ * \param p_mi the Media Player
+ * \return 0 on success, -1 on error
+ * \version LibVLC 4.0.0 and later.
+ */
+LIBVLC_API int
+libvlc_media_player_reset_abloop( libvlc_media_player_t *p_mi );
+
+/**
+ * Get the A to B loop status
+ *
+ * @note If the returned status is VLC_PLAYER_ABLOOP_A, then a_time and a_pos
+ * will be valid. If the returned status is VLC_PLAYER_ABLOOP_B, then all
+ * output parameters are valid. If the returned status is
+ * VLC_PLAYER_ABLOOP_NONE, then all output parameters are invalid.
+ *
+ * @see vlc_player_cbs.on_atobloop_changed
+ *
+ * \param p_mi the Media Player
+ * \param a_time A time (in ms) or -1 (if the media doesn't have valid times)
+ * \param a_pos A position
+ * \param b_time B time (in ms) or -1 (if the media doesn't have valid times)
+ * \param b_pos B position
+ * \return A to B loop status
+ * \version LibVLC 4.0.0 and later.
+ */
+LIBVLC_API libvlc_abloop_t
+libvlc_media_player_get_abloop( libvlc_media_player_t *p_mi,
+ libvlc_time_t *a_time, double *a_pos,
+ libvlc_time_t *b_time, double *b_pos );
+/**
+ * Set movie chapter (if applicable).
+ *
+ * \param p_mi the Media Player
+ * \param i_chapter chapter number to play
+ */
+LIBVLC_API void libvlc_media_player_set_chapter( libvlc_media_player_t *p_mi, int i_chapter );
+
+/**
+ * Get movie chapter.
+ *
+ * \param p_mi the Media Player
+ * \return chapter number currently playing, or -1 if there is no media.
+ */
+LIBVLC_API int libvlc_media_player_get_chapter( libvlc_media_player_t *p_mi );
+
+/**
+ * Get movie chapter count
+ *
+ * \param p_mi the Media Player
+ * \return number of chapters in movie, or -1.
+ */
+LIBVLC_API int libvlc_media_player_get_chapter_count( libvlc_media_player_t *p_mi );
+
+/**
+ * Get title chapter count
+ *
+ * \param p_mi the Media Player
+ * \param i_title title
+ * \return number of chapters in title, or -1
+ */
+LIBVLC_API int libvlc_media_player_get_chapter_count_for_title(
+ libvlc_media_player_t *p_mi, int i_title );
+
+/**
+ * Set movie title
+ *
+ * \param p_mi the Media Player
+ * \param i_title title number to play
+ */
+LIBVLC_API void libvlc_media_player_set_title( libvlc_media_player_t *p_mi, int i_title );
+
+/**
+ * Get movie title
+ *
+ * \param p_mi the Media Player
+ * \return title number currently playing, or -1
+ */
+LIBVLC_API int libvlc_media_player_get_title( libvlc_media_player_t *p_mi );
+
+/**
+ * Get movie title count
+ *
+ * \param p_mi the Media Player
+ * \return title number count, or -1
+ */
+LIBVLC_API int libvlc_media_player_get_title_count( libvlc_media_player_t *p_mi );
+
+/**
+ * Set previous chapter (if applicable)
+ *
+ * \param p_mi the Media Player
+ */
+LIBVLC_API void libvlc_media_player_previous_chapter( libvlc_media_player_t *p_mi );
+
+/**
+ * Set next chapter (if applicable)
+ *
+ * \param p_mi the Media Player
+ */
+LIBVLC_API void libvlc_media_player_next_chapter( libvlc_media_player_t *p_mi );
+
+/**
+ * Get the requested movie play rate.
+ * @warning Depending on the underlying media, the requested rate may be
+ * different from the real playback rate.
+ *
+ * \param p_mi the Media Player
+ * \return movie play rate
+ */
+LIBVLC_API float libvlc_media_player_get_rate( libvlc_media_player_t *p_mi );
+
+/**
+ * Set movie play rate
+ *
+ * \param p_mi the Media Player
+ * \param rate movie play rate to set
+ * \return -1 if an error was detected, 0 otherwise (but even then, it might
+ * not actually work depending on the underlying media protocol)
+ */
+LIBVLC_API int libvlc_media_player_set_rate( libvlc_media_player_t *p_mi, float rate );
+
+/**
+ * Get current movie state
+ *
+ * \param p_mi the Media Player
+ * \return the current state of the media player (playing, paused, ...) \see libvlc_state_t
+ */
+LIBVLC_API libvlc_state_t libvlc_media_player_get_state( libvlc_media_player_t *p_mi );
+
+/**
+ * How many video outputs does this media player have?
+ *
+ * \param p_mi the media player
+ * \return the number of video outputs
+ */
+LIBVLC_API unsigned libvlc_media_player_has_vout( libvlc_media_player_t *p_mi );
+
+/**
+ * Is this media player seekable?
+ *
+ * \param p_mi the media player
+ * \retval true media player can seek
+ * \retval false media player cannot seek
+ */
+LIBVLC_API bool libvlc_media_player_is_seekable(libvlc_media_player_t *p_mi);
+
+/**
+ * Can this media player be paused?
+ *
+ * \param p_mi the media player
+ * \retval true media player can be paused
+ * \retval false media player cannot be paused
+ */
+LIBVLC_API bool libvlc_media_player_can_pause(libvlc_media_player_t *p_mi);
+
+/**
+ * Check if the current program is scrambled
+ *
+ * \param p_mi the media player
+ * \retval true current program is scrambled
+ * \retval false current program is not scrambled
+ *
+ * \version LibVLC 2.2.0 or later
+ */
+LIBVLC_API bool libvlc_media_player_program_scrambled( libvlc_media_player_t *p_mi );
+
+/**
+ * Display the next frame (if supported)
+ *
+ * \param p_mi the media player
+ */
+LIBVLC_API void libvlc_media_player_next_frame( libvlc_media_player_t *p_mi );
+
+/**
+ * Navigate through DVD Menu
+ *
+ * \param p_mi the Media Player
+ * \param navigate the Navigation mode
+ * \version libVLC 2.0.0 or later
+ */
+LIBVLC_API void libvlc_media_player_navigate( libvlc_media_player_t* p_mi,
+ unsigned navigate );
+
+/**
+ * Set if, and how, the video title will be shown when media is played.
+ *
+ * \param p_mi the media player
+ * \param position position at which to display the title, or libvlc_position_disable to prevent the title from being displayed
+ * \param timeout title display timeout in milliseconds (ignored if libvlc_position_disable)
+ * \version libVLC 2.1.0 or later
+ */
+LIBVLC_API void libvlc_media_player_set_video_title_display( libvlc_media_player_t *p_mi, libvlc_position_t position, unsigned int timeout );
+
+/**
+ * Get the track list for one type
+ *
+ * \version LibVLC 4.0.0 and later.
+ *
+ * \note You need to call libvlc_media_parse_request() or play the media
+ * at least once before calling this function. Not doing this will result in
+ * an empty list.
+ *
+ * \note This track list is a snapshot of the current tracks when this function
+ * is called. If a track is updated after this call, the user will need to call
+ * this function again to get the updated track.
+ *
+ *
+ * The track list can be used to get track information and to select specific
+ * tracks.
+ *
+ * \param p_mi the media player
+ * \param type type of the track list to request
+ * \param selected filter only selected tracks if true (return all tracks, even
+ * selected ones if false)
+ *
+ * \return a valid libvlc_media_tracklist_t or NULL in case of error, if there
+ * is no track for a category, the returned list will have a size of 0, delete
+ * with libvlc_media_tracklist_delete()
+ */
+LIBVLC_API libvlc_media_tracklist_t *
+libvlc_media_player_get_tracklist( libvlc_media_player_t *p_mi,
+ libvlc_track_type_t type, bool selected );
+
+/**
+ * Get the selected track for one type
+ *
+ * \version LibVLC 4.0.0 and later.
+ *
+ * \warning More than one tracks can be selected for one type. In that case,
+ * libvlc_media_player_get_tracklist() should be used.
+ *
+ * \param p_mi the media player
+ * \param type type of the selected track
+ *
+ * \return a valid track or NULL if there is no selected tracks for this type,
+ * release it with libvlc_media_track_release().
+ */
+LIBVLC_API libvlc_media_track_t *
+libvlc_media_player_get_selected_track( libvlc_media_player_t *p_mi,
+ libvlc_track_type_t type );
+
+/*
+ * Get a track from a track id
+ *
+ * \version LibVLC 4.0.0 and later.
+ *
+ * This function can be used to get the last updated information of a track.
+ *
+ * \param p_mi the media player
+ * \param psz_id valid string representing a track id (cf. psz_id from \ref
+ * libvlc_media_track_t)
+ *
+ * \return a valid track or NULL if there is currently no tracks identified by
+ * the string id, release it with libvlc_media_track_release().
+ */
+LIBVLC_API libvlc_media_track_t *
+libvlc_media_player_get_track_from_id( libvlc_media_player_t *p_mi,
+ const char *psz_id );
+
+
+/**
+ * Select a track
+ *
+ * This will unselected the current track.
+ *
+ * \version LibVLC 4.0.0 and later.
+ *
+ * \note Use libvlc_media_player_select_tracks() for multiple selection
+ *
+ * \warning Only use a \ref libvlc_media_track_t retrieved with \ref libvlc_media_player_get_tracklist
+ *
+ * \param p_mi the media player
+ * \param track track to select, can't be NULL
+ */
+LIBVLC_API void
+libvlc_media_player_select_track( libvlc_media_player_t *p_mi,
+ const libvlc_media_track_t *track );
+
+/**
+ * Unselect all tracks for a given type
+ *
+ * \version LibVLC 4.0.0 and later.
+ *
+ * \param p_mi the media player
+ * \param type type to unselect
+ */
+LIBVLC_API void
+libvlc_media_player_unselect_track_type( libvlc_media_player_t *p_mi,
+ libvlc_track_type_t type );
+
+/**
+ * Select multiple tracks for one type
+ *
+ * \version LibVLC 4.0.0 and later.
+ *
+ * \note The internal track list can change between the calls of
+ * libvlc_media_player_get_tracklist() and
+ * libvlc_media_player_set_tracks(). If a track selection change but the
+ * track is not present anymore, the player will just ignore it.
+ *
+ * \note selecting multiple audio tracks is currently not supported.
+ *
+ * \warning Only use a \ref libvlc_media_track_t retrieved with \ref libvlc_media_player_get_tracklist
+ *
+ * \param p_mi the media player
+ * \param type type of the selected track
+ * \param tracks pointer to the track array, or NULL if track_count is 0
+ * \param track_count number of tracks in the track array
+ */
+LIBVLC_API void
+libvlc_media_player_select_tracks( libvlc_media_player_t *p_mi,
+ libvlc_track_type_t type,
+ const libvlc_media_track_t **tracks,
+ size_t track_count );
+
+/**
+ * Select tracks by their string identifier
+ *
+ * \version LibVLC 4.0.0 and later.
+ *
+ * This function can be used pre-select a list of tracks before starting the
+ * player. It has only effect for the current media. It can also be used when
+ * the player is already started.
+ *
+ * 'str_ids' can contain more than one track id, delimited with ','. "" or any
+ * invalid track id will cause the player to unselect all tracks of that
+ * category. NULL will disable the preference for newer tracks without
+ * unselecting any current tracks.
+ *
+ * Example:
+ * - (libvlc_track_video, "video/1,video/2") will select these 2 video tracks.
+ * If there is only one video track with the id "video/0", no tracks will be
+ * selected.
+ * - (libvlc_track_type_t, "${slave_url_md5sum}/spu/0) will select one spu
+ * added by an input slave with the corresponding url.
+ *
+ * \note The string identifier of a track can be found via psz_id from \ref
+ * libvlc_media_track_t
+ *
+ * \note selecting multiple audio tracks is currently not supported.
+ *
+ * \warning Only use a \ref libvlc_media_track_t id retrieved with \ref libvlc_media_player_get_tracklist
+ *
+ * \param p_mi the media player
+ * \param type type to select
+ * \param psz_ids list of string identifier or NULL
+ */
+LIBVLC_API void
+libvlc_media_player_select_tracks_by_ids( libvlc_media_player_t *p_mi,
+ libvlc_track_type_t type,
+ const char *psz_ids );
+
+/**
+ * Add a slave to the current media player.
+ *
+ * \note If the player is playing, the slave will be added directly. This call
+ * will also update the slave list of the attached libvlc_media_t.
+ *
+ * \version LibVLC 3.0.0 and later.
+ *
+ * \see libvlc_media_slaves_add
+ *
+ * \param p_mi the media player
+ * \param i_type subtitle or audio
+ * \param psz_uri Uri of the slave (should contain a valid scheme).
+ * \param b_select True if this slave should be selected when it's loaded
+ *
+ * \return 0 on success, -1 on error.
+ */
+LIBVLC_API
+int libvlc_media_player_add_slave( libvlc_media_player_t *p_mi,
+ libvlc_media_slave_type_t i_type,
+ const char *psz_uri, bool b_select );
+
+typedef struct libvlc_player_program_t
+{
+ /** Id used for libvlc_media_player_select_program() */
+ int i_group_id;
+ /** Program name, always valid */
+ char *psz_name;
+ /** True if the program is selected */
+ bool b_selected;
+ /** True if the program is scrambled */
+ bool b_scrambled;
+} libvlc_player_program_t;
+
+/**
+ * Opaque struct containing a list of program
+ */
+typedef struct libvlc_player_programlist_t libvlc_player_programlist_t;
+
+/**
+ * Delete a program struct
+ *
+ * \version LibVLC 4.0.0 and later.
+ *
+ * \param program returned by libvlc_media_player_get_selected_program() or
+ * libvlc_media_player_get_program_from_id()
+ *
+ */
+LIBVLC_API void
+libvlc_player_program_delete( libvlc_player_program_t *program );
+
+/**
+ * Get the number of programs in a programlist
+ *
+ * \version LibVLC 4.0.0 and later.
+ *
+ * \param list valid programlist
+ *
+ * \return number of programs, or 0 if the list is empty
+ */
+LIBVLC_API size_t
+libvlc_player_programlist_count( const libvlc_player_programlist_t *list );
+
+/**
+ * Get a program at a specific index
+ *
+ * \warning The behaviour is undefined if the index is not valid.
+ *
+ * \version LibVLC 4.0.0 and later.
+ *
+ * \param list valid programlist
+ * \param index valid index in the range [0; count[
+ *
+ * \return a valid program (can't be NULL if libvlc_player_programlist_count()
+ * returned a valid count)
+ */
+LIBVLC_API libvlc_player_program_t *
+libvlc_player_programlist_at( libvlc_player_programlist_t *list, size_t index );
+
+/**
+ * Release a programlist
+ *
+ * \note program structs from the list are also deleted.
+ *
+ * \version LibVLC 4.0.0 and later.
+ *
+ * \see libvlc_media_player_get_programlist
+ *
+ * \param list valid programlist
+ */
+LIBVLC_API void
+libvlc_player_programlist_delete( libvlc_player_programlist_t *list );
+
+/**
+ * Select program with a given program id.
+ *
+ * \note program ids are sent via the libvlc_MediaPlayerProgramAdded event or
+ * can be fetch via libvlc_media_player_get_programlist()
+ *
+ * \version LibVLC 4.0.0 or later
+ *
+ * \param p_mi opaque media player handle
+ * \param i_group_id program id
+ */
+LIBVLC_API void libvlc_media_player_select_program_id( libvlc_media_player_t *p_mi, int i_group_id);
+
+/**
+ * Get the selected program
+ *
+ * \version LibVLC 4.0.0 or later
+ *
+ * \param p_mi opaque media player handle
+ *
+ * \return a valid program struct or NULL if no programs are selected. The
+ * program need to be freed with libvlc_player_program_delete().
+ */
+LIBVLC_API libvlc_player_program_t *
+libvlc_media_player_get_selected_program( libvlc_media_player_t *p_mi);
+
+/**
+ * Get a program struct from a program id
+ *
+ * \version LibVLC 4.0.0 or later
+ *
+ * \param p_mi opaque media player handle
+ * \param i_group_id program id
+ *
+ * \return a valid program struct or NULL if the i_group_id is not found. The
+ * program need to be freed with libvlc_player_program_delete().
+ */
+LIBVLC_API libvlc_player_program_t *
+libvlc_media_player_get_program_from_id( libvlc_media_player_t *p_mi, int i_group_id );
+
+/**
+ * Get the program list
+ *
+ * \version LibVLC 4.0.0 and later.
+ * \note This program list is a snapshot of the current programs when this
+ * function is called. If a program is updated after this call, the user will
+ * need to call this function again to get the updated program.
+ *
+ * The program list can be used to get program information and to select
+ * specific programs.
+ *
+ * \param p_mi the media player
+ *
+ * \return a valid libvlc_media_programlist_t or NULL in case of error or empty
+ * list, delete with libvlc_media_programlist_delete()
+ */
+LIBVLC_API libvlc_player_programlist_t *
+libvlc_media_player_get_programlist( libvlc_media_player_t *p_mi );
+
+
+/** \defgroup libvlc_video LibVLC video controls
+ * @{
+ */
+
+/**
+ * Toggle fullscreen status on non-embedded video outputs.
+ *
+ * @warning The same limitations applies to this function
+ * as to libvlc_set_fullscreen().
+ *
+ * \param p_mi the media player
+ */
+LIBVLC_API void libvlc_toggle_fullscreen( libvlc_media_player_t *p_mi );
+
+/**
+ * Enable or disable fullscreen.
+ *
+ * @warning With most window managers, only a top-level windows can be in
+ * full-screen mode. Hence, this function will not operate properly if
+ * libvlc_media_player_set_xwindow() was used to embed the video in a
+ * non-top-level window. In that case, the embedding window must be reparented
+ * to the root window before fullscreen mode is enabled. You will want
+ * to reparent it back to its normal parent when disabling fullscreen.
+ *
+ * \note This setting applies to any and all current or future active video
+ * tracks and windows for the given media player. The choice of fullscreen
+ * output for each window is left to the operating system.
+ *
+ * \param p_mi the media player
+ * \param b_fullscreen boolean for fullscreen status
+ */
+LIBVLC_API void libvlc_set_fullscreen(libvlc_media_player_t *p_mi, bool b_fullscreen);
+
+/**
+ * Get current fullscreen status.
+ *
+ * \param p_mi the media player
+ * \return the fullscreen status (boolean)
+ *
+ * \retval false media player is windowed
+ * \retval true media player is in fullscreen mode
+ */
+LIBVLC_API bool libvlc_get_fullscreen( libvlc_media_player_t *p_mi );
+
+/**
+ * Enable or disable key press events handling, according to the LibVLC hotkeys
+ * configuration. By default and for historical reasons, keyboard events are
+ * handled by the LibVLC video widget.
+ *
+ * \note On X11, there can be only one subscriber for key press and mouse
+ * click events per window. If your application has subscribed to those events
+ * for the X window ID of the video widget, then LibVLC will not be able to
+ * handle key presses and mouse clicks in any case.
+ *
+ * \warning This function is only implemented for X11 and Win32 at the moment.
+ *
+ * \param p_mi the media player
+ * \param on true to handle key press events, false to ignore them.
+ */
+LIBVLC_API
+void libvlc_video_set_key_input( libvlc_media_player_t *p_mi, unsigned on );
+
+/**
+ * Enable or disable mouse click events handling. By default, those events are
+ * handled. This is needed for DVD menus to work, as well as a few video
+ * filters such as "puzzle".
+ *
+ * \see libvlc_video_set_key_input().
+ *
+ * \warning This function is only implemented for X11 and Win32 at the moment.
+ *
+ * \param p_mi the media player
+ * \param on true to handle mouse click events, false to ignore them.
+ */
+LIBVLC_API
+void libvlc_video_set_mouse_input( libvlc_media_player_t *p_mi, unsigned on );
+
+/**
+ * Get the pixel dimensions of a video.
+ *
+ * \param p_mi media player
+ * \param num number of the video (starting from, and most commonly 0)
+ * \param[out] px pointer to get the pixel width
+ * \param[out] py pointer to get the pixel height
+ * \return 0 on success, -1 if the specified video does not exist
+ */
+LIBVLC_API
+int libvlc_video_get_size( libvlc_media_player_t *p_mi, unsigned num,
+ unsigned *px, unsigned *py );
+
+/**
+ * Get the mouse pointer coordinates over a video.
+ * Coordinates are expressed in terms of the decoded video resolution,
+ * not in terms of pixels on the screen/viewport (to get the latter,
+ * you can query your windowing system directly).
+ *
+ * Either of the coordinates may be negative or larger than the corresponding
+ * dimension of the video, if the cursor is outside the rendering area.
+ *
+ * @warning The coordinates may be out-of-date if the pointer is not located
+ * on the video rendering area. LibVLC does not track the pointer if it is
+ * outside of the video widget.
+ *
+ * @note LibVLC does not support multiple pointers (it does of course support
+ * multiple input devices sharing the same pointer) at the moment.
+ *
+ * \param p_mi media player
+ * \param num number of the video (starting from, and most commonly 0)
+ * \param[out] px pointer to get the abscissa
+ * \param[out] py pointer to get the ordinate
+ * \return 0 on success, -1 if the specified video does not exist
+ */
+LIBVLC_API
+int libvlc_video_get_cursor( libvlc_media_player_t *p_mi, unsigned num,
+ int *px, int *py );
+
+/**
+ * Get the current video scaling factor.
+ * See also libvlc_video_set_scale().
+ *
+ * \param p_mi the media player
+ * \return the currently configured zoom factor, or 0. if the video is set
+ * to fit to the output window/drawable automatically.
+ */
+LIBVLC_API float libvlc_video_get_scale( libvlc_media_player_t *p_mi );
+
+/**
+ * Set the video scaling factor. That is the ratio of the number of pixels on
+ * screen to the number of pixels in the original decoded video in each
+ * dimension. Zero is a special value; it will adjust the video to the output
+ * window/drawable (in windowed mode) or the entire screen.
+ *
+ * Note that not all video outputs support scaling.
+ *
+ * \param p_mi the media player
+ * \param f_factor the scaling factor, or zero
+ */
+LIBVLC_API void libvlc_video_set_scale( libvlc_media_player_t *p_mi, float f_factor );
+
+/**
+ * Get current video aspect ratio.
+ *
+ * \param p_mi the media player
+ * \return the video aspect ratio or NULL if unspecified
+ * (the result must be released with free() or libvlc_free()).
+ */
+LIBVLC_API char *libvlc_video_get_aspect_ratio( libvlc_media_player_t *p_mi );
+
+/**
+ * Set new video aspect ratio.
+ *
+ * \param p_mi the media player
+ * \param psz_aspect new video aspect-ratio or NULL to reset to source aspect ratio
+ * \note Invalid aspect ratios are ignored.
+ */
+LIBVLC_API void libvlc_video_set_aspect_ratio( libvlc_media_player_t *p_mi, const char *psz_aspect );
+
+/**
+ * Get current video display fit mode.
+ *
+ * \version LibVLC 4.0.0 or later
+ *
+ * \param p_mi the media player
+ * \return the video display fit mode.
+ */
+LIBVLC_API libvlc_video_fit_mode_t libvlc_video_get_display_fit( libvlc_media_player_t *p_mi );
+
+/**
+ * Set new video display fit.
+ *
+ * \version LibVLC 4.0.0 or later
+ *
+ * \param p_mi the media player
+ * \param fit new display fit mode
+ * \note Invalid fit mode are ignored.
+ */
+LIBVLC_API void libvlc_video_set_display_fit( libvlc_media_player_t *p_mi, libvlc_video_fit_mode_t fit );
+
+/**
+ * Create a video viewpoint structure.
+ *
+ * \version LibVLC 3.0.0 and later
+ *
+ * \return video viewpoint or NULL
+ * (the result must be released with free()).
+ */
+LIBVLC_API libvlc_video_viewpoint_t *libvlc_video_new_viewpoint(void);
+
+/**
+ * Update the video viewpoint information.
+ *
+ * \note It is safe to call this function before the media player is started.
+ *
+ * \version LibVLC 3.0.0 and later
+ *
+ * \param p_mi the media player
+ * \param p_viewpoint video viewpoint allocated via libvlc_video_new_viewpoint()
+ * \param b_absolute if true replace the old viewpoint with the new one. If
+ * false, increase/decrease it.
+ * \return -1 in case of error, 0 otherwise
+ *
+ * \note the values are set asynchronously, it will be used by the next frame displayed.
+ */
+LIBVLC_API int libvlc_video_update_viewpoint( libvlc_media_player_t *p_mi,
+ const libvlc_video_viewpoint_t *p_viewpoint,
+ bool b_absolute);
+
+/**
+ * Video stereo modes
+ */
+typedef enum libvlc_video_stereo_mode_t {
+ libvlc_VideoStereoAuto = 0,
+ libvlc_VideoStereoStereo,
+ libvlc_VideoStereoLeftEye,
+ libvlc_VideoStereoRightEye,
+ libvlc_VideoStereoSideBySide,
+} libvlc_video_stereo_mode_t;
+
+/**
+ * Get current video stereo mode.
+ *
+ * \param p_mi the media player
+ * \return the video stereo mode.
+ */
+LIBVLC_API libvlc_video_stereo_mode_t libvlc_video_get_video_stereo_mode(
+ libvlc_media_player_t *p_mi );
+
+/**
+ * Set new video stereo mode.
+ *
+ * \param p_mi the media player
+ * \param i_mode new video stereo mode
+ */
+LIBVLC_API void libvlc_video_set_video_stereo_mode( libvlc_media_player_t *p_mi,
+ const libvlc_video_stereo_mode_t i_mode );
+
+/**
+ * Get the current subtitle delay. Positive values means subtitles are being
+ * displayed later, negative values earlier.
+ *
+ * \param p_mi media player
+ * \return time (in microseconds) the display of subtitles is being delayed
+ * \version LibVLC 2.0.0 or later
+ */
+LIBVLC_API int64_t libvlc_video_get_spu_delay( libvlc_media_player_t *p_mi );
+
+/**
+ * Get the current subtitle text scale
+ *
+ * The scale factor is expressed as a percentage of the default size, where
+ * 1.0 represents 100 percent.
+ *
+ * \param p_mi media player
+ * \version LibVLC 4.0.0 or later
+ */
+LIBVLC_API float libvlc_video_get_spu_text_scale( libvlc_media_player_t *p_mi );
+
+/**
+ * Set the subtitle text scale.
+ *
+ * The scale factor is expressed as a percentage of the default size, where
+ * 1.0 represents 100 percent.
+ *
+ * A value of 0.5 would result in text half the normal size, and a value of 2.0
+ * would result in text twice the normal size.
+ *
+ * The minimum acceptable value for the scale factor is 0.1.
+ *
+ * The maximum is 5.0 (five times normal size).
+ *
+ * \param p_mi media player
+ * \param f_scale scale factor in the range [0.1;5.0] (default: 1.0)
+ * \version LibVLC 4.0.0 or later
+ */
+LIBVLC_API void libvlc_video_set_spu_text_scale( libvlc_media_player_t *p_mi, float f_scale );
+
+/**
+ * Set the subtitle delay. This affects the timing of when the subtitle will
+ * be displayed. Positive values result in subtitles being displayed later,
+ * while negative values will result in subtitles being displayed earlier.
+ *
+ * The subtitle delay will be reset to zero each time the media changes.
+ *
+ * \param p_mi media player
+ * \param i_delay time (in microseconds) the display of subtitles should be delayed
+ * \return 0 on success, -1 on error
+ * \version LibVLC 2.0.0 or later
+ */
+LIBVLC_API int libvlc_video_set_spu_delay( libvlc_media_player_t *p_mi, int64_t i_delay );
+
+/**
+ * Get the full description of available titles
+ *
+ * \version LibVLC 3.0.0 and later.
+ *
+ * \param p_mi the media player
+ * \param[out] titles address to store an allocated array of title descriptions
+ * descriptions (must be freed with libvlc_title_descriptions_release()
+ * by the caller)
+ *
+ * \return the number of titles (-1 on error)
+ */
+LIBVLC_API int libvlc_media_player_get_full_title_descriptions( libvlc_media_player_t *p_mi,
+ libvlc_title_description_t ***titles );
+
+/**
+ * Release a title description
+ *
+ * \version LibVLC 3.0.0 and later
+ *
+ * \param p_titles title description array to release
+ * \param i_count number of title descriptions to release
+ */
+LIBVLC_API
+ void libvlc_title_descriptions_release( libvlc_title_description_t **p_titles,
+ unsigned i_count );
+
+/**
+ * Get the full description of available chapters
+ *
+ * \version LibVLC 3.0.0 and later.
+ *
+ * \param p_mi the media player
+ * \param i_chapters_of_title index of the title to query for chapters (uses current title if set to -1)
+ * \param[out] pp_chapters address to store an allocated array of chapter descriptions
+ * descriptions (must be freed with libvlc_chapter_descriptions_release()
+ * by the caller)
+ *
+ * \return the number of chapters (-1 on error)
+ */
+LIBVLC_API int libvlc_media_player_get_full_chapter_descriptions( libvlc_media_player_t *p_mi,
+ int i_chapters_of_title,
+ libvlc_chapter_description_t *** pp_chapters );
+
+/**
+ * Release a chapter description
+ *
+ * \version LibVLC 3.0.0 and later
+ *
+ * \param p_chapters chapter description array to release
+ * \param i_count number of chapter descriptions to release
+ */
+LIBVLC_API
+void libvlc_chapter_descriptions_release( libvlc_chapter_description_t **p_chapters,
+ unsigned i_count );
+
+/**
+ * Set/unset the video crop ratio.
+ *
+ * This function forces a crop ratio on any and all video tracks rendered by
+ * the media player. If the display aspect ratio of a video does not match the
+ * crop ratio, either the top and bottom, or the left and right of the video
+ * will be cut out to fit the crop ratio.
+ *
+ * For instance, a ratio of 1:1 will force the video to a square shape.
+ *
+ * To disable video crop, set a crop ratio with zero as denominator.
+ *
+ * A call to this function overrides any previous call to any of
+ * libvlc_video_set_crop_ratio(), libvlc_video_set_crop_border() and/or
+ * libvlc_video_set_crop_window().
+ *
+ * \see libvlc_video_set_aspect_ratio()
+ *
+ * \param mp the media player
+ * \param num crop ratio numerator (ignored if denominator is 0)
+ * \param den crop ratio denominator (or 0 to unset the crop ratio)
+ *
+ * \version LibVLC 4.0.0 and later
+ */
+LIBVLC_API
+void libvlc_video_set_crop_ratio(libvlc_media_player_t *mp,
+ unsigned num, unsigned den);
+
+/**
+ * Set the video crop window.
+ *
+ * This function selects a sub-rectangle of video to show. Any pixels outside
+ * the rectangle will not be shown.
+ *
+ * To unset the video crop window, use libvlc_video_set_crop_ratio() or
+ * libvlc_video_set_crop_border().
+ *
+ * A call to this function overrides any previous call to any of
+ * libvlc_video_set_crop_ratio(), libvlc_video_set_crop_border() and/or
+ * libvlc_video_set_crop_window().
+ *
+ * \param mp the media player
+ * \param x abscissa (i.e. leftmost sample column offset) of the crop window
+ * \param y ordinate (i.e. topmost sample row offset) of the crop window
+ * \param width sample width of the crop window (cannot be zero)
+ * \param height sample height of the crop window (cannot be zero)
+ *
+ * \version LibVLC 4.0.0 and later
+ */
+LIBVLC_API
+void libvlc_video_set_crop_window(libvlc_media_player_t *mp,
+ unsigned x, unsigned y,
+ unsigned width, unsigned height);
+
+/**
+ * Set the video crop borders.
+ *
+ * This function selects the size of video edges to be cropped out.
+ *
+ * To unset the video crop borders, set all borders to zero.
+ *
+ * A call to this function overrides any previous call to any of
+ * libvlc_video_set_crop_ratio(), libvlc_video_set_crop_border() and/or
+ * libvlc_video_set_crop_window().
+ *
+ * \param mp the media player
+ * \param left number of sample columns to crop on the left
+ * \param right number of sample columns to crop on the right
+ * \param top number of sample rows to crop on the top
+ * \param bottom number of sample rows to corp on the bottom
+ *
+ * \version LibVLC 4.0.0 and later
+ */
+LIBVLC_API
+void libvlc_video_set_crop_border(libvlc_media_player_t *mp,
+ unsigned left, unsigned right,
+ unsigned top, unsigned bottom);
+
+/**
+ * Get current teletext page requested or 0 if it's disabled.
+ *
+ * Teletext is disabled by default, call libvlc_video_set_teletext() to enable
+ * it.
+ *
+ * \param p_mi the media player
+ * \return the current teletext page requested.
+ */
+LIBVLC_API int libvlc_video_get_teletext( libvlc_media_player_t *p_mi );
+
+/**
+ * Set new teletext page to retrieve.
+ *
+ * This function can also be used to send a teletext key.
+ *
+ * \param p_mi the media player
+ * \param i_page teletex page number requested. This value can be 0 to disable
+ * teletext, a number in the range ]0;1000[ to show the requested page, or a
+ * \ref libvlc_teletext_key_t. 100 is the default teletext page.
+ */
+LIBVLC_API void libvlc_video_set_teletext( libvlc_media_player_t *p_mi, int i_page );
+
+/**
+ * Set teletext background transparency.
+ *
+ * \param p_mi the media player
+ * \param transparent whether background should be transparent.
+ * \version LibVLC 4.0.0 or later
+ */
+LIBVLC_API void libvlc_video_set_teletext_transparency( libvlc_media_player_t *p_mi, bool transparent );
+
+/**
+ * Get teletext background transparency.
+ *
+ * \param p_mi the media player
+ * \retval true teletext has transparent background
+ * \retval false teletext has opaque background
+ * \version LibVLC 4.0.0 or later
+ */
+LIBVLC_API bool libvlc_video_get_teletext_transparency( libvlc_media_player_t *p_mi );
+
+/**
+ * Take a snapshot of the current video window.
+ *
+ * If i_width AND i_height is 0, original size is used.
+ * If i_width XOR i_height is 0, original aspect-ratio is preserved.
+ *
+ * \param p_mi media player instance
+ * \param num number of video output (typically 0 for the first/only one)
+ * \param psz_filepath the path of a file or a folder to save the screenshot into
+ * \param i_width the snapshot's width
+ * \param i_height the snapshot's height
+ * \return 0 on success, -1 if the video was not found
+ */
+LIBVLC_API
+int libvlc_video_take_snapshot( libvlc_media_player_t *p_mi, unsigned num,
+ const char *psz_filepath, unsigned int i_width,
+ unsigned int i_height );
+
+/**
+ * Enable or disable deinterlace filter
+ *
+ * \param p_mi libvlc media player
+ * \param deinterlace state -1: auto (default), 0: disabled, 1: enabled
+ * \param psz_mode type of deinterlace filter, NULL for current/default filter
+ * \version LibVLC 4.0.0 and later
+ */
+LIBVLC_API void libvlc_video_set_deinterlace( libvlc_media_player_t *p_mi,
+ int deinterlace,
+ const char *psz_mode );
+
+/**
+ * Get an integer marquee option value
+ *
+ * \param p_mi libvlc media player
+ * \param option marq option to get \see libvlc_video_marquee_option_t
+ */
+LIBVLC_API int libvlc_video_get_marquee_int( libvlc_media_player_t *p_mi,
+ unsigned option );
+
+/**
+ * Enable, disable or set an integer marquee option
+ *
+ * Setting libvlc_marquee_Enable has the side effect of enabling (arg !0)
+ * or disabling (arg 0) the marq filter.
+ *
+ * \param p_mi libvlc media player
+ * \param option marq option to set \see libvlc_video_marquee_option_t
+ * \param i_val marq option value
+ */
+LIBVLC_API void libvlc_video_set_marquee_int( libvlc_media_player_t *p_mi,
+ unsigned option, int i_val );
+
+/**
+ * Set a marquee string option
+ *
+ * \param p_mi libvlc media player
+ * \param option marq option to set \see libvlc_video_marquee_option_t
+ * \param psz_text marq option value
+ */
+LIBVLC_API void libvlc_video_set_marquee_string( libvlc_media_player_t *p_mi,
+ unsigned option, const char *psz_text );
+
+/** option values for libvlc_video_{get,set}_logo_{int,string} */
+enum libvlc_video_logo_option_t {
+ libvlc_logo_enable,
+ libvlc_logo_file, /**< string argument, "file,d,t;file,d,t;..." */
+ libvlc_logo_x,
+ libvlc_logo_y,
+ libvlc_logo_delay,
+ libvlc_logo_repeat,
+ libvlc_logo_opacity,
+ libvlc_logo_position
+};
+
+/**
+ * Get integer logo option.
+ *
+ * \param p_mi libvlc media player instance
+ * \param option logo option to get, values of libvlc_video_logo_option_t
+ */
+LIBVLC_API int libvlc_video_get_logo_int( libvlc_media_player_t *p_mi,
+ unsigned option );
+
+/**
+ * Set logo option as integer. Options that take a different type value
+ * are ignored.
+ * Passing libvlc_logo_enable as option value has the side effect of
+ * starting (arg !0) or stopping (arg 0) the logo filter.
+ *
+ * \param p_mi libvlc media player instance
+ * \param option logo option to set, values of libvlc_video_logo_option_t
+ * \param value logo option value
+ */
+LIBVLC_API void libvlc_video_set_logo_int( libvlc_media_player_t *p_mi,
+ unsigned option, int value );
+
+/**
+ * Set logo option as string. Options that take a different type value
+ * are ignored.
+ *
+ * \param p_mi libvlc media player instance
+ * \param option logo option to set, values of libvlc_video_logo_option_t
+ * \param psz_value logo option value
+ */
+LIBVLC_API void libvlc_video_set_logo_string( libvlc_media_player_t *p_mi,
+ unsigned option, const char *psz_value );
+
+
+/** option values for libvlc_video_{get,set}_adjust_{int,float,bool} */
+enum libvlc_video_adjust_option_t {
+ libvlc_adjust_Enable = 0,
+ libvlc_adjust_Contrast,
+ libvlc_adjust_Brightness,
+ libvlc_adjust_Hue,
+ libvlc_adjust_Saturation,
+ libvlc_adjust_Gamma
+};
+
+/**
+ * Get integer adjust option.
+ *
+ * \param p_mi libvlc media player instance
+ * \param option adjust option to get, values of libvlc_video_adjust_option_t
+ * \version LibVLC 1.1.1 and later.
+ */
+LIBVLC_API int libvlc_video_get_adjust_int( libvlc_media_player_t *p_mi,
+ unsigned option );
+
+/**
+ * Set adjust option as integer. Options that take a different type value
+ * are ignored.
+ * Passing libvlc_adjust_enable as option value has the side effect of
+ * starting (arg !0) or stopping (arg 0) the adjust filter.
+ *
+ * \param p_mi libvlc media player instance
+ * \param option adjust option to set, values of libvlc_video_adjust_option_t
+ * \param value adjust option value
+ * \version LibVLC 1.1.1 and later.
+ */
+LIBVLC_API void libvlc_video_set_adjust_int( libvlc_media_player_t *p_mi,
+ unsigned option, int value );
+
+/**
+ * Get float adjust option.
+ *
+ * \param p_mi libvlc media player instance
+ * \param option adjust option to get, values of libvlc_video_adjust_option_t
+ * \version LibVLC 1.1.1 and later.
+ */
+LIBVLC_API float libvlc_video_get_adjust_float( libvlc_media_player_t *p_mi,
+ unsigned option );
+
+/**
+ * Set adjust option as float. Options that take a different type value
+ * are ignored.
+ *
+ * \param p_mi libvlc media player instance
+ * \param option adjust option to set, values of libvlc_video_adjust_option_t
+ * \param value adjust option value
+ * \version LibVLC 1.1.1 and later.
+ */
+LIBVLC_API void libvlc_video_set_adjust_float( libvlc_media_player_t *p_mi,
+ unsigned option, float value );
+/**
+ * Change the projection mode used for rendering the source.
+ *
+ * This changes how the source is mapped to the output w.r.t. 360 playback.
+ *
+ * \param p_mi libvlc media player instance
+ * \param projection_mode the considered projection mode for the source
+ * \version LibVLC 4.0.0 and later.
+ */
+LIBVLC_API void
+libvlc_video_set_projection_mode(libvlc_media_player_t *player,
+ libvlc_video_projection_t projection_mode);
+
+/**
+ * Remove previously set projection mode.
+ *
+ * Remove the effects from previous call to libvlc_video_set_projection_mode.
+ *
+ * \param p_mi libvlc media player instance
+ * \version LibVLC 4.0.0 and later.
+ */
+LIBVLC_API void
+libvlc_video_unset_projection_mode(libvlc_media_player_t *player);
+
+/** @} video */
+
+/** \defgroup libvlc_audio LibVLC audio controls
+ * @{
+ */
+
+/**
+ * Audio stereo modes
+ */
+typedef enum libvlc_audio_output_stereomode_t {
+ libvlc_AudioStereoMode_Unset = 0,
+ libvlc_AudioStereoMode_Stereo = 1,
+ libvlc_AudioStereoMode_RStereo = 2,
+ libvlc_AudioStereoMode_Left = 3,
+ libvlc_AudioStereoMode_Right = 4,
+ libvlc_AudioStereoMode_Dolbys = 5,
+ libvlc_AudioStereoMode_Mono = 7,
+} libvlc_audio_output_stereomode_t;
+
+/**
+ * Audio mix modes
+ */
+typedef enum libvlc_audio_output_mixmode_t {
+ libvlc_AudioMixMode_Unset = 0,
+ libvlc_AudioMixMode_Stereo = 1,
+ libvlc_AudioMixMode_Binaural = 2,
+ libvlc_AudioMixMode_4_0 = 3,
+ libvlc_AudioMixMode_5_1 = 4,
+ libvlc_AudioMixMode_7_1 = 5,
+} libvlc_audio_output_mixmode_t;
+
+/**
+ * Gets the list of available audio output modules.
+ *
+ * \param p_instance libvlc instance
+ * \return list of available audio outputs. It must be freed with
+* \see libvlc_audio_output_list_release \see libvlc_audio_output_t .
+ * In case of error, NULL is returned.
+ */
+LIBVLC_API libvlc_audio_output_t *
+libvlc_audio_output_list_get( libvlc_instance_t *p_instance );
+
+/**
+ * Frees the list of available audio output modules.
+ *
+ * \param p_list list with audio outputs for release
+ */
+LIBVLC_API
+void libvlc_audio_output_list_release( libvlc_audio_output_t *p_list );
+
+/**
+ * Selects an audio output module.
+ * \note Any change will take be effect only after playback is stopped and
+ * restarted. Audio output cannot be changed while playing.
+ *
+ * \param p_mi media player
+ * \param psz_name name of audio output,
+ * use psz_name of \see libvlc_audio_output_t
+ * \return 0 if function succeeded, -1 on error
+ */
+LIBVLC_API int libvlc_audio_output_set( libvlc_media_player_t *p_mi,
+ const char *psz_name );
+
+/**
+ * Gets a list of potential audio output devices.
+ *
+ * See also libvlc_audio_output_device_set().
+ *
+ * \note Not all audio outputs support enumerating devices.
+ * The audio output may be functional even if the list is empty (NULL).
+ *
+ * \note The list may not be exhaustive.
+ *
+ * \warning Some audio output devices in the list might not actually work in
+ * some circumstances. By default, it is recommended to not specify any
+ * explicit audio device.
+ *
+ * \param mp media player
+ * \return A NULL-terminated linked list of potential audio output devices.
+ * It must be freed with libvlc_audio_output_device_list_release()
+ * \version LibVLC 2.2.0 or later.
+ */
+LIBVLC_API libvlc_audio_output_device_t *
+libvlc_audio_output_device_enum( libvlc_media_player_t *mp );
+
+#if defined (__GNUC__) && !defined (__clang__)
+__attribute__((unused))
+__attribute__((noinline))
+__attribute__((error("Use libvlc_audio_output_device_enum() instead")))
+static libvlc_audio_output_device_t *
+libvlc_audio_output_device_list_get( libvlc_instance_t *p_instance,
+ const char *aout )
+{
+ (void) p_instance; (void) aout;
+ return NULL;
+}
+#endif
+
+/**
+ * Frees a list of available audio output devices.
+ *
+ * \param p_list list with audio outputs for release
+ * \version LibVLC 2.1.0 or later.
+ */
+LIBVLC_API void libvlc_audio_output_device_list_release(
+ libvlc_audio_output_device_t *p_list );
+
+/**
+ * Configures an explicit audio output device.
+ *
+ * A list of adequate potential device strings can be obtained with
+ * libvlc_audio_output_device_enum().
+ *
+ * \note This function does not select the specified audio output plugin.
+ * libvlc_audio_output_set() is used for that purpose.
+ *
+ * \warning The syntax for the device parameter depends on the audio output.
+ *
+ * Some audio output modules require further parameters (e.g. a channels map
+ * in the case of ALSA).
+ *
+ * \version This function originally expected three parameters.
+ * The middle parameter was removed from LibVLC 4.0 onward.
+ *
+ * \param mp media player
+ * \param device_id device identifier string
+ * (see \ref libvlc_audio_output_device_t::psz_device)
+ *
+ * \return If the change of device was requested successfully, zero is returned
+ * (the actual change is asynchronous and not guaranteed to succeed).
+ * On error, a non-zero value is returned.
+ */
+LIBVLC_API int libvlc_audio_output_device_set( libvlc_media_player_t *mp,
+ const char *device_id );
+
+/**
+ * Get the current audio output device identifier.
+ *
+ * This complements libvlc_audio_output_device_set().
+ *
+ * \warning The initial value for the current audio output device identifier
+ * may not be set or may be some unknown value. A LibVLC application should
+ * compare this value against the known device identifiers (e.g. those that
+ * were previously retrieved by a call to libvlc_audio_output_device_enum) to
+ * find the current audio output device.
+ *
+ * It is possible that the selected audio output device changes (an external
+ * change) without a call to libvlc_audio_output_device_set. That may make this
+ * method unsuitable to use if a LibVLC application is attempting to track
+ * dynamic audio device changes as they happen.
+ *
+ * \param mp media player
+ * \return the current audio output device identifier
+ * NULL if no device is selected or in case of error
+ * (the result must be released with free()).
+ * \version LibVLC 3.0.0 or later.
+ */
+LIBVLC_API char *libvlc_audio_output_device_get( libvlc_media_player_t *mp );
+
+/**
+ * Toggle mute status.
+ *
+ * \param p_mi media player
+ * \warning Toggling mute atomically is not always possible: On some platforms,
+ * other processes can mute the VLC audio playback stream asynchronously. Thus,
+ * there is a small race condition where toggling will not work.
+ * See also the limitations of libvlc_audio_set_mute().
+ */
+LIBVLC_API void libvlc_audio_toggle_mute( libvlc_media_player_t *p_mi );
+
+/**
+ * Get current mute status.
+ *
+ * \param p_mi media player
+ * \return the mute status (boolean) if defined, -1 if undefined/unapplicable
+ */
+LIBVLC_API int libvlc_audio_get_mute( libvlc_media_player_t *p_mi );
+
+/**
+ * Set mute status.
+ *
+ * \param p_mi media player
+ * \param status If status is true then mute, otherwise unmute
+ * \warning This function does not always work. If there are no active audio
+ * playback stream, the mute status might not be available. If digital
+ * pass-through (S/PDIF, HDMI...) is in use, muting may be unapplicable. Also
+ * some audio output plugins do not support muting at all.
+ * \note To force silent playback, disable all audio tracks. This is more
+ * efficient and reliable than mute.
+ */
+LIBVLC_API void libvlc_audio_set_mute( libvlc_media_player_t *p_mi, int status );
+
+/**
+ * Get current software audio volume.
+ *
+ * \param p_mi media player
+ * \return the software volume in percents
+ * (0 = mute, 100 = nominal / 0dB)
+ */
+LIBVLC_API int libvlc_audio_get_volume( libvlc_media_player_t *p_mi );
+
+/**
+ * Set current software audio volume.
+ *
+ * \param p_mi media player
+ * \param i_volume the volume in percents (0 = mute, 100 = 0dB)
+ * \return 0 if the volume was set, -1 if it was out of range
+ */
+LIBVLC_API int libvlc_audio_set_volume( libvlc_media_player_t *p_mi, int i_volume );
+
+/**
+ * Get current audio stereo-mode.
+ *
+ * \param p_mi media player
+ * \return the audio stereo-mode, \see libvlc_audio_output_stereomode_t
+ * \version LibVLC 4.0.0 or later
+ */
+LIBVLC_API libvlc_audio_output_stereomode_t libvlc_audio_get_stereomode( libvlc_media_player_t *p_mi );
+
+/**
+ * Set current audio stereo-mode.
+ *
+ * \param p_mi media player
+ * \param mode the audio stereo-mode, \see libvlc_audio_output_stereomode_t
+ * \return 0 on success, -1 on error
+ * \version LibVLC 4.0.0 or later
+ */
+LIBVLC_API int libvlc_audio_set_stereomode( libvlc_media_player_t *p_mi,
+ libvlc_audio_output_stereomode_t mode );
+
+/**
+ * Get current audio mix-mode.
+ *
+ * \param p_mi media player
+ * \return the audio mix-mode, \see libvlc_audio_output_mixmode_t
+ * \version LibVLC 4.0.0 or later
+ */
+LIBVLC_API libvlc_audio_output_mixmode_t libvlc_audio_get_mixmode( libvlc_media_player_t *p_mi );
+
+/**
+ * Set current audio mix-mode.
+ *
+ * By default (::libvlc_AudioMixMode_Unset), the audio output will keep its
+ * original channel configuration (play stereo as stereo, or 5.1 as 5.1). Yet,
+ * the OS and Audio API might refuse a channel configuration and asks VLC to
+ * adapt (Stereo played as 5.1 or vice-versa).
+ *
+ * This function allows to force a channel configuration, it will only work if
+ * the OS and Audio API accept this configuration (otherwise, it won't have any
+ * effects). Here are some examples:
+ * - Play multi-channels (5.1, 7.1...) as stereo (::libvlc_AudioMixMode_Stereo)
+ * - Play Stereo or 5.1 as 7.1 (::libvlc_AudioMixMode_7_1)
+ * - Play multi-channels as stereo with a binaural effect
+ * (::libvlc_AudioMixMode_Binaural). It might be selected automatically if the
+ * OS and Audio API can detect if a headphone is plugged.
+ *
+ * \param p_mi media player
+ * \param mode the audio mix-mode, \see libvlc_audio_output_mixmode_t
+ * \return 0 on success, -1 on error
+ * \version LibVLC 4.0.0 or later
+ */
+LIBVLC_API int libvlc_audio_set_mixmode( libvlc_media_player_t *p_mi,
+ libvlc_audio_output_mixmode_t mode );
+
+
+/**
+ * Get current audio delay.
+ *
+ * \param p_mi media player
+ * \return the audio delay (microseconds)
+ * \version LibVLC 1.1.1 or later
+ */
+LIBVLC_API int64_t libvlc_audio_get_delay( libvlc_media_player_t *p_mi );
+
+/**
+ * Set current audio delay. The audio delay will be reset to zero each time the media changes.
+ *
+ * \param p_mi media player
+ * \param i_delay the audio delay (microseconds)
+ * \return 0 on success, -1 on error
+ * \version LibVLC 1.1.1 or later
+ */
+LIBVLC_API int libvlc_audio_set_delay( libvlc_media_player_t *p_mi, int64_t i_delay );
+
+/**
+ * Get the number of equalizer presets.
+ *
+ * \return number of presets
+ * \version LibVLC 2.2.0 or later
+ */
+LIBVLC_API unsigned libvlc_audio_equalizer_get_preset_count( void );
+
+/**
+ * Get the name of a particular equalizer preset.
+ *
+ * This name can be used, for example, to prepare a preset label or menu in a user
+ * interface.
+ *
+ * \param u_index index of the preset, counting from zero
+ * \return preset name, or NULL if there is no such preset
+ * \version LibVLC 2.2.0 or later
+ */
+LIBVLC_API const char *libvlc_audio_equalizer_get_preset_name( unsigned u_index );
+
+/**
+ * Get the number of distinct frequency bands for an equalizer.
+ *
+ * \return number of frequency bands
+ * \version LibVLC 2.2.0 or later
+ */
+LIBVLC_API unsigned libvlc_audio_equalizer_get_band_count( void );
+
+/**
+ * Get a particular equalizer band frequency.
+ *
+ * This value can be used, for example, to create a label for an equalizer band control
+ * in a user interface.
+ *
+ * \param u_index index of the band, counting from zero
+ * \return equalizer band frequency (Hz), or -1 if there is no such band
+ * \version LibVLC 2.2.0 or later
+ */
+LIBVLC_API float libvlc_audio_equalizer_get_band_frequency( unsigned u_index );
+
+/**
+ * Create a new default equalizer, with all frequency values zeroed.
+ *
+ * The new equalizer can subsequently be applied to a media player by invoking
+ * libvlc_media_player_set_equalizer().
+ *
+ * The returned handle should be freed via libvlc_audio_equalizer_release() when
+ * it is no longer needed.
+ *
+ * \return opaque equalizer handle, or NULL on error
+ * \version LibVLC 2.2.0 or later
+ */
+LIBVLC_API libvlc_equalizer_t *libvlc_audio_equalizer_new( void );
+
+/**
+ * Create a new equalizer, with initial frequency values copied from an existing
+ * preset.
+ *
+ * The new equalizer can subsequently be applied to a media player by invoking
+ * libvlc_media_player_set_equalizer().
+ *
+ * The returned handle should be freed via libvlc_audio_equalizer_release() when
+ * it is no longer needed.
+ *
+ * \param u_index index of the preset, counting from zero
+ * \return opaque equalizer handle, or NULL on error
+ * (it must be released with libvlc_audio_equalizer_release())
+ * \version LibVLC 2.2.0 or later
+ */
+LIBVLC_API libvlc_equalizer_t *libvlc_audio_equalizer_new_from_preset( unsigned u_index );
+
+/**
+ * Release a previously created equalizer instance.
+ *
+ * The equalizer was previously created by using libvlc_audio_equalizer_new() or
+ * libvlc_audio_equalizer_new_from_preset().
+ *
+ * It is safe to invoke this method with a NULL p_equalizer parameter for no effect.
+ *
+ * \param p_equalizer opaque equalizer handle, or NULL
+ * \version LibVLC 2.2.0 or later
+ */
+LIBVLC_API void libvlc_audio_equalizer_release( libvlc_equalizer_t *p_equalizer );
+
+/**
+ * Set a new pre-amplification value for an equalizer.
+ *
+ * The new equalizer settings are subsequently applied to a media player by invoking
+ * libvlc_media_player_set_equalizer().
+ *
+ * The supplied amplification value will be clamped to the -20.0 to +20.0 range.
+ *
+ * \param p_equalizer valid equalizer handle, must not be NULL
+ * \param f_preamp preamp value (-20.0 to 20.0 Hz)
+ * \return zero on success, -1 on error
+ * \version LibVLC 2.2.0 or later
+ */
+LIBVLC_API int libvlc_audio_equalizer_set_preamp( libvlc_equalizer_t *p_equalizer, float f_preamp );
+
+/**
+ * Get the current pre-amplification value from an equalizer.
+ *
+ * \param p_equalizer valid equalizer handle, must not be NULL
+ * \return preamp value (Hz)
+ * \version LibVLC 2.2.0 or later
+ */
+LIBVLC_API float libvlc_audio_equalizer_get_preamp( libvlc_equalizer_t *p_equalizer );
+
+/**
+ * Set a new amplification value for a particular equalizer frequency band.
+ *
+ * The new equalizer settings are subsequently applied to a media player by invoking
+ * libvlc_media_player_set_equalizer().
+ *
+ * The supplied amplification value will be clamped to the -20.0 to +20.0 range.
+ *
+ * \param p_equalizer valid equalizer handle, must not be NULL
+ * \param f_amp amplification value (-20.0 to 20.0 Hz)
+ * \param u_band index, counting from zero, of the frequency band to set
+ * \return zero on success, -1 on error
+ * \version LibVLC 2.2.0 or later
+ */
+LIBVLC_API int libvlc_audio_equalizer_set_amp_at_index( libvlc_equalizer_t *p_equalizer, float f_amp, unsigned u_band );
+
+/**
+ * Get the amplification value for a particular equalizer frequency band.
+ *
+ * \param p_equalizer valid equalizer handle, must not be NULL
+ * \param u_band index, counting from zero, of the frequency band to get
+ * \return amplification value (Hz); NaN if there is no such frequency band
+ * \version LibVLC 2.2.0 or later
+ */
+LIBVLC_API float libvlc_audio_equalizer_get_amp_at_index( libvlc_equalizer_t *p_equalizer, unsigned u_band );
+
+/**
+ * Apply new equalizer settings to a media player.
+ *
+ * The equalizer is first created by invoking libvlc_audio_equalizer_new() or
+ * libvlc_audio_equalizer_new_from_preset().
+ *
+ * It is possible to apply new equalizer settings to a media player whether the media
+ * player is currently playing media or not.
+ *
+ * Invoking this method will immediately apply the new equalizer settings to the audio
+ * output of the currently playing media if there is any.
+ *
+ * If there is no currently playing media, the new equalizer settings will be applied
+ * later if and when new media is played.
+ *
+ * Equalizer settings will automatically be applied to subsequently played media.
+ *
+ * To disable the equalizer for a media player invoke this method passing NULL for the
+ * p_equalizer parameter.
+ *
+ * The media player does not keep a reference to the supplied equalizer so it is safe
+ * for an application to release the equalizer reference any time after this method
+ * returns.
+ *
+ * \param p_mi opaque media player handle
+ * \param p_equalizer opaque equalizer handle, or NULL to disable the equalizer for this media player
+ * \return zero on success, -1 on error
+ * \version LibVLC 2.2.0 or later
+ */
+LIBVLC_API int libvlc_media_player_set_equalizer( libvlc_media_player_t *p_mi, libvlc_equalizer_t *p_equalizer );
+
+/**
+ * Media player roles.
+ *
+ * \version LibVLC 3.0.0 and later.
+ *
+ * See \ref libvlc_media_player_set_role()
+ */
+typedef enum libvlc_media_player_role {
+ libvlc_role_None = 0, /**< Don't use a media player role */
+ libvlc_role_Music, /**< Music (or radio) playback */
+ libvlc_role_Video, /**< Video playback */
+ libvlc_role_Communication, /**< Speech, real-time communication */
+ libvlc_role_Game, /**< Video game */
+ libvlc_role_Notification, /**< User interaction feedback */
+ libvlc_role_Animation, /**< Embedded animation (e.g. in web page) */
+ libvlc_role_Production, /**< Audio editing/production */
+ libvlc_role_Accessibility, /**< Accessibility */
+ libvlc_role_Test /** Testing */
+#define libvlc_role_Last libvlc_role_Test
+} libvlc_media_player_role_t;
+
+/**
+ * Gets the media role.
+ *
+ * \version LibVLC 3.0.0 and later.
+ *
+ * \param p_mi media player
+ * \return the media player role (\ref libvlc_media_player_role_t)
+ */
+LIBVLC_API int libvlc_media_player_get_role(libvlc_media_player_t *p_mi);
+
+/**
+ * Sets the media role.
+ *
+ * \param p_mi media player
+ * \param role the media player role (\ref libvlc_media_player_role_t)
+ * \return 0 on success, -1 on error
+ */
+LIBVLC_API int libvlc_media_player_set_role(libvlc_media_player_t *p_mi,
+ unsigned role);
+
+/**
+ * Start/stop recording
+ *
+ * \note The user should listen to the libvlc_MediaPlayerRecordChanged event,
+ * to monitor the recording state.
+ *
+ * \version LibVLC 4.0.0 and later.
+ *
+ * \param p_mi media player
+ * \param enable true to start recording, false to stop
+ * \param dir_path path of the recording directory or NULL (use default path),
+ * has only an effect when first enabling recording.
+ */
+LIBVLC_API void libvlc_media_player_record(libvlc_media_player_t *p_mi,
+ bool enable, const char *dir_path);
+
+/** @} audio */
+
+/** \defgroup libvlc_media_player_watch_time LibVLC media player time watch API
+ * @{
+ */
+
+/**
+ * Media Player timer point
+ *
+ * \note ts and system_date values should not be used directly by the user.
+ * libvlc_media_player_time_point_interpolate() will read these values and
+ * return an interpolated ts.
+ *
+ * @see libvlc_media_player_watch_time_on_update
+ */
+typedef struct libvlc_media_player_time_point_t
+{
+ /** Position in the range [0.0f;1.0] */
+ double position;
+ /** Rate of the player */
+ double rate;
+ /** Valid time, in us >= 0 or -1 */
+ int64_t ts_us;
+ /** Valid length, in us >= 1 or 0 */
+ int64_t length_us;
+ /**
+ * System date, in us, of this record (always valid).
+ * Based on libvlc_clock(). This date can be in the future or in the past.
+ * The special value of INT64_MAX mean that the clock was paused when this
+ * point was updated. In that case,
+ * libvlc_media_player_time_point_interpolate() will return the current
+ * ts/pos of this point (there is nothing to interpolate).
+ * */
+ int64_t system_date_us;
+} libvlc_media_player_time_point_t;
+
+/**
+ * Callback prototype that notify when the player state or time changed.
+ *
+ * Get notified when the time is updated by the input or output source. The
+ * input source is the 'demux' or the 'access_demux'. The output source are
+ * audio and video outputs: an update is received each time a video frame is
+ * displayed or an audio sample is written. The delay between each updates may
+ * depend on the input and source type (it can be every 5ms, 30ms, 1s or
+ * 10s...). Users of this timer may need to update the position at a higher
+ * frequency from their own mainloop via
+ * libvlc_media_player_time_point_interpolate().
+ *
+ * \warning It is forbidden to call any Media Player functions from here.
+ *
+ * \param value always valid, the time corresponding to the state
+ * \param data opaque pointer set by libvlc_media_player_watch_time()
+ */
+typedef void (*libvlc_media_player_watch_time_on_update)(
+ const libvlc_media_player_time_point_t *value, void *data);
+
+/**
+ * Callback prototype that notify when the timer is paused.
+ *
+ * This event is sent when the player is paused or stopping. The player
+ * user should stop its "interpolate" timer.
+ *
+ * \note libvlc_media_player_watch_time_on_update() can be called when paused
+ * for those 2 reasons:
+ * - playback is resumed (libvlc_media_player_time_point_t.system_date is valid)
+ * - a track, likely video (next-frame) is outputted when paused
+ * (libvlc_media_player_time_point_t.system_date = INT64_MAX)
+ *
+ * \warning It is forbidden to call any Media Player functions from here.
+ *
+ * \param system_date_us system date, in us, of this event, only valid (> 0)
+ * when paused. It can be used to interpolate the last updated point to this
+ * date in order to get the last paused ts/position.
+ * \param data opaque pointer set by libvlc_media_player_watch_time()
+ */
+typedef void (*libvlc_media_player_watch_time_on_paused)(
+ int64_t system_date_us, void *data);
+
+/**
+ * Callback prototype that notify when the player is seeking or finished
+ * seeking
+ *
+ * \warning It is forbidden to call any Media Player functions from here.
+ *
+ * \note It is not possible to receive points via on_update() while seeking.
+ *
+ * \param value point of the seek request or NULL when seeking is finished
+ * \param data opaque pointer set by libvlc_media_player_watch_time()
+ */
+typedef void (*libvlc_media_player_watch_time_on_seek)(
+ const libvlc_media_player_time_point_t *value, void *data);
+
+/**
+ * Watch for times updates
+ *
+ * \warning Only one watcher can be registered at a time. Calling this function
+ * a second time (if libvlc_media_player_unwatch_time() was not called
+ * in-between) will fail.
+ *
+ * \param p_mi the media player
+ * \param min_period_us corresponds to the minimum period, in us, between each
+ * updates, use it to avoid flood from too many source updates, set it to 0 to
+ * receive all updates.
+ * \param on_update callback to listen to update events (must not be NULL)
+ * \param on_paused callback to listen to paused events (can be NULL)
+ * \param on_seek callback to listen to seek events (can be NULL)
+ * \param cbs_data opaque pointer used by the callbacks
+ * \return 0 on success, -1 on error (allocation error, or if already watching)
+ * \version LibVLC 4.0.0 or later
+ */
+LIBVLC_API int
+libvlc_media_player_watch_time(libvlc_media_player_t *p_mi,
+ int64_t min_period_us,
+ libvlc_media_player_watch_time_on_update on_update,
+ libvlc_media_player_watch_time_on_paused on_paused,
+ libvlc_media_player_watch_time_on_seek on_seek,
+ void *cbs_data);
+
+/**
+ * Unwatch time updates
+ *
+ * \param p_mi the media player
+ * \version LibVLC 4.0.0 or later
+ */
+LIBVLC_API void
+libvlc_media_player_unwatch_time(libvlc_media_player_t *p_mi);
+
+/**
+ * Interpolate a timer value to now
+
+ * \param point time update obtained via the
+ * libvlc_media_player_watch_time_on_update() callback
+ * \param system_now_us current system date, in us, returned by libvlc_clock()
+ * \param out_ts_us pointer where to set the interpolated ts, in us
+ * \param out_pos pointer where to set the interpolated position
+ * \return 0 in case of success, -1 if the interpolated ts is negative (could
+ * happen during the buffering step)
+ * \version LibVLC 4.0.0 or later
+ */
+LIBVLC_API int
+libvlc_media_player_time_point_interpolate(const libvlc_media_player_time_point_t *point,
+ int64_t system_now_us,
+ int64_t *out_ts_us, double *out_pos);
+
+/**
+ * Get the date of the next interval
+ *
+ * Can be used to setup an UI timer in order to update some widgets at specific
+ * interval. A next_interval of VLC_TICK_FROM_SEC(1) can be used to update a
+ * time widget when the media reaches a new second.
+ *
+ * \note The media time doesn't necessarily correspond to the system time, that
+ * is why this function is needed and uses the rate of the current point.
+ *
+ * \param point time update obtained via the
+ * libvlc_media_player_watch_time_on_update()
+ * \param system_now_us same system date used by
+ * libvlc_media_player_time_point_interpolate()
+ * \param interpolated_ts_us ts returned by
+ * libvlc_media_player_time_point_interpolate()
+ * \param next_interval_us next interval, in us
+ * \return the absolute system date, in us, of the next interval,
+ * use libvlc_delay() to get a relative delay.
+ * \version LibVLC 4.0.0 or later
+ */
+LIBVLC_API int64_t
+libvlc_media_player_time_point_get_next_date(const libvlc_media_player_time_point_t *point,
+ int64_t system_now_us,
+ int64_t interpolated_ts_us,
+ int64_t next_interval_us);
+
+/** @} libvlc_media_player_watch_time */
+
+/** \defgroup libvlc_media_player_concurrency LibVLC media player concurrency API
+ * @{
+ */
+
+/**
+ * Lock the media_player internal lock
+
+ * The lock is recursive, so it's safe to use it multiple times from the same
+ * thread. You must call libvlc_media_player_unlock() the same number of times
+ * you called libvlc_media_player_lock().
+ *
+ * Locking is not mandatory before calling a libvlc_media_player_t function
+ * since they will automatically hold the lock internally.
+ *
+ * This lock can be used to synchronise user variables that interact with the
+ * libvlc_media_player_t or can be used to call several functions together.
+ *
+ * \param mp media player object
+ * \version LibVLC 4.0.0 or later
+ */
+LIBVLC_API void libvlc_media_player_lock( libvlc_media_player_t *mp );
+
+/**
+ * Unlock the media_player internal lock
+ *
+ * \see libvlc_media_player_lock
+ *
+ * \param mp media player object locked using /ref libvlc_media_player_lock
+ * \version LibVLC 4.0.0 or later
+ */
+LIBVLC_API void libvlc_media_player_unlock( libvlc_media_player_t *mp );
+
+/**
+ * Wait for an event to be signalled
+ *
+ * \note this is equivalent to pthread_cond_wait() with the
+ * libvlc_media_player_t internal mutex and condition variable. This function
+ * may spuriously wake up even without libvlc_media_player_signal() being
+ * called.
+ *
+ * \warning this function must not be called from any libvlc callbacks and
+ * events. The lock should be held only one time before waiting.
+ *
+ * \param mp media player object locked using /ref libvlc_media_player_lock
+ * \version LibVLC 4.0.0 or later
+ */
+LIBVLC_API void libvlc_media_player_wait( libvlc_media_player_t *mp );
+
+/**
+ * Signal all threads waiting for a signalling event
+ *
+ * \note this is equivalent to pthread_cond_broadcast() with the
+ * libvlc_media_player_t internal condition variable.
+ *
+ * \param mp media player object locked using /ref libvlc_media_player_lock
+ * \version LibVLC 4.0.0 or later
+ */
+LIBVLC_API void libvlc_media_player_signal( libvlc_media_player_t *mp );
+
+/** @} libvlc_media_player_concurrency */
+
+/** @} media_player */
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif /* VLC_LIBVLC_MEDIA_PLAYER_H */
diff --git a/Libs/vlc/libvlc_media_track.h b/Libs/vlc/libvlc_media_track.h
new file mode 100644
index 000000000..d44c12e5e
--- /dev/null
+++ b/Libs/vlc/libvlc_media_track.h
@@ -0,0 +1,212 @@
+/*****************************************************************************
+ * libvlc_media_track.h: libvlc external API
+ *****************************************************************************
+ * Copyright (C) 1998-2020 VLC authors and VideoLAN
+ *
+ * Authors: Clément Stenac
+ * Jean-Paul Saman
+ * Pierre d'Herbemont
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef VLC_LIBVLC_MEDIA_TRACK_H
+#define VLC_LIBVLC_MEDIA_TRACK_H 1
+
+# include "libvlc_video.h"
+
+# ifdef __cplusplus
+extern "C" {
+# else
+# include
+# endif
+
+/** \defgroup libvlc_media_track LibVLC media track
+ * \ingroup libvlc
+ * @ref libvlc_media_track_t is an abstract representation of a media track.
+ * @{
+ * \file
+ * LibVLC media track
+ */
+
+typedef enum libvlc_track_type_t
+{
+ libvlc_track_unknown = -1,
+ libvlc_track_audio = 0,
+ libvlc_track_video = 1,
+ libvlc_track_text = 2
+} libvlc_track_type_t;
+
+typedef struct libvlc_audio_track_t
+{
+ unsigned i_channels;
+ unsigned i_rate;
+} libvlc_audio_track_t;
+
+/**
+ * Viewpoint
+ *
+ * \warning allocate using libvlc_video_new_viewpoint()
+ */
+typedef struct libvlc_video_viewpoint_t
+{
+ float f_yaw; /**< view point yaw in degrees ]-180;180] */
+ float f_pitch; /**< view point pitch in degrees ]-90;90] */
+ float f_roll; /**< view point roll in degrees ]-180;180] */
+ float f_field_of_view; /**< field of view in degrees ]0;180[ (default 80.)*/
+} libvlc_video_viewpoint_t;
+
+typedef struct libvlc_video_track_t
+{
+ unsigned i_height;
+ unsigned i_width;
+ unsigned i_sar_num;
+ unsigned i_sar_den;
+ unsigned i_frame_rate_num;
+ unsigned i_frame_rate_den;
+
+ libvlc_video_orient_t i_orientation;
+ libvlc_video_projection_t i_projection;
+ libvlc_video_viewpoint_t pose; /**< Initial view point */
+ libvlc_video_multiview_t i_multiview;
+} libvlc_video_track_t;
+
+typedef struct libvlc_subtitle_track_t
+{
+ char *psz_encoding;
+} libvlc_subtitle_track_t;
+
+typedef struct libvlc_media_track_t
+{
+ /* Codec fourcc */
+ uint32_t i_codec;
+ uint32_t i_original_fourcc;
+ int i_id; /* DEPRECATED: use psz_id */
+ libvlc_track_type_t i_type;
+
+ /* Codec specific */
+ int i_profile;
+ int i_level;
+
+ union {
+ libvlc_audio_track_t *audio;
+ libvlc_video_track_t *video;
+ libvlc_subtitle_track_t *subtitle;
+ };
+
+ unsigned int i_bitrate;
+ char *psz_language;
+ char *psz_description;
+
+ /** String identifier of track, can be used to save the track preference
+ * from an other LibVLC run */
+ const char *psz_id;
+ /** A string identifier is stable when it is certified to be the same
+ * across different playback instances for the same track. */
+ bool id_stable;
+ /** Name of the track, only valid when the track is fetch from a
+ * media_player */
+ char *psz_name;
+ /** true if the track is selected, only valid when the track is fetch from
+ * a media_player */
+ bool selected;
+
+} libvlc_media_track_t;
+
+/**
+ * Opaque struct containing a list of tracks
+ */
+typedef struct libvlc_media_tracklist_t libvlc_media_tracklist_t;
+
+/**
+ * Get the number of tracks in a tracklist
+ *
+ * \version LibVLC 4.0.0 and later.
+ *
+ * \param list valid tracklist
+ *
+ * \return number of tracks, or 0 if the list is empty
+ */
+LIBVLC_API size_t
+libvlc_media_tracklist_count( const libvlc_media_tracklist_t *list );
+
+/**
+ * Get a track at a specific index
+ *
+ * \warning The behaviour is undefined if the index is not valid.
+ *
+ * \version LibVLC 4.0.0 and later.
+ *
+ * \param list valid tracklist
+ * \param index valid index in the range [0; count[
+ *
+ * \return a valid track (can't be NULL if libvlc_media_tracklist_count()
+ * returned a valid count)
+ */
+LIBVLC_API libvlc_media_track_t *
+libvlc_media_tracklist_at( libvlc_media_tracklist_t *list, size_t index );
+
+/**
+ * Release a tracklist
+ *
+ * \version LibVLC 4.0.0 and later.
+ *
+ * \see libvlc_media_get_tracklist
+ * \see libvlc_media_player_get_tracklist
+ *
+ * \param list valid tracklist
+ */
+LIBVLC_API void
+libvlc_media_tracklist_delete( libvlc_media_tracklist_t *list );
+
+
+/**
+ * Hold a single track reference
+ *
+ * \version LibVLC 4.0.0 and later.
+ *
+ * This function can be used to hold a track from a tracklist. In that case,
+ * the track can outlive its tracklist.
+ *
+ * \param track valid track
+ * \return the same track, need to be released with libvlc_media_track_release()
+ */
+LIBVLC_API libvlc_media_track_t *
+libvlc_media_track_hold( libvlc_media_track_t *track );
+
+/**
+ * Release a single track
+ *
+ * \version LibVLC 4.0.0 and later.
+ *
+ * \warning Tracks from a tracklist are released alongside the list with
+ * libvlc_media_tracklist_delete().
+ *
+ * \note You only need to release tracks previously held with
+ * libvlc_media_track_hold() or returned by
+ * libvlc_media_player_get_selected_track() and
+ * libvlc_media_player_get_track_from_id()
+ *
+ * \param track valid track
+ */
+LIBVLC_API void
+libvlc_media_track_release( libvlc_media_track_t *track );
+/** @}*/
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif /* VLC_LIBVLC_MEDIA_TRACK_H */
diff --git a/Libs/vlc/libvlc_picture.h b/Libs/vlc/libvlc_picture.h
new file mode 100644
index 000000000..24e1d565d
--- /dev/null
+++ b/Libs/vlc/libvlc_picture.h
@@ -0,0 +1,151 @@
+/*****************************************************************************
+ * libvlc_picture.h: libvlc external API
+ *****************************************************************************
+ * Copyright (C) 2018 VLC authors and VideoLAN
+ *
+ * Authors: Hugo Beauzée-Luyssen
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef VLC_LIBVLC_PICTURE_H
+#define VLC_LIBVLC_PICTURE_H 1
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+typedef struct libvlc_picture_t libvlc_picture_t;
+typedef struct libvlc_picture_list_t libvlc_picture_list_t;
+
+typedef enum libvlc_picture_type_t
+{
+ libvlc_picture_Argb,
+ libvlc_picture_Png,
+ libvlc_picture_Jpg,
+ libvlc_picture_WebP,
+} libvlc_picture_type_t;
+
+/**
+ * Increment the reference count of this picture.
+ *
+ * \see libvlc_picture_release()
+ * \param pic A picture object
+ * \return the same object
+ */
+LIBVLC_API libvlc_picture_t *
+libvlc_picture_retain( libvlc_picture_t* pic );
+
+/**
+ * Decrement the reference count of this picture.
+ * When the reference count reaches 0, the picture will be released.
+ * The picture must not be accessed after calling this function.
+ *
+ * \see libvlc_picture_retain
+ * \param pic A picture object
+ */
+LIBVLC_API void
+libvlc_picture_release( libvlc_picture_t* pic );
+
+/**
+ * Saves this picture to a file. The image format is the same as the one
+ * returned by \link libvlc_picture_type \endlink
+ *
+ * \param pic A picture object
+ * \param path The path to the generated file
+ * \return 0 in case of success, -1 otherwise
+ */
+LIBVLC_API int
+libvlc_picture_save( const libvlc_picture_t* pic, const char* path );
+
+/**
+ * Returns the image internal buffer, including potential padding.
+ * The libvlc_picture_t owns the returned buffer, which must not be modified nor
+ * freed.
+ *
+ * \param pic A picture object
+ * \param size A pointer to a size_t that will hold the size of the buffer [required]
+ * \return A pointer to the internal buffer.
+ */
+LIBVLC_API const unsigned char*
+libvlc_picture_get_buffer( const libvlc_picture_t* pic, size_t *size );
+
+/**
+ * Returns the picture type
+ *
+ * \param pic A picture object
+ * \see libvlc_picture_type_t
+ */
+LIBVLC_API libvlc_picture_type_t
+libvlc_picture_type( const libvlc_picture_t* pic );
+
+/**
+ * Returns the image stride, ie. the number of bytes per line.
+ * This can only be called on images of type libvlc_picture_Argb
+ *
+ * \param pic A picture object
+ */
+LIBVLC_API unsigned int
+libvlc_picture_get_stride( const libvlc_picture_t* pic );
+
+/**
+ * Returns the width of the image in pixels
+ *
+ * \param pic A picture object
+ */
+LIBVLC_API unsigned int
+libvlc_picture_get_width( const libvlc_picture_t* pic );
+
+/**
+ * Returns the height of the image in pixels
+ *
+ * \param pic A picture object
+ */
+LIBVLC_API unsigned int
+libvlc_picture_get_height( const libvlc_picture_t* pic );
+
+/**
+ * Returns the time at which this picture was generated, in milliseconds
+ * \param pic A picture object
+ */
+LIBVLC_API libvlc_time_t
+libvlc_picture_get_time( const libvlc_picture_t* pic );
+
+/**
+ * Returns the number of pictures in the list
+ */
+LIBVLC_API size_t libvlc_picture_list_count( const libvlc_picture_list_t* list );
+
+/**
+ * Returns the picture at the provided index.
+ *
+ * If the index is out of bound, the result is undefined.
+ */
+LIBVLC_API libvlc_picture_t* libvlc_picture_list_at( const libvlc_picture_list_t* list,
+ size_t index );
+
+/**
+ * Destroys a picture list and releases the pictures it contains
+ * \param list The list to destroy
+ *
+ * Calling this function with a NULL list is safe and will return immediately
+ */
+LIBVLC_API void libvlc_picture_list_destroy( libvlc_picture_list_t* list );
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif // VLC_LIBVLC_PICTURE_H
diff --git a/Libs/vlc/libvlc_renderer_discoverer.h b/Libs/vlc/libvlc_renderer_discoverer.h
new file mode 100644
index 000000000..e63a8c9c2
--- /dev/null
+++ b/Libs/vlc/libvlc_renderer_discoverer.h
@@ -0,0 +1,255 @@
+/*****************************************************************************
+ * libvlc_renderer_discoverer.h: libvlc external API
+ *****************************************************************************
+ * Copyright © 2016 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef VLC_LIBVLC_RENDERER_DISCOVERER_H
+#define VLC_LIBVLC_RENDERER_DISCOVERER_H 1
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+/**
+ * @defgroup libvlc_renderer_discoverer LibVLC renderer discoverer
+ * @ingroup libvlc
+ * LibVLC renderer discoverer finds available renderers available on the local
+ * network
+ * @{
+ * @file
+ * LibVLC renderer discoverer external API
+ */
+
+typedef struct libvlc_renderer_discoverer_t libvlc_renderer_discoverer_t;
+
+/**
+ * Renderer discoverer description
+ *
+ * \see libvlc_renderer_discoverer_list_get()
+ */
+typedef struct libvlc_rd_description_t
+{
+ char *psz_name;
+ char *psz_longname;
+} libvlc_rd_description_t;
+
+/** The renderer can render audio */
+#define LIBVLC_RENDERER_CAN_AUDIO 0x0001
+/** The renderer can render video */
+#define LIBVLC_RENDERER_CAN_VIDEO 0x0002
+
+/**
+ * Renderer item
+ *
+ * This struct is passed by a @ref libvlc_event_t when a new renderer is added
+ * or deleted.
+ *
+ * An item is valid until the @ref libvlc_RendererDiscovererItemDeleted event
+ * is called with the same pointer.
+ *
+ * \see libvlc_renderer_discoverer_event_manager()
+ */
+typedef struct libvlc_renderer_item_t libvlc_renderer_item_t;
+
+
+/**
+ * Hold a renderer item, i.e. creates a new reference
+ *
+ * This functions need to called from the libvlc_RendererDiscovererItemAdded
+ * callback if the libvlc user wants to use this item after. (for display or
+ * for passing it to the mediaplayer for example).
+ *
+ * \version LibVLC 3.0.0 or later
+ *
+ * \return the current item
+ */
+LIBVLC_API libvlc_renderer_item_t *
+libvlc_renderer_item_hold(libvlc_renderer_item_t *p_item);
+
+/**
+ * Releases a renderer item, i.e. decrements its reference counter
+ *
+ * \version LibVLC 3.0.0 or later
+ */
+LIBVLC_API void
+libvlc_renderer_item_release(libvlc_renderer_item_t *p_item);
+
+/**
+ * Get the human readable name of a renderer item
+ *
+ * \version LibVLC 3.0.0 or later
+ *
+ * \return the name of the item (can't be NULL, must *not* be freed)
+ */
+LIBVLC_API const char *
+libvlc_renderer_item_name(const libvlc_renderer_item_t *p_item);
+
+/**
+ * Get the type (not translated) of a renderer item. For now, the type can only
+ * be "chromecast" ("upnp", "airplay" may come later).
+ *
+ * \version LibVLC 3.0.0 or later
+ *
+ * \return the type of the item (can't be NULL, must *not* be freed)
+ */
+LIBVLC_API const char *
+libvlc_renderer_item_type(const libvlc_renderer_item_t *p_item);
+
+/**
+ * Get the icon uri of a renderer item
+ *
+ * \version LibVLC 3.0.0 or later
+ *
+ * \return the uri of the item's icon (can be NULL, must *not* be freed)
+ */
+LIBVLC_API const char *
+libvlc_renderer_item_icon_uri(const libvlc_renderer_item_t *p_item);
+
+/**
+ * Get the flags of a renderer item
+ *
+ * \see LIBVLC_RENDERER_CAN_AUDIO
+ * \see LIBVLC_RENDERER_CAN_VIDEO
+ *
+ * \version LibVLC 3.0.0 or later
+ *
+ * \return bitwise flag: capabilities of the renderer, see
+ */
+LIBVLC_API int
+libvlc_renderer_item_flags(const libvlc_renderer_item_t *p_item);
+
+/**
+ * Create a renderer discoverer object by name
+ *
+ * After this object is created, you should attach to events in order to be
+ * notified of the discoverer events.
+ *
+ * You need to call libvlc_renderer_discoverer_start() in order to start the
+ * discovery.
+ *
+ * \see libvlc_renderer_discoverer_event_manager()
+ * \see libvlc_renderer_discoverer_start()
+ *
+ * \version LibVLC 3.0.0 or later
+ *
+ * \param p_inst libvlc instance
+ * \param psz_name service name; use libvlc_renderer_discoverer_list_get() to
+ * get a list of the discoverer names available in this libVLC instance
+ * \return media discover object or NULL in case of error
+ */
+LIBVLC_API libvlc_renderer_discoverer_t *
+libvlc_renderer_discoverer_new( libvlc_instance_t *p_inst,
+ const char *psz_name );
+
+/**
+ * Release a renderer discoverer object
+ *
+ * \version LibVLC 3.0.0 or later
+ *
+ * \param p_rd renderer discoverer object
+ */
+LIBVLC_API void
+libvlc_renderer_discoverer_release( libvlc_renderer_discoverer_t *p_rd );
+
+/**
+ * Start renderer discovery
+ *
+ * To stop it, call libvlc_renderer_discoverer_stop() or
+ * libvlc_renderer_discoverer_release() directly.
+ *
+ * \see libvlc_renderer_discoverer_stop()
+ *
+ * \version LibVLC 3.0.0 or later
+ *
+ * \param p_rd renderer discoverer object
+ * \return -1 in case of error, 0 otherwise
+ */
+LIBVLC_API int
+libvlc_renderer_discoverer_start( libvlc_renderer_discoverer_t *p_rd );
+
+/**
+ * Stop renderer discovery.
+ *
+ * \see libvlc_renderer_discoverer_start()
+ *
+ * \version LibVLC 3.0.0 or later
+ *
+ * \param p_rd renderer discoverer object
+ */
+LIBVLC_API void
+libvlc_renderer_discoverer_stop( libvlc_renderer_discoverer_t *p_rd );
+
+/**
+ * Get the event manager of the renderer discoverer
+ *
+ * The possible events to attach are @ref libvlc_RendererDiscovererItemAdded
+ * and @ref libvlc_RendererDiscovererItemDeleted.
+ *
+ * The @ref libvlc_renderer_item_t struct passed to event callbacks is owned by
+ * VLC, users should take care of holding/releasing this struct for their
+ * internal usage.
+ *
+ * \see libvlc_event_t.u.renderer_discoverer_item_added.item
+ * \see libvlc_event_t.u.renderer_discoverer_item_removed.item
+ *
+ * \version LibVLC 3.0.0 or later
+ *
+ * \return a valid event manager (can't fail)
+ */
+LIBVLC_API libvlc_event_manager_t *
+libvlc_renderer_discoverer_event_manager( libvlc_renderer_discoverer_t *p_rd );
+
+/**
+ * Get media discoverer services
+ *
+ * \see libvlc_renderer_list_release()
+ *
+ * \version LibVLC 3.0.0 and later
+ *
+ * \param p_inst libvlc instance
+ * \param ppp_services address to store an allocated array of renderer
+ * discoverer services (must be freed with libvlc_renderer_list_release() by
+ * the caller) [OUT]
+ *
+ * \return the number of media discoverer services (0 on error)
+ */
+LIBVLC_API size_t
+libvlc_renderer_discoverer_list_get( libvlc_instance_t *p_inst,
+ libvlc_rd_description_t ***ppp_services );
+
+/**
+ * Release an array of media discoverer services
+ *
+ * \see libvlc_renderer_discoverer_list_get()
+ *
+ * \version LibVLC 3.0.0 and later
+ *
+ * \param pp_services array to release
+ * \param i_count number of elements in the array
+ */
+LIBVLC_API void
+libvlc_renderer_discoverer_list_release( libvlc_rd_description_t **pp_services,
+ size_t i_count );
+
+/** @} */
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif
diff --git a/Libs/vlc/libvlc_version.h b/Libs/vlc/libvlc_version.h
new file mode 100644
index 000000000..a7fd2cddf
--- /dev/null
+++ b/Libs/vlc/libvlc_version.h
@@ -0,0 +1,79 @@
+/*****************************************************************************
+ * libvlc_version.h
+ *****************************************************************************
+ * Copyright (C) 2010 Rémi Denis-Courmont
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+/**
+ * \file
+ * This file defines version macros for LibVLC.
+ * Those macros are primilarly intended for conditional (pre)compilation.
+ * To get the run-time LibVLC version, use libvlc_get_version() instead
+ * (the run-time version may be more recent than build-time one, thanks to
+ * backward binary compatibility).
+ *
+ * \version This header file is available in LibVLC 1.1.4 and higher.
+ */
+
+#ifndef LIBVLC_VERSION_H
+# define LIBVLC_VERSION_H 1
+
+/** LibVLC major version number */
+# define LIBVLC_VERSION_MAJOR (4)
+
+/** LibVLC minor version number */
+# define LIBVLC_VERSION_MINOR (0)
+
+/** LibVLC revision */
+# define LIBVLC_VERSION_REVISION (0)
+
+# define LIBVLC_VERSION_EXTRA (0)
+
+/** Makes a single integer from a LibVLC version numbers */
+# define LIBVLC_VERSION(maj,min,rev,extra) \
+ ((maj << 24) | (min << 16) | (rev << 8) | (extra))
+
+/** LibVLC full version as a single integer (for comparison) */
+# define LIBVLC_VERSION_INT \
+ LIBVLC_VERSION(LIBVLC_VERSION_MAJOR, LIBVLC_VERSION_MINOR, \
+ LIBVLC_VERSION_REVISION, LIBVLC_VERSION_EXTRA)
+
+
+/** LibVLC ABI major version number, updated when incompatible changes are added */
+# define LIBVLC_ABI_VERSION_MAJOR (12)
+
+/** LibVLC ABI minor version number, updated when compatible changes are added */
+# define LIBVLC_ABI_VERSION_MINOR (0)
+
+/** LibVLC ABI micro version number, updated with new releases */
+# define LIBVLC_ABI_VERSION_MICRO (0)
+
+/** LibVLC full ABI version combining the major VLC version and the .so version:
+ * - A 0xFF000000 mask gives the VLC major version,
+ * - A 0x00FF0000 mask gives the LibVLC major ABI version,
+ * - A 0x0000FF00 mask gives the LibVLC minor ABI version,
+ * - A 0x000000FF mask gives the LibVLC ABI revision.
+ *
+ * LibVLC is considered compatible with your code if the VLC major and LibVLC
+ * major values are equal and the minor ABI version is equal or higher than the
+ * value you compiled with.
+ */
+# define LIBVLC_ABI_VERSION_INT \
+ LIBVLC_VERSION(LIBVLC_VERSION_MAJOR, LIBVLC_ABI_VERSION_MAJOR, \
+ LIBVLC_ABI_VERSION_MINOR, LIBVLC_ABI_VERSION_MICRO )
+
+#endif
diff --git a/Libs/vlc/libvlc_video.h b/Libs/vlc/libvlc_video.h
new file mode 100644
index 000000000..afe2b45a7
--- /dev/null
+++ b/Libs/vlc/libvlc_video.h
@@ -0,0 +1,67 @@
+/*****************************************************************************
+ * libvlc_video.h: libvlc video-related enumerations
+ *****************************************************************************
+ * Copyright (C) 1998-2010 VLC authors and VideoLAN
+ * Copyright (C) 2023 Videolabs
+ *
+ * Authors: Filippo Carone
+ * Pierre d'Herbemont
+ * Alexandre Janniaux
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+#ifndef VLC_LIBVLC_VIDEO_H
+#define VLC_LIBVLC_VIDEO_H 1
+
+# ifdef __cplusplus
+extern "C"{
+# endif
+
+typedef enum libvlc_video_orient_t
+{
+ libvlc_video_orient_top_left, /**< Normal. Top line represents top, left column left. */
+ libvlc_video_orient_top_right, /**< Flipped horizontally */
+ libvlc_video_orient_bottom_left, /**< Flipped vertically */
+ libvlc_video_orient_bottom_right, /**< Rotated 180 degrees */
+ libvlc_video_orient_left_top, /**< Transposed */
+ libvlc_video_orient_left_bottom, /**< Rotated 90 degrees clockwise (or 270 anti-clockwise) */
+ libvlc_video_orient_right_top, /**< Rotated 90 degrees anti-clockwise */
+ libvlc_video_orient_right_bottom /**< Anti-transposed */
+} libvlc_video_orient_t;
+
+typedef enum libvlc_video_projection_t
+{
+ libvlc_video_projection_rectangular,
+ libvlc_video_projection_equirectangular, /**< 360 spherical */
+
+ libvlc_video_projection_cubemap_layout_standard = 0x100,
+} libvlc_video_projection_t;
+
+typedef enum libvlc_video_multiview_t
+{
+ libvlc_video_multiview_2d, /**< No stereoscopy: 2D picture. */
+ libvlc_video_multiview_stereo_sbs, /**< Side-by-side */
+ libvlc_video_multiview_stereo_tb, /**< Top-bottom */
+ libvlc_video_multiview_stereo_row, /**< Row sequential */
+ libvlc_video_multiview_stereo_col, /**< Column sequential */
+ libvlc_video_multiview_stereo_frame, /**< Frame sequential */
+ libvlc_video_multiview_stereo_checkerboard, /**< Checkerboard pattern */
+} libvlc_video_multiview_t;
+
+# ifdef __cplusplus
+} // extern "C"
+# endif
+
+#endif
diff --git a/Libs/vlc/vlc.h b/Libs/vlc/vlc.h
new file mode 100644
index 000000000..1413d9b1b
--- /dev/null
+++ b/Libs/vlc/vlc.h
@@ -0,0 +1,55 @@
+/*****************************************************************************
+ * vlc.h: global header for libvlc
+ *****************************************************************************
+ * Copyright (C) 1998-2008 VLC authors and VideoLAN
+ *
+ * Authors: Vincent Seguin
+ * Samuel Hocevar
+ * Gildas Bazin
+ * Derk-Jan Hartman
+ * Pierre d'Herbemont
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef VLC_VLC_H
+#define VLC_VLC_H 1
+
+/**
+ * \file
+ * This file defines libvlc new external API
+ */
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+#include "libvlc.h"
+#include "libvlc_renderer_discoverer.h"
+#include "libvlc_picture.h"
+#include "libvlc_media.h"
+#include "libvlc_media_player.h"
+#include "libvlc_media_list.h"
+#include "libvlc_media_list_player.h"
+#include "libvlc_media_discoverer.h"
+#include "libvlc_events.h"
+#include "libvlc_dialog.h"
+#include "libvlc_version.h"
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif /* _VLC_VLC_H */
diff --git a/Libs/vlc/x64/libvlc.dll b/Libs/vlc/x64/libvlc.dll
new file mode 100644
index 0000000000000000000000000000000000000000..f66e2b5a4fdd589d410b1aae3a6a65116fd70da1
GIT binary patch
literal 170496
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