From 7dc2e43db390ff4f66f8a17fb81069fcfcec0a7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sat, 16 Dec 2017 11:18:00 +0200 Subject: [PATCH] Clean-up GstPlayer bindings Various nullability, types and usability fixes. The player configuration is a new type now that can deref to a structure --- Gir_GstPlayer.toml | 69 +++++++++- gir-files/GstPlayer-1.0.gir | 8 +- gstreamer-player/Cargo.toml | 2 + gstreamer-player/src/auto/player.rs | 129 +++++++----------- .../src/auto/player_media_info.rs | 2 +- .../src/auto/player_stream_info.rs | 4 +- .../src/auto/player_video_info.rs | 18 --- gstreamer-player/src/config.rs | 108 +++++++++++++++ gstreamer-player/src/lib.rs | 8 +- gstreamer-player/src/player.rs | 90 ++++++++---- gstreamer-player/src/player_video_info.rs | 37 +++++ .../player_video_overlay_video_renderer.rs | 15 +- 12 files changed, 341 insertions(+), 149 deletions(-) create mode 100644 gstreamer-player/src/config.rs create mode 100644 gstreamer-player/src/player_video_info.rs diff --git a/Gir_GstPlayer.toml b/Gir_GstPlayer.toml index 01d9debce..49d4fa54a 100644 --- a/Gir_GstPlayer.toml +++ b/Gir_GstPlayer.toml @@ -19,7 +19,6 @@ generate = [ "GstPlayer.PlayerSignalDispatcher", "GstPlayer.PlayerSnapshotFormat", "GstPlayer.PlayerState", - "GstPlayer.PlayerStreamInfo", "GstPlayer.PlayerVideoRenderer", "GstPlayer.PlayerVisualization", ] @@ -29,6 +28,8 @@ manual = [ "GLib.MainContext", "GObject.Object", "Gst.Element", + "GstVideo.VideoMultiviewFlags", + "GstVideo.VideoMultiviewFramePacking", ] [[object]] @@ -64,13 +65,52 @@ trait = false [[object.function]] name = "set_config" - # Pass by value + # Custom type ignore = true [[object.function]] name = "new" ignore = true + [[object.function]] + name = "get_config" + # Custom type + ignore = true + + [[object.function]] + pattern = "config_.*" + # Custom type + ignore = true + + [[object.function]] + name = "get_pipeline" + [object.function.return] + nullable = false + + [[object.function]] + name = "set_audio_track" + [object.function.return] + bool_return_is_error = "Failed to set audio track" + + [[object.function]] + name = "set_subtitle_track" + [object.function.return] + bool_return_is_error = "Failed to set subtitle track" + + [[object.function]] + name = "set_video_track" + [object.function.return] + bool_return_is_error = "Failed to set video track" + + [[object.function]] + name = "set_visualization" + [[object.function.parameter]] + name = "name" + nullable = true + + [object.function.return] + bool_return_is_error = "Failed to set visualization" + [[object.signal]] name = "buffering" concurrency = "send" @@ -129,6 +169,16 @@ trait = false name = "warning" concurrency = "send" + +[[object]] +name = "GstPlayer.PlayerStreamInfo" +status = "generate" + + [[object.function]] + name = "get_stream_type" + [object.function.return] + nullable = false + [[object]] name = "GstPlayer.PlayerAudioInfo" status = "generate" @@ -139,6 +189,16 @@ name = "GstPlayer.PlayerVideoInfo" status = "generate" trait = false + [[object.function]] + name = "get_framerate" + # Fraction + ignore = true + + [[object.function]] + name = "get_pixel_aspect_ratio" + # Fraction + ignore = true + [[object]] name = "GstPlayer.PlayerSubtitleInfo" status = "generate" @@ -149,6 +209,11 @@ name = "GstPlayer.PlayerMediaInfo" status = "generate" trait = false + [[object.function]] + name = "get_uri" + [object.function.return] + nullable = false + [[object]] name = "GstPlayer.PlayerVideoOverlayVideoRenderer" status = "generate" diff --git a/gir-files/GstPlayer-1.0.gir b/gir-files/GstPlayer-1.0.gir index 47f6631d6..ce95d355a 100644 --- a/gir-files/GstPlayer-1.0.gir +++ b/gir-files/GstPlayer-1.0.gir @@ -405,8 +405,8 @@ The caller should free it with g_object_unref() Retrieve the current value of the indicated @type. The current value of @type, Default: -1 "none" - + @@ -733,8 +733,8 @@ value. The new value for the @type - + diff --git a/gstreamer-player/Cargo.toml b/gstreamer-player/Cargo.toml index 8ccded38f..c0945f940 100644 --- a/gstreamer-player/Cargo.toml +++ b/gstreamer-player/Cargo.toml @@ -17,9 +17,11 @@ bitflags = "1.0" libc = "0.2" glib-sys = { git = "https://github.com/gtk-rs/sys" } gobject-sys = { git = "https://github.com/gtk-rs/sys" } +gstreamer-sys = { git = "https://github.com/sdroege/gstreamer-sys", features = ["v1_12"] } gstreamer-player-sys = { git = "https://github.com/sdroege/gstreamer-sys", features = ["v1_12"] } glib = { git = "https://github.com/gtk-rs/glib" } gstreamer = { path = "../gstreamer", features = ["v1_12"] } +gstreamer-video = { path = "../gstreamer-video", features = ["v1_12"] } [build-dependencies.rustdoc-stripper] version = "0.1" diff --git a/gstreamer-player/src/auto/player.rs b/gstreamer-player/src/auto/player.rs index e8be24415..93720c871 100644 --- a/gstreamer-player/src/auto/player.rs +++ b/gstreamer-player/src/auto/player.rs @@ -11,6 +11,7 @@ use PlayerSubtitleInfo; use PlayerVideoInfo; use PlayerVisualization; use ffi; +use glib; use glib::StaticType; use glib::Value; use glib::signal::SignalHandlerId; @@ -19,6 +20,7 @@ use glib::translate::*; use glib_ffi; use gobject_ffi; use gst; +use gst_video; use libc; use std::boxed::Box as Box_; use std::mem; @@ -34,12 +36,6 @@ glib_wrapper! { } impl Player { - pub fn config_set_seek_accurate(&self, accurate: bool) { - unsafe { - ffi::gst_player_config_set_seek_accurate(self.to_glib_none().0, accurate.to_glib()); - } - } - pub fn get_audio_video_offset(&self) -> i64 { unsafe { ffi::gst_player_get_audio_video_offset(self.to_glib_none().0) @@ -52,12 +48,6 @@ impl Player { } } - pub fn get_config(&self) -> Option { - unsafe { - from_glib_full(ffi::gst_player_get_config(self.to_glib_none().0)) - } - } - pub fn get_current_audio_track(&self) -> Option { unsafe { from_glib_full(ffi::gst_player_get_current_audio_track(self.to_glib_none().0)) @@ -94,13 +84,17 @@ impl Player { } } - //pub fn get_multiview_flags(&self) -> /*Ignored*/gst_video::VideoMultiviewFlags { - // unsafe { TODO: call ffi::gst_player_get_multiview_flags() } - //} + pub fn get_multiview_flags(&self) -> gst_video::VideoMultiviewFlags { + unsafe { + from_glib(ffi::gst_player_get_multiview_flags(self.to_glib_none().0)) + } + } - //pub fn get_multiview_mode(&self) -> /*Ignored*/gst_video::VideoMultiviewMode { - // unsafe { TODO: call ffi::gst_player_get_multiview_mode() } - //} + pub fn get_multiview_mode(&self) -> gst_video::VideoMultiviewFramePacking { + unsafe { + from_glib(ffi::gst_player_get_multiview_mode(self.to_glib_none().0)) + } + } pub fn get_mute(&self) -> bool { unsafe { @@ -108,7 +102,7 @@ impl Player { } } - pub fn get_pipeline(&self) -> Option { + pub fn get_pipeline(&self) -> gst::Element { unsafe { from_glib_full(ffi::gst_player_get_pipeline(self.to_glib_none().0)) } @@ -176,9 +170,9 @@ impl Player { } } - pub fn set_audio_track(&self, stream_index: i32) -> bool { + pub fn set_audio_track(&self, stream_index: i32) -> Result<(), glib::error::BoolError> { unsafe { - from_glib(ffi::gst_player_set_audio_track(self.to_glib_none().0, stream_index)) + glib::error::BoolError::from_glib(ffi::gst_player_set_audio_track(self.to_glib_none().0, stream_index), "Failed to set audio track") } } @@ -200,13 +194,17 @@ impl Player { } } - //pub fn set_multiview_flags(&self, flags: /*Ignored*/gst_video::VideoMultiviewFlags) { - // unsafe { TODO: call ffi::gst_player_set_multiview_flags() } - //} + pub fn set_multiview_flags(&self, flags: gst_video::VideoMultiviewFlags) { + unsafe { + ffi::gst_player_set_multiview_flags(self.to_glib_none().0, flags.to_glib()); + } + } - //pub fn set_multiview_mode(&self, mode: /*Ignored*/gst_video::VideoMultiviewMode) { - // unsafe { TODO: call ffi::gst_player_set_multiview_mode() } - //} + pub fn set_multiview_mode(&self, mode: gst_video::VideoMultiviewFramePacking) { + unsafe { + ffi::gst_player_set_multiview_mode(self.to_glib_none().0, mode.to_glib()); + } + } pub fn set_mute(&self, val: bool) { unsafe { @@ -220,9 +218,9 @@ impl Player { } } - pub fn set_subtitle_track(&self, stream_index: i32) -> bool { + pub fn set_subtitle_track(&self, stream_index: i32) -> Result<(), glib::error::BoolError> { unsafe { - from_glib(ffi::gst_player_set_subtitle_track(self.to_glib_none().0, stream_index)) + glib::error::BoolError::from_glib(ffi::gst_player_set_subtitle_track(self.to_glib_none().0, stream_index), "Failed to set subtitle track") } } @@ -244,9 +242,9 @@ impl Player { } } - pub fn set_video_track(&self, stream_index: i32) -> bool { + pub fn set_video_track(&self, stream_index: i32) -> Result<(), glib::error::BoolError> { unsafe { - from_glib(ffi::gst_player_set_video_track(self.to_glib_none().0, stream_index)) + glib::error::BoolError::from_glib(ffi::gst_player_set_video_track(self.to_glib_none().0, stream_index), "Failed to set video track") } } @@ -256,9 +254,11 @@ impl Player { } } - pub fn set_visualization(&self, name: &str) -> bool { + pub fn set_visualization<'a, P: Into>>(&self, name: P) -> Result<(), glib::error::BoolError> { + let name = name.into(); + let name = name.to_glib_none(); unsafe { - from_glib(ffi::gst_player_set_visualization(self.to_glib_none().0, name.to_glib_none().0)) + glib::error::BoolError::from_glib(ffi::gst_player_set_visualization(self.to_glib_none().0, name.0), "Failed to set visualization") } } @@ -295,68 +295,33 @@ impl Player { } } - //pub fn get_property_video_multiview_flags(&self) -> /*Ignored*/gst_video::VideoMultiviewFlags { - // unsafe { - // let mut value = Value::uninitialized(); - // gobject_ffi::g_value_init(value.to_glib_none_mut().0, ::static_type().to_glib()); - // gobject_ffi::g_object_get_property(self.to_glib_none().0, "video-multiview-flags".to_glib_none().0, value.to_glib_none_mut().0); - // value.get().unwrap() - // } - //} - - //pub fn set_property_video_multiview_flags(&self, video_multiview_flags: /*Ignored*/gst_video::VideoMultiviewFlags) { - // unsafe { - // gobject_ffi::g_object_set_property(self.to_glib_none().0, "video-multiview-flags".to_glib_none().0, Value::from(&video_multiview_flags).to_glib_none().0); - // } - //} - - //pub fn get_property_video_multiview_mode(&self) -> /*Ignored*/gst_video::VideoMultiviewFramePacking { - // unsafe { - // let mut value = Value::uninitialized(); - // gobject_ffi::g_value_init(value.to_glib_none_mut().0, ::static_type().to_glib()); - // gobject_ffi::g_object_get_property(self.to_glib_none().0, "video-multiview-mode".to_glib_none().0, value.to_glib_none_mut().0); - // value.get().unwrap() - // } - //} - - //pub fn set_property_video_multiview_mode(&self, video_multiview_mode: /*Ignored*/gst_video::VideoMultiviewFramePacking) { - // unsafe { - // gobject_ffi::g_object_set_property(self.to_glib_none().0, "video-multiview-mode".to_glib_none().0, Value::from(&video_multiview_mode).to_glib_none().0); - // } - //} - - pub fn config_get_position_update_interval(config: &gst::Structure) -> u32 { - assert_initialized_main_thread!(); + pub fn get_property_video_multiview_flags(&self) -> gst_video::VideoMultiviewFlags { unsafe { - ffi::gst_player_config_get_position_update_interval(config.to_glib_none().0) + let mut value = Value::uninitialized(); + gobject_ffi::g_value_init(value.to_glib_none_mut().0, ::static_type().to_glib()); + gobject_ffi::g_object_get_property(self.to_glib_none().0, "video-multiview-flags".to_glib_none().0, value.to_glib_none_mut().0); + value.get().unwrap() } } - pub fn config_get_seek_accurate(config: &gst::Structure) -> bool { - assert_initialized_main_thread!(); + pub fn set_property_video_multiview_flags(&self, video_multiview_flags: gst_video::VideoMultiviewFlags) { unsafe { - from_glib(ffi::gst_player_config_get_seek_accurate(config.to_glib_none().0)) + gobject_ffi::g_object_set_property(self.to_glib_none().0, "video-multiview-flags".to_glib_none().0, Value::from(&video_multiview_flags).to_glib_none().0); } } - pub fn config_get_user_agent(config: &gst::Structure) -> Option { - assert_initialized_main_thread!(); + pub fn get_property_video_multiview_mode(&self) -> gst_video::VideoMultiviewFramePacking { unsafe { - from_glib_full(ffi::gst_player_config_get_user_agent(config.to_glib_none().0)) + let mut value = Value::uninitialized(); + gobject_ffi::g_value_init(value.to_glib_none_mut().0, ::static_type().to_glib()); + gobject_ffi::g_object_get_property(self.to_glib_none().0, "video-multiview-mode".to_glib_none().0, value.to_glib_none_mut().0); + value.get().unwrap() } } - pub fn config_set_position_update_interval(config: &mut gst::Structure, interval: u32) { - assert_initialized_main_thread!(); + pub fn set_property_video_multiview_mode(&self, video_multiview_mode: gst_video::VideoMultiviewFramePacking) { unsafe { - ffi::gst_player_config_set_position_update_interval(config.to_glib_none_mut().0, interval); - } - } - - pub fn config_set_user_agent(config: &mut gst::Structure, agent: &str) { - assert_initialized_main_thread!(); - unsafe { - ffi::gst_player_config_set_user_agent(config.to_glib_none_mut().0, agent.to_glib_none().0); + gobject_ffi::g_object_set_property(self.to_glib_none().0, "video-multiview-mode".to_glib_none().0, Value::from(&video_multiview_mode).to_glib_none().0); } } diff --git a/gstreamer-player/src/auto/player_media_info.rs b/gstreamer-player/src/auto/player_media_info.rs index 7c3e88464..35354d24f 100644 --- a/gstreamer-player/src/auto/player_media_info.rs +++ b/gstreamer-player/src/auto/player_media_info.rs @@ -94,7 +94,7 @@ impl PlayerMediaInfo { } } - pub fn get_uri(&self) -> Option { + pub fn get_uri(&self) -> String { unsafe { from_glib_none(ffi::gst_player_media_info_get_uri(self.to_glib_none().0)) } diff --git a/gstreamer-player/src/auto/player_stream_info.rs b/gstreamer-player/src/auto/player_stream_info.rs index a1a8e2ada..4e30429b3 100644 --- a/gstreamer-player/src/auto/player_stream_info.rs +++ b/gstreamer-player/src/auto/player_stream_info.rs @@ -28,7 +28,7 @@ pub trait PlayerStreamInfoExt { fn get_index(&self) -> i32; - fn get_stream_type(&self) -> Option; + fn get_stream_type(&self) -> String; fn get_tags(&self) -> Option; } @@ -52,7 +52,7 @@ impl> PlayerStreamInfoExt for O { } } - fn get_stream_type(&self) -> Option { + fn get_stream_type(&self) -> String { unsafe { from_glib_none(ffi::gst_player_stream_info_get_stream_type(self.to_glib_none().0)) } diff --git a/gstreamer-player/src/auto/player_video_info.rs b/gstreamer-player/src/auto/player_video_info.rs index a69fe36a7..c4d84b48f 100644 --- a/gstreamer-player/src/auto/player_video_info.rs +++ b/gstreamer-player/src/auto/player_video_info.rs @@ -24,15 +24,6 @@ impl PlayerVideoInfo { } } - pub fn get_framerate(&self) -> (i32, i32) { - unsafe { - let mut fps_n = mem::uninitialized(); - let mut fps_d = mem::uninitialized(); - ffi::gst_player_video_info_get_framerate(self.to_glib_none().0, &mut fps_n, &mut fps_d); - (fps_n, fps_d) - } - } - pub fn get_height(&self) -> i32 { unsafe { ffi::gst_player_video_info_get_height(self.to_glib_none().0) @@ -45,15 +36,6 @@ impl PlayerVideoInfo { } } - pub fn get_pixel_aspect_ratio(&self) -> (u32, u32) { - unsafe { - let mut par_n = mem::uninitialized(); - let mut par_d = mem::uninitialized(); - ffi::gst_player_video_info_get_pixel_aspect_ratio(self.to_glib_none().0, &mut par_n, &mut par_d); - (par_n, par_d) - } - } - pub fn get_width(&self) -> i32 { unsafe { ffi::gst_player_video_info_get_width(self.to_glib_none().0) diff --git a/gstreamer-player/src/config.rs b/gstreamer-player/src/config.rs new file mode 100644 index 000000000..a71e59584 --- /dev/null +++ b/gstreamer-player/src/config.rs @@ -0,0 +1,108 @@ +// Copyright (C) 2017 Sebastian Dröge +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use ffi; +use gst_ffi; +use glib::translate::*; +use gst; + +use std::mem; +use std::ops; + +#[derive(Debug, PartialEq, Eq)] +pub struct PlayerConfig(gst::Structure); + +impl ops::Deref for PlayerConfig { + type Target = gst::StructureRef; + + fn deref(&self) -> &gst::StructureRef { + self.0.deref() + } +} + +impl ops::DerefMut for PlayerConfig { + fn deref_mut(&mut self) -> &mut gst::StructureRef { + self.0.deref_mut() + } +} + +impl AsRef for PlayerConfig { + fn as_ref(&self) -> &gst::StructureRef { + self.0.as_ref() + } +} + +impl AsMut for PlayerConfig { + fn as_mut(&mut self) -> &mut gst::StructureRef { + self.0.as_mut() + } +} + +impl PlayerConfig { + pub fn get_position_update_interval(&self) -> u32 { + assert_initialized_main_thread!(); + unsafe { ffi::gst_player_config_get_position_update_interval(self.0.to_glib_none().0) } + } + + pub fn get_seek_accurate(&self) -> bool { + assert_initialized_main_thread!(); + unsafe { + from_glib(ffi::gst_player_config_get_seek_accurate( + self.0.to_glib_none().0, + )) + } + } + + pub fn get_user_agent(&self) -> Option { + assert_initialized_main_thread!(); + unsafe { + from_glib_full(ffi::gst_player_config_get_user_agent( + self.0.to_glib_none().0, + )) + } + } + + pub fn set_position_update_interval(&mut self, interval: u32) { + assert_initialized_main_thread!(); + unsafe { + ffi::gst_player_config_set_position_update_interval( + self.0.to_glib_none_mut().0, + interval, + ); + } + } + + pub fn set_seek_accurate(&mut self, accurate: bool) { + assert_initialized_main_thread!(); + // FIXME: Work-around for + // http://cgit.freedesktop.org/gstreamer/gst-plugins-bad/commit/?id=cc58bd6ae071dec4ea7b4be626034accd0372755 + self.set("accurate-seek", &accurate); + } + + pub fn set_user_agent(&mut self, agent: &str) { + assert_initialized_main_thread!(); + unsafe { + ffi::gst_player_config_set_user_agent( + self.0.to_glib_none_mut().0, + agent.to_glib_none().0, + ); + } + } + + pub unsafe fn into_ptr(mut self) -> *mut gst_ffi::GstStructure { + let ptr = self.0.to_glib_none_mut().0; + mem::forget(self); + ptr + } +} + +impl FromGlibPtrFull<*mut gst_ffi::GstStructure> for PlayerConfig { + unsafe fn from_glib_full(ptr: *mut gst_ffi::GstStructure) -> Self { + PlayerConfig(from_glib_full(ptr)) + } +} diff --git a/gstreamer-player/src/lib.rs b/gstreamer-player/src/lib.rs index 1f978f678..54d9b61cf 100644 --- a/gstreamer-player/src/lib.rs +++ b/gstreamer-player/src/lib.rs @@ -10,7 +10,9 @@ extern crate libc; extern crate glib_sys as glib_ffi; extern crate gobject_sys as gobject_ffi; +extern crate gstreamer_sys as gst_ffi; extern crate gstreamer as gst; +extern crate gstreamer_video as gst_video; extern crate gstreamer_player_sys as ffi; #[macro_use] @@ -44,9 +46,12 @@ mod auto; pub use auto::*; mod player; +mod config; +pub use config::*; + +mod player_video_info; mod player_video_overlay_video_renderer; -pub use player_video_overlay_video_renderer::PlayerVideoOverlayVideoRendererExtManual; mod player_g_main_context_signal_dispatcher; // Re-export all the traits in a prelude module, so that applications @@ -56,5 +61,4 @@ pub mod prelude { pub use gst::prelude::*; pub use auto::traits::*; - pub use player_video_overlay_video_renderer::PlayerVideoOverlayVideoRendererExtManual; } diff --git a/gstreamer-player/src/player.rs b/gstreamer-player/src/player.rs index db2757c34..6cff2bf79 100644 --- a/gstreamer-player/src/player.rs +++ b/gstreamer-player/src/player.rs @@ -11,6 +11,7 @@ use PlayerSignalDispatcher; use PlayerVideoRenderer; use ffi; use glib_ffi; +use glib; use glib::signal::SignalHandlerId; use glib::signal::connect; use glib::translate::*; @@ -37,55 +38,94 @@ impl Player { } } - pub fn set_config(&self, config: gst::Structure) -> bool { + pub fn get_config(&self) -> ::PlayerConfig { + unsafe { from_glib_full(ffi::gst_player_get_config(self.to_glib_none().0)) } + } + + pub fn set_config(&self, config: ::PlayerConfig) -> Result<(), glib::error::BoolError> { unsafe { - from_glib(ffi::gst_player_set_config( + glib::error::BoolError::from_glib( + ffi::gst_player_set_config(self.to_glib_none().0, config.into_ptr()), + "Failed to set config", + ) + } + } + + pub fn connect_duration_changed( + &self, + f: F, + ) -> SignalHandlerId { + unsafe { + let f: Box_> = + Box_::new(Box_::new(f)); + connect( self.to_glib_none().0, - config.into_ptr(), - )) + "duration-changed", + transmute(duration_changed_trampoline as usize), + Box_::into_raw(f) as *mut _, + ) } } - pub fn connect_duration_changed(&self, f: F) -> SignalHandlerId { + pub fn connect_position_updated( + &self, + f: F, + ) -> SignalHandlerId { unsafe { - let f: Box_> = Box_::new(Box_::new(f)); - connect(self.to_glib_none().0, "duration-changed", - transmute(duration_changed_trampoline as usize), Box_::into_raw(f) as *mut _) + let f: Box_> = + Box_::new(Box_::new(f)); + connect( + self.to_glib_none().0, + "position-updated", + transmute(position_updated_trampoline as usize), + Box_::into_raw(f) as *mut _, + ) } } - pub fn connect_position_updated(&self, f: F) -> SignalHandlerId { + + pub fn connect_seek_done( + &self, + f: F, + ) -> SignalHandlerId { unsafe { - let f: Box_> = Box_::new(Box_::new(f)); - connect(self.to_glib_none().0, "position-updated", - transmute(position_updated_trampoline as usize), Box_::into_raw(f) as *mut _) + let f: Box_> = + Box_::new(Box_::new(f)); + connect( + self.to_glib_none().0, + "seek-done", + transmute(seek_done_trampoline as usize), + Box_::into_raw(f) as *mut _, + ) } } - - - pub fn connect_seek_done(&self, f: F) -> SignalHandlerId { - unsafe { - let f: Box_> = Box_::new(Box_::new(f)); - connect(self.to_glib_none().0, "seek-done", - transmute(seek_done_trampoline as usize), Box_::into_raw(f) as *mut _) - } - } - } -unsafe extern "C" fn duration_changed_trampoline(this: *mut ffi::GstPlayer, object: u64, f: glib_ffi::gpointer) { +unsafe extern "C" fn duration_changed_trampoline( + this: *mut ffi::GstPlayer, + object: u64, + f: glib_ffi::gpointer, +) { callback_guard!(); let f: &&(Fn(&Player, gst::ClockTime) + Send + 'static) = transmute(f); f(&from_glib_borrow(this), gst::ClockTime(Some(object))) } -unsafe extern "C" fn position_updated_trampoline(this: *mut ffi::GstPlayer, object: u64, f: glib_ffi::gpointer) { +unsafe extern "C" fn position_updated_trampoline( + this: *mut ffi::GstPlayer, + object: u64, + f: glib_ffi::gpointer, +) { callback_guard!(); let f: &&(Fn(&Player, gst::ClockTime) + Send + Sync + 'static) = transmute(f); f(&from_glib_borrow(this), gst::ClockTime(Some(object))) } -unsafe extern "C" fn seek_done_trampoline(this: *mut ffi::GstPlayer, object: u64, f: glib_ffi::gpointer) { +unsafe extern "C" fn seek_done_trampoline( + this: *mut ffi::GstPlayer, + object: u64, + f: glib_ffi::gpointer, +) { callback_guard!(); let f: &&(Fn(&Player, gst::ClockTime) + Send + 'static) = transmute(f); f(&from_glib_borrow(this), gst::ClockTime(Some(object))) diff --git a/gstreamer-player/src/player_video_info.rs b/gstreamer-player/src/player_video_info.rs new file mode 100644 index 000000000..55fbf86c9 --- /dev/null +++ b/gstreamer-player/src/player_video_info.rs @@ -0,0 +1,37 @@ +// Copyright (C) 2017 Sebastian Dröge +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use ffi; +use glib::translate::*; +use gst; +use PlayerVideoInfo; +use std::mem; + +impl PlayerVideoInfo { + pub fn get_framerate(&self) -> gst::Fraction { + unsafe { + let mut fps_n = mem::uninitialized(); + let mut fps_d = mem::uninitialized(); + ffi::gst_player_video_info_get_framerate(self.to_glib_none().0, &mut fps_n, &mut fps_d); + (fps_n as i32, fps_d as i32).into() + } + } + + pub fn get_pixel_aspect_ratio(&self) -> gst::Fraction { + unsafe { + let mut par_n = mem::uninitialized(); + let mut par_d = mem::uninitialized(); + ffi::gst_player_video_info_get_pixel_aspect_ratio( + self.to_glib_none().0, + &mut par_n, + &mut par_d, + ); + (par_n as i32, par_d as i32).into() + } + } +} diff --git a/gstreamer-player/src/player_video_overlay_video_renderer.rs b/gstreamer-player/src/player_video_overlay_video_renderer.rs index a1d584674..91de8cf78 100644 --- a/gstreamer-player/src/player_video_overlay_video_renderer.rs +++ b/gstreamer-player/src/player_video_overlay_video_renderer.rs @@ -8,7 +8,6 @@ use PlayerVideoOverlayVideoRenderer; use ffi; -use glib; use glib::IsA; use glib::translate::*; use gst; @@ -48,23 +47,13 @@ impl PlayerVideoOverlayVideoRenderer { ) as *mut _) } } -} -pub trait PlayerVideoOverlayVideoRendererExtManual { - unsafe fn get_window_handle(&self) -> uintptr_t; - - unsafe fn set_window_handle(&self, window_handle: uintptr_t); -} - -impl< - O: IsA + IsA, -> PlayerVideoOverlayVideoRendererExtManual for O { - unsafe fn get_window_handle(&self) -> uintptr_t { + pub unsafe fn get_window_handle(&self) -> uintptr_t { ffi::gst_player_video_overlay_video_renderer_get_window_handle(self.to_glib_none().0) as uintptr_t } - unsafe fn set_window_handle(&self, window_handle: uintptr_t) { + pub unsafe fn set_window_handle(&self, window_handle: uintptr_t) { ffi::gst_player_video_overlay_video_renderer_set_window_handle( self.to_glib_none().0, window_handle as *mut _,