From 0417f9e2e83ec7d30f95464b9fc7d71666d7706c Mon Sep 17 00:00:00 2001
From: "T. Okubo" <t.okubo.rx78+devel@gmail.com>
Date: Thu, 21 Nov 2019 20:00:26 +0900
Subject: [PATCH 01/28] Add libvlc-sys crate

---
 .gitignore            |  1 +
 libvlc-sys/Cargo.toml | 14 ++++++++++++++
 libvlc-sys/build.rs   | 24 ++++++++++++++++++++++++
 libvlc-sys/src/lib.rs |  6 ++++++
 libvlc-sys/wrapper.h  |  1 +
 5 files changed, 46 insertions(+)
 create mode 100644 libvlc-sys/Cargo.toml
 create mode 100644 libvlc-sys/build.rs
 create mode 100644 libvlc-sys/src/lib.rs
 create mode 100644 libvlc-sys/wrapper.h

diff --git a/.gitignore b/.gitignore
index 94408df..2ad8632 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,4 +9,5 @@
 
 # Generated by Cargo
 /target/
+/libvlc-sys/target
 Cargo.lock
diff --git a/libvlc-sys/Cargo.toml b/libvlc-sys/Cargo.toml
new file mode 100644
index 0000000..e855636
--- /dev/null
+++ b/libvlc-sys/Cargo.toml
@@ -0,0 +1,14 @@
+[package]
+name = "libvlc-sys"
+version = "0.1.0"
+authors = ["T. Okubo <t.okubo.rx78+devel@gmail.com>"]
+edition = "2018"
+build = "build.rs"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+libc = "0.2"
+
+[build-dependencies]
+bindgen = "0.52"
\ No newline at end of file
diff --git a/libvlc-sys/build.rs b/libvlc-sys/build.rs
new file mode 100644
index 0000000..e62ec93
--- /dev/null
+++ b/libvlc-sys/build.rs
@@ -0,0 +1,24 @@
+use bindgen;
+
+use std::env;
+use std::path::PathBuf;
+
+fn main() {
+    println!("cargo:rustc-link-lib=libvlc");
+    println!("cargo:rerun-if-changed=wrapper.h");
+
+    let bindings = bindgen::Builder::default()
+        .header("wrapper.h")
+        // For no_std
+        .use_core()
+        // Use libc
+        .ctypes_prefix("libc")
+        .parse_callbacks(Box::new(bindgen::CargoCallbacks))
+        .generate()
+        .expect("Unable to generate bindings");
+
+    let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
+    bindings
+        .write_to_file(out_path.join("bindings.rs"))
+        .expect("Couldn't write bindings!");
+}
diff --git a/libvlc-sys/src/lib.rs b/libvlc-sys/src/lib.rs
new file mode 100644
index 0000000..da4a48d
--- /dev/null
+++ b/libvlc-sys/src/lib.rs
@@ -0,0 +1,6 @@
+#![allow(non_upper_case_globals)]
+#![allow(non_camel_case_types)]
+#![allow(non_snake_case)]
+#![no_std]
+
+include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
diff --git a/libvlc-sys/wrapper.h b/libvlc-sys/wrapper.h
new file mode 100644
index 0000000..6fd7ccc
--- /dev/null
+++ b/libvlc-sys/wrapper.h
@@ -0,0 +1 @@
+#include <vlc/vlc.h>

From 73e8e21637bf231b55d3a1ba291fb70602b07eab Mon Sep 17 00:00:00 2001
From: "T. Okubo" <t.okubo.rx78+devel@gmail.com>
Date: Sat, 23 Nov 2019 20:12:56 +0900
Subject: [PATCH 02/28] Add libvlc-sys to dependencies

---
 Cargo.toml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Cargo.toml b/Cargo.toml
index faf9be5..3f10934 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -16,3 +16,4 @@ crate-type = ["rlib"]
 
 [dependencies]
 libc = "0.2"
+libvlc-sys = { path = "libvlc-sys" }

From 28fafc02f57f1e004ddd983812d023a662e14f8d Mon Sep 17 00:00:00 2001
From: "T. Okubo" <t.okubo.rx78+devel@gmail.com>
Date: Sat, 23 Nov 2019 20:13:41 +0900
Subject: [PATCH 03/28] Fix link lib

---
 libvlc-sys/build.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libvlc-sys/build.rs b/libvlc-sys/build.rs
