gstreamer_player/
player.rs1use std::{boxed::Box as Box_, mem::transmute};
4
5use glib::{
6 object::ObjectType,
7 signal::{SignalHandlerId, connect_raw},
8 translate::*,
9};
10
11use crate::{Player, ffi};
12
13impl Player {
14 #[doc(alias = "get_config")]
15 #[doc(alias = "gst_player_get_config")]
16 pub fn config(&self) -> crate::PlayerConfig {
17 unsafe { from_glib_full(ffi::gst_player_get_config(self.to_glib_none().0)) }
18 }
19
20 #[doc(alias = "gst_player_set_config")]
21 pub fn set_config(&self, config: crate::PlayerConfig) -> Result<(), glib::error::BoolError> {
22 unsafe {
23 glib::result_from_gboolean!(
24 ffi::gst_player_set_config(self.to_glib_none().0, config.into_glib_ptr()),
25 "Failed to set config",
26 )
27 }
28 }
29
30 pub fn connect_duration_changed<F: Fn(&Player, Option<gst::ClockTime>) + Send + 'static>(
31 &self,
32 f: F,
33 ) -> SignalHandlerId {
34 #[allow(clippy::cast_ptr_alignment)]
35 unsafe {
36 let f: Box_<F> = Box_::new(f);
37 connect_raw(
38 self.as_ptr() as *mut _,
39 b"duration-changed\0".as_ptr() as *const _,
40 Some(transmute::<*const (), unsafe extern "C" fn()>(
41 duration_changed_trampoline::<F> as *const (),
42 )),
43 Box_::into_raw(f),
44 )
45 }
46 }
47
48 pub fn connect_position_updated<F: Fn(&Player, Option<gst::ClockTime>) + Send + 'static>(
49 &self,
50 f: F,
51 ) -> SignalHandlerId {
52 #[allow(clippy::cast_ptr_alignment)]
53 unsafe {
54 let f: Box_<F> = Box_::new(f);
55 connect_raw(
56 self.as_ptr() as *mut _,
57 b"position-updated\0".as_ptr() as *const _,
58 Some(transmute::<*const (), unsafe extern "C" fn()>(
59 position_updated_trampoline::<F> as *const (),
60 )),
61 Box_::into_raw(f),
62 )
63 }
64 }
65
66 pub fn connect_seek_done<F: Fn(&Player, gst::ClockTime) + Send + 'static>(
67 &self,
68 f: F,
69 ) -> SignalHandlerId {
70 #[allow(clippy::cast_ptr_alignment)]
71 unsafe {
72 let f: Box_<F> = Box_::new(f);
73 connect_raw(
74 self.as_ptr() as *mut _,
75 b"seek-done\0".as_ptr() as *const _,
76 Some(transmute::<*const (), unsafe extern "C" fn()>(
77 seek_done_trampoline::<F> as *const (),
78 )),
79 Box_::into_raw(f),
80 )
81 }
82 }
83
84 #[doc(alias = "gst_player_get_video_snapshot")]
85 #[doc(alias = "get_video_snapshot")]
86 pub fn video_snapshot(
87 &self,
88 format: crate::PlayerSnapshotFormat,
89 config: Option<&gst::StructureRef>,
90 ) -> Option<gst::Sample> {
91 unsafe {
92 from_glib_full(ffi::gst_player_get_video_snapshot(
93 self.to_glib_none().0,
94 format.into_glib(),
95 mut_override(config.map(|c| c.as_ptr()).unwrap_or(std::ptr::null())),
96 ))
97 }
98 }
99}
100
101impl Default for Player {
102 fn default() -> Self {
103 Self::new(
104 None::<crate::PlayerVideoRenderer>,
105 None::<crate::PlayerSignalDispatcher>,
106 )
107 }
108}
109
110unsafe extern "C" fn duration_changed_trampoline<
111 F: Fn(&Player, Option<gst::ClockTime>) + Send + 'static,
112>(
113 this: *mut ffi::GstPlayer,
114 object: u64,
115 f: glib::ffi::gpointer,
116) {
117 unsafe {
118 let f: &F = &*(f as *const F);
119 f(&from_glib_borrow(this), FromGlib::from_glib(object))
120 }
121}
122
123unsafe extern "C" fn position_updated_trampoline<
124 F: Fn(&Player, Option<gst::ClockTime>) + Send + 'static,
125>(
126 this: *mut ffi::GstPlayer,
127 object: u64,
128 f: glib::ffi::gpointer,
129) {
130 unsafe {
131 let f: &F = &*(f as *const F);
132 f(&from_glib_borrow(this), FromGlib::from_glib(object))
133 }
134}
135
136unsafe extern "C" fn seek_done_trampoline<F: Fn(&Player, gst::ClockTime) + Send + 'static>(
137 this: *mut ffi::GstPlayer,
138 object: u64,
139 f: glib::ffi::gpointer,
140) {
141 unsafe {
142 let f: &F = &*(f as *const F);
143 f(
144 &from_glib_borrow(this),
145 try_from_glib(object).expect("undefined seek position"),
146 )
147 }
148}