index e62ec93..c8489cc 100644
--- a/libvlc-sys/build.rs
+++ b/libvlc-sys/build.rs
@@ -4,7 +4,7 @@ use std::env;
 use std::path::PathBuf;
 
 fn main() {
-    println!("cargo:rustc-link-lib=libvlc");
+    println!("cargo:rustc-link-lib=vlc");
     println!("cargo:rerun-if-changed=wrapper.h");
 
     let bindings = bindgen::Builder::default()

From c52205075c85852b787ff11c16cef6a01178d4b0 Mon Sep 17 00:00:00 2001
From: "T. Okubo" <t.okubo.rx78+devel@gmail.com>
Date: Sat, 23 Nov 2019 20:14:44 +0900
Subject: [PATCH 04/28] Rewrite enums to use libvlc-sys symbols

---
 src/core.rs  |   4 +-
 src/enums.rs | 304 ++++++++++++++++++++++++++-------------------------
 2 files changed, 160 insertions(+), 148 deletions(-)

diff --git a/src/core.rs b/src/core.rs
index 003ad11..2cab1b6 100644
--- a/src/core.rs
+++ b/src/core.rs
@@ -154,7 +154,7 @@ unsafe extern "C" fn logging_cb(
 
     vsnprintf(buf.as_mut_ptr(), BUF_SIZE, fmt, args);
 
-    f(::std::mem::transmute(level), Log{ptr: ctx}, from_cstr_ref(buf.as_ptr()).unwrap());
+    f((level as u32).into(), Log{ptr: ctx}, from_cstr_ref(buf.as_ptr()).unwrap());
 }
 
 /// List of module description.
@@ -349,7 +349,7 @@ unsafe extern "C" fn event_manager_callback(pe: *const sys::libvlc_event_t, data
 
 // Convert c-style libvlc_event_t to Event
 fn conv_event(pe: *const sys::libvlc_event_t) -> Event {
-    let event_type: EventType = unsafe{ ::std::mem::transmute((*pe)._type) };
+    let event_type: EventType = (unsafe{ (*pe)._type } as u32).into();
 
     match event_type {
         EventType::MediaMetaChanged => {
diff --git a/src/enums.rs b/src/enums.rs
index c957b60..1522532 100644
--- a/src/enums.rs
+++ b/src/enums.rs
@@ -2,158 +2,170 @@
 // This file is part of vlc-rs.
 // Licensed under the MIT license, see the LICENSE file.
 
-#[repr(C)]
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
-pub enum LogLevel {
-    Debug = 0,
-    Notice = 2,
-    Warning = 3,
-    Error = 4,
+use libvlc_sys as sys;
+
+macro_rules! define_enum {
+    ($enum_name:ident, $original_type:ident; $($value:ident = $c_value:ident,)*) => {
+        #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
+        #[repr(C)]
+        pub enum $enum_name {
+            $(
+                $value = sys::$c_value as isize,
+            )*
+        }
+
+        impl From<sys::$original_type> for $enum_name {
+            fn from(a: sys::$original_type) -> Self {
+                match a {
+                    $(
+                        sys::$c_value => Self::$value,
+                    )*
+                    _ => unreachable!(),
+                }
+            }
+        }
+    }
 }
 
-#[repr(C)]
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
-pub enum Meta {
-    Title,
-    Artist,
-    Genre,
-    Copyright,
-    Album,
-    TrackNumber,
-    Description,
-    Rating,
-    Date,
-    Setting,
-    URL,
-    Language,
-    NowPlaying,
-    Publisher,
-    EncodedBy,
-    ArtworkURL,
-    TrackID,
-    TrackTotal,
-    Director,
-    Season,
-    Episode,
-    ShowName,
-    Actors
-}
+define_enum!(
+    LogLevel, libvlc_log_level;
+    Debug = libvlc_log_level_LIBVLC_DEBUG,
+    Dotice = libvlc_log_level_LIBVLC_NOTICE,
+    Warning = libvlc_log_level_LIBVLC_WARNING,
+    Error = libvlc_log_level_LIBVLC_ERROR,
+);
 
-#[repr(C)]
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
-pub enum State {
-    NothingSpecial = 0,
-    Opening,
-    Buffering,
-    Playing,
-    Paused,
-    Stopped,
-    Ended,
-    Error
-}
+define_enum!(
+    Meta, libvlc_meta_t;
+    Title = libvlc_meta_t_libvlc_meta_Title,
+    Artist = libvlc_meta_t_libvlc_meta_Artist,
+    Genre = libvlc_meta_t_libvlc_meta_Genre,
+    Copyright = libvlc_meta_t_libvlc_meta_Copyright,
+    Album = libvlc_meta_t_libvlc_meta_Album,
+    TrackNumber = libvlc_meta_t_libvlc_meta_TrackNumber,
+    Description = libvlc_meta_t_libvlc_meta_Description,
+    Rating = libvlc_meta_t_libvlc_meta_Rating,
+    Date = libvlc_meta_t_libvlc_meta_Date,
+    Setting = libvlc_meta_t_libvlc_meta_Setting,
+    URL = libvlc_meta_t_libvlc_meta_URL,
+    Language = libvlc_meta_t_libvlc_meta_Language,
+    NowPlaying = libvlc_meta_t_libvlc_meta_NowPlaying,
+    Publisher = libvlc_meta_t_libvlc_meta_Publisher,
+    EncodedBy = libvlc_meta_t_libvlc_meta_EncodedBy,
+    ArtworkURL = libvlc_meta_t_libvlc_meta_ArtworkURL,
+    TrackID = libvlc_meta_t_libvlc_meta_TrackID,
+    TrackTotal = libvlc_meta_t_libvlc_meta_TrackTotal,
+    Director = libvlc_meta_t_libvlc_meta_Director,
+    Season = libvlc_meta_t_libvlc_meta_Season,
+    Episode = libvlc_meta_t_libvlc_meta_Episode,
+    ShowName = libvlc_meta_t_libvlc_meta_ShowName,
+    Actors = libvlc_meta_t_libvlc_meta_Actors,
+);
 
-#[repr(C)]
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
-pub enum TrackType {
-    Unknown = -1,
-    Audio   = 0,
-    Video   = 1,
-    Text    = 2
-}
+define_enum!(
+    State, libvlc_state_t;
+    NothingSpecial = libvlc_state_t_libvlc_NothingSpecial,
+    Opening = libvlc_state_t_libvlc_Opening,
+    Buffering = libvlc_state_t_libvlc_Buffering,
+    Playing = libvlc_state_t_libvlc_Playing,
+    Paused = libvlc_state_t_libvlc_Paused,
+    Stopped = libvlc_state_t_libvlc_Stopped,
+    Ended = libvlc_state_t_libvlc_Ended,
+    Error = libvlc_state_t_libvlc_Error,
+);
 
-#[repr(C)]
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
-pub enum Position {
-    Disable = -1,
-    Center,
-    Left,
-    Right,
-    Top,
-    TopLeft,
-    TopRight,
-    Bottom,
-    BottomLeft,
-    BottomRight,
-}
+define_enum!(
+    TrackType, libvlc_track_type_t;
+    Unknown = libvlc_track_type_t_libvlc_track_unknown,
+    Audio = libvlc_track_type_t_libvlc_track_audio,
+    Video = libvlc_track_type_t_libvlc_track_video,
+    Text = libvlc_track_type_t_libvlc_track_text,
+);
 
-#[repr(C)]
-#[derive(Clone, Copy, Debug)]
-pub enum VideoAdjustOption {
-    Enable = 0,
-    Contrast,
-    Brightness,
-    Hue,
-    Saturation,
-    Gamma
-}
+define_enum!(
+    Position, libvlc_position_t;
+    Disable = libvlc_position_t_libvlc_position_disable,
+    Center = libvlc_position_t_libvlc_position_center,
+    Left = libvlc_position_t_libvlc_position_left,
+    Right = libvlc_position_t_libvlc_position_right,
+    Top = libvlc_position_t_libvlc_position_top,
+    TopLeft = libvlc_position_t_libvlc_position_top_left,
+    TopRight = libvlc_position_t_libvlc_position_top_right,
+    Bottom = libvlc_position_t_libvlc_position_bottom,
+    BottomLeft = libvlc_position_t_libvlc_position_bottom_left,
+    BottomRight = libvlc_position_t_libvlc_position_bottom_right,
+);
 
-// #[repr(C)]
-// #[derive(Clone, Copy, PartialEq, Eq, Debug)]
-// pub enum ParseFlag {
-//     ParseLocal,
-//     ParseNetwork,
-//     FetchLocal,
-//     FetchNetwork,
-// }
+define_enum!(
+    VideoAdjustOption, libvlc_video_adjust_option_t;
+    Enable = libvlc_video_adjust_option_t_libvlc_adjust_Enable,
+    Contrast = libvlc_video_adjust_option_t_libvlc_adjust_Contrast,
+    Brightness = libvlc_video_adjust_option_t_libvlc_adjust_Brightness,
+    Hue = libvlc_video_adjust_option_t_libvlc_adjust_Hue,
+    Saturation = libvlc_video_adjust_option_t_libvlc_adjust_Saturation,
+    Gamma = libvlc_video_adjust_option_t_libvlc_adjust_Gamma,
+);
 
-#[repr(C)]
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
-pub enum EventType {
-    MediaMetaChanged = 0,
-    MediaSubItemAdded,
-    MediaDurationChanged,
-    MediaParsedChanged,
-    MediaFreed,
-    MediaStateChanged,
-    MediaSubItemTreeAdded,
+define_enum!(
+    ParseFlag, libvlc_media_parse_flag_t;
+    DoInteract = libvlc_media_parse_flag_t_libvlc_media_do_interact,
+    FetchLocal = libvlc_media_parse_flag_t_libvlc_media_fetch_local,
+    FetchNetwork = libvlc_media_parse_flag_t_libvlc_media_fetch_network,
+    ParseLocal = libvlc_media_parse_flag_t_libvlc_media_parse_local,
+    ParseNetwork = libvlc_media_parse_flag_t_libvlc_media_parse_network,
+);
 
-    MediaPlayerMediaChanged = 0x100,
-    MediaPlayerNothingSpecial,
-    MediaPlayerOpening,
-    MediaPlayerBuffering,
-    MediaPlayerPlaying,
-    MediaPlayerPaused,
-    MediaPlayerStopped,
-    MediaPlayerForward,
-    MediaPlayerBackward,
-    MediaPlayerEndReached,
-    MediaPlayerEncounteredError,
-    MediaPlayerTimeChanged,
-    MediaPlayerPositionChanged,
-    MediaPlayerSeekableChanged,
-    MediaPlayerPausableChanged,
-    MediaPlayerTitleChanged,
-    MediaPlayerSnapshotTaken,
-    MediaPlayerLengthChanged,
-    MediaPlayerVout,
-    MediaPlayerScrambledChanged,
-
-    MediaListItemAdded = 0x200,
-    MediaListWillAddItem,
-    MediaListItemDeleted,
-    MediaListWillDeleteItem,
-
-    MediaListViewItemAdded = 0x300,
-    MediaListViewWillAddItem,
-    MediaListViewItemDeleted,
-    MediaListViewWillDeleteItem,
-
-    MediaListPlayerPlayed = 0x400,
-    MediaListPlayerNextItemSet,
-    MediaListPlayerStopped,
-
-    MediaDiscovererStarted = 0x500,
-    MediaDiscovererEnded,
-
-    VlmMediaAdded = 0x600,
-    VlmMediaRemoved,
-    VlmMediaChanged,
-    VlmMediaInstanceStarted,
-    VlmMediaInstanceStopped,
-    VlmMediaInstanceStatusInit,
-    VlmMediaInstanceStatusOpening,
-    VlmMediaInstanceStatusPlaying,
-    VlmMediaInstanceStatusPause,
-    VlmMediaInstanceStatusEnd,
-    VlmMediaInstanceStatusError
-}
+define_enum!(
+    EventType, libvlc_event_e;
+    MediaMetaChanged = libvlc_event_e_libvlc_MediaMetaChanged,
+    MediaSubItemAdded = libvlc_event_e_libvlc_MediaSubItemAdded,
+    MediaDurationChanged = libvlc_event_e_libvlc_MediaDurationChanged,
+    MediaParsedChanged = libvlc_event_e_libvlc_MediaParsedChanged,
+    MediaFreed = libvlc_event_e_libvlc_MediaFreed,
+    MediaStateChanged = libvlc_event_e_libvlc_MediaStateChanged,
+    MediaSubItemTreeAdded = libvlc_event_e_libvlc_MediaSubItemTreeAdded,
+    MediaPlayerMediaChanged = libvlc_event_e_libvlc_MediaPlayerMediaChanged,
+    MediaPlayerNothingSpecial = libvlc_event_e_libvlc_MediaPlayerNothingSpecial,
+    MediaPlayerOpening = libvlc_event_e_libvlc_MediaPlayerOpening,
+    MediaPlayerBuffering = libvlc_event_e_libvlc_MediaPlayerBuffering,
+    MediaPlayerPlaying = libvlc_event_e_libvlc_MediaPlayerPlaying,
+    MediaPlayerPaused = libvlc_event_e_libvlc_MediaPlayerPaused,
+    MediaPlayerStopped = libvlc_event_e_libvlc_MediaPlayerStopped,
+    MediaPlayerForward = libvlc_event_e_libvlc_MediaPlayerForward,
+    MediaPlayerBackward = libvlc_event_e_libvlc_MediaPlayerBackward,
+    MediaPlayerEndReached = libvlc_event_e_libvlc_MediaPlayerEndReached,
+    MediaPlayerEncounteredError = libvlc_event_e_libvlc_MediaPlayerEncounteredError,
+    MediaPlayerTimeChanged = libvlc_event_e_libvlc_MediaPlayerTimeChanged,
+    MediaPlayerPositionChanged = libvlc_event_e_libvlc_MediaPlayerPositionChanged,
+    MediaPlayerSeekableChanged = libvlc_event_e_libvlc_MediaPlayerSeekableChanged,
+    MediaPlayerPausableChanged = libvlc_event_e_libvlc_MediaPlayerPausableChanged,
+    MediaPlayerTitleChanged = libvlc_event_e_libvlc_MediaPlayerTitleChanged,
+    MediaPlayerSnapshotTaken = libvlc_event_e_libvlc_MediaPlayerSnapshotTaken,
+    MediaPlayerLengthChanged = libvlc_event_e_libvlc_MediaPlayerLengthChanged,
+    MediaPlayerVout = libvlc_event_e_libvlc_MediaPlayerVout,
+    MediaPlayerScrambledChanged = libvlc_event_e_libvlc_MediaPlayerScrambledChanged,
+    MediaListItemAdded = libvlc_event_e_libvlc_MediaListItemAdded,
+    MediaListWillAddItem = libvlc_event_e_libvlc_MediaListWillAddItem,
+    MediaListItemDeleted = libvlc_event_e_libvlc_MediaListItemDeleted,
+    MediaListWillDeleteItem = libvlc_event_e_libvlc_MediaListWillDeleteItem,
+    MediaListViewItemAdded = libvlc_event_e_libvlc_MediaListViewItemAdded,
+    MediaListViewWillAddItem = libvlc_event_e_libvlc_MediaListViewWillAddItem,
+    MediaListViewItemDeleted = libvlc_event_e_libvlc_MediaListViewItemDeleted,
+    MediaListViewWillDeleteItem = libvlc_event_e_libvlc_MediaListViewWillDeleteItem,
+    MediaListPlayerPlayed = libvlc_event_e_libvlc_MediaListPlayerPlayed,
+    MediaListPlayerNextItemSet = libvlc_event_e_libvlc_MediaListPlayerNextItemSet,
+    MediaListPlayerStopped = libvlc_event_e_libvlc_MediaListPlayerStopped,
+    MediaDiscovererStarted = libvlc_event_e_libvlc_MediaDiscovererStarted,
+    MediaDiscovererEnded = libvlc_event_e_libvlc_MediaDiscovererEnded,
+    VlmMediaAdded = libvlc_event_e_libvlc_VlmMediaAdded,
+    VlmMediaRemoved = libvlc_event_e_libvlc_VlmMediaRemoved,
+    VlmMediaChanged = libvlc_event_e_libvlc_VlmMediaChanged,
+    VlmMediaInstanceStarted = libvlc_event_e_libvlc_VlmMediaInstanceStarted,
+    VlmMediaInstanceStopped = libvlc_event_e_libvlc_VlmMediaInstanceStopped,
+    VlmMediaInstanceStatusInit = libvlc_event_e_libvlc_VlmMediaInstanceStatusInit,
+    VlmMediaInstanceStatusOpening = libvlc_event_e_libvlc_VlmMediaInstanceStatusOpening,
+    VlmMediaInstanceStatusPlaying = libvlc_event_e_libvlc_VlmMediaInstanceStatusPlaying,
+    VlmMediaInstanceStatusPause = libvlc_event_e_libvlc_VlmMediaInstanceStatusPause,
+    VlmMediaInstanceStatusEnd = libvlc_event_e_libvlc_VlmMediaInstanceStatusEnd,
+    VlmMediaInstanceStatusError = libvlc_event_e_libvlc_VlmMediaInstanceStatusError,
+);

From b5b053dad2ebfaa8cca298d582a465edf3a00967 Mon Sep 17 00:00:00 2001
From: "T. Okubo" <t.okubo.rx78+devel@gmail.com>
Date: Sat, 23 Nov 2019 20:20:52 +0900
Subject: [PATCH 05/28] Add lib section to Cargo.toml

---
 libvlc-sys/Cargo.toml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/libvlc-sys/Cargo.toml b/libvlc-sys/Cargo.toml
index e855636..896f131 100644
--- a/libvlc-sys/Cargo.toml
+++ b/libvlc-sys/Cargo.toml
@@ -5,7 +5,9 @@ authors = ["T. Okubo <t.okubo.rx78+devel@gmail.com>"]
 edition = "2018"
 build = "build.rs"
 
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+[lib]
+name = "libvlc_sys"
+crate-type = ["rlib"]
 
 [dependencies]
 libc = "0.2"

From 1cc3be26dd027afb5f4b61078931c70516418e2e Mon Sep 17 00:00:00 2001
From: "T. Okubo" <t.okubo.rx78+devel@gmail.com>
Date: Sat, 23 Nov 2019 20:21:35 +0900
Subject: [PATCH 06/28] Add whitelist for bindgen

---
 libvlc-sys/build.rs | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/libvlc-sys/build.rs b/libvlc-sys/build.rs
index c8489cc..b37b8e2 100644
--- a/libvlc-sys/build.rs
+++ b/libvlc-sys/build.rs
@@ -13,6 +13,11 @@ fn main() {
         .use_core()
         // Use libc
         .ctypes_prefix("libc")
+        // Whitelist
+        .whitelist_type(".*vlc.*")
+        .whitelist_function(".*vlc.*")
+        .whitelist_var(".*vlc.*")
+        .whitelist_function("vsnprintf")
         .parse_callbacks(Box::new(bindgen::CargoCallbacks))
         .generate()
         .expect("Unable to generate bindings");

From 2ce884fc5c1d99fa4fff0b6873d46db48b686c9b Mon Sep 17 00:00:00 2001
From: "T. Okubo" <t.okubo.rx78+devel@gmail.com>
Date: Mon, 25 Nov 2019 20:10:17 +0900
Subject: [PATCH 07/28] Fix to use libvlc-sys

---
 libvlc-sys/Cargo.toml |  2 +-
 src/audio.rs          |  2 +-
 src/core.rs           | 21 ++++++++++-----------
 src/enums.rs          |  2 +-
 src/media.rs          | 19 ++++++++++---------
 src/media_library.rs  |  2 +-
 src/media_list.rs     |  2 +-
 src/media_player.rs   |  6 +++---
 src/video.rs          |  2 +-
 9 files changed, 29 insertions(+), 29 deletions(-)

diff --git a/libvlc-sys/Cargo.toml b/libvlc-sys/Cargo.toml
index 896f131..ae445ea 100644
--- a/libvlc-sys/Cargo.toml
+++ b/libvlc-sys/Cargo.toml
@@ -6,7 +6,7 @@ edition = "2018"
 build = "build.rs"
 
 [lib]
-name = "libvlc_sys"
+name = "vlc_sys"
 crate-type = ["rlib"]
 
 [dependencies]
diff --git a/src/audio.rs b/src/audio.rs
index 697e1c6..c39891c 100644
--- a/src/audio.rs
+++ b/src/audio.rs
@@ -2,7 +2,7 @@
 // This file is part of vlc-rs.
 // Licensed under the MIT license, see the LICENSE file.
 
-use crate::sys;
+use vlc_sys as sys;
 use crate::MediaPlayer;
 use crate::TrackDescription;
 use crate::tools::from_cstr;
diff --git a/src/core.rs b/src/core.rs
index 2cab1b6..433dbd6 100644
--- a/src/core.rs
+++ b/src/core.rs
@@ -7,8 +7,9 @@ use std::borrow::Cow;
 use std::marker::PhantomData;
 use std::ffi::CString;
 use std::i32;
+use std::convert::TryInto;
 use libc::{c_void, c_char, c_int};
-use crate::sys;
+use vlc_sys as sys;
 use crate::tools::{to_cstr, from_cstr, from_cstr_ref};
 use crate::enums::*;
 
@@ -124,7 +125,7 @@ impl Instance {
         let cb: Box<Box<dyn Fn(LogLevel, Log, Cow<str>) + Send + 'static>> = Box::new(Box::new(f));
 
         unsafe{
-            sys::libvlc_log_set(self.ptr, logging_cb, Box::into_raw(cb) as *mut _);
+            sys::libvlc_log_set(self.ptr, Some(logging_cb), Box::into_raw(cb) as *mut _);
         }
     }
 
@@ -142,17 +143,14 @@ impl Drop for Instance {
     }
 }
 
-extern "C" {
-    fn vsnprintf(s: *mut c_char, n: usize, fmt: *const c_char, arg: sys::va_list);
-}
 const BUF_SIZE: usize = 1024; // Write log message to the buffer by vsnprintf.
 unsafe extern "C" fn logging_cb(
-    data: *mut c_void, level: c_int, ctx: *const sys::libvlc_log_t, fmt: *const c_char, args: sys::va_list) {
+    data: *mut c_void, level: c_int, ctx: *const sys::libvlc_log_t, fmt: *const c_char, args: *mut sys::__va_list_tag) {
 
     let f: &Box<dyn Fn(LogLevel, Log, Cow<str>) + Send + 'static> = ::std::mem::transmute(data);
     let mut buf: [c_char; BUF_SIZE] = [0; BUF_SIZE];
 
-    vsnprintf(buf.as_mut_ptr(), BUF_SIZE, fmt, args);
+    sys::vsnprintf(buf.as_mut_ptr(), BUF_SIZE.try_into().unwrap(), fmt, args);
 
     f((level as u32).into(), Log{ptr: ctx}, from_cstr_ref(buf.as_ptr()).unwrap());
 }
@@ -324,7 +322,7 @@ impl<'a> EventManager<'a> {
 
         let result = unsafe{
             sys::libvlc_event_attach(
-                self.ptr, event_type as i32, event_manager_callback,
+                self.ptr, event_type as i32, Some(event_manager_callback),
                 Box::into_raw(callback) as *mut c_void)
         };
 
@@ -349,12 +347,12 @@ unsafe extern "C" fn event_manager_callback(pe: *const sys::libvlc_event_t, data
 
 // Convert c-style libvlc_event_t to Event
 fn conv_event(pe: *const sys::libvlc_event_t) -> Event {
-    let event_type: EventType = (unsafe{ (*pe)._type } as u32).into();
+    let event_type: EventType = (unsafe{ (*pe).type_ } as u32).into();
 
     match event_type {
         EventType::MediaMetaChanged => {
             unsafe{
-                Event::MediaMetaChanged((*pe).u.media_meta_changed.meta_type)
+                Event::MediaMetaChanged((*pe).u.media_meta_changed.meta_type.into())
             }
         },
         EventType::MediaSubItemAdded => {
@@ -375,7 +373,8 @@ fn conv_event(pe: *const sys::libvlc_event_t) -> Event {
         },
         EventType::MediaStateChanged => {
             unsafe{
-                Event::MediaStateChanged((*pe).u.media_state_changed.new_state)
+                let new_state: sys::libvlc_state_t = (*pe).u.media_state_changed.new_state.try_into().unwrap();
+                Event::MediaStateChanged(new_state.into())
             }
         },
         EventType::MediaSubItemTreeAdded => {
diff --git a/src/enums.rs b/src/enums.rs
index 1522532..93675f7 100644
--- a/src/enums.rs
+++ b/src/enums.rs
@@ -2,7 +2,7 @@
 // This file is part of vlc-rs.
 // Licensed under the MIT license, see the LICENSE file.
 
-use libvlc_sys as sys;
+use vlc_sys as sys;
 
 macro_rules! define_enum {
     ($enum_name:ident, $original_type:ident; $($value:ident = $c_value:ident,)*) => {
diff --git a/src/media.rs b/src/media.rs
index 4c4a44f..1805d8c 100644
--- a/src/media.rs
+++ b/src/media.rs
@@ -2,7 +2,7 @@
 // This file is part of vlc-rs.
 // Licensed under the MIT license, see the LICENSE file.
 
-use crate::sys;
+use vlc_sys as sys;
 use crate::{Instance, EventManager};
 use crate::enums::{State, Meta, TrackType};
 use crate::tools::{to_cstr, from_cstr, path_to_cstr};
@@ -76,7 +76,7 @@ impl Media {
     /// If the media has not yet been parsed this will return None.
     pub fn get_meta(&self, meta: Meta) -> Option<String> {
         unsafe{
-            let p_str = sys::libvlc_media_get_meta(self.ptr, meta);
+            let p_str = sys::libvlc_media_get_meta(self.ptr, meta as u32);
             let s = from_cstr(p_str);
             sys::libvlc_free(p_str as *mut ::libc::c_void);
             s
@@ -87,7 +87,7 @@ impl Media {
     /// (This function will not save the meta, call save_meta in order to save the meta)
     pub fn set_meta(&self, meta: Meta, value: &str) {
         unsafe{
-            sys::libvlc_media_set_meta(self.ptr, meta, to_cstr(value).as_ptr());
+            sys::libvlc_media_set_meta(self.ptr, meta as u32, to_cstr(value).as_ptr());
         }
     }
 
@@ -98,7 +98,7 @@ impl Media {
 
     /// Get current state of media descriptor object.
     pub fn state(&self) -> State {
-        unsafe{ sys::libvlc_media_get_state(self.ptr) }
+        unsafe{ sys::libvlc_media_get_state(self.ptr).into() }
     }
 
     /// Get duration (in ms) of media descriptor object item.
@@ -136,16 +136,17 @@ impl Media {
 
             for i in 0..n {
                 let p = p_track.offset(i as isize);
-                let type_specific_data = match (**p).i_type {
+                let i_type: TrackType = (**p).i_type.into();
+                let type_specific_data = match i_type {
                     TrackType::Audio => {
-                        let audio = (**p).audio();
+                        let audio = (**p).__bindgen_anon_1.audio;
                         MediaTrackUnion::Audio(AudioTrack{
                             channels: (*audio).i_channels,
                             rate:     (*audio).i_rate,
                         })
                     },
                     TrackType::Video => {
-                        let video = (**p).video();
+                        let video = (**p).__bindgen_anon_1.video;
                         MediaTrackUnion::Video(VideoTrack{
                             height:         (*video).i_height,
                             width:          (*video).i_width,
@@ -156,7 +157,7 @@ impl Media {
                         })
                     },
                     TrackType::Text => {
-                        let subtitle = (**p).subtitle();
+                        let subtitle = (**p).__bindgen_anon_1.subtitle;
                         MediaTrackUnion::Subtitle(SubtitleTrack{
                             encoding: from_cstr((*subtitle).psz_encoding)
                         })
@@ -167,7 +168,7 @@ impl Media {
                     codec:              (**p).i_codec,
                     original_fourcc:    (**p).i_original_fourcc,
                     id:                 (**p).i_id,
-                    track_type:         (**p).i_type,
+                    track_type:         (**p).i_type.into(),
                     profile:            (**p).i_profile,
                     level:              (**p).i_level,
                     bitrate:            (**p).i_bitrate,
diff --git a/src/media_library.rs b/src/media_library.rs
index e8e5551..3abf357 100644
--- a/src/media_library.rs
+++ b/src/media_library.rs
@@ -2,7 +2,7 @@
 // This file is part of vlc-rs.
 // Licensed under the MIT license, see the LICENSE file.
 
-use crate::sys;
+use vlc_sys as sys;
 use crate::{Instance, MediaList};
 
 pub struct MediaLibrary {
diff --git a/src/media_list.rs b/src/media_list.rs
index c6e2f5b..048d821 100644
--- a/src/media_list.rs
+++ b/src/media_list.rs
@@ -2,7 +2,7 @@
 // This file is part of vlc-rs.
 // Licensed under the MIT license, see the LICENSE file.
 
-use crate::sys;
+use vlc_sys as sys;
 use crate::{Instance, Media, EventManager};
 
 pub struct MediaList {
diff --git a/src/media_player.rs b/src/media_player.rs
index 8bbcc6f..0f9e5fd 100644
--- a/src/media_player.rs
+++ b/src/media_player.rs
@@ -2,7 +2,7 @@
 // This file is part of vlc-rs.
 // Licensed under the MIT license, see the LICENSE file.
 
-use crate::sys;
+use vlc_sys as sys;
 use crate::Instance;
 use crate::Media;
 use crate::EventManager;
@@ -265,7 +265,7 @@ impl MediaPlayer {
 
     /// Get current movie state.
     pub fn state(&self) -> State {
-        unsafe{ sys::libvlc_media_player_get_state(self.ptr) }
+        unsafe{ sys::libvlc_media_player_get_state(self.ptr) }.into()
     }
 
     /// How many video outputs does this media player have?
@@ -309,7 +309,7 @@ impl MediaPlayer {
 
     /// Set if, and how, the video title will be shown when media is played.
     pub fn set_video_title_display(&self, position: Position, timeout: u32) {
-        unsafe{ sys::libvlc_media_player_set_video_title_display(self.ptr, position, timeout); }
+        unsafe{ sys::libvlc_media_player_set_video_title_display(self.ptr, position as i32, timeout); }
     }
 
     /// Returns raw pointer
diff --git a/src/video.rs b/src/video.rs
index a71bd82..e9ca4fc 100644
--- a/src/video.rs
+++ b/src/video.rs
@@ -2,7 +2,7 @@
 // This file is part of vlc-rs.
 // Licensed under the MIT license, see the LICENSE file.
 
-use crate::sys;
+use vlc_sys as sys;
 use crate::MediaPlayer;
 use crate::TrackDescription;
 use crate::enums::VideoAdjustOption;

From 469c81dd8ea078278f0d8834a28e371132dccffb Mon Sep 17 00:00:00 2001
From: "T. Okubo" <t.okubo.rx78+devel@gmail.com>
Date: Thu, 28 Nov 2019 19:42:33 +0900
Subject: [PATCH 08/28] Use vlc_sys in vlm

---
 src/vlm.rs | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/vlm.rs b/src/vlm.rs
index 9ad7283..0f03cab 100644
--- a/src/vlm.rs
+++ b/src/vlm.rs
@@ -2,7 +2,8 @@ use std::ffi::CString;
 use std::os::raw::c_char;
 use std::ptr;
 
-use crate::{Instance, sys};
+use vlc_sys as sys;
+use crate::Instance;
 use crate::tools::{from_cstr, to_cstr};
 
 pub trait Vlm {

From b82a40571af8ea0fc1a41523c187d21013dbf659 Mon Sep 17 00:00:00 2001
From: "T. Okubo" <t.okubo.rx78+devel@gmail.com>
Date: Thu, 28 Nov 2019 20:01:56 +0900
Subject: [PATCH 09/28] Fix warning

---
 src/core.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core.rs b/src/core.rs
index 9d217f2..8ba4ce2 100644
--- a/src/core.rs
+++ b/src/core.rs
@@ -5,7 +5,7 @@
 use std::ptr;
 use std::borrow::Cow;
 use std::marker::PhantomData;
-use std::ffi::{CString, CStr};
+use std::ffi::CString;
 use std::i32;
 use std::convert::TryInto;
 use libc::{c_void, c_char, c_int};

From 48683a905fa6ffde10c1a8cc3a07ddde055377ff Mon Sep 17 00:00:00 2001
From: "T. Okubo" <t.okubo.rx78+devel@gmail.com>
Date: Thu, 28 Nov 2019 20:15:56 +0900
Subject: [PATCH 10/28] Add feature v3_00

---
 Cargo.toml   | 4 ++++
 src/enums.rs | 1 +
 2 files changed, 5 insertions(+)

diff --git a/Cargo.toml b/Cargo.toml
index 3f10934..61c3203 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -17,3 +17,7 @@ crate-type = ["rlib"]
 [dependencies]
 libc = "0.2"
 libvlc-sys = { path = "libvlc-sys" }
+
+[features]
+default = []
+v3_00 = []
diff --git a/src/enums.rs b/src/enums.rs
index 93675f7..8d73157 100644
--- a/src/enums.rs
+++ b/src/enums.rs
@@ -106,6 +106,7 @@ define_enum!(
     Gamma = libvlc_video_adjust_option_t_libvlc_adjust_Gamma,
 );
 
+#[cfg(feature = "v3_00")]
 define_enum!(
     ParseFlag, libvlc_media_parse_flag_t;
     DoInteract = libvlc_media_parse_flag_t_libvlc_media_do_interact,

From aa188aa0f0c4084aaffc36d0df34f62feed4359e Mon Sep 17 00:00:00 2001
From: "T. Okubo" <t.okubo.rx78+devel@gmail.com>
Date: Thu, 28 Nov 2019 20:19:54 +0900
Subject: [PATCH 11/28] Remove old hand-written sys

---
 src/lib.rs |   2 -
 src/sys.rs | 853 -----------------------------------------------------
 2 files changed, 855 deletions(-)
 delete mode 100644 src/sys.rs

diff --git a/src/lib.rs b/src/lib.rs
index db9d611..5fdb4f8 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -4,8 +4,6 @@
 
 extern crate libc;
 
-pub mod sys;
-
 mod tools;
 mod core;
 mod media;
diff --git a/src/sys.rs b/src/sys.rs
deleted file mode 100644
index 7221369..0000000
--- a/src/sys.rs
+++ /dev/null
@@ -1,853 +0,0 @@
-// Copyright (c) 2015 T. Okubo
-// This file is part of vlc-rs.
-// Licensed under the MIT license, see the LICENSE file.
-
-#![allow(non_camel_case_types, non_upper_case_globals)]
-
-#[link(name = "vlc")]
-extern "C" {}
-
-use libc::{c_void, c_int, c_uint, c_char, c_float, uintptr_t, FILE};
-
-pub type c_bool = u8;
-
-pub type libvlc_event_type_t = c_int;
-
-// From libvlc_structures.h
-pub enum libvlc_instance_t {}
-pub enum libvlc_log_iterator_t {}
-
-pub type libvlc_time_t = i64;
-
-#[repr(C)]
-#[derive(Clone, Copy)]
-pub struct libvlc_log_message_t {
-    pub i_severity: c_int,
-    pub psz_type: *const c_char,
-    pub psz_name: *const c_char,
-    pub psz_header: *const c_char,
-    pub psz_message: *const c_char,
-}
-
-// From libvlc.h
-pub enum libvlc_event_manager_t {}
-pub enum libvlc_log_t {}
-pub enum vlc_log_t {}
-
-pub type libvlc_callback_t = unsafe extern "C" fn(*const libvlc_event_t, *mut c_void);
-pub type va_list = *mut c_void;
-pub type libvlc_log_cb = unsafe extern "C" fn(*mut c_void, c_int, *const libvlc_log_t, *const c_char, va_list);
-
-pub use crate::enums::LogLevel as libvlc_log_level;
-
-#[repr(C)]
-#[derive(Clone, Copy)]
-pub struct libvlc_module_description_t
-{
-    pub psz_name: *const c_char,
-    pub psz_shortname: *const c_char,
-    pub psz_longname: *const c_char,
-    pub psz_help: *const c_char,
-    pub p_next: *mut libvlc_module_description_t,
-}
-
-extern "C" {
-    pub fn libvlc_errmsg() -> *const c_char;
-    pub fn libvlc_clearerr();
-    pub fn libvlc_new(argc: c_int, argv: *const *const c_char) -> *mut libvlc_instance_t;
-    pub fn libvlc_release(p_instance: *mut libvlc_instance_t);
-    pub fn libvlc_retain(p_instance: *mut libvlc_instance_t);
-    pub fn libvlc_add_intf(p_instance: *mut libvlc_instance_t, name: *const c_char) -> c_int;
-    pub fn libvlc_set_exit_handler(
-        p_instance: *mut libvlc_instance_t,
-        cb: extern "C" fn(*mut c_void), opaque: *mut c_void);
-    pub fn libvlc_wait(p_instance: *mut libvlc_instance_t);
-    pub fn libvlc_set_user_agent(
-        p_instance: *mut libvlc_instance_t, name: *const c_char, http: *const c_char);
-    pub fn libvlc_set_app_id(
-        p_instance: *mut libvlc_instance_t, id: *const c_char, version: *const c_char,
-        icon: *const c_char);
-    pub fn libvlc_get_version() -> *const c_char;
-    pub fn libvlc_get_compiler() -> *const c_char;
-    pub fn libvlc_get_changeset() -> *const c_char;
-    pub fn libvlc_free(ptr: *mut c_void);
-    pub fn libvlc_event_attach(
-        p_event_manager: *mut libvlc_event_manager_t, i_event_type: libvlc_event_type_t,
-        f_callback: libvlc_callback_t, user_data: *mut c_void) -> c_int;
-    pub fn libvlc_event_type_name(event_type: libvlc_event_type_t) -> *const c_char;
-    pub fn libvlc_log_get_context(
-        ctx: *const libvlc_log_t, module: *const *const c_char, file: *const *const c_char,
-        line: *mut c_uint);
-    pub fn libvlc_log_get_object(
-        ctx: *const libvlc_log_t, name: *const *const c_char,
-        header: *const *const c_char, id: *mut uintptr_t);
-    pub fn libvlc_log_unset(_: *mut libvlc_instance_t);
-    pub fn libvlc_log_set(instance: *mut libvlc_instance_t, cb: libvlc_log_cb, data: *mut c_void);
-    pub fn libvlc_log_set_file(_: *mut libvlc_instance_t, stream: *mut FILE);
-    pub fn libvlc_module_description_list_release(p_list: *mut libvlc_module_description_t);
-    pub fn libvlc_audio_filter_list_get(
-        p_instance: *mut libvlc_instance_t) -> *mut libvlc_module_description_t;
-    pub fn libvlc_video_filter_list_get(
-        p_instance: *mut libvlc_instance_t) -> *mut libvlc_module_description_t;
-    pub fn libvlc_clock() -> i64;
-}
-
-pub unsafe fn libvlc_delay(pts: i64) -> i64 {
-    pts - libvlc_clock()
-}
-
-// From libvlc_media.h
-pub enum libvlc_media_t {}
-
-pub use crate::enums::Meta as libvlc_meta_t;
-pub use crate::enums::State as libvlc_state_t;
-
-pub const libvlc_media_option_trusted: u32 = 0x2;
-pub const libvlc_media_option_unique: u32 = 0x100;
-
-pub use crate::enums::TrackType as libvlc_track_type_t;
-
-#[repr(C)]
-#[derive(Clone, Copy)]
-pub struct libvlc_media_stats_t {
-    /* Input */
-    pub i_read_bytes: c_int,
-    pub f_input_bitrate: c_float,
-    /* Demux */
-    pub i_demux_read_bytes: c_int,
-    pub f_demux_bitrate: c_float,
-    pub i_demux_corrupted: c_int,
-    pub i_demux_discontinuity: c_int,
-    /* Decoders */
-    pub i_decoded_video: c_int,
-    pub i_decoded_audio: c_int,
-    /* Video Output */
-    pub i_displayed_pictures: c_int,
-    pub i_lost_pictures: c_int,
-    /* Audio output */
-    pub i_played_abuffers: c_int,
-    pub i_lost_abuffers: c_int,
-    /* Stream output */
-    pub i_sent_packets: c_int,
-    pub i_sent_bytes: c_int,
-    pub f_send_bitrate: c_float,
-}
-
-#[repr(C)]
-#[derive(Clone, Copy)]
-pub struct libvlc_media_track_info_t {
-    /* Codec fourcc */
-    pub i_codec: u32,
-    pub i_id: c_int,
-    pub i_type: libvlc_track_type_t,
-    /* Codec specific */
-    pub i_profile: c_int,
-    pub i_level: c_int,
-    
-    pub u: libvlc_media_track_info_t_types::u,
-}
-
-pub mod libvlc_media_track_info_t_types {
-    use libc::c_uint;
-    #[repr(C)]
-    #[derive(Clone, Copy)]
-    pub union u {
-        pub audio: audio,
-        pub video: video,
-    }
-
-    #[repr(C)]
-    #[derive(Clone, Copy)]
-    pub struct audio {
-        pub i_channels: c_uint,
-        pub i_rate: c_uint,
-    }
-
-    #[repr(C)]
-    #[derive(Clone, Copy)]
-    pub struct video {
-        pub i_height: c_uint,
-        pub i_width: c_uint,
-    }
-}
-
-#[repr(C)]
-#[derive(Clone, Copy)]
-pub struct libvlc_audio_track_t
-{
-    pub i_channels: c_uint,
-    pub i_rate: c_uint,
-}
-
-#[derive(Clone, Copy)]
-#[repr(C)]
-pub struct libvlc_video_track_t
-{
-    pub i_height: c_uint,
-    pub i_width: c_uint,
-    pub i_sar_num: c_uint,
-    pub i_sar_den: c_uint,
-    pub i_frame_rate_num: c_uint,
-    pub i_frame_rate_den: c_uint,
-}
-
-#[repr(C)]
-#[derive(Clone, Copy)]
-pub struct libvlc_subtitle_track_t {
-    pub psz_encoding: *const c_char,
-}
-
-#[repr(C)]
-#[derive(Clone, Copy)]
-pub struct libvlc_media_track_t {
-    pub i_codec: u32,
-    pub i_original_fourcc: u32,
-    pub i_id: c_int,
-    pub i_type: libvlc_track_type_t,
-    pub i_profile: c_int,
-    pub i_level: c_int,
-    pub u: libvlc_media_track_t_types::u,
-    pub i_bitrate: c_uint,
-    pub psz_language: *mut c_char,
-    pub psz_description: *mut c_char,
-}
-
-pub mod libvlc_media_track_t_types {
-    use super::*;
-    #[repr(C)]
-    #[derive(Clone, Copy)]
-    pub union u {
-        pub audio: *mut libvlc_audio_track_t,
-        pub video: *mut libvlc_video_track_t,
-        pub subtitle: *mut libvlc_subtitle_track_t,
-    }
-}
-
-impl libvlc_media_track_t {
-    pub unsafe fn audio(&self) -> *mut libvlc_audio_track_t {
-        self.u.audio
-    }
-    pub unsafe fn video(&self) -> *mut libvlc_video_track_t {
-        self.u.video
-    }
-    pub unsafe fn subtitle(&self) -> *mut libvlc_subtitle_track_t {
-        self.u.subtitle
-    }
-}
-
-extern "C" {
-    pub fn libvlc_media_new_location(p_instance: *mut libvlc_instance_t, psz_mrl: *const c_char)
-                                     -> *mut libvlc_media_t;
-    pub fn libvlc_media_new_path(p_instance: *mut libvlc_instance_t, path: *const c_char)
-                                 -> *mut libvlc_media_t;
-    pub fn libvlc_media_new_fd(p_instance: *mut libvlc_instance_t, fd: c_int)
-                               -> *mut libvlc_media_t;
-    pub fn libvlc_media_as_node(p_instance: *mut libvlc_instance_t, psz_name: *const c_char)
-                                -> *mut libvlc_media_t;
-    pub fn libvlc_media_add_option(p_md: *mut libvlc_media_t, psz_options: *const c_char);
-    pub fn libvlc_media_add_option_flag(
-        p_md: *mut libvlc_media_t, psz_options: *const c_char, i_flags: c_uint);
-    pub fn libvlc_media_retain(p_md: *mut libvlc_media_t);
-    pub fn libvlc_media_release(p_md: *mut libvlc_media_t);
-    pub fn libvlc_media_get_mrl(p_md: *mut libvlc_media_t) -> *mut c_char;
-    pub fn libvlc_media_duplicate(p_md: *mut libvlc_media_t) -> *mut libvlc_media_t;
-    pub fn libvlc_media_get_meta(p_md: *mut libvlc_media_t, e_meta: libvlc_meta_t) -> *mut c_char;
-    pub fn libvlc_media_set_meta(p_md: *mut libvlc_media_t, e_meta: libvlc_meta_t,
-                                 psz_value: *const c_char);
-    pub fn libvlc_media_save_meta(p_md: *mut libvlc_media_t) -> c_int;
-    pub fn libvlc_media_get_state(p_md: *mut libvlc_media_t) -> libvlc_state_t;
-    pub fn libvlc_media_get_stats(p_md: *mut libvlc_media_t, p_stats: *mut libvlc_media_stats_t)
-                                  -> c_int;
-    pub fn libvlc_media_subitems(p_md: *mut libvlc_media_t)
-                                 -> *mut libvlc_media_list_t;
-    pub fn libvlc_media_event_manager(p_md: *mut libvlc_media_t)
-                                      -> *mut libvlc_event_manager_t;
-    pub fn libvlc_media_get_duration(p_md: *mut libvlc_media_t)
-                                     -> libvlc_time_t;
-    pub fn libvlc_media_parse(p_md: *mut libvlc_media_t);
-    pub fn libvlc_media_parse_async(p_md: *mut libvlc_media_t);
-    pub fn libvlc_media_is_parsed(p_md: *mut libvlc_media_t) -> c_int;
-    pub fn libvlc_media_set_user_data(p_md: *mut libvlc_media_t,
-                                      p_new_user_data: *mut c_void);
-    pub fn libvlc_media_get_user_data(p_md: *mut libvlc_media_t) -> *mut c_void;
-    pub fn libvlc_media_tracks_get(p_md: *mut libvlc_media_t,
-                                   tracks: *mut *mut *mut libvlc_media_track_t) -> c_uint;
-    pub fn libvlc_media_tracks_release(p_tracks: *mut *mut libvlc_media_track_t, i_count: c_uint);
-}
-
-// From libvlc_media_player.h
-
-pub enum libvlc_media_player_t {}
-pub enum libvlc_equalizer_t {}
-
-#[repr(C)]
-#[derive(Clone, Copy, Debug)]
-pub struct libvlc_track_description_t {
-    pub i_id: c_int,
-    pub psz_name: *mut c_char,
-    pub p_next: *mut libvlc_track_description_t,
-}
-
-#[repr(C)]
-#[derive(Clone, Copy)]
-pub struct libvlc_audio_output_t {
-    pub psz_name: *mut c_char,
-    pub psz_description: *mut c_char,
-    pub p_next: *mut libvlc_audio_output_t,
-}
-
-#[repr(C)]
-#[derive(Clone, Copy)]
-pub struct libvlc_audio_output_device_t {
-    pub p_next: *mut libvlc_audio_output_device_t,
-    pub psz_device: *mut c_char,
-    pub psz_description: *mut c_char,
-}
-
-#[repr(C)]
-#[derive(Clone, Copy, Debug)]
-pub struct libvlc_rectangle_t {
-    pub top: c_int, pub left: c_int, pub bottom: c_int, pub right: c_int,
-}
-
-#[repr(C)]
-#[derive(Clone, Copy, Debug)]
-pub enum libvlc_video_marquee_option_t {
-    libvlc_marquee_Enable = 0,
-    libvlc_marquee_Text,
-    libvlc_marquee_Color,
-    libvlc_marquee_Opacity,
-    libvlc_marquee_Position,
-    libvlc_marquee_Refresh,
-    libvlc_marquee_Size,
-    libvlc_marquee_Timeout,
-    libvlc_marquee_X,
-    libvlc_marquee_Y,
-}
-
-#[repr(C)]
-#[derive(Clone, Copy, Debug)]
-pub enum libvlc_navigate_mode_t {
-    libvlc_navigate_activate = 0,
-    libvlc_navigate_up,
-    libvlc_navigate_down,
-    libvlc_navigate_left,
-    libvlc_navigate_right,
-}
-
-pub use crate::enums::Position as libvlc_position_t;
-pub use crate::enums::VideoAdjustOption as libvlc_video_adjust_option;
-
-#[repr(C)]
-#[derive(Clone, Copy, Debug)]
-pub enum libvlc_video_logo_option_t {
-    libvlc_logo_enable,
-    libvlc_logo_file,
-    libvlc_logo_x,
-    libvlc_logo_y,
-    libvlc_logo_delay,
-    libvlc_logo_repeat,
-    libvlc_logo_opacity,
-    libvlc_logo_position
-}
-
-#[repr(C)]
-#[derive(Clone, Copy, Debug)]
-pub enum libvlc_audio_output_device_types_t {
-    libvlc_AudioOutputDevice_Error  = -1,
-    libvlc_AudioOutputDevice_Mono   =  1,
-    libvlc_AudioOutputDevice_Stereo =  2,
-    libvlc_AudioOutputDevice_2F2R   =  4,
-    libvlc_AudioOutputDevice_3F2R   =  5,
-    libvlc_AudioOutputDevice_5_1    =  6,
-    libvlc_AudioOutputDevice_6_1    =  7,
-    libvlc_AudioOutputDevice_7_1    =  8,
-    libvlc_AudioOutputDevice_SPDIF  = 10
-}
-
-#[repr(C)]
-#[derive(Clone, Copy, Debug)]
-pub enum libvlc_audio_output_channel_t {
-    libvlc_AudioChannel_Error   = -1,
-    libvlc_AudioChannel_Stereo  =  1,
-    libvlc_AudioChannel_RStereo =  2,
-    libvlc_AudioChannel_Left    =  3,
-    libvlc_AudioChannel_Right   =  4,
-    libvlc_AudioChannel_Dolbys  =  5
-}
-
-pub type libvlc_video_lock_cb = Option<unsafe extern "C" fn(*mut c_void, *mut c_void) -> *mut c_void>;
-pub type libvlc_video_unlock_cb = Option<unsafe extern "C" fn(
-    *mut c_void, *mut c_void, *const *mut c_void)>;
-pub type libvlc_video_display_cb = Option<unsafe extern "C" fn(*mut c_void, *mut c_void)>;
-pub type libvlc_video_format_cb = Option<unsafe extern "C" fn(
-    *mut *mut c_void, *mut c_char, *mut c_uint, *mut c_uint, *mut c_uint, *mut c_uint)>;
-pub type libvlc_video_cleanup_cb = Option<unsafe extern "C" fn(*mut c_void)>;
-pub type libvlc_audio_play_cb = Option<unsafe extern "C" fn(*mut c_void, *const c_void, c_uint, i64)>;
-pub type libvlc_audio_pause_cb = Option<unsafe extern "C" fn(*mut c_void, i64)>;
-pub type libvlc_audio_resume_cb = Option<unsafe extern "C" fn(*mut c_void, i64)>;
-pub type libvlc_audio_flush_cb = Option<unsafe extern "C" fn(*mut c_void, i64)>;
-pub type libvlc_audio_drain_cb = Option<unsafe extern "C" fn(*mut c_void)>;
-pub type libvlc_audio_set_volume_cb = Option<unsafe extern "C" fn(*mut c_void, c_float, c_bool)>;
-pub type libvlc_audio_setup_cb = Option<unsafe extern "C" fn(
-    *mut *mut c_void, *mut c_char, *mut c_uint, *mut c_uint)>;
-pub type libvlc_audio_cleanup_cb = Option<unsafe extern "C" fn(*mut c_void)>;
-
-extern "C" {
-    pub fn libvlc_media_player_new(p_libvlc_instance: *mut libvlc_instance_t)
-                                   -> *mut libvlc_media_player_t;
-    pub fn libvlc_media_player_new_from_media(p_md: *mut libvlc_media_t)
-                                              -> *mut libvlc_media_player_t;
-    pub fn libvlc_media_player_release(p_mi: *mut libvlc_media_player_t);
-    pub fn libvlc_media_player_retain(p_mi: *mut libvlc_media_player_t);
-    pub fn libvlc_media_player_set_media(p_mi: *mut libvlc_media_player_t,
-                                         p_md: *mut libvlc_media_t);
-    pub fn libvlc_media_player_get_media(p_mi: *mut libvlc_media_player_t) -> *mut libvlc_media_t;
-    pub fn libvlc_media_player_event_manager(p_mi: *mut libvlc_media_player_t)
-                                             -> *mut libvlc_event_manager_t;
-    pub fn libvlc_media_player_is_playing(p_mi: *mut libvlc_media_player_t) -> c_int;
-    pub fn libvlc_media_player_play(p_mi: *mut libvlc_media_player_t) -> c_int;
-    pub fn libvlc_media_player_set_pause(mp: *mut libvlc_media_player_t, do_pause: c_int);
-    pub fn libvlc_media_player_pause(p_mi: *mut libvlc_media_player_t);
-    pub fn libvlc_media_player_stop(p_mi: *mut libvlc_media_player_t);
-    pub fn libvlc_video_set_callbacks(
-        mp: *mut libvlc_media_player_t, lock: libvlc_video_lock_cb,
-        unlock: libvlc_video_unlock_cb, display: libvlc_video_display_cb,
-        opaque: *mut c_void);
-    pub fn libvlc_video_set_format(
-        mp: *mut libvlc_media_player_t, chroma: *const c_char, width: c_uint, height: c_uint,
-        pitch: c_uint);
-    pub fn libvlc_video_set_format_callbacks(
-        mp: *mut libvlc_media_player_t, setup: libvlc_video_format_cb,
-        cleanup: libvlc_video_cleanup_cb);
-    pub fn libvlc_media_player_set_nsobject(
-        p_mi: *mut libvlc_media_player_t, drawable: *mut c_void);
-    pub fn libvlc_media_player_get_nsobject(p_mi: *mut libvlc_media_player_t) -> *mut c_void;
-    pub fn libvlc_media_player_set_xwindow(
-        p_mi: *mut libvlc_media_player_t, drawable: u32);
-    pub fn libvlc_media_player_get_xwindow(p_mi: *mut libvlc_media_player_t) -> u32;
-    pub fn libvlc_media_player_set_hwnd(
-        p_mi: *mut libvlc_media_player_t, drawable: *mut c_void);
-    pub fn libvlc_media_player_get_hwnd(p_mi: *mut libvlc_media_player_t) -> *mut c_void;
-    pub fn libvlc_audio_set_callbacks(
-        mp: *mut libvlc_media_player_t, play: libvlc_audio_play_cb, pause: libvlc_audio_pause_cb,
-        resume: libvlc_audio_resume_cb, flush: libvlc_audio_flush_cb,
-        drain: libvlc_audio_drain_cb, opaque: *mut c_void);
-    pub fn libvlc_audio_set_volume_callback(
-        mp: *mut libvlc_media_player_t, set_volume: libvlc_audio_set_volume_cb);
-    pub fn libvlc_audio_set_format_callbacks(
-        mp: *mut libvlc_media_player_t, setup: libvlc_audio_setup_cb,
-        cleanup: libvlc_audio_cleanup_cb);
-    pub fn libvlc_audio_set_format(
-        mp: *mut libvlc_media_player_t, format: *const c_char, rate: c_uint, channels: c_uint);
-    pub fn libvlc_media_player_get_length(p_mi: *mut libvlc_media_player_t) -> libvlc_time_t;
-    pub fn libvlc_media_player_get_time(p_mi: *mut libvlc_media_player_t) -> libvlc_time_t;
-    pub fn libvlc_media_player_set_time(
-        p_mi: *mut libvlc_media_player_t, i_time: libvlc_time_t);
-    pub fn libvlc_media_player_get_position(p_mi: *mut libvlc_media_player_t) -> c_float;
-    pub fn libvlc_media_player_set_position(p_mi: *mut libvlc_media_player_t, f_pos: c_float);
-    pub fn libvlc_media_player_set_chapter(p_mi: *mut libvlc_media_player_t, i_chapter: c_int);
-    pub fn libvlc_media_player_get_chapter(p_mi: *mut libvlc_media_player_t) -> c_int;
-    pub fn libvlc_media_player_get_chapter_count(p_mi: *mut libvlc_media_player_t) -> c_int;
-    pub fn libvlc_media_player_will_play(p_mi: *mut libvlc_media_player_t) -> c_int;
-    pub fn libvlc_media_player_set_title(p_mi: *mut libvlc_media_player_t, i_title: c_int);
-    pub fn libvlc_media_player_get_chapter_count_for_title(
-        p_mi: *mut libvlc_media_player_t, i_title: c_int) -> c_int;
-    pub fn libvlc_media_player_get_title(p_mi: *mut libvlc_media_player_t) -> c_int;
-    pub fn libvlc_media_player_get_title_count(p_mi: *mut libvlc_media_player_t) -> c_int;
-    pub fn libvlc_media_player_previous_chapter(p_mi: *mut libvlc_media_player_t);
-    pub fn libvlc_media_player_next_chapter(p_mi: *mut libvlc_media_player_t);
-    pub fn libvlc_media_player_get_rate(p_mi: *mut libvlc_media_player_t) -> c_float;
-    pub fn libvlc_media_player_set_rate(p_mi: *mut libvlc_media_player_t, rate: c_float) -> c_int;
-    pub fn libvlc_media_player_get_state(p_mi: *mut libvlc_media_player_t) -> libvlc_state_t;
-    pub fn libvlc_media_player_get_fps(p_mi: *mut libvlc_media_player_t) -> c_float;
-    pub fn libvlc_media_player_has_vout(p_mi: *mut libvlc_media_player_t) -> c_uint;
-    pub fn libvlc_media_player_is_seekable(p_mi: *mut libvlc_media_player_t) -> c_int;
-    pub fn libvlc_media_player_can_pause(p_mi: *mut libvlc_media_player_t) -> c_int;
-    pub fn libvlc_media_player_program_scrambled(p_mi: *mut libvlc_media_player_t) -> c_int;
-    pub fn libvlc_media_player_next_frame(p_mi: *mut libvlc_media_player_t);
-    pub fn libvlc_media_player_navigate(p_mi: *mut libvlc_media_player_t, navigate: c_uint);
-    pub fn libvlc_media_player_set_video_title_display(
-        p_mi: *mut libvlc_media_player_t, position: libvlc_position_t, timeout: c_uint);
-    pub fn libvlc_track_description_list_release(p_track_description: *mut libvlc_track_description_t);
-    pub fn libvlc_toggle_fullscreen(p_mi: *mut libvlc_media_player_t);
-    pub fn libvlc_set_fullscreen(p_mi: *mut libvlc_media_player_t, b_fullscreen: c_int);
-    pub fn libvlc_get_fullscreen(p_mi: *mut libvlc_media_player_t) -> c_int;
-    pub fn libvlc_video_set_key_input(p_mi: *mut libvlc_media_player_t, on: c_uint);
-    pub fn libvlc_video_set_mouse_input(p_mi: *mut libvlc_media_player_t, on: c_uint);
-    pub fn libvlc_video_get_size(
-        p_mi: *mut libvlc_media_player_t, num: c_uint, px: *mut c_uint, py: *mut c_uint) -> c_int;
-    pub fn libvlc_video_get_cursor(
-        p_mi: *mut libvlc_media_player_t, num: c_uint, px: *mut c_int, py: *mut c_int) -> c_int;
-    pub fn libvlc_video_get_scale(p_mi: *mut libvlc_media_player_t) -> c_float;
-    pub fn libvlc_video_set_scale(p_mi: *mut libvlc_media_player_t, f_factor: c_float);
-    pub fn libvlc_video_get_aspect_ratio(p_mi: *mut libvlc_media_player_t) -> *mut c_char;
-    pub fn libvlc_video_set_aspect_ratio(p_mi: *mut libvlc_media_player_t, psz_aspect: *const c_char);
-    pub fn libvlc_video_get_spu(p_mi: *mut libvlc_media_player_t) -> c_int;
-    pub fn libvlc_video_get_spu_count(p_mi: *mut libvlc_media_player_t) -> c_int;
-    pub fn libvlc_video_get_spu_description(p_mi: *mut libvlc_media_player_t)
-     -> *mut libvlc_track_description_t;
-    pub fn libvlc_video_set_spu(p_mi: *mut libvlc_media_player_t, i_spu: c_int) -> c_int;
-    pub fn libvlc_video_set_subtitle_file(
-        p_mi: *mut libvlc_media_player_t, psz_subtitle: *const c_char) -> c_int;
-    pub fn libvlc_video_get_spu_delay(p_mi: *mut libvlc_media_player_t) -> i64;
-    pub fn libvlc_video_set_spu_delay(
-        p_mi: *mut libvlc_media_player_t, i_delay: i64) -> c_int;
-    pub fn libvlc_video_get_title_description(
-        p_mi: *mut libvlc_media_player_t) -> *mut libvlc_track_description_t;
-    pub fn libvlc_video_get_chapter_description(
-        p_mi: *mut libvlc_media_player_t, i_title: c_int) -> *mut libvlc_track_description_t;
-    pub fn libvlc_video_get_crop_geometry(p_mi: *mut libvlc_media_player_t) -> *mut c_char;
-    pub fn libvlc_video_set_crop_geometry(
-        p_mi: *mut libvlc_media_player_t, psz_geometry: *const c_char);
-    pub fn libvlc_video_get_teletext(p_mi: *mut libvlc_media_player_t) -> c_int;
-    pub fn libvlc_video_set_teletext(p_mi: *mut libvlc_media_player_t, i_page: c_int);
-    pub fn libvlc_toggle_teletext(p_mi: *mut libvlc_media_player_t);
-    pub fn libvlc_video_get_track_count(p_mi: *mut libvlc_media_player_t) -> c_int;
-    pub fn libvlc_video_get_track_description(
-        p_mi: *mut libvlc_media_player_t) -> *mut libvlc_track_description_t;
-    pub fn libvlc_video_get_track(p_mi: *mut libvlc_media_player_t) -> c_int;
-    pub fn libvlc_video_set_track(p_mi: *mut libvlc_media_player_t, i_track: c_int) -> c_int;
-    pub fn libvlc_video_take_snapshot(
-        p_mi: *mut libvlc_media_player_t, num: c_uint, psz_filepath: *const c_char,
-        i_width: c_uint, i_height: c_uint) -> c_int;
-    pub fn libvlc_video_set_deinterlace(p_mi: *mut libvlc_media_player_t, psz_mode: *const c_char);
-    pub fn libvlc_video_get_marquee_int(p_mi: *mut libvlc_media_player_t, option: c_uint) -> c_int;
-    pub fn libvlc_video_get_marquee_string(
-        p_mi: *mut libvlc_media_player_t, option: c_uint) -> *mut c_char;
-    pub fn libvlc_video_set_marquee_int(
-        p_mi: *mut libvlc_media_player_t, option: c_uint, i_val: c_int);
-    pub fn libvlc_video_set_marquee_string(
-        p_mi: *mut libvlc_media_player_t, option: c_uint, psz_text: *const c_char);
-    pub fn libvlc_video_get_logo_int(p_mi: *mut libvlc_media_player_t, option: c_uint) -> c_int;
-    pub fn libvlc_video_set_logo_int(p_mi: *mut libvlc_media_player_t, option: c_uint, value: c_int);
-    pub fn libvlc_video_set_logo_string(
-        p_mi: *mut libvlc_media_player_t, option: c_uint, psz_value: *const c_char);
-    pub fn libvlc_video_get_adjust_int(
-        p_mi: *mut libvlc_media_player_t, option: c_uint) -> c_int;
-    pub fn libvlc_video_set_adjust_int(
-        p_mi: *mut libvlc_media_player_t, option: c_uint, value: c_int);
-    pub fn libvlc_video_get_adjust_float(
-        p_mi: *mut libvlc_media_player_t, option: c_uint) -> c_float;
-    pub fn libvlc_video_set_adjust_float(
-        p_mi: *mut libvlc_media_player_t, option: c_uint, value: c_float);
-    pub fn libvlc_audio_output_list_get(p_instance: *mut libvlc_instance_t)
-     -> *mut libvlc_audio_output_t;
-    pub fn libvlc_audio_output_list_release(p_list: *mut libvlc_audio_output_t);
-    pub fn libvlc_audio_output_set(p_mi: *mut libvlc_media_player_t, psz_name: *const c_char) -> c_int;
-    pub fn libvlc_audio_output_device_enum(
-        mp: *mut libvlc_media_player_t) -> *mut libvlc_audio_output_device_t;
-    pub fn libvlc_audio_output_device_list_get(
-        p_instance: *mut libvlc_instance_t, aout: *const c_char) -> *mut libvlc_audio_output_device_t;
-    pub fn libvlc_audio_output_device_list_release(p_list: *mut libvlc_audio_output_device_t);
-    pub fn libvlc_audio_output_device_set(
-        mp: *mut libvlc_media_player_t, module: *const c_char, device_id: *const c_char);
-    pub fn libvlc_audio_toggle_mute(p_mi: *mut libvlc_media_player_t);
-    pub fn libvlc_audio_get_mute(p_mi: *mut libvlc_media_player_t) -> c_int;
-    pub fn libvlc_audio_set_mute(p_mi: *mut libvlc_media_player_t, status: c_int);
-    pub fn libvlc_audio_get_volume(p_mi: *mut libvlc_media_player_t) -> c_int;
-    pub fn libvlc_audio_set_volume(p_mi: *mut libvlc_media_player_t, i_volume: c_int) -> c_int;
-    pub fn libvlc_audio_get_track_count(p_mi: *mut libvlc_media_player_t) -> c_int;
-    pub fn libvlc_audio_get_track_description(
-        p_mi: *mut libvlc_media_player_t) -> *mut libvlc_track_description_t;
-    pub fn libvlc_audio_get_track(p_mi: *mut libvlc_media_player_t) -> c_int;
-    pub fn libvlc_audio_set_track(p_mi: *mut libvlc_media_player_t, i_track: c_int) -> c_int;
-    pub fn libvlc_audio_get_channel(p_mi: *mut libvlc_media_player_t) -> c_int;
-    pub fn libvlc_audio_set_channel(p_mi: *mut libvlc_media_player_t, channel: c_int) -> c_int;
-    pub fn libvlc_audio_get_delay(p_mi: *mut libvlc_media_player_t) -> i64;
-    pub fn libvlc_audio_set_delay(p_mi: *mut libvlc_media_player_t, i_delay: i64) -> c_int;
-    pub fn libvlc_audio_equalizer_get_preset_count() -> c_uint;
-    pub fn libvlc_audio_equalizer_get_preset_name(u_index: c_uint) -> *const c_char;
-    pub fn libvlc_audio_equalizer_get_band_count() -> c_uint;
-    pub fn libvlc_audio_equalizer_get_band_frequency(u_index: c_uint) -> c_float;
-    pub fn libvlc_audio_equalizer_new() -> *mut libvlc_equalizer_t;
-    pub fn libvlc_audio_equalizer_new_from_preset(u_index: c_uint) -> *mut libvlc_equalizer_t;
-    pub fn libvlc_audio_equalizer_release(p_equalizer: *mut libvlc_equalizer_t);
-    pub fn libvlc_audio_equalizer_set_preamp(
-        p_equalizer: *mut libvlc_equalizer_t, f_preamp: c_float) -> c_int;
-    pub fn libvlc_audio_equalizer_get_preamp(p_equalizer: *mut libvlc_equalizer_t) -> c_float;
-    pub fn libvlc_audio_equalizer_set_amp_at_index(
-        p_equalizer: *mut libvlc_equalizer_t, f_amp: c_float, u_band: c_uint) -> c_int;
-    pub fn libvlc_audio_equalizer_get_amp_at_index(
-        p_equalizer: *mut libvlc_equalizer_t, u_band: c_uint) -> c_float;
-    pub fn libvlc_media_player_set_equalizer(
-        p_mi: *mut libvlc_media_player_t, p_equalizer: *mut libvlc_equalizer_t) -> c_int;
-}
-
-// From libvlc_events.h
-pub use crate::enums::EventType as libvlc_event_e;
-
-#[repr(C)]
-#[derive(Clone, Copy)]
-pub struct libvlc_event_t {
-    pub _type: c_int,
-    pub p_obj: *mut c_void,
-    pub u: libvlc_event_t_types::u,
-}
-
-pub mod libvlc_event_t_types {
-    use super::*;
-    use libc::{c_int, c_char, c_float};
-    #[repr(C)]
-    #[derive(Clone, Copy)]
-    pub union u {
-        pub media_meta_changed: media_meta_changed,
-        pub media_subitem_added: media_subitem_added,
-        pub media_duration_changed: media_duration_changed,
-        pub media_parsed_changed: media_parsed_changed,
-        pub media_freed: media_freed,
-        pub media_state_changed: media_state_changed,
-        pub media_subitemtree_added: media_subitemtree_added,
-        pub media_player_buffering: media_player_buffering,
-        pub media_player_position_changed: media_player_position_changed,
-        pub media_player_time_changed: media_player_time_changed,
-        pub media_player_title_changed: media_player_title_changed,
-        pub media_player_seekable_changed: media_player_seekable_changed,
-        pub media_player_pausable_changed: media_player_pausable_changed,
-        pub media_player_scrambled_changed: media_player_scrambled_changed,
-        pub media_player_vout: media_player_vout,
-        pub media_list_item_added: media_list_item_added,
-        pub media_list_will_add_item: media_list_will_add_item,
-        pub media_list_item_deleted: media_list_item_deleted,
-        pub media_list_will_delete_item: media_list_will_delete_item,
-        pub media_list_player_next_item_set: media_list_player_next_item_set,
-        pub media_player_snapshot_taken: media_player_snapshot_taken,
-        pub media_player_length_changed: media_player_length_changed,
-        pub vlm_media_event: vlm_media_event,
-        pub media_player_media_changed: media_player_media_changed,
-    }
-    #[repr(C)]
-    #[derive(Clone, Copy)]
-    pub struct media_meta_changed {
-        pub meta_type: libvlc_meta_t,
-    }
-    #[repr(C)]
-    #[derive(Clone, Copy)]
-    pub struct media_subitem_added {
-        pub new_child: *mut libvlc_media_t,
-    }
-    #[repr(C)]
-    #[derive(Clone, Copy)]
-    pub struct media_duration_changed {
-        pub new_duration: i64,
-    }
-    #[repr(C)]
-    #[derive(Clone, Copy)]
-    pub struct media_parsed_changed {
-        pub new_status: c_int,
-    }
-    #[repr(C)]
-    #[derive(Clone, Copy)]
-    pub struct media_freed {
-        pub md: *mut libvlc_media_t,
-    }
-    #[repr(C)]
-    #[derive(Clone, Copy)]
-    pub struct media_state_changed {
-        pub new_state: libvlc_state_t,
-    }
-    #[repr(C)]
-    #[derive(Clone, Copy)]
-    pub struct media_subitemtree_added {
-        pub item: *mut libvlc_media_t,
-    }
-    #[repr(C)]
-    #[derive(Clone, Copy)]
-    pub struct media_player_buffering {
-        pub new_cache: c_float,
-    }
-    #[repr(C)]
-    #[derive(Clone, Copy)]
-    pub struct media_player_position_changed {
-        pub new_position: c_float,
-    }
-    #[repr(C)]
-    #[derive(Clone, Copy)]
-    pub struct media_player_time_changed {
-        pub new_time: libvlc_time_t,
-    }
-    #[repr(C)]
-    #[derive(Clone, Copy)]
-    pub struct media_player_title_changed {
-        pub new_titie: c_int,
-    }
-    #[repr(C)]
-    #[derive(Clone, Copy)]
-    pub struct media_player_seekable_changed {
-        pub new_seekable: c_int,
-    }
-    #[repr(C)]
-    #[derive(Clone, Copy)]
-    pub struct media_player_pausable_changed {
-        pub new_pausable: c_int,
-    }
-    #[repr(C)]
-    #[derive(Clone, Copy)]
-    pub struct media_player_scrambled_changed {
-        pub new_scrambled: c_int,
-    }
-    #[repr(C)]
-    #[derive(Clone, Copy)]
-    pub struct media_player_vout {
-        pub new_count: c_int,
-    }
-    #[repr(C)]
-    #[derive(Clone, Copy)]
-    pub struct media_list_item_added {
-        pub item: *mut libvlc_media_t,
-        pub index: c_int,
-    }
-    #[repr(C)]
-    #[derive(Clone, Copy)]
-    pub struct media_list_will_add_item {
-        pub item: *mut libvlc_media_t,
-        pub index: c_int,
-    }
-    #[repr(C)]
-    #[derive(Clone, Copy)]
-    pub struct media_list_item_deleted {
-        pub item: *mut libvlc_media_t,
-        pub index: c_int,
-    }
-    #[repr(C)]
-    #[derive(Clone, Copy)]
-    pub struct media_list_will_delete_item {
-        pub item: *mut libvlc_media_t,
-        pub index: c_int,
-    }
-    #[repr(C)]
-    #[derive(Clone, Copy)]
-    pub struct media_list_player_next_item_set {
-        pub item: *mut libvlc_media_t,
-    }
-    #[repr(C)]
-    #[derive(Clone, Copy)]
-    pub struct media_player_snapshot_taken {
-        pub psz_filename: *mut c_char,
-    }
-    #[repr(C)]
-    #[derive(Clone, Copy)]
-    pub struct media_player_length_changed {
-        pub new_length: libvlc_time_t,
-    }
-    #[repr(C)]
-    #[derive(Clone, Copy)]
-    pub struct vlm_media_event {
-        pub psz_media_name: *mut c_char,
-        pub psz_instance_name: *mut c_char,
-    }
-    #[repr(C)]
-    #[derive(Clone, Copy)]
-    pub struct media_player_media_changed {
-        pub new_media: *mut libvlc_media_t,
-    }
-}
-
-// From libvlc_media_list.h
-
-pub enum libvlc_media_list_t {}
-
-extern "C" {
-    pub fn libvlc_media_list_new(p_instance: *mut libvlc_instance_t) -> *mut libvlc_media_list_t;
-    pub fn libvlc_media_list_release(p_ml: *mut libvlc_media_list_t);
-    pub fn libvlc_media_list_retain(p_ml: *mut libvlc_media_list_t);
-    pub fn libvlc_media_list_set_media(p_ml: *mut libvlc_media_list_t, p_md: *mut libvlc_media_t);
-    pub fn libvlc_media_list_media(p_ml: *mut libvlc_media_list_t) -> *mut libvlc_media_t;
-    pub fn libvlc_media_list_add_media(
-        p_ml: *mut libvlc_media_list_t, p_md: *mut libvlc_media_t) -> c_int;
-    pub fn libvlc_media_list_insert_media(
-        p_ml: *mut libvlc_media_list_t, p_md: *mut libvlc_media_t, i_pos: c_int) -> c_int;
-    pub fn libvlc_media_list_remove_index(p_ml: *mut libvlc_media_list_t, i_pos: c_int) -> c_int;
-    pub fn libvlc_media_list_count(p_ml: *mut libvlc_media_list_t) -> c_int;
-    pub fn libvlc_media_list_item_at_index(
-        p_ml: *mut libvlc_media_list_t, i_pos: c_int) -> *mut libvlc_media_t;
-    pub fn libvlc_media_list_index_of_item(
-        p_ml: *mut libvlc_media_list_t, p_md: *mut libvlc_media_t) -> c_int;
-    pub fn libvlc_media_list_is_readonly(p_ml: *mut libvlc_media_list_t) -> c_int;
-    pub fn libvlc_media_list_lock(p_ml: *mut libvlc_media_list_t);
-    pub fn libvlc_media_list_unlock(p_ml: *mut libvlc_media_list_t);
-    pub fn libvlc_media_list_event_manager(
-        p_ml: *mut libvlc_media_list_t) -> *mut libvlc_event_manager_t;
-}
-
-// From libvlc_media_library.h
-
-pub enum libvlc_media_library_t {}
-
-extern "C" {
-    pub fn libvlc_media_library_new(p_instance: *mut libvlc_instance_t) -> *mut libvlc_media_library_t;
-    pub fn libvlc_media_library_release(p_mlib: *mut libvlc_media_library_t);
-    pub fn libvlc_media_library_retain(p_mlib: *mut libvlc_media_library_t);
-    pub fn libvlc_media_library_load(p_mlib: *mut libvlc_media_library_t) -> c_int;
-    pub fn libvlc_media_library_media_list(
-        p_mlib: *mut libvlc_media_library_t) -> *mut libvlc_media_list_t;
-}
-
-// From libvlc_media_discoverer.h
-
-pub enum libvlc_media_discoverer_t {}
-
-extern "C" {
-    pub fn libvlc_media_discoverer_new_from_name(
-        p_inst: *mut libvlc_instance_t, psz_name: *const c_char) -> *mut libvlc_media_discoverer_t;
-    pub fn libvlc_media_discoverer_release(p_mdis: *mut libvlc_media_discoverer_t);
-    pub fn libvlc_media_discoverer_localized_name(
-        p_mdis: *mut libvlc_media_discoverer_t) -> *mut c_char;
-    pub fn libvlc_media_discoverer_media_list(
-        p_mdis: *mut libvlc_media_discoverer_t) -> *mut libvlc_media_list_t;
-    pub fn libvlc_media_discoverer_event_manager(
-        p_mdis: *mut libvlc_media_discoverer_t) -> *mut libvlc_event_manager_t;
-    pub fn libvlc_media_discoverer_is_running(p_mdis: *mut libvlc_media_discoverer_t) -> c_int;
-}
-
-// From libvlc_vlm.h
-
-extern "C" {
-    pub fn libvlc_vlm_release(p_instance: *mut libvlc_instance_t);
-    pub fn libvlc_vlm_add_broadcast(
-        p_instance: *mut libvlc_instance_t, psz_name: *const c_char, psz_input: *const c_char,
-        psz_output: *const c_char, i_options: c_int, ppsz_options: *const *const c_char,
-        b_enabled: c_int, b_loop: c_int) -> c_int;
-    pub fn libvlc_vlm_add_vod(
-        p_instance: *mut libvlc_instance_t, psz_name: *const c_char, psz_input: *const c_char,
-        i_options: c_int, ppsz_options: *const *const c_char, b_enabled: c_int,
-        psz_mux: *const c_char) -> c_int;
-    pub fn libvlc_vlm_del_media(
-        p_instance: *mut libvlc_instance_t, psz_name: *const c_char) -> c_int;
-    pub fn libvlc_vlm_set_enabled(
-        p_instance: *mut libvlc_instance_t, psz_name: *const c_char, b_enabled: c_int) -> c_int;
-    pub fn libvlc_vlm_set_output(
-        p_instance: *mut libvlc_instance_t, psz_name: *const c_char, psz_output: *const c_char) -> c_int;
-    pub fn libvlc_vlm_set_input(
-        p_instance: *mut libvlc_instance_t, psz_name: *const c_char, psz_input: *const c_char) -> c_int;
-    pub fn libvlc_vlm_add_input(
-        p_instance: *mut libvlc_instance_t, psz_name: *const c_char, psz_input: *const c_char) -> c_int;
-    pub fn libvlc_vlm_set_loop(
-        p_instance: *mut libvlc_instance_t, psz_name: *const c_char, b_loop: c_int) -> c_int;
-    pub fn libvlc_vlm_set_mux(
-        p_instance: *mut libvlc_instance_t, psz_name: *const c_char, psz_mux: *const c_char) -> c_int;
-    pub fn libvlc_vlm_change_media(
-        p_instance: *mut libvlc_instance_t, psz_name: *const c_char, psz_input: *const c_char,
-        psz_output: *const c_char, i_options: c_int, ppsz_options: *const *const c_char,
-        b_enabled: c_int, b_loop: c_int) -> c_int;
-    pub fn libvlc_vlm_play_media(
-        p_instance: *mut libvlc_instance_t, psz_name: *const c_char) -> c_int;
-    pub fn libvlc_vlm_stop_media(
-        p_instance: *mut libvlc_instance_t, psz_name: *const c_char) -> c_int;
-    pub fn libvlc_vlm_pause_media(
-        p_instance: *mut libvlc_instance_t, psz_name: *const c_char) -> c_int;
-    pub fn libvlc_vlm_seek_media(
-        p_instance: *mut libvlc_instance_t, psz_name: *const c_char, f_percentage: c_float) -> c_int;
-    pub fn libvlc_vlm_show_media(
-        p_instance: *mut libvlc_instance_t, psz_name: *const c_char) -> *const c_char;
-    pub fn libvlc_vlm_get_media_instance_position(
-        p_instance: *mut libvlc_instance_t, psz_name: *const c_char, i_instance: c_int) -> c_float;
-    pub fn libvlc_vlm_get_media_instance_time(
-        p_instance: *mut libvlc_instance_t, psz_name: *const c_char, i_instance: c_int) -> c_int;
-    pub fn libvlc_vlm_get_media_instance_length(
-        p_instance: *mut libvlc_instance_t, psz_name: *const c_char, i_instance: c_int) -> c_int;
-    pub fn libvlc_vlm_get_media_instance_rate(
-        p_instance: *mut libvlc_instance_t, psz_name: *const c_char, i_instance: c_int) -> c_int;
-    pub fn libvlc_vlm_get_event_manager(
-        p_instance: *mut libvlc_instance_t) -> *mut libvlc_event_manager_t;
-}

From a79003543f835d022ecf56807c1054cc1f031cb9 Mon Sep 17 00:00:00 2001
From: "T. Okubo" <t.okubo.rx78+devel@gmail.com>
Date: Thu, 28 Nov 2019 21:02:59 +0900
Subject: [PATCH 12/28] Add some infomation to libvlc-sys/Carto.toml

---
 libvlc-sys/Cargo.toml | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/libvlc-sys/Cargo.toml b/libvlc-sys/Cargo.toml
index ae445ea..42d548d 100644
--- a/libvlc-sys/Cargo.toml
+++ b/libvlc-sys/Cargo.toml
@@ -2,6 +2,12 @@
 name = "libvlc-sys"
 version = "0.1.0"
 authors = ["T. Okubo <t.okubo.rx78+devel@gmail.com>"]
+
+description = "libVLC C API"
+keywords = ["libVLC", "bindings"]
+categories = ["external-ffi-bindings", "multimedia"]
+repository = "https://github.com/garkimasera/vlc-rs"
+license = "MIT"
 edition = "2018"
 build = "build.rs"
 
@@ -13,4 +19,4 @@ crate-type = ["rlib"]
 libc = "0.2"
 
 [build-dependencies]
-bindgen = "0.52"
\ No newline at end of file
+bindgen = "0.52"

From cef535cc22111baad274f211139d67e9bba6a75b Mon Sep 17 00:00:00 2001
From: "T. Okubo" <t.okubo.rx78+devel@gmail.com>
Date: Thu, 28 Nov 2019 21:07:29 +0900
Subject: [PATCH 13/28] Use libvlc-sys on crates.io

---
 Cargo.toml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Cargo.toml b/Cargo.toml
index 61c3203..d4c9076 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -16,7 +16,7 @@ crate-type = ["rlib"]
 
 [dependencies]
 libc = "0.2"
-libvlc-sys = { path = "libvlc-sys" }
+libvlc-sys = "0.1"
 
 [features]
 default = []

From 2b54b72054352453919e36acef18af2293eb3f00 Mon Sep 17 00:00:00 2001
From: "T. Okubo" <t.okubo.rx78+devel@gmail.com>
Date: Sat, 30 Nov 2019 19:37:07 +0900
Subject: [PATCH 14/28] Add some information to Cargo.toml

---
 Cargo.toml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Cargo.toml b/Cargo.toml
index d4c9076..b97a98a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -4,7 +4,9 @@ version = "0.3.0"
 authors = ["T. Okubo <t.okubo.rx78+github@gmail.com>"]
 
 description = "Rust bindings for libVLC media framework."
-keywords = ["libVLC", "bindings"]
+keywords = ["libVLC", "bindings", "multimedia"]
+categories = ["external-ffi-bindings", "multimedia"]
+documentation = "https://docs.rs/vlc-rs"
 repository = "https://github.com/garkimasera/vlc-rs"
 license = "MIT"
 readme = "README.md"

From 0444f7bd642c832c880dd893e311acd1731b1f6c Mon Sep 17 00:00:00 2001
From: "T. Okubo" <t.okubo.rx78+devel@gmail.com>
Date: Sun, 15 Dec 2019 14:22:50 +0900
Subject: [PATCH 15/28] Use pkg-config

---
 libvlc-sys/Cargo.toml |  1 +
 libvlc-sys/build.rs   | 15 ++++++++++-----
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/libvlc-sys/Cargo.toml b/libvlc-sys/Cargo.toml
index 42d548d..f8843ee 100644
--- a/libvlc-sys/Cargo.toml
+++ b/libvlc-sys/Cargo.toml
@@ -20,3 +20,4 @@ libc = "0.2"
 
 [build-dependencies]
 bindgen = "0.52"
+pkg-config = "0.3"
diff --git a/libvlc-sys/build.rs b/libvlc-sys/build.rs
index b37b8e2..153727f 100644
--- a/libvlc-sys/build.rs
+++ b/libvlc-sys/build.rs
@@ -4,10 +4,9 @@ use std::env;
 use std::path::PathBuf;
 
 fn main() {
-    println!("cargo:rustc-link-lib=vlc");
     println!("cargo:rerun-if-changed=wrapper.h");
 
-    let bindings = bindgen::Builder::default()
+    let mut bindings = bindgen::Builder::default()
         .header("wrapper.h")
         // For no_std
         .use_core()
@@ -18,9 +17,15 @@ fn main() {
         .whitelist_function(".*vlc.*")
         .whitelist_var(".*vlc.*")
         .whitelist_function("vsnprintf")
-        .parse_callbacks(Box::new(bindgen::CargoCallbacks))
-        .generate()
-        .expect("Unable to generate bindings");
+        .parse_callbacks(Box::new(bindgen::CargoCallbacks));
+
+    // Set header include paths
+    let pkg_config_library = pkg_config::Config::new().probe("libvlc").unwrap();
+    for include_path in &pkg_config_library.include_paths {
+        bindings = bindings.clang_arg(format!("-I{}", include_path.display()));
+    }
+
+    let bindings = bindings.generate().expect("Unable to generate bindings");
 
     let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
     bindings

From 70c717ba62411fc0ceda932ff7f637835dad2dc2 Mon Sep 17 00:00:00 2001
From: "T. Okubo" <t.okubo.rx78+devel@gmail.com>
Date: Sun, 15 Dec 2019 14:26:06 +0900
Subject: [PATCH 16/28] libvlc-sys 0.2

---
 Cargo.toml            | 2 +-
 libvlc-sys/Cargo.toml | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index b97a98a..5be309b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -18,7 +18,7 @@ crate-type = ["rlib"]
 
 [dependencies]
 libc = "0.2"
-libvlc-sys = "0.1"
+libvlc-sys = "0.2"
 
 [features]
 default = []
diff --git a/libvlc-sys/Cargo.toml b/libvlc-sys/Cargo.toml
index f8843ee..06bb3b7 100644
--- a/libvlc-sys/Cargo.toml
+++ b/libvlc-sys/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "libvlc-sys"
-version = "0.1.0"
+version = "0.2.0"
 authors = ["T. Okubo <t.okubo.rx78+devel@gmail.com>"]
 
 description = "libVLC C API"

From 74a22d74143f1bd51c3a61251289ccab2f0430a7 Mon Sep 17 00:00:00 2001
From: "T. Okubo" <t.okubo.rx78+devel@gmail.com>
Date: Sun, 15 Dec 2019 14:40:00 +0900
Subject: [PATCH 17/28] Comment out features for libvlc 3.0

---
 Cargo.toml   |  3 ---
 src/enums.rs | 18 +++++++++---------
 2 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index 5be309b..b35e2e7 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -20,6 +20,3 @@ crate-type = ["rlib"]
 libc = "0.2"
 libvlc-sys = "0.2"
 
-[features]
-default = []
-v3_00 = []
diff --git a/src/enums.rs b/src/enums.rs
index 8d73157..2b90e38 100644
--- a/src/enums.rs
+++ b/src/enums.rs
@@ -106,15 +106,15 @@ define_enum!(
     Gamma = libvlc_video_adjust_option_t_libvlc_adjust_Gamma,
 );
 
-#[cfg(feature = "v3_00")]
-define_enum!(
-    ParseFlag, libvlc_media_parse_flag_t;
-    DoInteract = libvlc_media_parse_flag_t_libvlc_media_do_interact,
-    FetchLocal = libvlc_media_parse_flag_t_libvlc_media_fetch_local,
-    FetchNetwork = libvlc_media_parse_flag_t_libvlc_media_fetch_network,
-    ParseLocal = libvlc_media_parse_flag_t_libvlc_media_parse_local,
-    ParseNetwork = libvlc_media_parse_flag_t_libvlc_media_parse_network,
-);
+// libvlc 3.0
+// define_enum!(
+//     ParseFlag, libvlc_media_parse_flag_t;
+//     DoInteract = libvlc_media_parse_flag_t_libvlc_media_do_interact,
+//     FetchLocal = libvlc_media_parse_flag_t_libvlc_media_fetch_local,
+//     FetchNetwork = libvlc_media_parse_flag_t_libvlc_media_fetch_network,
+//     ParseLocal = libvlc_media_parse_flag_t_libvlc_media_parse_local,
+//     ParseNetwork = libvlc_media_parse_flag_t_libvlc_media_parse_network,
+// );
 
 define_enum!(
     EventType, libvlc_event_e;

From a69bd47517b30199861eeaead25ce122ed989ae4 Mon Sep 17 00:00:00 2001
From: Grubshka <pierre@lail.fr>
Date: Tue, 2 Nov 2021 23:37:10 +0100
Subject: [PATCH 18/28] CI fix

---
 .gitignore     |  3 +++
 .gitlab-ci.yml | 17 +++++++++++++++++
 .travis.yml    | 16 ----------------
 3 files changed, 20 insertions(+), 16 deletions(-)
 create mode 100644 .gitlab-ci.yml
 delete mode 100644 .travis.yml

diff --git a/.gitignore b/.gitignore
index 94408df..9e92baa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,9 @@
 # Executables
 *.exe
 
+# IDE
+.*.swp
+
 # Generated by Cargo
 /target/
 Cargo.lock
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..dc5f9dd
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,17 @@
+stages:
+    - build
+
+variables:
+    VLC_UBUNTU_IMAGE: registry.videolan.org/vlc-rs-libvlc-stable-ubuntu:202110210936
+
+vlc-rs-build:
+    tags:
+        - docker
+        - amd64
+    stage: build
+    image:
+        name: $VLC_UBUNTU_IMAGE
+
+    script:
+        - . $HOME/.cargo/env
+        - cargo build --all
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 255d403..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-language: rust
-
-rust:
-  - stable
-
-script:
-  - cargo build --all
-
-os:
-  - linux
-
-addons:
-  apt:
-    packages:
-      - libvlc-dev
-

From 90a34a2f5b4a97a15e554bfd20de62de512bfb62 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pierre=20R=C3=A9veillon?= <pierre@citronmauve.com>
Date: Tue, 9 Nov 2021 22:51:43 +0100
Subject: [PATCH 19/28] image tag fix

---
 .gitlab-ci.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index dc5f9dd..97e45a2 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -2,7 +2,7 @@ stages:
     - build
 
 variables:
-    VLC_UBUNTU_IMAGE: registry.videolan.org/vlc-rs-libvlc-stable-ubuntu:202110210936
+    VLC_UBUNTU_IMAGE: registry.videolan.org/vlc-rs-libvlc-stable-ubuntu:20211102174954
 
 vlc-rs-build:
     tags:

From f3534654d7978c5abc45ce8d8722333638ccd5a4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pierre=20R=C3=A9veillon?= <pierre@citronmauve.com>
Date: Tue, 9 Nov 2021 23:07:08 +0100
Subject: [PATCH 20/28] libvlc-sys was removed by mistake

---
 Cargo.toml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Cargo.toml b/Cargo.toml
index b62c360..202a247 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -18,6 +18,7 @@ crate-type = ["rlib"]
 
 [dependencies]
 libc = "0.2"
+libvlc-sys = "0.2"
 
 [target.'cfg(target_os = "windows")'.build-dependencies]
 vswhom = "0.1.0"
\ No newline at end of file

From 1c04065056f9915532357bca6d5f21dd5f43e375 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pierre=20R=C3=A9veillon?= <pierre@citronmauve.com>
Date: Fri, 19 Nov 2021 10:02:43 +0100
Subject: [PATCH 21/28] Fix most clippy errors and warnings, applied rustfmt

---
 examples/cli_player.rs    |  37 ++-
 examples/print_version.rs |   1 -
 src/audio.rs              |  39 ++--
 src/core.rs               | 467 ++++++++++++++++++--------------------
 src/lib.rs                |  30 +--
 src/media.rs              | 113 ++++-----
 src/media_library.rs      |  30 ++-
 src/media_list.rs         |  89 +++++---
 src/media_player.rs       | 264 +++++++++++++--------
 src/tools.rs              |  14 +-
 src/video.rs              |  91 +++++---
 src/vlm.rs                | 241 ++++++++++++++------
 12 files changed, 826 insertions(+), 590 deletions(-)

diff --git a/examples/cli_player.rs b/examples/cli_player.rs
index 8cc9d92..c3e18c1 100644
--- a/examples/cli_player.rs
+++ b/examples/cli_player.rs
@@ -1,4 +1,3 @@
-
 // This file is an example for vlc-rs, licensed under CC0.
 // https://creativecommons.org/publicdomain/zero/1.0/deed
 
@@ -6,7 +5,7 @@ extern crate vlc;
 
 use std::sync::mpsc::channel;
 
-use vlc::{Instance, Media, MediaPlayer, Event, EventType, State};
+use vlc::{Event, EventType, Instance, Media, MediaPlayer, State};
 
 fn main() {
     let args: Vec<String> = std::env::args().collect();
@@ -19,32 +18,28 @@ fn main() {
         }
     };
     let instance = Instance::new().unwrap();
-    
-    let md = Media::new_path(&instance, path).unwrap();    
+
+    let md = Media::new_path(&instance, path).unwrap();
     let mdp = MediaPlayer::new(&instance).unwrap();
-    
+
     let (tx, rx) = channel::<()>();
-    
+
     let em = md.event_manager();
-    let _ = em.attach(EventType::MediaStateChanged, move |e, _| {
-        match e {
-            Event::MediaStateChanged(s) => {
-                println!("State : {:?}", s);
-                if s == State::Ended || s == State::Error {
-                    tx.send(()).unwrap();
-                }
-            },
-            _ => (),
+    let _ = em.attach(EventType::MediaStateChanged, move |e, _| match e {
+        Event::MediaStateChanged(s) => {
+            println!("State : {:?}", s);
+            if s == State::Ended || s == State::Error {
+                tx.send(()).unwrap();
+            }
         }
+        _ => (),
     });
-    
+
     mdp.set_media(&md);
-    
+
     // Start playing
     mdp.play().unwrap();
-    
+
     // Wait for end state
-    rx.recv().unwrap();    
+    rx.recv().unwrap();
 }
-
-
diff --git a/examples/print_version.rs b/examples/print_version.rs
index 7e1909e..991ad47 100644
--- a/examples/print_version.rs
+++ b/examples/print_version.rs
@@ -1,4 +1,3 @@
-
 // This file is an example for vlc-rs, licensed under CC0.
 // https://creativecommons.org/publicdomain/zero/1.0/deed
 
diff --git a/src/audio.rs b/src/audio.rs
index c39891c..68e0e8a 100644
--- a/src/audio.rs
+++ b/src/audio.rs
@@ -2,58 +2,67 @@
 // This file is part of vlc-rs.
 // Licensed under the MIT license, see the LICENSE file.
 
-use vlc_sys as sys;
+use crate::tools::from_cstr;
+use crate::InternalError;
 use crate::MediaPlayer;
 use crate::TrackDescription;
-use crate::tools::from_cstr;
+use vlc_sys as sys;
 
 pub trait MediaPlayerAudioEx {
     fn get_mute(&self) -> Option<bool>;
     fn set_mute(&self, muted: bool);
     fn get_volume(&self) -> i32;
-    fn set_volume(&self, volume: i32) -> Result<(), ()>;
+    fn set_volume(&self, volume: i32) -> Result<(), InternalError>;
     fn get_audio_track_description(&self) -> Option<Vec<TrackDescription>>;
 }
 
 impl MediaPlayerAudioEx for MediaPlayer {
     fn get_mute(&self) -> Option<bool> {
-        let r = unsafe{ sys::libvlc_audio_get_mute(self.ptr) };
+        let r = unsafe { sys::libvlc_audio_get_mute(self.ptr) };
 
         if r == 0 {
             Some(false)
-        }else if r == -1 {
+        } else if r == -1 {
             None
-        }else{
+        } else {
             Some(true)
         }
     }
 
     fn set_mute(&self, status: bool) {
-        unsafe{ sys::libvlc_audio_set_mute(self.ptr, if status { 1 }else{ 0 }) };
+        unsafe { sys::libvlc_audio_set_mute(self.ptr, if status { 1 } else { 0 }) };
     }
 
     fn get_volume(&self) -> i32 {
-        unsafe{ sys::libvlc_audio_get_volume(self.ptr) }
+        unsafe { sys::libvlc_audio_get_volume(self.ptr) }
     }
-    fn set_volume(&self, volume: i32) -> Result<(), ()> {
-        unsafe{
-            if sys::libvlc_audio_set_volume(self.ptr, volume) == 0 { Ok(()) }else{ Err(()) }
+    fn set_volume(&self, volume: i32) -> Result<(), InternalError> {
+        unsafe {
+            if sys::libvlc_audio_set_volume(self.ptr, volume) == 0 {
+                Ok(())
+            } else {
+                Err(InternalError)
+            }
         }
     }
     fn get_audio_track_description(&self) -> Option<Vec<TrackDescription>> {
-        unsafe{
+        unsafe {
             let p0 = sys::libvlc_audio_get_track_description(self.ptr);
-            if p0.is_null() { return None; }
+            if p0.is_null() {
+                return None;
+            }
             let mut td = Vec::new();
             let mut p = p0;
 
             while !(*p).p_next.is_null() {
-                td.push(TrackDescription{ id: (*p).i_id, name: from_cstr((*p).psz_name) });
+                td.push(TrackDescription {
+                    id: (*p).i_id,
+                    name: from_cstr((*p).psz_name),
+                });
                 p = (*p).p_next;
             }
             sys::libvlc_track_description_list_release(p0);
             Some(td)
         }
     }
-
 }
diff --git a/src/core.rs b/src/core.rs
index 8ba4ce2..93c8c9b 100644
--- a/src/core.rs
+++ b/src/core.rs
@@ -2,34 +2,49 @@
 // This file is part of vlc-rs.
 // Licensed under the MIT license, see the LICENSE file.
 
-use std::ptr;
-use std::borrow::Cow;
-use std::marker::PhantomData;
-use std::ffi::CString;
-use std::i32;
-use std::convert::TryInto;
-use libc::{c_void, c_char, c_int};
-use vlc_sys as sys;
-use crate::tools::{to_cstr, from_cstr, from_cstr_ref};
 use crate::enums::*;
+use crate::tools::{from_cstr, from_cstr_ref, to_cstr};
+use libc::{c_char, c_int, c_void};
+use std::borrow::Cow;
+use std::convert::TryInto;
+use std::ffi::CString;
+use std::fmt;
+use std::i32;
+use std::marker::PhantomData;
+use std::ptr;
+use vlc_sys as sys;
+
+#[derive(Debug)]
+pub struct InternalError;
+
+impl fmt::Display for InternalError {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "libvlc internal error")
+    }
+}
+
+impl std::error::Error for InternalError {}
 
 /// Retrieve libvlc version.
 pub fn version() -> String {
-    unsafe{
-        from_cstr_ref(sys::libvlc_get_version()).unwrap().into_owned()
+    unsafe {
+        from_cstr_ref(sys::libvlc_get_version())
+            .unwrap()
+            .into_owned()
     }
 }
 
 /// Retrieve libvlc compiler version.
 pub fn compiler() -> String {
-    unsafe{
-        from_cstr_ref(sys::libvlc_get_compiler()).unwrap().into_owned()
+    unsafe {
+        from_cstr_ref(sys::libvlc_get_compiler())
+            .unwrap()
+            .into_owned()
     }
 }
 
 pub struct Instance {
     pub(crate) ptr: *mut sys::libvlc_instance_t,
-
 }
 
 unsafe impl Send for Instance {}
@@ -39,18 +54,19 @@ impl Instance {
     /// Note: args.len() has to be less or equal to i32::MAX
     /// Note: libvlc discourages using arguments as these are not guaranteed to be stable between different versions of libvlc
     pub fn with_args(args: Option<Vec<String>>) -> Option<Instance> {
-        let args_c_ptr: Vec<*const c_char> ;
+        let args_c_ptr: Vec<*const c_char>;
         let args_c: Vec<CString>;
         if let Some(argv) = args {
-            args_c = argv.into_iter()
-                .map(|x| CString::new(x).expect("Error: Unexpected null byte")).collect();
+            args_c = argv
+                .into_iter()
+                .map(|x| CString::new(x).expect("Error: Unexpected null byte"))
+                .collect();
             args_c_ptr = args_c.iter().map(|x| x.as_ptr()).collect();
         } else {
             args_c_ptr = Vec::new();
         }
 
-
-        unsafe{
+        unsafe {
             let p = if args_c_ptr.is_empty() {
                 sys::libvlc_new(0, ptr::null())
             } else {
@@ -61,7 +77,7 @@ impl Instance {
                 return None;
             }
 
-            Some(Instance{ptr: p})
+            Some(Instance { ptr: p })
         }
     }
 
@@ -71,63 +87,76 @@ impl Instance {
     }
 
     /// Try to start a user interface for the libvlc instance.
-    pub fn add_intf(&self, name: &str) -> Result<(), ()> {
+    pub fn add_intf(&self, name: &str) -> Result<(), InternalError> {
         let cstr = to_cstr(name);
 
-        let result = unsafe{
-            sys::libvlc_add_intf(self.ptr, cstr.as_ptr())
-        };
+        let result = unsafe { sys::libvlc_add_intf(self.ptr, cstr.as_ptr()) };
 
-        if result == 0 { Ok(()) }
-        else { Err(()) }
+        if result == 0 {
+            Ok(())
+        } else {
+            Err(InternalError)
+        }
     }
 
     /// Sets the application name.
     /// LibVLC passes this as the user agent string when a protocol requires it.
     pub fn set_user_agent(&self, name: &str, http: &str) {
-        unsafe{
-            sys::libvlc_set_user_agent(
-                self.ptr, to_cstr(name).as_ptr(), to_cstr(http).as_ptr());
+        unsafe {
+            sys::libvlc_set_user_agent(self.ptr, to_cstr(name).as_ptr(), to_cstr(http).as_ptr());
         }
     }
 
     /// Waits until an interface causes the instance to exit.
     pub fn wait(&self) {
-        unsafe{ sys::libvlc_wait(self.ptr) };
+        unsafe { sys::libvlc_wait(self.ptr) };
     }
 
     /// Sets some meta-information about the application.
     pub fn set_app_id(&self, id: &str, version: &str, icon: &str) {
-        unsafe{
+        unsafe {
             sys::libvlc_set_app_id(
-                self.ptr, to_cstr(id).as_ptr(), to_cstr(version).as_ptr(), to_cstr(icon).as_ptr());
+                self.ptr,
+                to_cstr(id).as_ptr(),
+                to_cstr(version).as_ptr(),
+                to_cstr(icon).as_ptr(),
+            );
         }
     }
 
     /// Returns a list of audio filters that are available.
     pub fn audio_filter_list_get(&self) -> Option<ModuleDescriptionList> {
-        unsafe{
+        unsafe {
             let p = sys::libvlc_audio_filter_list_get(self.ptr);
-            if p.is_null() { None }
-            else { Some(ModuleDescriptionList{ptr: p}) }
+            if p.is_null() {
+                None
+            } else {
+                Some(ModuleDescriptionList { ptr: p })
+            }
         }
     }
 
     /// Returns a list of video filters that are available.
     pub fn video_filter_list_get(&self) -> Option<ModuleDescriptionList> {
-        unsafe{
+        unsafe {
             let p = sys::libvlc_video_filter_list_get(self.ptr);
-            if p.is_null() { None }
-            else { Some(ModuleDescriptionList{ptr: p}) }
+            if p.is_null() {
+                None
+            } else {
+                Some(ModuleDescriptionList { ptr: p })
+            }
         }
     }
 
     /// Returns the VLM event manager
     pub fn vlm_event_manager<'a>(&'a self) -> EventManager<'a> {
-        unsafe{
+        unsafe {
             let p = sys::libvlc_vlm_get_event_manager(self.ptr);
             assert!(!p.is_null());
-            EventManager{ptr: p, _phantomdata: ::std::marker::PhantomData}
+            EventManager {
+                ptr: p,
+                _phantomdata: ::std::marker::PhantomData,
+            }
         }
     }
 
@@ -135,7 +164,7 @@ impl Instance {
     pub fn set_log<F: Fn(LogLevel, Log, Cow<str>) + Send + 'static>(&self, f: F) {
         let cb: Box<Box<dyn Fn(LogLevel, Log, Cow<str>) + Send + 'static>> = Box::new(Box::new(f));
 
-        unsafe{
+        unsafe {
             sys::libvlc_log_set(self.ptr, Some(logging_cb), Box::into_raw(cb) as *mut _);
         }
     }
@@ -148,7 +177,7 @@ impl Instance {
 
 impl Drop for Instance {
     fn drop(&mut self) {
-        unsafe{
+        unsafe {
             sys::libvlc_release(self.ptr);
         }
     }
@@ -156,14 +185,22 @@ impl Drop for Instance {
 
 const BUF_SIZE: usize = 1024; // Write log message to the buffer by vsnprintf.
 unsafe extern "C" fn logging_cb(
-    data: *mut c_void, level: c_int, ctx: *const sys::libvlc_log_t, fmt: *const c_char, args: *mut sys::__va_list_tag) {
-
+    data: *mut c_void,
+    level: c_int,
+    ctx: *const sys::libvlc_log_t,
+    fmt: *const c_char,
+    args: *mut sys::__va_list_tag,
+) {
     let f: &Box<dyn Fn(LogLevel, Log, Cow<str>) + Send + 'static> = ::std::mem::transmute(data);
     let mut buf: [c_char; BUF_SIZE] = [0; BUF_SIZE];
 
     sys::vsnprintf(buf.as_mut_ptr(), BUF_SIZE.try_into().unwrap(), fmt, args);
 
-    f((level as u32).into(), Log{ptr: ctx}, from_cstr_ref(buf.as_ptr()).unwrap());
+    f(
+        (level as u32).into(),
+        Log { ptr: ctx },
+        from_cstr_ref(buf.as_ptr()).unwrap(),
+    );
 }
 
 /// List of module description.
@@ -180,7 +217,7 @@ impl ModuleDescriptionList {
 
 impl Drop for ModuleDescriptionList {
     fn drop(&mut self) {
-        unsafe{ sys::libvlc_module_description_list_release(self.ptr) };
+        unsafe { sys::libvlc_module_description_list_release(self.ptr) };
     }
 }
 
@@ -189,7 +226,10 @@ impl<'a> IntoIterator for &'a ModuleDescriptionList {
     type IntoIter = ModuleDescriptionListIter<'a>;
 
     fn into_iter(self) -> Self::IntoIter {
-        ModuleDescriptionListIter{ptr: self.ptr, _phantomdata: PhantomData}
+        ModuleDescriptionListIter {
+            ptr: self.ptr,
+            _phantomdata: PhantomData,
+        }
     }
 }
 
@@ -202,36 +242,36 @@ pub struct ModuleDescriptionListIter<'a> {
 /// The strings are owned.
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
 pub struct ModuleDescription {
-    pub name:      Option<String>,
+    pub name: Option<String>,
     pub shortname: Option<String>,
-    pub longname:  Option<String>,
-    pub help:      Option<String>,
+    pub longname: Option<String>,
+    pub help: Option<String>,
 }
 
 /// Description of a module.
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
 pub struct ModuleDescriptionRef<'a> {
-    pub name:      Option<Cow<'a, str>>,
+    pub name: Option<Cow<'a, str>>,
     pub shortname: Option<Cow<'a, str>>,
-    pub longname:  Option<Cow<'a, str>>,
-    pub help:      Option<Cow<'a, str>>,
+    pub longname: Option<Cow<'a, str>>,
+    pub help: Option<Cow<'a, str>>,
 }
 
 impl<'a> Iterator for ModuleDescriptionListIter<'a> {
     type Item = ModuleDescriptionRef<'a>;
 
     fn next(&mut self) -> Option<Self::Item> {
-        unsafe{
+        unsafe {
             if self.ptr.is_null() {
                 return None;
             }
             let p = self.ptr;
             self.ptr = (*p).p_next;
-            Some(ModuleDescriptionRef{
-                name:      from_cstr_ref((*p).psz_name),
+            Some(ModuleDescriptionRef {
+                name: from_cstr_ref((*p).psz_name),
                 shortname: from_cstr_ref((*p).psz_shortname),
-                longname:  from_cstr_ref((*p).psz_longname),
-                help:      from_cstr_ref((*p).psz_help),
+                longname: from_cstr_ref((*p).psz_longname),
+                help: from_cstr_ref((*p).psz_help),
             })
         }
     }
@@ -241,20 +281,20 @@ impl<'a> ModuleDescriptionRef<'a> {
     /// Convert to owned strings.
     pub fn into_owned(&'a self) -> ModuleDescription {
         ModuleDescription {
-            name:      self.name     .as_ref().map(|s| s.clone().into_owned()),
+            name: self.name.as_ref().map(|s| s.clone().into_owned()),
             shortname: self.shortname.as_ref().map(|s| s.clone().into_owned()),
-            longname:  self.name     .as_ref().map(|s| s.clone().into_owned()),
-            help:      self.shortname.as_ref().map(|s| s.clone().into_owned()),
+            longname: self.name.as_ref().map(|s| s.clone().into_owned()),
+            help: self.shortname.as_ref().map(|s| s.clone().into_owned()),
         }
     }
 }
 
 pub fn errmsg() -> Option<String> {
-    unsafe{ from_cstr(sys::libvlc_errmsg()) }
+    unsafe { from_cstr(sys::libvlc_errmsg()) }
 }
 
 pub fn clearerr() {
-    unsafe{ sys::libvlc_clearerr() };
+    unsafe { sys::libvlc_clearerr() };
 }
 
 #[derive(Clone, Debug)]
@@ -315,7 +355,7 @@ pub enum Event {
     VlmMediaInstanceStatusPlaying(Option<String>, Option<String>),
     VlmMediaInstanceStatusPause(Option<String>, Option<String>),
     VlmMediaInstanceStatusEnd(Option<String>, Option<String>),
-    VlmMediaInstanceStatusError(Option<String>, Option<String>)
+    VlmMediaInstanceStatusError(Option<String>, Option<String>),
 }
 
 pub struct EventManager<'a> {
@@ -324,23 +364,27 @@ pub struct EventManager<'a> {
 }
 
 impl<'a> EventManager<'a> {
-    pub fn attach<F>(&self, event_type: EventType, callback: F) -> Result<(), ()>
-        where F: Fn(Event, VLCObject) + Send + 'static
+    pub fn attach<F>(&self, event_type: EventType, callback: F) -> Result<(), InternalError>
+    where
+        F: Fn(Event, VLCObject) + Send + 'static,
     {
         // Explicit type annotation is needed
         let callback: Box<Box<dyn Fn(Event, VLCObject) + Send + 'static>> =
             Box::new(Box::new(callback));
 
-        let result = unsafe{
+        let result = unsafe {
             sys::libvlc_event_attach(
-                self.ptr, event_type as i32, Some(event_manager_callback),
-                Box::into_raw(callback) as *mut c_void)
+                self.ptr,
+                event_type as i32,
+                Some(event_manager_callback),
+                Box::into_raw(callback) as *mut c_void,
+            )
         };
 
         if result == 0 {
             Ok(())
-        }else{
-            Err(())
+        } else {
+            Err(InternalError)
         }
     }
 
@@ -353,201 +397,133 @@ impl<'a> EventManager<'a> {
 unsafe extern "C" fn event_manager_callback(pe: *const sys::libvlc_event_t, data: *mut c_void) {
     let f: &Box<dyn Fn(Event, VLCObject) + Send + 'static> = ::std::mem::transmute(data);
 
-    f(conv_event(pe), VLCObject{ ptr: (*pe).p_obj });
+    f(conv_event(pe), VLCObject { ptr: (*pe).p_obj });
 }
 
 // Convert c-style libvlc_event_t to Event
 fn conv_event(pe: *const sys::libvlc_event_t) -> Event {
-    let event_type: EventType = (unsafe{ (*pe).type_ } as u32).into();
+    let event_type: EventType = (unsafe { (*pe).type_ } as u32).into();
 
     match event_type {
-        EventType::MediaMetaChanged => {
-            unsafe{
-                Event::MediaMetaChanged((*pe).u.media_meta_changed.meta_type.into())
-            }
+        EventType::MediaMetaChanged => unsafe {
+            Event::MediaMetaChanged((*pe).u.media_meta_changed.meta_type.into())
         },
-        EventType::MediaSubItemAdded => {
-            Event::MediaSubItemAdded
+        EventType::MediaSubItemAdded => Event::MediaSubItemAdded,
+        EventType::MediaDurationChanged => unsafe {
+            Event::MediaDurationChanged((*pe).u.media_duration_changed.new_duration)
         },
-        EventType::MediaDurationChanged => {
-            unsafe{
-                Event::MediaDurationChanged((*pe).u.media_duration_changed.new_duration)
-            }
+        EventType::MediaParsedChanged => unsafe {
+            Event::MediaParsedChanged((*pe).u.media_parsed_changed.new_status)
         },
-        EventType::MediaParsedChanged => {
-            unsafe{
-                Event::MediaParsedChanged((*pe).u.media_parsed_changed.new_status)
-            }
+        EventType::MediaFreed => Event::MediaFreed,
+        EventType::MediaStateChanged => unsafe {
+            let new_state: sys::libvlc_state_t =
+                (*pe).u.media_state_changed.new_state.try_into().unwrap();
+            Event::MediaStateChanged(new_state.into())
         },
-        EventType::MediaFreed => {
-            Event::MediaFreed
+        EventType::MediaSubItemTreeAdded => Event::MediaSubItemTreeAdded,
+        EventType::MediaPlayerMediaChanged => Event::MediaPlayerMediaChanged,
+        EventType::MediaPlayerNothingSpecial => Event::MediaPlayerNothingSpecial,
+        EventType::MediaPlayerOpening => Event::MediaPlayerOpening,
+        EventType::MediaPlayerBuffering => unsafe {
+            Event::MediaPlayerBuffering((*pe).u.media_player_buffering.new_cache)
         },
-        EventType::MediaStateChanged => {
-            unsafe{
-                let new_state: sys::libvlc_state_t = (*pe).u.media_state_changed.new_state.try_into().unwrap();
-                Event::MediaStateChanged(new_state.into())
-            }
+        EventType::MediaPlayerPlaying => Event::MediaPlayerPlaying,
+        EventType::MediaPlayerPaused => Event::MediaPlayerPaused,
+        EventType::MediaPlayerStopped => Event::MediaPlayerStopped,
+        EventType::MediaPlayerForward => Event::MediaPlayerForward,
+        EventType::MediaPlayerBackward => Event::MediaPlayerBackward,
+        EventType::MediaPlayerEndReached => Event::MediaPlayerEndReached,
+        EventType::MediaPlayerEncounteredError => Event::MediaPlayerEncounteredError,
+        EventType::MediaPlayerTimeChanged => Event::MediaPlayerTimeChanged,
+        EventType::MediaPlayerPositionChanged => unsafe {
+            Event::MediaPlayerPositionChanged((*pe).u.media_player_position_changed.new_position)
         },
-        EventType::MediaSubItemTreeAdded => {
-            Event::MediaSubItemTreeAdded
+        EventType::MediaPlayerSeekableChanged => Event::MediaPlayerSeekableChanged,
+        EventType::MediaPlayerPausableChanged => Event::MediaPlayerPausableChanged,
+        EventType::MediaPlayerTitleChanged => Event::MediaPlayerTitleChanged,
+        EventType::MediaPlayerSnapshotTaken => Event::MediaPlayerSnapshotTaken,
+        EventType::MediaPlayerLengthChanged => Event::MediaPlayerLengthChanged,
+        EventType::MediaPlayerVout => Event::MediaPlayerVout,
+        EventType::MediaPlayerScrambledChanged => Event::MediaPlayerScrambledChanged,
+        EventType::MediaListItemAdded => Event::MediaListItemAdded,
+        EventType::MediaListWillAddItem => Event::MediaListWillAddItem,
+        EventType::MediaListItemDeleted => Event::MediaListItemDeleted,
+        EventType::MediaListWillDeleteItem => Event::MediaListWillDeleteItem,
+        EventType::MediaListViewItemAdded => Event::MediaListViewItemAdded,
+        EventType::MediaListViewWillAddItem => Event::MediaListViewWillAddItem,
+        EventType::MediaListViewItemDeleted => Event::MediaListViewItemDeleted,
+        EventType::MediaListViewWillDeleteItem => Event::MediaListViewWillDeleteItem,
+        EventType::MediaListPlayerPlayed => Event::MediaListPlayerPlayed,
+        EventType::MediaListPlayerNextItemSet => Event::MediaListPlayerNextItemSet,
+        EventType::MediaListPlayerStopped => Event::MediaListPlayerStopped,
+        EventType::MediaDiscovererStarted => Event::MediaDiscovererStarted,
+        EventType::MediaDiscovererEnded => Event::MediaDiscovererEnded,
+        EventType::VlmMediaAdded => unsafe {
+            Event::VlmMediaAdded(
+                from_cstr((*pe).u.vlm_media_event.psz_instance_name),
+                from_cstr((*pe).u.vlm_media_event.psz_media_name),
+            )
         },
-        EventType::MediaPlayerMediaChanged => {
-            Event::MediaPlayerMediaChanged
+        EventType::VlmMediaRemoved => unsafe {
+            Event::VlmMediaRemoved(
+                from_cstr((*pe).u.vlm_media_event.psz_instance_name),
+                from_cstr((*pe).u.vlm_media_event.psz_media_name),
+            )
         },
-        EventType::MediaPlayerNothingSpecial => {
-            Event::MediaPlayerNothingSpecial
+        EventType::VlmMediaChanged => unsafe {
+            Event::VlmMediaChanged(
+                from_cstr((*pe).u.vlm_media_event.psz_instance_name),
+                from_cstr((*pe).u.vlm_media_event.psz_media_name),
+            )
         },
-        EventType::MediaPlayerOpening => {
-            Event::MediaPlayerOpening
+        EventType::VlmMediaInstanceStarted => unsafe {
+            Event::VlmMediaInstanceStarted(
+                from_cstr((*pe).u.vlm_media_event.psz_instance_name),
+                from_cstr((*pe).u.vlm_media_event.psz_media_name),
+            )
         },
-        EventType::MediaPlayerBuffering => {
-            unsafe{
-                Event::MediaPlayerBuffering((*pe).u.media_player_buffering.new_cache)
-            }
+        EventType::VlmMediaInstanceStopped => unsafe {
+            Event::VlmMediaInstanceStopped(
+                from_cstr((*pe).u.vlm_media_event.psz_instance_name),
+                from_cstr((*pe).u.vlm_media_event.psz_media_name),
+            )
         },
-        EventType::MediaPlayerPlaying => {
-            Event::MediaPlayerPlaying
+        EventType::VlmMediaInstanceStatusInit => unsafe {
+            Event::VlmMediaInstanceStatusInit(
+                from_cstr((*pe).u.vlm_media_event.psz_instance_name),
+                from_cstr((*pe).u.vlm_media_event.psz_media_name),
+            )
         },
-        EventType::MediaPlayerPaused => {
-            Event::MediaPlayerPaused
+        EventType::VlmMediaInstanceStatusOpening => unsafe {
+            Event::VlmMediaInstanceStatusOpening(
+                from_cstr((*pe).u.vlm_media_event.psz_instance_name),
+                from_cstr((*pe).u.vlm_media_event.psz_media_name),
+            )
         },
-        EventType::MediaPlayerStopped => {
-            Event::MediaPlayerStopped
+        EventType::VlmMediaInstanceStatusPlaying => unsafe {
+            Event::VlmMediaInstanceStatusPlaying(
+                from_cstr((*pe).u.vlm_media_event.psz_instance_name),
+                from_cstr((*pe).u.vlm_media_event.psz_media_name),
+            )
         },
-        EventType::MediaPlayerForward => {
-            Event::MediaPlayerForward
+        EventType::VlmMediaInstanceStatusPause => unsafe {
+            Event::VlmMediaInstanceStatusPause(
+                from_cstr((*pe).u.vlm_media_event.psz_instance_name),
+                from_cstr((*pe).u.vlm_media_event.psz_media_name),
+            )
         },
-        EventType::MediaPlayerBackward => {
-            Event::MediaPlayerBackward
+        EventType::VlmMediaInstanceStatusEnd => unsafe {
+            Event::VlmMediaInstanceStatusEnd(
+                from_cstr((*pe).u.vlm_media_event.psz_instance_name),
+                from_cstr((*pe).u.vlm_media_event.psz_media_name),
+            )
         },
-        EventType::MediaPlayerEndReached => {
-            Event::MediaPlayerEndReached
-        },
-        EventType::MediaPlayerEncounteredError => {
-            Event::MediaPlayerEncounteredError
-        },
-        EventType::MediaPlayerTimeChanged => {
-            Event::MediaPlayerTimeChanged
-        },
-        EventType::MediaPlayerPositionChanged => {
-            unsafe{
-                Event::MediaPlayerPositionChanged((*pe).u.media_player_position_changed.new_position)
-            }
-        },
-        EventType::MediaPlayerSeekableChanged => {
-            Event::MediaPlayerSeekableChanged
-        },
-        EventType::MediaPlayerPausableChanged => {
-            Event::MediaPlayerPausableChanged
-        },
-        EventType::MediaPlayerTitleChanged => {
-            Event::MediaPlayerTitleChanged
-        },
-        EventType::MediaPlayerSnapshotTaken => {
-            Event::MediaPlayerSnapshotTaken
-        },
-        EventType::MediaPlayerLengthChanged => {
-            Event::MediaPlayerLengthChanged
-        },
-        EventType::MediaPlayerVout => {
-            Event::MediaPlayerVout
-        },
-        EventType::MediaPlayerScrambledChanged => {
-            Event::MediaPlayerScrambledChanged
-        },
-        EventType::MediaListItemAdded => {
-            Event::MediaListItemAdded
-        },
-        EventType::MediaListWillAddItem => {
-            Event::MediaListWillAddItem
-        },
-        EventType::MediaListItemDeleted => {
-            Event::MediaListItemDeleted
-        },
-        EventType::MediaListWillDeleteItem => {
-            Event::MediaListWillDeleteItem
-        },
-        EventType::MediaListViewItemAdded => {
-            Event::MediaListViewItemAdded
-        },
-        EventType::MediaListViewWillAddItem => {
-            Event::MediaListViewWillAddItem
-        },
-        EventType::MediaListViewItemDeleted => {
-            Event::MediaListViewItemDeleted
-        },
-        EventType::MediaListViewWillDeleteItem => {
-            Event::MediaListViewWillDeleteItem
-        },
-        EventType::MediaListPlayerPlayed => {
-            Event::MediaListPlayerPlayed
-        },
-        EventType::MediaListPlayerNextItemSet => {
-            Event::MediaListPlayerNextItemSet
-        },
-        EventType::MediaListPlayerStopped => {
-            Event::MediaListPlayerStopped
-        },
-        EventType::MediaDiscovererStarted => {
-            Event::MediaDiscovererStarted
-        },
-        EventType::MediaDiscovererEnded => {
-            Event::MediaDiscovererEnded
-        },
-        EventType::VlmMediaAdded => {
-            unsafe {
-                Event::VlmMediaAdded(from_cstr((*pe).u.vlm_media_event.psz_instance_name), from_cstr((*pe).u.vlm_media_event.psz_media_name))
-            }
-        },
-        EventType::VlmMediaRemoved => {
-            unsafe {
-                Event::VlmMediaRemoved(from_cstr((*pe).u.vlm_media_event.psz_instance_name), from_cstr((*pe).u.vlm_media_event.psz_media_name))
-            }
-        },
-        EventType::VlmMediaChanged => {
-            unsafe {
-                Event::VlmMediaChanged(from_cstr((*pe).u.vlm_media_event.psz_instance_name), from_cstr((*pe).u.vlm_media_event.psz_media_name))
-            }
-        },
-        EventType::VlmMediaInstanceStarted => {
-            unsafe {
-                Event::VlmMediaInstanceStarted(from_cstr((*pe).u.vlm_media_event.psz_instance_name), from_cstr((*pe).u.vlm_media_event.psz_media_name))
-            }
-        },
-        EventType::VlmMediaInstanceStopped => {
-            unsafe {
-                Event::VlmMediaInstanceStopped(from_cstr((*pe).u.vlm_media_event.psz_instance_name), from_cstr((*pe).u.vlm_media_event.psz_media_name))
-            }
-        },
-        EventType::VlmMediaInstanceStatusInit => {
-            unsafe {
-                Event::VlmMediaInstanceStatusInit(from_cstr((*pe).u.vlm_media_event.psz_instance_name), from_cstr((*pe).u.vlm_media_event.psz_media_name))
-            }
-        },
-        EventType::VlmMediaInstanceStatusOpening => {
-            unsafe {
-                Event::VlmMediaInstanceStatusOpening(from_cstr((*pe).u.vlm_media_event.psz_instance_name), from_cstr((*pe).u.vlm_media_event.psz_media_name))
-            }
-        },
-        EventType::VlmMediaInstanceStatusPlaying => {
-            unsafe {
-                Event::VlmMediaInstanceStatusPlaying(from_cstr((*pe).u.vlm_media_event.psz_instance_name), from_cstr((*pe).u.vlm_media_event.psz_media_name))
-            }
-        },
-        EventType::VlmMediaInstanceStatusPause => {
-            unsafe {
-                Event::VlmMediaInstanceStatusPause(from_cstr((*pe).u.vlm_media_event.psz_instance_name), from_cstr((*pe).u.vlm_media_event.psz_media_name))
-            }
-        },
-        EventType::VlmMediaInstanceStatusEnd => {
-            unsafe {
-                Event::VlmMediaInstanceStatusEnd(from_cstr((*pe).u.vlm_media_event.psz_instance_name), from_cstr((*pe).u.vlm_media_event.psz_media_name))
-            }
-        },
-        EventType::VlmMediaInstanceStatusError => {
-            unsafe {
-                Event::VlmMediaInstanceStatusError(from_cstr((*pe).u.vlm_media_event.psz_instance_name), from_cstr((*pe).u.vlm_media_event.psz_media_name))
-            }
+        EventType::VlmMediaInstanceStatusError => unsafe {
+            Event::VlmMediaInstanceStatusError(
+                from_cstr((*pe).u.vlm_media_event.psz_instance_name),
+                from_cstr((*pe).u.vlm_media_event.psz_media_name),
+            )
         },
     }
 }
@@ -564,7 +540,7 @@ impl VLCObject {
 }
 
 pub struct Log {
-    pub(crate) ptr: *const sys::libvlc_log_t
+    pub(crate) ptr: *const sys::libvlc_log_t,
 }
 
 impl Log {
@@ -573,4 +549,3 @@ impl Log {
         self.ptr
     }
 }
-
diff --git a/src/lib.rs b/src/lib.rs
index 5fdb4f8..2141d7b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -4,23 +4,23 @@
 
 extern crate libc;
 
-mod tools;
-mod core;
-mod media;
-mod media_player;
-mod media_list;
-mod media_library;
-mod enums;
-mod video;
 mod audio;
+mod core;
+mod enums;
+mod media;
+mod media_library;
+mod media_list;
+mod media_player;
+mod tools;
+mod video;
 mod vlm;
 
-pub use crate::enums::*;
-pub use crate::core::*;
-pub use crate::media::*;
-pub use crate::media_player::*;
-pub use crate::media_list::*;
-pub use crate::media_library::*;
-pub use crate::video::*;
 pub use crate::audio::*;
+pub use crate::core::*;
+pub use crate::enums::*;
+pub use crate::media::*;
+pub use crate::media_library::*;
+pub use crate::media_list::*;
+pub use crate::media_player::*;
+pub use crate::video::*;
 pub use crate::vlm::*;
diff --git a/src/media.rs b/src/media.rs
index eaa5d17..749f139 100644
--- a/src/media.rs
+++ b/src/media.rs
@@ -2,11 +2,11 @@
 // This file is part of vlc-rs.
 // Licensed under the MIT license, see the LICENSE file.
 
-use vlc_sys as sys;
-use crate::{Instance, EventManager};
-use crate::enums::{State, Meta, TrackType};
-use crate::tools::{to_cstr, from_cstr, path_to_cstr};
+use crate::enums::{Meta, State, TrackType};
+use crate::tools::{from_cstr, path_to_cstr, to_cstr};
+use crate::{EventManager, Instance};
 use std::path::Path;
+use vlc_sys as sys;
 
 pub struct Media {
     pub(crate) ptr: *mut sys::libvlc_media_t,
@@ -19,13 +19,13 @@ impl Media {
     pub fn new_location(instance: &Instance, mrl: &str) -> Option<Media> {
         let cstr = to_cstr(mrl);
 
-        unsafe{
+        unsafe {
             let p = sys::libvlc_media_new_location(instance.ptr, cstr.as_ptr());
             if p.is_null() {
                 return None;
             }
 
-            Some(Media{ptr: p})
+            Some(Media { ptr: p })
         }
     }
 
@@ -33,32 +33,34 @@ impl Media {
     pub fn new_path<T: AsRef<Path>>(instance: &Instance, path: T) -> Option<Media> {
         let cstr = match path_to_cstr(path.as_ref()) {
             Ok(s) => s,
-            Err(_) => { return None; },
+            Err(_) => {
+                return None;
+            }
         };
 
-        unsafe{
+        unsafe {
             let p = sys::libvlc_media_new_path(instance.ptr, cstr.as_ptr());
             if p.is_null() {
                 return None;
             }
 
-            Some(Media{ptr: p})
+            Some(Media { ptr: p })
         }
     }
 
     pub fn new_fd(instance: &Instance, fd: i32) -> Option<Media> {
-        unsafe{
+        unsafe {
             let p = sys::libvlc_media_new_fd(instance.ptr, fd);
             if p.is_null() {
                 return None;
             }
 
-            Some(Media{ptr: p})
+            Some(Media { ptr: p })
         }
     }
 
     pub fn mrl(&self) -> Option<String> {
-        unsafe{
+        unsafe {
             let p_str = sys::libvlc_media_get_mrl(self.ptr);
             let s = from_cstr(p_str);
             sys::libvlc_free(p_str as *mut ::libc::c_void);
@@ -67,17 +69,20 @@ impl Media {
     }
 
     pub fn event_manager<'a>(&'a self) -> EventManager<'a> {
-        unsafe{
+        unsafe {
             let p = sys::libvlc_media_event_manager(self.ptr);
             assert!(!p.is_null());
-            EventManager{ptr: p, _phantomdata: ::std::marker::PhantomData}
+            EventManager {
+                ptr: p,
+                _phantomdata: ::std::marker::PhantomData,
+            }
         }
     }
 
     /// Read the meta of the media.
     /// If the media has not yet been parsed this will return None.
     pub fn get_meta(&self, meta: Meta) -> Option<String> {
-        unsafe{
+        unsafe {
             let p_str = sys::libvlc_media_get_meta(self.ptr, meta as u32);
             let s = from_cstr(p_str);
             sys::libvlc_free(p_str as *mut ::libc::c_void);
@@ -88,46 +93,48 @@ impl Media {
     /// Set the meta of the media.
     /// (This function will not save the meta, call save_meta in order to save the meta)
     pub fn set_meta(&self, meta: Meta, value: &str) {
-        unsafe{
+        unsafe {
             sys::libvlc_media_set_meta(self.ptr, meta as u32, to_cstr(value).as_ptr());
         }
     }
 
     /// Save the meta previously set.
     pub fn save_meta(&self) -> bool {
-        if unsafe{ sys::libvlc_media_save_meta(self.ptr) } == 0 { false }else{ true }
+        (unsafe { sys::libvlc_media_save_meta(self.ptr) } != 0)
     }
 
     /// Get current state of media descriptor object.
     pub fn state(&self) -> State {
-        unsafe{ sys::libvlc_media_get_state(self.ptr).into() }
+        unsafe { sys::libvlc_media_get_state(self.ptr).into() }
     }
 
     /// Get duration (in ms) of media descriptor object item.
     pub fn duration(&self) -> Option<i64> {
-        let time = unsafe{
-            sys::libvlc_media_get_duration(self.ptr)
-        };
-        if time != -1 { Some(time) }else{ None }
+        let time = unsafe { sys::libvlc_media_get_duration(self.ptr) };
+        if time != -1 {
+            Some(time)
+        } else {
+            None
+        }
     }
 
     /// Parse a media.
     pub fn parse(&self) {
-        unsafe{ sys::libvlc_media_parse(self.ptr) };
+        unsafe { sys::libvlc_media_parse(self.ptr) };
     }
 
     /// Parse a media.
     pub fn parse_async(&self) {
-        unsafe{ sys::libvlc_media_parse_async(self.ptr) };
+        unsafe { sys::libvlc_media_parse_async(self.ptr) };
     }
 
     /// Get Parsed status for media descriptor object.
     pub fn is_parsed(&self) -> bool {
-        if unsafe{ sys::libvlc_media_is_parsed(self.ptr) } == 0 { false }else{ true }
+        (unsafe { sys::libvlc_media_is_parsed(self.ptr) } != 0)
     }
 
     pub fn tracks(&self) -> Option<Vec<MediaTrack>> {
-        unsafe{
+        unsafe {
             let mut p_track: *mut *mut sys::libvlc_media_track_t = ::std::ptr::null_mut();
             let n = sys::libvlc_media_tracks_get(self.ptr, &mut p_track);
             if n == 0 {
@@ -142,41 +149,41 @@ impl Media {
                 let type_specific_data = match i_type {
                     TrackType::Audio => {
                         let audio = (**p).__bindgen_anon_1.audio;
-                        MediaTrackUnion::Audio(AudioTrack{
+                        MediaTrackUnion::Audio(AudioTrack {
                             channels: (*audio).i_channels,
-                            rate:     (*audio).i_rate,
+                            rate: (*audio).i_rate,
                         })
-                    },
+                    }
                     TrackType::Video => {
                         let video = (**p).__bindgen_anon_1.video;
-                        MediaTrackUnion::Video(VideoTrack{
-                            height:         (*video).i_height,
-                            width:          (*video).i_width,
-                            sar_num:        (*video).i_sar_num,
-                            sar_den:        (*video).i_sar_den,
+                        MediaTrackUnion::Video(VideoTrack {
+                            height: (*video).i_height,
+                            width: (*video).i_width,
+                            sar_num: (*video).i_sar_num,
+                            sar_den: (*video).i_sar_den,
                             frame_rate_num: (*video).i_frame_rate_num,
                             frame_rate_den: (*video).i_frame_rate_den,
                         })
-                    },
+                    }
                     TrackType::Text => {
                         let subtitle = (**p).__bindgen_anon_1.subtitle;
-                        MediaTrackUnion::Subtitle(SubtitleTrack{
-                            encoding: from_cstr((*subtitle).psz_encoding)
+                        MediaTrackUnion::Subtitle(SubtitleTrack {
+                            encoding: from_cstr((*subtitle).psz_encoding),
                         })
-                    },
+                    }
                     TrackType::Unknown => MediaTrackUnion::None,
                 };
-                track.push(MediaTrack{
-                    codec:              (**p).i_codec,
-                    original_fourcc:    (**p).i_original_fourcc,
-                    id:                 (**p).i_id,
-                    track_type:         (**p).i_type.into(),
-                    profile:            (**p).i_profile,
-                    level:              (**p).i_level,
-                    bitrate:            (**p).i_bitrate,
-                    language:           from_cstr((**p).psz_language),
-                    description:        from_cstr((**p).psz_description),
-                    type_specific_data: type_specific_data,
+                track.push(MediaTrack {
+                    codec: (**p).i_codec,
+                    original_fourcc: (**p).i_original_fourcc,
+                    id: (**p).i_id,
+                    track_type: (**p).i_type.into(),
+                    profile: (**p).i_profile,
+                    level: (**p).i_level,
+                    bitrate: (**p).i_bitrate,
+                    language: from_cstr((**p).psz_language),
+                    description: from_cstr((**p).psz_description),
+                    type_specific_data,
                 });
             }
 
@@ -193,7 +200,7 @@ impl Media {
 
 impl Drop for Media {
     fn drop(&mut self) {
-        unsafe{ sys::libvlc_media_release(self.ptr) };
+        unsafe { sys::libvlc_media_release(self.ptr) };
     }
 }
 
@@ -213,7 +220,10 @@ pub struct MediaTrack {
 
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
 pub enum MediaTrackUnion {
-    Audio(AudioTrack), Video(VideoTrack), Subtitle(SubtitleTrack), None,
+    Audio(AudioTrack),
+    Video(VideoTrack),
+    Subtitle(SubtitleTrack),
+    None,
 }
 
 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
@@ -236,4 +246,3 @@ pub struct VideoTrack {
 pub struct SubtitleTrack {
     pub encoding: Option<String>,
 }
-
diff --git a/src/media_library.rs b/src/media_library.rs
index 3abf357..8e66de8 100644
--- a/src/media_library.rs
+++ b/src/media_library.rs
@@ -2,8 +2,8 @@
 // This file is part of vlc-rs.
 // Licensed under the MIT license, see the LICENSE file.
 
+use crate::{Instance, InternalError, MediaList};
 use vlc_sys as sys;
-use crate::{Instance, MediaList};
 
 pub struct MediaLibrary {
     pub(crate) ptr: *mut sys::libvlc_media_library_t,
@@ -12,24 +12,36 @@ pub struct MediaLibrary {
 impl MediaLibrary {
     /// Create an new Media Library object.
     pub fn new(instance: &Instance) -> Option<MediaLibrary> {
-        unsafe{
+        unsafe {
             let p = sys::libvlc_media_library_new(instance.ptr);
-            if p.is_null() { None }else{ Some(MediaLibrary{ptr: p}) }
+            if p.is_null() {
+                None
+            } else {
+                Some(MediaLibrary { ptr: p })
+            }
         }
     }
 
     /// Load media library.
-    pub fn load(&self) -> Result<(), ()> {
-        unsafe{
-            if sys::libvlc_media_library_load(self.ptr) == 0 { Ok(()) }else{ Err(()) }
+    pub fn load(&self) -> Result<(), InternalError> {
+        unsafe {
+            if sys::libvlc_media_library_load(self.ptr) == 0 {
+                Ok(())
+            } else {
+                Err(InternalError)
+            }
         }
     }
 
     /// Get media library subitems.
     pub fn media_list(&self) -> Option<MediaList> {
-        unsafe{
+        unsafe {
             let p = sys::libvlc_media_library_media_list(self.ptr);
-            if p.is_null() { None }else{ Some(MediaList{ptr: p}) }
+            if p.is_null() {
+                None
+            } else {
+                Some(MediaList { ptr: p })
+            }
         }
     }
 
@@ -41,6 +53,6 @@ impl MediaLibrary {
 
 impl Drop for MediaLibrary {
     fn drop(&mut self) {
-        unsafe{ sys::libvlc_media_library_release(self.ptr) };
+        unsafe { sys::libvlc_media_library_release(self.ptr) };
     }
 }
diff --git a/src/media_list.rs b/src/media_list.rs
index 048d821..7eb99b1 100644
--- a/src/media_list.rs
+++ b/src/media_list.rs
@@ -2,8 +2,8 @@
 // This file is part of vlc-rs.
 // Licensed under the MIT license, see the LICENSE file.
 
+use crate::{EventManager, Instance, InternalError, Media};
 use vlc_sys as sys;
-use crate::{Instance, Media, EventManager};
 
 pub struct MediaList {
     pub(crate) ptr: *mut sys::libvlc_media_list_t,
@@ -12,96 +12,133 @@ pub struct MediaList {
 impl MediaList {
     /// Create an empty media list.
     pub fn new(instance: &Instance) -> Option<MediaList> {
-        unsafe{
+        unsafe {
             let p = sys::libvlc_media_list_new(instance.ptr);
-            if p.is_null() { None }else{ Some(MediaList{ptr: p}) }
+            if p.is_null() {
+                None
+            } else {
+                Some(MediaList { ptr: p })
+            }
         }
     }
 
     /// 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.
     pub fn set_media(&self, md: &Media) {
-        unsafe{ sys::libvlc_media_list_set_media(self.ptr, md.ptr); }
+        unsafe {
+            sys::libvlc_media_list_set_media(self.ptr, md.ptr);
+        }
     }
 
     /// Get media instance from this media list instance.
     /// The MediaList::lock should NOT be held upon entering this function.
     pub fn media(&self) -> Option<Media> {
-        unsafe{
+        unsafe {
             let p = sys::libvlc_media_list_media(self.ptr);
-            if p.is_null() { None }else{ Some(Media{ptr: p}) }
+            if p.is_null() {
+                None
+            } else {
+                Some(Media { ptr: p })
+            }
         }
     }
 
     /// Add media instance to media list.
     /// The MediaList::lock should be held upon entering this function.
-    pub fn add_media(&self, md: &Media) -> Result<(), ()> {
-        unsafe{
-            if sys::libvlc_media_list_add_media(self.ptr, md.ptr) == 0 { Ok(()) }else{ Err(()) }
+    pub fn add_media(&self, md: &Media) -> Result<(), InternalError> {
+        unsafe {
+            if sys::libvlc_media_list_add_media(self.ptr, md.ptr) == 0 {
+                Ok(())
+            } else {
+                Err(InternalError)
+            }
         }
     }
 
     /// Insert media instance in media list on a position.
     /// The MediaList::lock should be held upon entering this function.
-    pub fn insert_media(&self, md: &Media, pos: i32) -> Result<(), ()> {
-        unsafe{
-            if sys::libvlc_media_list_insert_media(self.ptr, md.ptr, pos) == 0 { Ok(()) }else{ Err(()) }
+    pub fn insert_media(&self, md: &Media, pos: i32) -> Result<(), InternalError> {
+        unsafe {
+            if sys::libvlc_media_list_insert_media(self.ptr, md.ptr, pos) == 0 {
+                Ok(())
+            } else {
+                Err(InternalError)
+            }
         }
     }
 
     /// Remove media instance from media list on a position.
     /// The MediaList::lock should be held upon entering this function.
-    pub fn remove_index(&self, pos: i32) -> Result<(), ()> {
-        unsafe{
-            if sys::libvlc_media_list_remove_index(self.ptr, pos) == 0 { Ok(()) }else{ Err(()) }
+    pub fn remove_index(&self, pos: i32) -> Result<(), InternalError> {
+        unsafe {
+            if sys::libvlc_media_list_remove_index(self.ptr, pos) == 0 {
+                Ok(())
+            } else {
+                Err(InternalError)
+            }
         }
     }
 
     /// Get count on media list items.
     /// The MediaList::lock should be held upon entering this function.
     pub fn count(&self) -> i32 {
-        unsafe{ sys::libvlc_media_list_count(self.ptr) }
+        unsafe { sys::libvlc_media_list_count(self.ptr) }
     }
 
     /// List media instance in media list at a position.
     /// The MediaList::lock should be held upon entering this function.
     pub fn item_at_index(&self, pos: i32) -> Option<Media> {
-        unsafe{
+        unsafe {
             let p = sys::libvlc_media_list_item_at_index(self.ptr, pos);
-            if p.is_null() { None }else{ Some(Media{ptr: p}) }
+            if p.is_null() {
+                None
+            } else {
+                Some(Media { ptr: p })
+            }
         }
     }
 
     /// Find index position of List media instance in media list.
     pub fn index_of_item(&self, md: &Media) -> Option<i32> {
-        unsafe{
+        unsafe {
             let i = sys::libvlc_media_list_index_of_item(self.ptr, md.ptr);
-            if i == -1 { None }else{ Some(i) }
+            if i == -1 {
+                None
+            } else {
+                Some(i)
+            }
         }
     }
 
     /// This indicates if this media list is read-only from a user point of view.
     pub fn is_readonly(&self) -> bool {
-        unsafe{ if sys::libvlc_media_list_is_readonly(self.ptr) == 0 { false }else{ true } }
+        unsafe { sys::libvlc_media_list_is_readonly(self.ptr) != 0 }
     }
 
     /// Get lock on media list items
     pub fn lock(&self) {
-        unsafe{ sys::libvlc_media_list_lock(self.ptr); }
+        unsafe {
+            sys::libvlc_media_list_lock(self.ptr);
+        }
     }
 
     /// Release lock on media list items
     /// The libvlc_media_list_lock should be held upon entering this function.
     pub fn unlock(&self) {
-        unsafe{ sys::libvlc_media_list_unlock(self.ptr); }
+        unsafe {
+            sys::libvlc_media_list_unlock(self.ptr);
+        }
     }
 
     /// Get EventManager from this media list instance.
     pub fn event_manager<'a>(&'a self) -> EventManager<'a> {
-        unsafe{
+        unsafe {
             let p = sys::libvlc_media_list_event_manager(self.ptr);
             assert!(!p.is_null());
-            EventManager{ptr: p, _phantomdata: ::std::marker::PhantomData}
+            EventManager {
+                ptr: p,
+                _phantomdata: ::std::marker::PhantomData,
+            }
         }
     }
 
@@ -113,6 +150,6 @@ impl MediaList {
 
 impl Drop for MediaList {
     fn drop(&mut self) {
-        unsafe{ sys::libvlc_media_list_release(self.ptr) };
+        unsafe { sys::libvlc_media_list_release(self.ptr) };
     }
 }
diff --git a/src/media_player.rs b/src/media_player.rs
index ee38b4c..ec8c0be 100644
--- a/src/media_player.rs
+++ b/src/media_player.rs
@@ -2,13 +2,14 @@
 // This file is part of vlc-rs.
 // Licensed under the MIT license, see the LICENSE file.
 
-use vlc_sys as sys;
-use crate::Instance;
-use crate::Media;
+use crate::enums::{Position, State};
 use crate::EventManager;
-use libc::{c_void, c_uint};
-use crate::enums::{State, Position};
+use crate::Instance;
+use crate::InternalError;
+use crate::Media;
+use libc::{c_uint, c_void};
 use std::mem::transmute;
+use vlc_sys as sys;
 
 /// A LibVLC media player plays one media (usually in a custom drawable).
 pub struct MediaPlayer {
@@ -20,71 +21,70 @@ unsafe impl Send for MediaPlayer {}
 impl MediaPlayer {
     /// Create an empty Media Player object
     pub fn new(instance: &Instance) -> Option<MediaPlayer> {
-        unsafe{
+        unsafe {
             let p = sys::libvlc_media_player_new(instance.ptr);
-
             if p.is_null() {
-                return None;
+                None
+            } else {
+                Some(MediaPlayer { ptr: p })
             }
-            Some(MediaPlayer{ptr: p})
         }
     }
 
     /// Set the media that will be used by the media_player. If any, previous md will be released.
     pub fn set_media(&self, md: &Media) {
-        unsafe{ sys::libvlc_media_player_set_media(self.ptr, md.ptr) };
+        unsafe { sys::libvlc_media_player_set_media(self.ptr, md.ptr) };
     }
 
     /// Get the media used by the media_player.
     pub fn get_media(&self) -> Option<Media> {
-        let p = unsafe{ sys::libvlc_media_player_get_media(self.ptr) };
+        let p = unsafe { sys::libvlc_media_player_get_media(self.ptr) };
         if p.is_null() {
             None
-        }else{
-            Some(Media{ptr: p})
+        } else {
+            Some(Media { ptr: p })
         }
     }
 
     /// Get the Event Manager from which the media player send event.
     pub fn event_manager<'a>(&'a self) -> EventManager<'a> {
-        unsafe{
+        unsafe {
             let p = sys::libvlc_media_player_event_manager(self.ptr);
             assert!(!p.is_null());
-            EventManager{ptr: p, _phantomdata: ::std::marker::PhantomData}
+            EventManager {
+                ptr: p,
+                _phantomdata: ::std::marker::PhantomData,
+            }
         }
     }
 
     /// is_playing
     pub fn is_playing(&self) -> bool {
-        if unsafe{ sys::libvlc_media_player_is_playing(self.ptr) } == 0 {
-            false
-        }else{
-            true
-        }
+        unsafe { sys::libvlc_media_player_is_playing(self.ptr) != 0 }
     }
 
     /// Play
-    pub fn play(&self) -> Result<(), ()> {
-        if unsafe{ sys::libvlc_media_player_play(self.ptr) } == 0 {
+    pub fn play(&self) -> Result<(), InternalError> {
+        if unsafe { sys::libvlc_media_player_play(self.ptr) } == 0 {
             Ok(())
-        }else{
-            Err(())
+        } else {
+            Err(InternalError)
         }
     }
 
     /// Pause or resume (no effect if there is no media)
     pub fn set_pause(&self, do_pause: bool) {
-        unsafe{ sys::libvlc_media_player_set_pause(self.ptr, if do_pause {1} else {0}) };
+        unsafe { sys::libvlc_media_player_set_pause(self.ptr, if do_pause { 1 } else { 0 }) };
     }
 
     /// Toggle pause (no effect if there is no media)
     pub fn pause(&self) {
-        unsafe{ sys::libvlc_media_player_pause(self.ptr) };
+        unsafe { sys::libvlc_media_player_pause(self.ptr) };
     }
 
     /// Stop (no effect if there is no media)
     pub fn stop(&self) {
-        unsafe{ sys::libvlc_media_player_stop(self.ptr) };
+        unsafe { sys::libvlc_media_player_stop(self.ptr) };
     }
 
     pub fn set_callbacks<F>(
@@ -93,8 +93,9 @@ impl MediaPlayer {
         pause: Option<Box<dyn Fn(i64) + Send + 'static>>,
         resume: Option<Box<dyn Fn(i64) + Send + 'static>>,
         flush: Option<Box<dyn Fn(i64) + Send + 'static>>,
-        drain: Option<Box<dyn Fn() + Send + 'static>>)
-        where F: Fn(*const c_void, u32, i64) + Send + 'static,
+        drain: Option<Box<dyn Fn() + Send + 'static>>,
+    ) where
+        F: Fn(*const c_void, u32, i64) + Send + 'static,
     {
         let flag_pause = pause.is_some();
         let flag_resume = resume.is_some();
@@ -102,164 +103,236 @@ impl MediaPlayer {
         let flag_drain = drain.is_some();
 
         let data = AudioCallbacksData {
-            play: Box::new(play), pause: pause, resume: resume,
-            flush: flush, drain: drain,
+            play: Box::new(play),
+            pause,
+            resume,
+            flush,
+            drain,
         };
         let data = Box::into_raw(Box::new(data));
 
-        unsafe{
+        unsafe {
             sys::libvlc_audio_set_callbacks(
                 self.ptr,
                 Some(audio_cb_play),
-                if flag_pause {Some(audio_cb_pause)} else {None},
-                if flag_resume {Some(audio_cb_resume)} else {None},
-                if flag_flush {Some(audio_cb_flush)} else {None},
-                if flag_drain {Some(audio_cb_drain)} else {None},
-                data as *mut c_void);
+                if flag_pause {
+                    Some(audio_cb_pause)
+                } else {
+                    None
+                },
+                if flag_resume {
+                    Some(audio_cb_resume)
+                } else {
+                    None
+                },
+                if flag_flush {
+                    Some(audio_cb_flush)
+                } else {
+                    None
+                },
+                if flag_drain {
+                    Some(audio_cb_drain)
+                } else {
+                    None
+                },
+                data as *mut c_void,
+            );
         }
     }
 
     /// Set the NSView handler where the media player should render its video output.
     pub fn set_nsobject(&self, drawable: *mut c_void) {
-        unsafe{ sys::libvlc_media_player_set_nsobject(self.ptr, drawable) };
+        let d = drawable;
+        unsafe { sys::libvlc_media_player_set_nsobject(self.ptr, d) };
     }
 
     /// Get the NSView handler previously set with set_nsobject().
     pub fn get_nsobject(&self) -> Option<*mut c_void> {
-        let nso = unsafe{ sys::libvlc_media_player_get_nsobject(self.ptr) };
-        if nso.is_null() { None }else{ Some(nso) }
+        let nso = unsafe { sys::libvlc_media_player_get_nsobject(self.ptr) };
+        if nso.is_null() {
+            None
+        } else {
+            Some(nso)
+        }
     }
 
     /// Set an X Window System drawable where the media player should render its video output.
     pub fn set_xwindow(&self, drawable: u32) {
-        unsafe{ sys::libvlc_media_player_set_xwindow(self.ptr, drawable) };
+        unsafe { sys::libvlc_media_player_set_xwindow(self.ptr, drawable) };
     }
 
     /// Get the X Window System window identifier previously set with set_xwindow().
     pub fn get_xwindow(&self) -> Option<u32> {
-        let id = unsafe{ sys::libvlc_media_player_get_xwindow(self.ptr) };
-        if id == 0 { None }else{ Some(id) }
+        let id = unsafe { sys::libvlc_media_player_get_xwindow(self.ptr) };
+        if id == 0 {
+            None
+        } else {
+            Some(id)
+        }
     }
 
     /// 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.
     pub fn set_hwnd(&self, drawable: *mut c_void) {
-        unsafe{ sys::libvlc_media_player_set_hwnd(self.ptr, drawable) };
+        let d = drawable;
+        unsafe { sys::libvlc_media_player_set_hwnd(self.ptr, d) };
     }
 
     /// Get the Windows API window handle (HWND) previously set with set_hwnd().
     pub fn get_hwnd(&self) -> Option<*mut c_void> {
-        let hwnd = unsafe{ sys::libvlc_media_player_get_hwnd(self.ptr) };
-        if hwnd.is_null() { None }else{ Some(hwnd) }
+        let hwnd = unsafe { sys::libvlc_media_player_get_hwnd(self.ptr) };
+        if hwnd.is_null() {
+            None
+        } else {
+            Some(hwnd)
+        }
     }
 
     /// Get the current movie time (in ms).
     pub fn get_time(&self) -> Option<i64> {
-        unsafe{
+        unsafe {
             let t = sys::libvlc_media_player_get_time(self.ptr);
-            if t == -1 { None }else{ Some(t) }
+            if t == -1 {
+                None
+            } else {
+                Some(t)
+            }
         }
     }
 
     /// Set the movie time (in ms).
     /// This has no effect if no media is being played. Not all formats and protocols support this.
     pub fn set_time(&self, time: i64) {
-        unsafe{ sys::libvlc_media_player_set_time(self.ptr, time); }
+        unsafe {
+            sys::libvlc_media_player_set_time(self.ptr, time);
+        }
     }
 
     /// Get movie position as percentage between 0.0 and 1.0.
     pub fn get_position(&self) -> Option<f32> {
-        unsafe{
+        unsafe {
             let pos = sys::libvlc_media_player_get_position(self.ptr);
-            if pos == -1f32 { None }else{ Some(pos) }
+            // if pos == -1f32 { None }else{ Some(pos) }
+            if (pos - -1f32).abs() < f32::EPSILON {
+                None
+            } else {
+                Some(pos)
+            }
         }
     }
 
     /// 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.
     pub fn set_position(&self, pos: f32) {
-        unsafe{ sys::libvlc_media_player_set_position(self.ptr, pos); }
+        unsafe {
+            sys::libvlc_media_player_set_position(self.ptr, pos);
+        }
     }
 
     /// Set movie chapter (if applicable).
     pub fn set_chapter(&self, chapter: i32) {
-        unsafe{ sys::libvlc_media_player_set_chapter(self.ptr, chapter); }
+        unsafe {
+            sys::libvlc_media_player_set_chapter(self.ptr, chapter);
+        }
     }
 
     /// Get movie chapter.
     pub fn get_chapter(&self) -> Option<i32> {
-        unsafe{
+        unsafe {
             let c = sys::libvlc_media_player_get_chapter(self.ptr);
-            if c == -1 { None }else{ Some(c) }
+            if c == -1 {
+                None
+            } else {
+                Some(c)
+            }
         }
     }
 
     /// Get movie chapter count.
     pub fn chapter_count(&self) -> Option<i32> {
-        unsafe{
+        unsafe {
             let c = sys::libvlc_media_player_get_chapter_count(self.ptr);
-            if c == -1 { None }else{ Some(c) }
+            if c == -1 {
+                None
+            } else {
+                Some(c)
+            }
         }
     }
 
     /// Is the player able to play.
     pub fn will_play(&self) -> bool {
-        unsafe{
-            let b = sys::libvlc_media_player_will_play(self.ptr);
-            if b == 0 { false }else{ true }
-        }
+        unsafe { sys::libvlc_media_player_will_play(self.ptr) != 0 }
     }
 
     /// Get title chapter count.
     pub fn chapter_count_for_title(&self, title: i32) -> Option<i32> {
-        unsafe{
+        unsafe {
             let c = sys::libvlc_media_player_get_chapter_count_for_title(self.ptr, title);
-            if c == -1 { None }else{ Some(c) }
+            if c == -1 {
+                None
+            } else {
+                Some(c)
+            }
         }
     }
 
     /// Set movie title.
     pub fn set_title(&self, title: i32) {
-        unsafe{ sys::libvlc_media_player_set_title(self.ptr, title); }
+        unsafe {
+            sys::libvlc_media_player_set_title(self.ptr, title);
+        }
     }
 
     /// Get movie title.
     pub fn get_title(&self) -> Option<i32> {
-        unsafe{
+        unsafe {
             let t = sys::libvlc_media_player_get_title(self.ptr);
-            if t == -1 { None }else{ Some(t) }
+            if t == -1 {
+                None
+            } else {
+                Some(t)
+            }
         }
     }
 
     /// Get movie title count.
     pub fn title_count(&self) -> Option<i32> {
-        unsafe{
+        unsafe {
             let t = sys::libvlc_media_player_get_title_count(self.ptr);
-            if t == -1 { Some(t) } else { None }
+            if t == -1 {
+                Some(t)
+            } else {
+                None
+            }
         }
     }
 
     /// Set previous chapter (if applicable)
     pub fn previous_chapter(&self) {
-        unsafe{ sys::libvlc_media_player_previous_chapter(self.ptr); }
+        unsafe {
+            sys::libvlc_media_player_previous_chapter(self.ptr);
+        }
     }
 
     /// Set next chapter (if applicable)
     pub fn next_chapter(&self) {
-        unsafe{ sys::libvlc_media_player_next_chapter(self.ptr); }
+        unsafe {
+            sys::libvlc_media_player_next_chapter(self.ptr);
+        }
     }
 
     /// Get the requested movie play rate.
     pub fn get_rate(&self) -> f32 {
-        unsafe{ sys::libvlc_media_player_get_rate(self.ptr) }
+        unsafe { sys::libvlc_media_player_get_rate(self.ptr) }
     }
 
     /// Set movie play rate.
-    pub fn set_rate(&self, rate: f32) -> Result<(),()> {
-        unsafe{
+    pub fn set_rate(&self, rate: f32) -> Result<(), InternalError> {
+        unsafe {
             if sys::libvlc_media_player_set_rate(self.ptr, rate) == -1 {
-                Err(())
-            }else{
+                Err(InternalError)
+            } else {
                 Ok(())
             }
         }
@@ -267,51 +340,48 @@ impl MediaPlayer {
 
     /// Get current movie state.
     pub fn state(&self) -> State {
-        unsafe{ sys::libvlc_media_player_get_state(self.ptr) }.into()
+        unsafe { sys::libvlc_media_player_get_state(self.ptr) }.into()
     }
 
     /// How many video outputs does this media player have?
     pub fn has_vout(&self) -> u32 {
-        unsafe{ sys::libvlc_media_player_has_vout(self.ptr) }
+        unsafe { sys::libvlc_media_player_has_vout(self.ptr) }
     }
 
     /// Is this media player seekable?
     pub fn is_seekable(&self) -> bool {
-        unsafe{
-            let b = sys::libvlc_media_player_is_seekable(self.ptr);
-            if b == 0 { false }else{ true }
-        }
+        unsafe { sys::libvlc_media_player_is_seekable(self.ptr) != 0 }
     }
 
     /// Can this media player be paused?
     pub fn can_pause(&self) -> bool {
-        unsafe{
-            let b = sys::libvlc_media_player_can_pause(self.ptr);
-            if b == 0 { false }else{ true }
-        }
+        unsafe { sys::libvlc_media_player_can_pause(self.ptr) != 0 }
     }
 
     /// Check if the current program is scrambled.
     pub fn program_scrambled(&self) -> bool {
-        unsafe{
-            let b = sys::libvlc_media_player_program_scrambled(self.ptr);
-            if b == 0 { false }else{ true }
-        }
+        unsafe { sys::libvlc_media_player_program_scrambled(self.ptr) != 0 }
     }
 
     /// Display the next frame (if supported)
     pub fn next_frame(&self) {
-        unsafe{ sys::libvlc_media_player_next_frame(self.ptr); }
+        unsafe {
+            sys::libvlc_media_player_next_frame(self.ptr);
+        }
     }
 
     /// Navigate through DVD Menu.
     pub fn navigate(&self, navigate: u32) {
-        unsafe{ sys::libvlc_media_player_navigate(self.ptr, navigate); }
+        unsafe {
+            sys::libvlc_media_player_navigate(self.ptr, navigate);
+        }
     }
 
     /// Set if, and how, the video title will be shown when media is played.
     pub fn set_video_title_display(&self, position: Position, timeout: u32) {
-        unsafe{ sys::libvlc_media_player_set_video_title_display(self.ptr, position as i32, timeout); }
+        unsafe {
+            sys::libvlc_media_player_set_video_title_display(self.ptr, position as i32, timeout);
+        }
     }
 
     /// Returns raw pointer
@@ -322,7 +392,7 @@ impl MediaPlayer {
 
 impl Drop for MediaPlayer {
     fn drop(&mut self) {
-        unsafe{ sys::libvlc_media_player_release(self.ptr) };
+        unsafe { sys::libvlc_media_player_release(self.ptr) };
     }
 }
 
@@ -336,10 +406,13 @@ struct AudioCallbacksData {
 }
 
 unsafe extern "C" fn audio_cb_play(
-    data: *mut c_void, samples: *const c_void, count: c_uint, pts: i64) {
+    data: *mut c_void,
+    samples: *const c_void,
+    count: c_uint,
+    pts: i64,
+) {
     let data: &AudioCallbacksData = transmute(data as *mut AudioCallbacksData);
     (data.play)(samples, count, pts);
-
 }
 
 unsafe extern "C" fn audio_cb_pause(data: *mut c_void, pts: i64) {
@@ -367,4 +440,3 @@ pub struct TrackDescription {
     pub id: i32,
     pub name: Option<String>,
 }
-
diff --git a/src/tools.rs b/src/tools.rs
index c44598a..abc6ea6 100644
--- a/src/tools.rs
+++ b/src/tools.rs
@@ -2,10 +2,10 @@
 // This file is part of vlc-rs.
 // Licensed under the MIT license, see the LICENSE file.
 
-use std::ffi::{CString, CStr, NulError};
-use std::path::Path;
-use std::borrow::Cow;
 use libc::c_char;
+use std::borrow::Cow;
+use std::ffi::{CStr, CString, NulError};
+use std::path::Path;
 
 // Convert String to CString.
 // Panic if the string includes null bytes.
@@ -16,8 +16,8 @@ pub fn to_cstr(s: &str) -> CString {
 // Convert *const c_char to String
 pub unsafe fn from_cstr(p: *const c_char) -> Option<String> {
     if p.is_null() {
-            None
-    }else{
+        None
+    } else {
         let cstr = CStr::from_ptr(p);
 
         Some(cstr.to_string_lossy().into_owned())
@@ -27,8 +27,8 @@ pub unsafe fn from_cstr(p: *const c_char) -> Option<String> {
 // Convert *const c_char to &str
 pub unsafe fn from_cstr_ref<'a>(p: *const c_char) -> Option<Cow<'a, str>> {
     if p.is_null() {
-            None
-    }else{
+        None
+    } else {
         let cstr = CStr::from_ptr(p);
 
         Some(cstr.to_string_lossy())
diff --git a/src/video.rs b/src/video.rs
index e9ca4fc..ffd620e 100644
--- a/src/video.rs
+++ b/src/video.rs
@@ -2,12 +2,12 @@
 // This file is part of vlc-rs.
 // Licensed under the MIT license, see the LICENSE file.
 
-use vlc_sys as sys;
+use crate::enums::VideoAdjustOption;
+use crate::tools::{from_cstr, to_cstr};
 use crate::MediaPlayer;
 use crate::TrackDescription;
-use crate::enums::VideoAdjustOption;
-use crate::tools::{to_cstr, from_cstr};
 use libc::c_void;
+use vlc_sys as sys;
 
 pub trait MediaPlayerVideoEx {
     fn toggle_fullscreen(&self);
@@ -32,77 +32,108 @@ pub trait MediaPlayerVideoEx {
 
 impl MediaPlayerVideoEx for MediaPlayer {
     fn toggle_fullscreen(&self) {
-        unsafe{ sys::libvlc_toggle_fullscreen(self.ptr); }
+        unsafe {
+            sys::libvlc_toggle_fullscreen(self.ptr);
+        }
     }
     fn set_fullscreen(&self, fullscreen: bool) {
-        unsafe{ sys::libvlc_set_fullscreen(self.ptr, if fullscreen { 1 }else{ 0 }); }
+        unsafe {
+            sys::libvlc_set_fullscreen(self.ptr, if fullscreen { 1 } else { 0 });
+        }
     }
     fn get_fullscreen(&self) -> bool {
-        unsafe{ if sys::libvlc_get_fullscreen(self.ptr) == 0 { false }else{ true } }
+        unsafe { sys::libvlc_get_fullscreen(self.ptr) != 0 }
     }
     fn set_key_input(&self, on: bool) {
-        unsafe{ sys::libvlc_video_set_key_input(self.ptr, if on { 1 }else{ 0 }); }
+        unsafe {
+            sys::libvlc_video_set_key_input(self.ptr, if on { 1 } else { 0 });
+        }
     }
     fn set_mouse_input(&self, on: bool) {
-        unsafe{ sys::libvlc_video_set_mouse_input(self.ptr, if on { 1 }else{ 0 }); }
+        unsafe {
+            sys::libvlc_video_set_mouse_input(self.ptr, if on { 1 } else { 0 });
+        }
     }
     fn get_size(&self, num: u32) -> Option<(u32, u32)> {
-        unsafe{
+        unsafe {
             let mut x = 0;
             let mut y = 0;
             let res = sys::libvlc_video_get_size(self.ptr, num, &mut x, &mut y);
-            if res == -1 { None }else{ Some((x, y)) }
+            if res == -1 {
+                None
+            } else {
+                Some((x, y))
+            }
         }
     }
     fn get_cursor(&self, num: u32) -> Option<(i32, i32)> {
-        unsafe{
+        unsafe {
             let mut x = 0;
             let mut y = 0;
             let res = sys::libvlc_video_get_cursor(self.ptr, num, &mut x, &mut y);
-            if res == -1 { None }else{ Some((x, y)) }
+            if res == -1 {
+                None
+            } else {
+                Some((x, y))
+            }
         }
     }
     fn get_scale(&self) -> f32 {
-        unsafe{ sys::libvlc_video_get_scale(self.ptr) }
+        unsafe { sys::libvlc_video_get_scale(self.ptr) }
     }
     fn set_scale(&self, factor: f32) {
-        unsafe{ sys::libvlc_video_set_scale(self.ptr, factor); }
+        unsafe {
+            sys::libvlc_video_set_scale(self.ptr, factor);
+        }
     }
     fn get_video_track(&self) -> Option<i32> {
-        unsafe{
+        unsafe {
             let track = sys::libvlc_video_get_track(self.ptr);
-            if track == -1 { None }else{ Some(track) }
+            if track == -1 {
+                None
+            } else {
+                Some(track)
+            }
         }
     }
     fn set_video_track(&self, track: i32) {
-        unsafe{ sys::libvlc_video_set_track(self.ptr, track); }
+        unsafe {
+            sys::libvlc_video_set_track(self.ptr, track);
+        }
     }
     fn get_aspect_ratio(&self) -> Option<String> {
-        unsafe{
+        unsafe {
             let p = sys::libvlc_video_get_aspect_ratio(self.ptr);
             let s = from_cstr(p);
-            if !p.is_null() { sys::libvlc_free(p as *mut c_void); }
+            if !p.is_null() {
+                sys::libvlc_free(p as *mut c_void);
+            }
             s
         }
     }
     fn set_aspect_ratio(&self, aspect: Option<&str>) {
-        unsafe{
+        unsafe {
             if let Some(a) = aspect {
                 sys::libvlc_video_set_aspect_ratio(self.ptr, to_cstr(a).as_ptr());
-            }else{
+            } else {
                 sys::libvlc_video_set_aspect_ratio(self.ptr, ::std::ptr::null());
             }
         }
     }
     fn get_video_track_description(&self) -> Option<Vec<TrackDescription>> {
-        unsafe{
+        unsafe {
             let p0 = sys::libvlc_video_get_track_description(self.ptr);
-            if p0.is_null() { return None; }
+            if p0.is_null() {
+                return None;
+            }
             let mut td = Vec::new();
             let mut p = p0;
 
             while !(*p).p_next.is_null() {
-                td.push(TrackDescription{ id: (*p).i_id, name: from_cstr((*p).psz_name) });
+                td.push(TrackDescription {
+                    id: (*p).i_id,
+                    name: from_cstr((*p).psz_name),
+                });
                 p = (*p).p_next;
             }
             sys::libvlc_track_description_list_release(p0);
@@ -110,15 +141,19 @@ impl MediaPlayerVideoEx for MediaPlayer {
         }
     }
     fn get_adjust_int(&self, option: VideoAdjustOption) -> i32 {
-        unsafe{ sys::libvlc_video_get_adjust_int(self.ptr, option as u32) }
+        unsafe { sys::libvlc_video_get_adjust_int(self.ptr, option as u32) }
     }
     fn set_adjust_int(&self, option: VideoAdjustOption, value: i32) {
-        unsafe{ sys::libvlc_video_set_adjust_int(self.ptr, option as u32, value); }
+        unsafe {
+            sys::libvlc_video_set_adjust_int(self.ptr, option as u32, value);
+        }
     }
     fn get_adjust_float(&self, option: VideoAdjustOption) -> f32 {
-        unsafe{ sys::libvlc_video_get_adjust_float(self.ptr, option as u32) }
+        unsafe { sys::libvlc_video_get_adjust_float(self.ptr, option as u32) }
     }
     fn set_adjust_float(&self, option: VideoAdjustOption, value: f32) {
-        unsafe{ sys::libvlc_video_set_adjust_float(self.ptr, option as u32, value); }
+        unsafe {
+            sys::libvlc_video_set_adjust_float(self.ptr, option as u32, value);
+        }
     }
 }
diff --git a/src/vlm.rs b/src/vlm.rs
index 0f03cab..f886289 100644
--- a/src/vlm.rs
+++ b/src/vlm.rs
@@ -2,34 +2,57 @@ use std::ffi::CString;
 use std::os::raw::c_char;
 use std::ptr;
 
-use vlc_sys as sys;
-use crate::Instance;
 use crate::tools::{from_cstr, to_cstr};
+use crate::{Instance, InternalError};
+use vlc_sys as sys;
 
 pub trait Vlm {
-    fn add_broadcast(&self, name: &str, input: &str, output: &str, options: Option<Vec<String>>, enabled: bool, loop_broadcast: bool, ) -> Result<(), ()>;
+    fn add_broadcast(
+        &self,
+        name: &str,
+        input: &str,
+        output: &str,
+        options: Option<Vec<String>>,
+        enabled: bool,
+        loop_broadcast: bool,
+    ) -> Result<(), InternalError>;
 
-    fn add_vod(&self, name: &str, input: &str, mux: &str, options: Option<Vec<String>>, enabled: bool) -> Result<(), ()>;
+    fn add_vod(
+        &self,
+        name: &str,
+        input: &str,
+        mux: &str,
+        options: Option<Vec<String>>,
+        enabled: bool,
+    ) -> Result<(), InternalError>;
 
-    fn play_media(&self, name: &str) -> Result<(), ()>;
+    fn play_media(&self, name: &str) -> Result<(), InternalError>;
 
-    fn pause_media(&self, name: &str) -> Result<(), ()>;
+    fn pause_media(&self, name: &str) -> Result<(), InternalError>;
 
-    fn stop_media(&self, name: &str) -> Result<(), ()>;
+    fn stop_media(&self, name: &str) -> Result<(), InternalError>;
 
-    fn get_media_instance_position(&self, name: &str, instance: i32) -> Result<f32, ()>;
+    fn get_media_instance_position(&self, name: &str, instance: i32) -> Result<f32, InternalError>;
 
-    fn get_media_instance_length(&self, name: &str, instance: i32) -> Result<i32, ()>;
+    fn get_media_instance_length(&self, name: &str, instance: i32) -> Result<i32, InternalError>;
 
-    fn get_media_instance_time(&self, name: &str, instance: i32) -> Result<i32, ()>;
+    fn get_media_instance_time(&self, name: &str, instance: i32) -> Result<i32, InternalError>;
 
-    fn get_media_instance_rate(&self, name: &str, instance: i32) -> Result<i32, ()>;
+    fn get_media_instance_rate(&self, name: &str, instance: i32) -> Result<i32, InternalError>;
 
-    fn show_media(&self, name: &str) -> Result<String, ()>;
+    fn show_media(&self, name: &str) -> Result<String, InternalError>;
 }
 
 impl Vlm for Instance {
-    fn add_broadcast(&self, name: &str, input: &str, output: &str, options: Option<Vec<String>>, enabled: bool, loop_broadcast: bool, ) -> Result<(), ()> {
+    fn add_broadcast(
+        &self,
+        name: &str,
+        input: &str,
+        output: &str,
+        options: Option<Vec<String>>,
+        enabled: bool,
+        loop_broadcast: bool,
+    ) -> Result<(), InternalError> {
         let name = to_cstr(name);
         let input = to_cstr(input);
         let output = to_cstr(output);
@@ -38,23 +61,54 @@ impl Vlm for Instance {
         let enabled = if enabled { 1 } else { 0 };
         let loop_broadcast = if loop_broadcast { 1 } else { 0 };
         if let Some(vec) = options {
-            opts_c = vec.into_iter()
-                .map(|x| CString::new(x).expect("Error: Unexpected null byte")).collect();
+            opts_c = vec
+                .into_iter()
+                .map(|x| CString::new(x).expect("Error: Unexpected null byte"))
+                .collect();
             opts_c_ptr = opts_c.iter().map(|x| x.as_ptr()).collect();
         } else {
             opts_c_ptr = Vec::new();
         }
         let result = unsafe {
             if opts_c_ptr.is_empty() {
-                sys::libvlc_vlm_add_broadcast(self.ptr, name.as_ptr(), input.as_ptr(), output.as_ptr(), 0, ptr::null(), enabled, loop_broadcast)
+                sys::libvlc_vlm_add_broadcast(
+                    self.ptr,
+                    name.as_ptr(),
+                    input.as_ptr(),
+                    output.as_ptr(),
+                    0,
+                    ptr::null(),
+                    enabled,
+                    loop_broadcast,
+                )
             } else {
-                sys::libvlc_vlm_add_broadcast(self.ptr, name.as_ptr(), input.as_ptr(), output.as_ptr(), opts_c_ptr.len() as i32, opts_c_ptr.as_ptr(), enabled, loop_broadcast)
+                sys::libvlc_vlm_add_broadcast(
+                    self.ptr,
+                    name.as_ptr(),
+                    input.as_ptr(),
+                    output.as_ptr(),
+                    opts_c_ptr.len() as i32,
+                    opts_c_ptr.as_ptr(),
+                    enabled,
+                    loop_broadcast,
+                )
             }
         };
-        if result == 0 { Ok(()) } else { Err(()) }
+        if result == 0 {
+            Ok(())
+        } else {
+            Err(InternalError)
+        }
     }
 
-    fn add_vod(&self, name: &str, input: &str, mux: &str, options: Option<Vec<String>>, enabled: bool) -> Result<(), ()> {
+    fn add_vod(
+        &self,
+        name: &str,
+        input: &str,
+        mux: &str,
+        options: Option<Vec<String>>,
+        enabled: bool,
+    ) -> Result<(), InternalError> {
         let name = to_cstr(name);
         let input = to_cstr(input);
         let mux = to_cstr(mux);
@@ -63,86 +117,125 @@ impl Vlm for Instance {
         let enabled = if enabled { 1 } else { 0 };
         if let Some(vec) = options {
             opts_c = vec.into_iter()
-                .map(|x| CString::new(x).expect("Error: Unexpected null byte")).collect();
+                        .map(|x| CString::new(x).expect("Error: Unexpected null byte"))
+                        .collect();
             opts_c_ptr = opts_c.iter().map(|x| x.as_ptr()).collect();
         } else {
             opts_c_ptr = Vec::new();
         }
         let result = unsafe {
             if opts_c_ptr.is_empty() {
-                sys::libvlc_vlm_add_vod(self.ptr, name.as_ptr(), input.as_ptr(), 0, ptr::null(), enabled, mux.as_ptr())
+                sys::libvlc_vlm_add_vod(
+                    self.ptr,
+                    name.as_ptr(),
+                    input.as_ptr(),
+                    0,
+                    ptr::null(),
+                    enabled,
+                    mux.as_ptr(),
+                )
             } else {
-                sys::libvlc_vlm_add_vod(self.ptr, name.as_ptr(), input.as_ptr(), opts_c_ptr.len() as i32, opts_c_ptr.as_ptr(), enabled, mux.as_ptr())
+                sys::libvlc_vlm_add_vod(
+                    self.ptr,
+                    name.as_ptr(),
+                    input.as_ptr(),
+                    opts_c_ptr.len() as i32,
+                    opts_c_ptr.as_ptr(),
+                    enabled,
+                    mux.as_ptr(),
+                )
             }
         };
-        if result == 0 { Ok(()) } else { Err(()) }
+        if result == 0 {
+            Ok(())
+        } else {
+            Err(InternalError)
+        }
     }
 
-    fn play_media(&self, name: &str) -> Result<(), ()> {
+    fn play_media(&self, name: &str) -> Result<(), InternalError> {
         let name = to_cstr(name);
-        let result = unsafe {
-            sys::libvlc_vlm_play_media(self.ptr, name.as_ptr())
-        };
-        if result == 0 { Ok(()) } else { Err(()) }
+        let result = unsafe { sys::libvlc_vlm_play_media(self.ptr, name.as_ptr()) };
+        if result == 0 {
+            Ok(())
+        } else {
+            Err(InternalError)
+        }
     }
 
-    fn pause_media(&self, name: &str) -> Result<(), ()> {
+    fn pause_media(&self, name: &str) -> Result<(), InternalError> {
         let name = to_cstr(name);
-        let result = unsafe {
-            sys::libvlc_vlm_pause_media(self.ptr, name.as_ptr())
-        };
-        if result == 0 { Ok(()) } else { Err(()) }
+        let result = unsafe { sys::libvlc_vlm_pause_media(self.ptr, name.as_ptr()) };
+        if result == 0 {
+            Ok(())
+        } else {
+            Err(InternalError)
+        }
     }
 
-    fn stop_media(&self, name: &str) -> Result<(), ()> {
+    fn stop_media(&self, name: &str) -> Result<(), InternalError> {
         let name = to_cstr(name);
-        let result = unsafe {
-            sys::libvlc_vlm_stop_media(self.ptr, name.as_ptr())
-        };
-        if result == 0 { Ok(()) } else { Err(()) }
+        let result = unsafe { sys::libvlc_vlm_stop_media(self.ptr, name.as_ptr()) };
+        if result == 0 {
+            Ok(())
+        } else {
+            Err(InternalError)
+        }
     }
 
-    fn get_media_instance_position(&self, name: &str, instance: i32) -> Result<f32, ()> {
+    fn get_media_instance_position(&self, name: &str, instance: i32) -> Result<f32, InternalError> {
         let name = to_cstr(name);
         let result = unsafe {
             sys::libvlc_vlm_get_media_instance_position(self.ptr, name.as_ptr(), instance)
         };
-        if result != -1f32 { Ok(result) } else { Err(()) }
-    }
-
-    fn get_media_instance_length(&self, name: &str, instance: i32) -> Result<i32, ()> {
-        let name = to_cstr(name);
-        let result = unsafe {
-            sys::libvlc_vlm_get_media_instance_length(self.ptr, name.as_ptr(), instance)
-        };
-        if result != -1 { Ok(result) } else { Err(()) }
-    }
-
-    fn get_media_instance_time(&self, name: &str, instance: i32) -> Result<i32, ()> {
-        let name = to_cstr(name);
-        let result = unsafe {
-            sys::libvlc_vlm_get_media_instance_time(self.ptr, name.as_ptr(), instance)
-        };
-        if result != -1 { Ok(result) } else { Err(()) }
-    }
-
-    fn get_media_instance_rate(&self, name: &str, instance: i32) -> Result<i32, ()> {
-        let name = to_cstr(name);
-        let result = unsafe {
-            sys::libvlc_vlm_get_media_instance_rate(self.ptr, name.as_ptr(), instance)
-        };
-        if result != -1 { Ok(result) } else { Err(()) }
-    }
-
-    fn show_media(&self, name: &str) -> Result<String, ()> {
-        let name = to_cstr(name);
-        let result = unsafe {
-            from_cstr(sys::libvlc_vlm_show_media(self.ptr, name.as_ptr()))
-        };
-        if let Some(data) = result {
-            Ok(data.to_string())
+        // if result != -1f32 { Ok(result) } else { Err(()) }
+        if (result - -1f32).abs() < f32::EPSILON {
+            Err(InternalError)
         } else {
-            Err(())
+            Ok(result)
+        }
+    }
+
+    fn get_media_instance_length(&self, name: &str, instance: i32) -> Result<i32, InternalError> {
+        let name = to_cstr(name);
+        let result =
+            unsafe { sys::libvlc_vlm_get_media_instance_length(self.ptr, name.as_ptr(), instance) };
+        if result != -1 {
+            Ok(result)
+        } else {
+            Err(InternalError)
+        }
+    }
+
+    fn get_media_instance_time(&self, name: &str, instance: i32) -> Result<i32, InternalError> {
+        let name = to_cstr(name);
+        let result =
+            unsafe { sys::libvlc_vlm_get_media_instance_time(self.ptr, name.as_ptr(), instance) };
+        if result != -1 {
+            Ok(result)
+        } else {
+            Err(InternalError)
+        }
+    }
+
+    fn get_media_instance_rate(&self, name: &str, instance: i32) -> Result<i32, InternalError> {
+        let name = to_cstr(name);
+        let result =
+            unsafe { sys::libvlc_vlm_get_media_instance_rate(self.ptr, name.as_ptr(), instance) };
+        if result != -1 {
+            Ok(result)
+        } else {
+            Err(InternalError)
+        }
+    }
+
+    fn show_media(&self, name: &str) -> Result<String, InternalError> {
+        let name = to_cstr(name);
+        let result = unsafe { from_cstr(sys::libvlc_vlm_show_media(self.ptr, name.as_ptr())) };
+        if let Some(data) = result {
+            Ok(data)
+        } else {
+            Err(InternalError)
         }
     }
 }

From b3ba9950c7c793618aca71ad6cc2ccb3c3c8826e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pierre=20R=C3=A9veillon?= <pierre@citronmauve.com>
Date: Fri, 19 Nov 2021 10:21:41 +0100
Subject: [PATCH 22/28] Fixed repository

---
 Cargo.toml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Cargo.toml b/Cargo.toml
index 4267262..a19c8bb 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -5,7 +5,8 @@ authors = ["T. Okubo <t.okubo.rx78+github@gmail.com>"]
 
 description = "Rust bindings for libVLC media framework."
 keywords = ["libVLC", "bindings"]
-repository = "https://github.com/garkimasera/vlc-rs"
+repository = "https://code.videolan.org/videolan/vlc-rs"
+homepage = "https://code.videolan.org/videolan/vlc-rs"
 license = "MIT"
 readme = "README.md"
 edition = "2018"

From c3a366726fdfb00209ff91d7c7c7bdb6cb1bf476 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pierre=20R=C3=A9veillon?= <pierre@citronmauve.com>
Date: Fri, 19 Nov 2021 10:33:14 +0100
Subject: [PATCH 23/28] fixed CI image

---
 .gitlab-ci.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 97e45a2..1fc3550 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -2,7 +2,7 @@ stages:
     - build
 
 variables:
-    VLC_UBUNTU_IMAGE: registry.videolan.org/vlc-rs-libvlc-stable-ubuntu:20211102174954
+    VLC_UBUNTU_IMAGE: registry.videolan.org/vlc-rs-libvlc-stable-ubuntu:20211117143343
 
 vlc-rs-build:
     tags:
@@ -13,5 +13,5 @@ vlc-rs-build:
         name: $VLC_UBUNTU_IMAGE
 
     script:
-        - . $HOME/.cargo/env
+        - . $CARGO_HOME/env
         - cargo build --all

From e7d7fe6740a0f66085f6069c2f7b570ca25de743 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pierre=20R=C3=A9veillon?= <pierre@citronmauve.com>
Date: Mon, 22 Nov 2021 09:23:46 +0100
Subject: [PATCH 24/28] fmt second pass

---
 src/vlm.rs | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/vlm.rs b/src/vlm.rs
index f886289..cce7b28 100644
--- a/src/vlm.rs
+++ b/src/vlm.rs
@@ -116,9 +116,10 @@ impl Vlm for Instance {
         let opts_c: Vec<CString>;
         let enabled = if enabled { 1 } else { 0 };
         if let Some(vec) = options {
-            opts_c = vec.into_iter()
-                        .map(|x| CString::new(x).expect("Error: Unexpected null byte"))
-                        .collect();
+            opts_c = vec
+                .into_iter()
+                .map(|x| CString::new(x).expect("Error: Unexpected null byte"))
+                .collect();
             opts_c_ptr = opts_c.iter().map(|x| x.as_ptr()).collect();
         } else {
             opts_c_ptr = Vec::new();

From f613e36ae588a5f4724f6e31971c8373392de57f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pierre=20R=C3=A9veillon?= <pierre@citronmauve.com>
Date: Tue, 23 Nov 2021 11:32:37 +0100
Subject: [PATCH 25/28] updated bindgen

---
 libvlc-sys/Cargo.toml | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/libvlc-sys/Cargo.toml b/libvlc-sys/Cargo.toml
index 06bb3b7..d19a3a5 100644
--- a/libvlc-sys/Cargo.toml
+++ b/libvlc-sys/Cargo.toml
@@ -6,7 +6,9 @@ authors = ["T. Okubo <t.okubo.rx78+devel@gmail.com>"]
 description = "libVLC C API"
 keywords = ["libVLC", "bindings"]
 categories = ["external-ffi-bindings", "multimedia"]
-repository = "https://github.com/garkimasera/vlc-rs"
+documentation = "https://docs.rs/vlc-rs"
+repository = "https://code.videolan.org/videolan/vlc-rs"
+homepage = "https://code.videolan.org/videolan/vlc-rs"
 license = "MIT"
 edition = "2018"
 build = "build.rs"
@@ -19,5 +21,5 @@ crate-type = ["rlib"]
 libc = "0.2"
 
 [build-dependencies]
-bindgen = "0.52"
+bindgen = "0.59"
 pkg-config = "0.3"

From 0107178024d8a683c953df6e042839019d42a3db Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pierre=20R=C3=A9veillon?= <pierre@citronmauve.com>
Date: Wed, 1 Dec 2021 08:19:21 +0100
Subject: [PATCH 26/28] fixed some method return error types

---
 src/audio.rs         |  1 +
 src/core.rs          | 22 +++++++++++-----------
 src/media_library.rs |  7 ++++---
 src/media_list.rs    |  7 ++++---
 4 files changed, 20 insertions(+), 17 deletions(-)

diff --git a/src/audio.rs b/src/audio.rs
index 68e0e8a..39a2be4 100644
--- a/src/audio.rs
+++ b/src/audio.rs
@@ -45,6 +45,7 @@ impl MediaPlayerAudioEx for MediaPlayer {
             }
         }
     }
+
     fn get_audio_track_description(&self) -> Option<Vec<TrackDescription>> {
         unsafe {
             let p0 = sys::libvlc_audio_get_track_description(self.ptr);
diff --git a/src/core.rs b/src/core.rs
index 93c8c9b..5bf6b56 100644
--- a/src/core.rs
+++ b/src/core.rs
@@ -53,7 +53,7 @@ impl Instance {
     /// Create and initialize a libvlc instance with specified args.
     /// Note: args.len() has to be less or equal to i32::MAX
     /// Note: libvlc discourages using arguments as these are not guaranteed to be stable between different versions of libvlc
-    pub fn with_args(args: Option<Vec<String>>) -> Option<Instance> {
+    pub fn with_args(args: Option<Vec<String>>) -> Result<Instance, InternalError> {
         let args_c_ptr: Vec<*const c_char>;
         let args_c: Vec<CString>;
         if let Some(argv) = args {
@@ -74,15 +74,15 @@ impl Instance {
             };
 
             if p.is_null() {
-                return None;
+                Err(InternalError)
+            } else {
+                Ok(Instance { ptr: p })
             }
-
-            Some(Instance { ptr: p })
         }
     }
 
     /// Create and initialize a libvlc instance.
-    pub fn new() -> Option<Instance> {
+    pub fn new() -> Result<Instance, InternalError> {
         Instance::with_args(None)
     }
 
@@ -125,25 +125,25 @@ impl Instance {
     }
 
     /// Returns a list of audio filters that are available.
-    pub fn audio_filter_list_get(&self) -> Option<ModuleDescriptionList> {
+    pub fn audio_filter_list_get(&self) -> Result<ModuleDescriptionList, InternalError> {
         unsafe {
             let p = sys::libvlc_audio_filter_list_get(self.ptr);
             if p.is_null() {
-                None
+                Err(InternalError)
             } else {
-                Some(ModuleDescriptionList { ptr: p })
+                Ok(ModuleDescriptionList { ptr: p })
             }
         }
     }
 
     /// Returns a list of video filters that are available.
-    pub fn video_filter_list_get(&self) -> Option<ModuleDescriptionList> {
+    pub fn video_filter_list_get(&self) -> Result<ModuleDescriptionList, InternalError> {
         unsafe {
             let p = sys::libvlc_video_filter_list_get(self.ptr);
             if p.is_null() {
-                None
+                Err(InternalError)
             } else {
-                Some(ModuleDescriptionList { ptr: p })
+                Ok(ModuleDescriptionList { ptr: p })
             }
         }
     }
diff --git a/src/media_library.rs b/src/media_library.rs
index 8e66de8..3a6b236 100644
--- a/src/media_library.rs
+++ b/src/media_library.rs
@@ -3,6 +3,7 @@
 // Licensed under the MIT license, see the LICENSE file.
 
 use crate::{Instance, InternalError, MediaList};
+use std::fmt;
 use vlc_sys as sys;
 
 pub struct MediaLibrary {
@@ -11,13 +12,13 @@ pub struct MediaLibrary {
 
 impl MediaLibrary {
     /// Create an new Media Library object.
-    pub fn new(instance: &Instance) -> Option<MediaLibrary> {
+    pub fn new(instance: &Instance) -> Result<MediaLibrary, InternalError> {
         unsafe {
             let p = sys::libvlc_media_library_new(instance.ptr);
             if p.is_null() {
-                None
+                Err(InternalError)
             } else {
-                Some(MediaLibrary { ptr: p })
+                Ok(MediaLibrary { ptr: p })
             }
         }
     }
diff --git a/src/media_list.rs b/src/media_list.rs
index 7eb99b1..b48022d 100644
--- a/src/media_list.rs
+++ b/src/media_list.rs
@@ -11,13 +11,13 @@ pub struct MediaList {
 
 impl MediaList {
     /// Create an empty media list.
-    pub fn new(instance: &Instance) -> Option<MediaList> {
+    pub fn new(instance: &Instance) -> Result<MediaList, InternalError> {
         unsafe {
             let p = sys::libvlc_media_list_new(instance.ptr);
             if p.is_null() {
-                None
+                Err(InternalError)
             } else {
-                Some(MediaList { ptr: p })
+                Ok(MediaList { ptr: p })
             }
         }
     }
@@ -45,6 +45,7 @@ impl MediaList {
 
     /// Add media instance to media list.
     /// The MediaList::lock should be held upon entering this function.
+    // TODO: use specific error type since documentation says "-1 if the media list is read-only"
     pub fn add_media(&self, md: &Media) -> Result<(), InternalError> {
         unsafe {
             if sys::libvlc_media_list_add_media(self.ptr, md.ptr) == 0 {

From 1f439aa464d748337f2800ac91fd168fa81f20de Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pierre=20R=C3=A9veillon?= <pierre@citronmauve.com>
Date: Sun, 5 Dec 2021 23:45:57 +0100
Subject: [PATCH 27/28] removed unused import

---
 src/media_library.rs | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/media_library.rs b/src/media_library.rs
index 3a6b236..8b75bd5 100644
--- a/src/media_library.rs
+++ b/src/media_library.rs
@@ -3,7 +3,6 @@
 // Licensed under the MIT license, see the LICENSE file.
 
 use crate::{Instance, InternalError, MediaList};
-use std::fmt;
 use vlc_sys as sys;
 
 pub struct MediaLibrary {

From 4c015edec43b255136c28939e1d1d800deaf01ed Mon Sep 17 00:00:00 2001
From: Rene Richter <richterrettich@gmail.com>
Date: Mon, 25 Oct 2021 12:53:39 +0200
Subject: [PATCH 28/28] Add EventManager::detach method

---
 src/core.rs | 20 +++++++++++++++++---
 src/sys.rs  |  3 +++
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/src/core.rs b/src/core.rs
index 236de3c..3da9e5f 100644
--- a/src/core.rs
+++ b/src/core.rs
@@ -326,21 +326,35 @@ pub struct EventManager<'a> {
 }
 
 impl<'a> EventManager<'a> {
-    pub fn attach<F>(&self, event_type: EventType, callback: F) -> Result<(), ()>
+
+    pub fn detach(&self, event_type: EventType, registered_callback: *mut c_void) -> Result<(),()> {
+        let result =  unsafe {
+            sys::libvlc_event_detach(self.ptr, event_type as i32, event_manager_callback, registered_callback)
+        };
+        if result == 0 {
+            Ok(())
+        } else {
+            Err(())
+        }
+    }
+
+    pub fn attach<F>(&self, event_type: EventType, callback: F) -> Result<*mut c_void, ()>
         where F: Fn(Event, VLCObject) + Send + 'static
     {
         // Explicit type annotation is needed
         let callback: Box<Box<dyn Fn(Event, VLCObject) + Send + 'static>> =
             Box::new(Box::new(callback));
+        
+        let raw = Box::into_raw(callback) as *mut c_void;
 
         let result = unsafe{
             sys::libvlc_event_attach(
                 self.ptr, event_type as i32, event_manager_callback,
-                Box::into_raw(callback) as *mut c_void)
+                raw)
         };
 
         if result == 0 {
-            Ok(())
+            Ok(raw)
         }else{
             Err(())
         }
diff --git a/src/sys.rs b/src/sys.rs
index 7221369..8994ecc 100644
--- a/src/sys.rs
+++ b/src/sys.rs
@@ -74,6 +74,9 @@ extern "C" {
     pub fn libvlc_event_attach(
         p_event_manager: *mut libvlc_event_manager_t, i_event_type: libvlc_event_type_t,
         f_callback: libvlc_callback_t, user_data: *mut c_void) -> c_int;
+    pub fn libvlc_event_detach(
+            p_event_manager: *mut libvlc_event_manager_t, i_event_type: libvlc_event_type_t,
+            f_callback: libvlc_callback_t, p_user_data: *mut c_void) -> c_int;
     pub fn libvlc_event_type_name(event_type: libvlc_event_type_t) -> *const c_char;
     pub fn libvlc_log_get_context(
         ctx: *const libvlc_log_t, module: *const *const c_char, file: *const *const c_char,