Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2021-01-21 21:21:29 +0300
committerSebastian Dröge <sebastian@centricular.com>2021-01-25 15:43:05 +0300
commitd4ce1a33f2257ea19f873711c78b7b57d5cb7e5f (patch)
tree7a4ff75e550640afd69786a2d8a41f07b6b6c593 /generic/threadshare
parent875c3efb916f2400df355f8517f1daeff6f7ae85 (diff)
Update for glib/gstreamer bindings API changes
Diffstat (limited to 'generic/threadshare')
-rw-r--r--generic/threadshare/src/appsrc/imp.rs265
-rw-r--r--generic/threadshare/src/inputselector/imp.rs162
-rw-r--r--generic/threadshare/src/jitterbuffer/imp.rs295
-rw-r--r--generic/threadshare/src/proxy/imp.rs316
-rw-r--r--generic/threadshare/src/queue/imp.rs215
-rw-r--r--generic/threadshare/src/tcpclientsrc/imp.rs212
-rw-r--r--generic/threadshare/src/udpsink/imp.rs599
-rw-r--r--generic/threadshare/src/udpsrc/imp.rs316
-rw-r--r--generic/threadshare/tests/pad.rs178
9 files changed, 1314 insertions, 1244 deletions
diff --git a/generic/threadshare/src/appsrc/imp.rs b/generic/threadshare/src/appsrc/imp.rs
index 908b99a53..e34ef3150 100644
--- a/generic/threadshare/src/appsrc/imp.rs
+++ b/generic/threadshare/src/appsrc/imp.rs
@@ -66,58 +66,6 @@ impl Default for Settings {
}
}
-static PROPERTIES: [subclass::Property; 5] = [
- subclass::Property("context", |name| {
- glib::ParamSpec::string(
- name,
- "Context",
- "Context name to share threads with",
- Some(DEFAULT_CONTEXT),
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("context-wait", |name| {
- glib::ParamSpec::uint(
- name,
- "Context Wait",
- "Throttle poll loop to run at most once every this many ms",
- 0,
- 1000,
- DEFAULT_CONTEXT_WAIT,
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("max-buffers", |name| {
- glib::ParamSpec::uint(
- name,
- "Max Buffers",
- "Maximum number of buffers to queue up",
- 1,
- u32::MAX,
- DEFAULT_MAX_BUFFERS,
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("caps", |name| {
- glib::ParamSpec::boxed(
- name,
- "Caps",
- "Caps to use",
- gst::Caps::static_type(),
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("do-timestamp", |name| {
- glib::ParamSpec::boolean(
- name,
- "Do Timestamp",
- "Timestamp buffers with the current running time on arrival",
- DEFAULT_DO_TIMESTAMP,
- glib::ParamFlags::READWRITE,
- )
- }),
-];
-
static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
gst::DebugCategory::new(
"ts-appsrc",
@@ -560,68 +508,12 @@ impl ObjectSubclass for AppSrc {
const NAME: &'static str = "RsTsAppSrc";
type Type = super::AppSrc;
type ParentType = gst::Element;
+ type Interfaces = ();
type Instance = gst::subclass::ElementInstanceStruct<Self>;
type Class = subclass::simple::ClassStruct<Self>;
glib::object_subclass!();
- fn class_init(klass: &mut Self::Class) {
- klass.set_metadata(
- "Thread-sharing app source",
- "Source/Generic",
- "Thread-sharing app source",
- "Sebastian Dröge <sebastian@centricular.com>",
- );
-
- let caps = gst::Caps::new_any();
-
- let src_pad_template = gst::PadTemplate::new(
- "src",
- gst::PadDirection::Src,
- gst::PadPresence::Always,
- &caps,
- )
- .unwrap();
- klass.add_pad_template(src_pad_template);
-
- klass.install_properties(&PROPERTIES);
-
- klass.add_signal_with_class_handler(
- "push-buffer",
- glib::SignalFlags::RUN_LAST | glib::SignalFlags::ACTION,
- &[gst::Buffer::static_type()],
- bool::static_type(),
- |_, args| {
- let element = args[0]
- .get::<super::AppSrc>()
- .expect("signal arg")
- .expect("missing signal arg");
- let buffer = args[1]
- .get::<gst::Buffer>()
- .expect("signal arg")
- .expect("missing signal arg");
- let appsrc = Self::from_instance(&element);
-
- Some(appsrc.push_buffer(&element, buffer).to_value())
- },
- );
-
- klass.add_signal_with_class_handler(
- "end-of-stream",
- glib::SignalFlags::RUN_LAST | glib::SignalFlags::ACTION,
- &[],
- bool::static_type(),
- |_, args| {
- let element = args[0]
- .get::<super::AppSrc>()
- .expect("signal arg")
- .expect("missing signal arg");
- let appsrc = Self::from_instance(&element);
- Some(appsrc.end_of_stream(&element).to_value())
- },
- );
- }
-
fn with_class(klass: &Self::Class) -> Self {
let src_pad_handler = AppSrcPadHandler::default();
@@ -639,43 +531,134 @@ impl ObjectSubclass for AppSrc {
}
impl ObjectImpl for AppSrc {
- fn set_property(&self, _obj: &Self::Type, id: usize, value: &glib::Value) {
- let prop = &PROPERTIES[id];
+ fn properties() -> &'static [glib::ParamSpec] {
+ static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
+ vec![
+ glib::ParamSpec::string(
+ "context",
+ "Context",
+ "Context name to share threads with",
+ Some(DEFAULT_CONTEXT),
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::uint(
+ "context-wait",
+ "Context Wait",
+ "Throttle poll loop to run at most once every this many ms",
+ 0,
+ 1000,
+ DEFAULT_CONTEXT_WAIT,
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::uint(
+ "max-buffers",
+ "Max Buffers",
+ "Maximum number of buffers to queue up",
+ 1,
+ u32::MAX,
+ DEFAULT_MAX_BUFFERS,
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::boxed(
+ "caps",
+ "Caps",
+ "Caps to use",
+ gst::Caps::static_type(),
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::boolean(
+ "do-timestamp",
+ "Do Timestamp",
+ "Timestamp buffers with the current running time on arrival",
+ DEFAULT_DO_TIMESTAMP,
+ glib::ParamFlags::READWRITE,
+ ),
+ ]
+ });
+
+ PROPERTIES.as_ref()
+ }
+ fn signals() -> &'static [glib::subclass::Signal] {
+ static SIGNALS: Lazy<Vec<glib::subclass::Signal>> = Lazy::new(|| {
+ vec![
+ glib::subclass::Signal::builder(
+ "push-buffer",
+ &[gst::Buffer::static_type()],
+ bool::static_type(),
+ )
+ .action()
+ .class_handler(|_, args| {
+ let element = args[0]
+ .get::<super::AppSrc>()
+ .expect("signal arg")
+ .expect("missing signal arg");
+ let buffer = args[1]
+ .get::<gst::Buffer>()
+ .expect("signal arg")
+ .expect("missing signal arg");
+ let appsrc = AppSrc::from_instance(&element);
+
+ Some(appsrc.push_buffer(&element, buffer).to_value())
+ })
+ .build(),
+ glib::subclass::Signal::builder("end-of-stream", &[], bool::static_type())
+ .action()
+ .class_handler(|_, args| {
+ let element = args[0]
+ .get::<super::AppSrc>()
+ .expect("signal arg")
+ .expect("missing signal arg");
+ let appsrc = AppSrc::from_instance(&element);
+
+ Some(appsrc.end_of_stream(&element).to_value())
+ })
+ .build(),
+ ]
+ });
+
+ SIGNALS.as_ref()
+ }
+
+ fn set_property(
+ &self,
+ _obj: &Self::Type,
+ _id: usize,
+ value: &glib::Value,
+ pspec: &glib::ParamSpec,
+ ) {
let mut settings = self.settings.lock().unwrap();
- match *prop {
- subclass::Property("context", ..) => {
+ match pspec.get_name() {
+ "context" => {
settings.context = value
.get()
.expect("type checked upstream")
.unwrap_or_else(|| "".into());
}
- subclass::Property("context-wait", ..) => {
+ "context-wait" => {
settings.context_wait = value.get_some().expect("type checked upstream");
}
- subclass::Property("caps", ..) => {
+ "caps" => {
settings.caps = value.get().expect("type checked upstream");
}
- subclass::Property("max-buffers", ..) => {
+ "max-buffers" => {
settings.max_buffers = value.get_some().expect("type checked upstream");
}
- subclass::Property("do-timestamp", ..) => {
+ "do-timestamp" => {
settings.do_timestamp = value.get_some().expect("type checked upstream");
}
_ => unimplemented!(),
}
}
- fn get_property(&self, _obj: &Self::Type, id: usize) -> glib::Value {
- let prop = &PROPERTIES[id];
-
+ fn get_property(&self, _obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
let settings = self.settings.lock().unwrap();
- match *prop {
- subclass::Property("context", ..) => settings.context.to_value(),
- subclass::Property("context-wait", ..) => settings.context_wait.to_value(),
- subclass::Property("caps", ..) => settings.caps.to_value(),
- subclass::Property("max-buffers", ..) => settings.max_buffers.to_value(),
- subclass::Property("do-timestamp", ..) => settings.do_timestamp.to_value(),
+ match pspec.get_name() {
+ "context" => settings.context.to_value(),
+ "context-wait" => settings.context_wait.to_value(),
+ "caps" => settings.caps.to_value(),
+ "max-buffers" => settings.max_buffers.to_value(),
+ "do-timestamp" => settings.do_timestamp.to_value(),
_ => unimplemented!(),
}
}
@@ -690,6 +673,36 @@ impl ObjectImpl for AppSrc {
}
impl ElementImpl for AppSrc {
+ fn metadata() -> Option<&'static gst::subclass::ElementMetadata> {
+ static ELEMENT_METADATA: Lazy<gst::subclass::ElementMetadata> = Lazy::new(|| {
+ gst::subclass::ElementMetadata::new(
+ "Thread-sharing app source",
+ "Source/Generic",
+ "Thread-sharing app source",
+ "Sebastian Dröge <sebastian@centricular.com>",
+ )
+ });
+
+ Some(&*ELEMENT_METADATA)
+ }
+
+ fn pad_templates() -> &'static [gst::PadTemplate] {
+ static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| {
+ let caps = gst::Caps::new_any();
+ let src_pad_template = gst::PadTemplate::new(
+ "src",
+ gst::PadDirection::Src,
+ gst::PadPresence::Always,
+ &caps,
+ )
+ .unwrap();
+
+ vec![src_pad_template]
+ });
+
+ PAD_TEMPLATES.as_ref()
+ }
+
fn change_state(
&self,
element: &Self::Type,
diff --git a/generic/threadshare/src/inputselector/imp.rs b/generic/threadshare/src/inputselector/imp.rs
index 3b03add30..36c736495 100644
--- a/generic/threadshare/src/inputselector/imp.rs
+++ b/generic/threadshare/src/inputselector/imp.rs
@@ -55,38 +55,6 @@ impl Default for Settings {
}
}
-static PROPERTIES: [subclass::Property; 3] = [
- subclass::Property("context", |name| {
- glib::ParamSpec::string(
- name,
- "Context",
- "Context name to share threads with",
- Some(DEFAULT_CONTEXT),
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("context-wait", |name| {
- glib::ParamSpec::uint(
- name,
- "Context Wait",
- "Throttle poll loop to run at most once every this many ms",
- 0,
- 1000,
- DEFAULT_CONTEXT_WAIT,
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("active-pad", |name| {
- glib::ParamSpec::object(
- name,
- "Active Pad",
- "Currently active pad",
- gst::Pad::static_type(),
- glib::ParamFlags::READWRITE,
- )
- }),
-];
-
#[derive(Debug)]
struct InputSelectorPadSinkHandlerInner {
segment: Option<gst::Segment>,
@@ -429,42 +397,12 @@ impl ObjectSubclass for InputSelector {
const NAME: &'static str = "RsTsInputSelector";
type Type = super::InputSelector;
type ParentType = gst::Element;
+ type Interfaces = ();
type Instance = gst::subclass::ElementInstanceStruct<Self>;
type Class = subclass::simple::ClassStruct<Self>;
glib::object_subclass!();
- fn class_init(klass: &mut Self::Class) {
- klass.set_metadata(
- "Thread-sharing input selector",
- "Generic",
- "Simple input selector element",
- "Mathieu Duponchelle <mathieu@centricular.com>",
- );
-
- let caps = gst::Caps::new_any();
-
- let sink_pad_template = gst::PadTemplate::new(
- "sink_%u",
- gst::PadDirection::Sink,
- gst::PadPresence::Request,
- &caps,
- )
- .unwrap();
- klass.add_pad_template(sink_pad_template);
-
- let src_pad_template = gst::PadTemplate::new(
- "src",
- gst::PadDirection::Src,
- gst::PadPresence::Always,
- &caps,
- )
- .unwrap();
- klass.add_pad_template(src_pad_template);
-
- klass.install_properties(&PROPERTIES);
- }
-
fn with_class(klass: &Self::Class) -> Self {
Self {
src_pad: PadSrc::new(
@@ -479,22 +417,58 @@ impl ObjectSubclass for InputSelector {
}
impl ObjectImpl for InputSelector {
- fn set_property(&self, _obj: &Self::Type, id: usize, value: &glib::Value) {
- let prop = &PROPERTIES[id];
+ fn properties() -> &'static [glib::ParamSpec] {
+ static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
+ vec![
+ glib::ParamSpec::string(
+ "context",
+ "Context",
+ "Context name to share threads with",
+ Some(DEFAULT_CONTEXT),
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::uint(
+ "context-wait",
+ "Context Wait",
+ "Throttle poll loop to run at most once every this many ms",
+ 0,
+ 1000,
+ DEFAULT_CONTEXT_WAIT,
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::object(
+ "active-pad",
+ "Active Pad",
+ "Currently active pad",
+ gst::Pad::static_type(),
+ glib::ParamFlags::READWRITE,
+ ),
+ ]
+ });
+
+ PROPERTIES.as_ref()
+ }
- match *prop {
- subclass::Property("context", ..) => {
+ fn set_property(
+ &self,
+ _obj: &Self::Type,
+ _id: usize,
+ value: &glib::Value,
+ pspec: &glib::ParamSpec,
+ ) {
+ match pspec.get_name() {
+ "context" => {
let mut settings = self.settings.lock().unwrap();
settings.context = value
.get()
.expect("type checked upstream")
.unwrap_or_else(|| "".into());
}
- subclass::Property("context-wait", ..) => {
+ "context-wait" => {
let mut settings = self.settings.lock().unwrap();
settings.context_wait = value.get_some().expect("type checked upstream");
}
- subclass::Property("active-pad", ..) => {
+ "active-pad" => {
let pad = value.get::<gst::Pad>().expect("type checked upstream");
let mut state = self.state.lock().unwrap();
let pads = self.pads.lock().unwrap();
@@ -526,19 +500,17 @@ impl ObjectImpl for InputSelector {
}
}
- fn get_property(&self, _obj: &Self::Type, id: usize) -> glib::Value {
- let prop = &PROPERTIES[id];
-
- match *prop {
- subclass::Property("context", ..) => {
+ fn get_property(&self, _obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
+ match pspec.get_name() {
+ "context" => {
let settings = self.settings.lock().unwrap();
settings.context.to_value()
}
- subclass::Property("context-wait", ..) => {
+ "context-wait" => {
let settings = self.settings.lock().unwrap();
settings.context_wait.to_value()
}
- subclass::Property("active-pad", ..) => {
+ "active-pad" => {
let state = self.state.lock().unwrap();
let active_pad = state.active_sinkpad.clone();
active_pad.to_value()
@@ -556,6 +528,44 @@ impl ObjectImpl for InputSelector {
}
impl ElementImpl for InputSelector {
+ fn metadata() -> Option<&'static gst::subclass::ElementMetadata> {
+ static ELEMENT_METADATA: Lazy<gst::subclass::ElementMetadata> = Lazy::new(|| {
+ gst::subclass::ElementMetadata::new(
+ "Thread-sharing input selector",
+ "Generic",
+ "Simple input selector element",
+ "Mathieu Duponchelle <mathieu@centricular.com>",
+ )
+ });
+
+ Some(&*ELEMENT_METADATA)
+ }
+
+ fn pad_templates() -> &'static [gst::PadTemplate] {
+ static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| {
+ let caps = gst::Caps::new_any();
+ let sink_pad_template = gst::PadTemplate::new(
+ "sink_%u",
+ gst::PadDirection::Sink,
+ gst::PadPresence::Request,
+ &caps,
+ )
+ .unwrap();
+
+ let src_pad_template = gst::PadTemplate::new(
+ "src",
+ gst::PadDirection::Src,
+ gst::PadPresence::Always,
+ &caps,
+ )
+ .unwrap();
+
+ vec![sink_pad_template, src_pad_template]
+ });
+
+ PAD_TEMPLATES.as_ref()
+ }
+
fn change_state(
&self,
element: &Self::Type,
diff --git a/generic/threadshare/src/jitterbuffer/imp.rs b/generic/threadshare/src/jitterbuffer/imp.rs
index 430f8fd35..19e376900 100644
--- a/generic/threadshare/src/jitterbuffer/imp.rs
+++ b/generic/threadshare/src/jitterbuffer/imp.rs
@@ -72,80 +72,6 @@ impl Default for Settings {
}
}
-static PROPERTIES: [subclass::Property; 7] = [
- subclass::Property("latency", |name| {
- glib::ParamSpec::uint(
- name,
- "Buffer latency in ms",
- "Amount of ms to buffer",
- 0,
- std::u32::MAX,
- DEFAULT_LATENCY_MS,
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("do-lost", |name| {
- glib::ParamSpec::boolean(
- name,
- "Do Lost",
- "Send an event downstream when a packet is lost",
- DEFAULT_DO_LOST,
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("max-dropout-time", |name| {
- glib::ParamSpec::uint(
- name,
- "Max dropout time",
- "The maximum time (milliseconds) of missing packets tolerated.",
- 0,
- std::u32::MAX,
- DEFAULT_MAX_DROPOUT_TIME,
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("max-misorder-time", |name| {
- glib::ParamSpec::uint(
- name,
- "Max misorder time",
- "The maximum time (milliseconds) of misordered packets tolerated.",
- 0,
- std::u32::MAX,
- DEFAULT_MAX_MISORDER_TIME,
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("stats", |name| {
- glib::ParamSpec::boxed(
- name,
- "Statistics",
- "Various statistics",
- gst::Structure::static_type(),
- glib::ParamFlags::READABLE,
- )
- }),
- subclass::Property("context", |name| {
- glib::ParamSpec::string(
- name,
- "Context",
- "Context name to share threads with",
- Some(DEFAULT_CONTEXT),
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("context-wait", |name| {
- glib::ParamSpec::uint(
- name,
- "Context Wait",
- "Throttle poll loop to run at most once every this many ms",
- 0,
- 1000,
- DEFAULT_CONTEXT_WAIT,
- glib::ParamFlags::READWRITE,
- )
- }),
-];
-
#[derive(Eq)]
struct GapPacket {
buffer: gst::Buffer,
@@ -1413,63 +1339,12 @@ impl ObjectSubclass for JitterBuffer {
const NAME: &'static str = "RsTsJitterBuffer";
type Type = super::JitterBuffer;
type ParentType = gst::Element;
+ type Interfaces = ();
type Instance = gst::subclass::ElementInstanceStruct<Self>;
type Class = subclass::simple::ClassStruct<Self>;
glib::object_subclass!();
- fn class_init(klass: &mut Self::Class) {
- klass.set_metadata(
- "Thread-sharing jitterbuffer",
- "Generic",
- "Simple jitterbuffer",
- "Mathieu Duponchelle <mathieu@centricular.com>",
- );
-
- let caps = gst::Caps::new_any();
-
- let sink_pad_template = gst::PadTemplate::new(
- "sink",
- gst::PadDirection::Sink,
- gst::PadPresence::Always,
- &caps,
- )
- .unwrap();
- klass.add_pad_template(sink_pad_template);
- klass.add_signal(
- "request-pt-map",
- glib::SignalFlags::RUN_LAST,
- &[u32::static_type()],
- gst::Caps::static_type(),
- );
-
- klass.add_signal_with_class_handler(
- "clear-pt-map",
- glib::SignalFlags::RUN_LAST | glib::SignalFlags::ACTION,
- &[],
- glib::types::Type::Unit,
- |_, args| {
- let element = args[0]
- .get::<super::JitterBuffer>()
- .expect("signal arg")
- .expect("missing signal arg");
- let jb = Self::from_instance(&element);
- jb.clear_pt_map(&element);
- None
- },
- );
-
- let src_pad_template = gst::PadTemplate::new(
- "src",
- gst::PadDirection::Src,
- gst::PadPresence::Always,
- &caps,
- )
- .unwrap();
- klass.add_pad_template(src_pad_template);
- klass.install_properties(&PROPERTIES);
- }
-
fn with_class(klass: &Self::Class) -> Self {
let sink_pad_handler = SinkHandler::default();
let src_pad_handler = SrcHandler::default();
@@ -1493,11 +1368,102 @@ impl ObjectSubclass for JitterBuffer {
}
impl ObjectImpl for JitterBuffer {
- fn set_property(&self, obj: &Self::Type, id: usize, value: &glib::Value) {
- let prop = &PROPERTIES[id];
+ fn properties() -> &'static [glib::ParamSpec] {
+ static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
+ vec![
+ glib::ParamSpec::string(
+ "context",
+ "Context",
+ "Context name to share threads with",
+ Some(DEFAULT_CONTEXT),
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::uint(
+ "context-wait",
+ "Context Wait",
+ "Throttle poll loop to run at most once every this many ms",
+ 0,
+ 1000,
+ DEFAULT_CONTEXT_WAIT,
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::uint(
+ "latency",
+ "Buffer latency in ms",
+ "Amount of ms to buffer",
+ 0,
+ std::u32::MAX,
+ DEFAULT_LATENCY_MS,
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::boolean(
+ "do-lost",
+ "Do Lost",
+ "Send an event downstream when a packet is lost",
+ DEFAULT_DO_LOST,
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::uint(
+ "max-dropout-time",
+ "Max dropout time",
+ "The maximum time (milliseconds) of missing packets tolerated.",
+ 0,
+ std::u32::MAX,
+ DEFAULT_MAX_DROPOUT_TIME,
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::uint(
+ "max-misorder-time",
+ "Max misorder time",
+ "The maximum time (milliseconds) of misordered packets tolerated.",
+ 0,
+ std::u32::MAX,
+ DEFAULT_MAX_MISORDER_TIME,
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::boxed(
+ "stats",
+ "Statistics",
+ "Various statistics",
+ gst::Structure::static_type(),
+ glib::ParamFlags::READABLE,
+ ),
+ ]
+ });
+
+ PROPERTIES.as_ref()
+ }
+
+ fn signals() -> &'static [glib::subclass::Signal] {
+ static SIGNALS: Lazy<Vec<glib::subclass::Signal>> = Lazy::new(|| {
+ vec![
+ glib::subclass::Signal::builder("clear-pt-map", &[], glib::types::Type::Unit)
+ .action()
+ .class_handler(|_, args| {
+ let element = args[0]
+ .get::<super::JitterBuffer>()
+ .expect("signal arg")
+ .expect("missing signal arg");
+ let jb = JitterBuffer::from_instance(&element);
+ jb.clear_pt_map(&element);
+ None
+ })
+ .build(),
+ ]
+ });
+
+ SIGNALS.as_ref()
+ }
- match *prop {
- subclass::Property("latency", ..) => {
+ fn set_property(
+ &self,
+ obj: &Self::Type,
+ _id: usize,
+ value: &glib::Value,
+ pspec: &glib::ParamSpec,
+ ) {
+ match pspec.get_name() {
+ "latency" => {
let latency_ms = {
let mut settings = self.settings.lock().unwrap();
settings.latency_ms = value.get_some().expect("type checked upstream");
@@ -1509,26 +1475,26 @@ impl ObjectImpl for JitterBuffer {
let _ = obj.post_message(gst::message::Latency::builder().src(obj).build());
}
- subclass::Property("do-lost", ..) => {
+ "do-lost" => {
let mut settings = self.settings.lock().unwrap();
settings.do_lost = value.get_some().expect("type checked upstream");
}
- subclass::Property("max-dropout-time", ..) => {
+ "max-dropout-time" => {
let mut settings = self.settings.lock().unwrap();
settings.max_dropout_time = value.get_some().expect("type checked upstream");
}
- subclass::Property("max-misorder-time", ..) => {
+ "max-misorder-time" => {
let mut settings = self.settings.lock().unwrap();
settings.max_misorder_time = value.get_some().expect("type checked upstream");
}
- subclass::Property("context", ..) => {
+ "context" => {
let mut settings = self.settings.lock().unwrap();
settings.context = value
.get()
.expect("type checked upstream")
.unwrap_or_else(|| "".into());
}
- subclass::Property("context-wait", ..) => {
+ "context-wait" => {
let mut settings = self.settings.lock().unwrap();
settings.context_wait = value.get_some().expect("type checked upstream");
}
@@ -1536,27 +1502,25 @@ impl ObjectImpl for JitterBuffer {
}
}
- fn get_property(&self, _obj: &Self::Type, id: usize) -> glib::Value {
- let prop = &PROPERTIES[id];
-
- match *prop {
- subclass::Property("latency", ..) => {
+ fn get_property(&self, _obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
+ match pspec.get_name() {
+ "latency" => {
let settings = self.settings.lock().unwrap();
settings.latency_ms.to_value()
}
- subclass::Property("do-lost", ..) => {
+ "do-lost" => {
let settings = self.settings.lock().unwrap();
settings.do_lost.to_value()
}
- subclass::Property("max-dropout-time", ..) => {
+ "max-dropout-time" => {
let settings = self.settings.lock().unwrap();
settings.max_dropout_time.to_value()
}
- subclass::Property("max-misorder-time", ..) => {
+ "max-misorder-time" => {
let settings = self.settings.lock().unwrap();
settings.max_misorder_time.to_value()
}
- subclass::Property("stats", ..) => {
+ "stats" => {
let state = self.state.lock().unwrap();
let s = gst::Structure::new(
"application/x-rtp-jitterbuffer-stats",
@@ -1568,11 +1532,11 @@ impl ObjectImpl for JitterBuffer {
);
s.to_value()
}
- subclass::Property("context", ..) => {
+ "context" => {
let settings = self.settings.lock().unwrap();
settings.context.to_value()
}
- subclass::Property("context-wait", ..) => {
+ "context-wait" => {
let settings = self.settings.lock().unwrap();
settings.context_wait.to_value()
}
@@ -1590,6 +1554,45 @@ impl ObjectImpl for JitterBuffer {
}
impl ElementImpl for JitterBuffer {
+ fn metadata() -> Option<&'static gst::subclass::ElementMetadata> {
+ static ELEMENT_METADATA: Lazy<gst::subclass::ElementMetadata> = Lazy::new(|| {
+ gst::subclass::ElementMetadata::new(
+ "Thread-sharing jitterbuffer",
+ "Generic",
+ "Simple jitterbuffer",
+ "Mathieu Duponchelle <mathieu@centricular.com>",
+ )
+ });
+
+ Some(&*ELEMENT_METADATA)
+ }
+
+ fn pad_templates() -> &'static [gst::PadTemplate] {
+ static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| {
+ let caps = gst::Caps::new_any();
+
+ let sink_pad_template = gst::PadTemplate::new(
+ "sink",
+ gst::PadDirection::Sink,
+ gst::PadPresence::Always,
+ &caps,
+ )
+ .unwrap();
+
+ let src_pad_template = gst::PadTemplate::new(
+ "src",
+ gst::PadDirection::Src,
+ gst::PadPresence::Always,
+ &caps,
+ )
+ .unwrap();
+
+ vec![sink_pad_template, src_pad_template]
+ });
+
+ PAD_TEMPLATES.as_ref()
+ }
+
fn change_state(
&self,
element: &Self::Type,
diff --git a/generic/threadshare/src/proxy/imp.rs b/generic/threadshare/src/proxy/imp.rs
index 52d408242..bc13654d4 100644
--- a/generic/threadshare/src/proxy/imp.rs
+++ b/generic/threadshare/src/proxy/imp.rs
@@ -93,81 +93,6 @@ impl Default for SettingsSrc {
}
}
-static PROPERTIES_SRC: [subclass::Property; 6] = [
- subclass::Property("max-size-buffers", |name| {
- glib::ParamSpec::uint(
- name,
- "Max Size Buffers",
- "Maximum number of buffers to queue (0=unlimited)",
- 0,
- u32::MAX,
- DEFAULT_MAX_SIZE_BUFFERS,
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("max-size-bytes", |name| {
- glib::ParamSpec::uint(
- name,
- "Max Size Bytes",
- "Maximum number of bytes to queue (0=unlimited)",
- 0,
- u32::MAX,
- DEFAULT_MAX_SIZE_BYTES,
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("max-size-time", |name| {
- glib::ParamSpec::uint64(
- name,
- "Max Size Time",
- "Maximum number of nanoseconds to queue (0=unlimited)",
- 0,
- u64::MAX - 1,
- DEFAULT_MAX_SIZE_TIME,
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("context", |name| {
- glib::ParamSpec::string(
- name,
- "Context",
- "Context name to share threads with",
- Some(DEFAULT_CONTEXT),
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("context-wait", |name| {
- glib::ParamSpec::uint(
- name,
- "Context Wait",
- "Throttle poll loop to run at most once every this many ms",
- 0,
- 1000,
- DEFAULT_CONTEXT_WAIT,
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("proxy-context", |name| {
- glib::ParamSpec::string(
- name,
- "Proxy Context",
- "Context name of the proxy to share with",
- Some(DEFAULT_PROXY_CONTEXT),
- glib::ParamFlags::READWRITE,
- )
- }),
-];
-
-static PROPERTIES_SINK: [subclass::Property; 1] = [subclass::Property("proxy-context", |name| {
- glib::ParamSpec::string(
- name,
- "Proxy Context",
- "Context name of the proxy to share with",
- Some(DEFAULT_PROXY_CONTEXT),
- glib::ParamFlags::READWRITE,
- )
-})];
-
// TODO: Refactor into a Sender and Receiver instead of the have_ booleans
#[derive(Debug, Default)]
@@ -650,34 +575,13 @@ impl ProxySink {
impl ObjectSubclass for ProxySink {
const NAME: &'static str = "RsTsProxySink";
type Type = super::ProxySink;
+ type Interfaces = ();
type ParentType = gst::Element;
type Instance = gst::subclass::ElementInstanceStruct<Self>;
type Class = subclass::simple::ClassStruct<Self>;
glib::object_subclass!();
- fn class_init(klass: &mut Self::Class) {
- klass.set_metadata(
- "Thread-sharing proxy sink",
- "Sink/Generic",
- "Thread-sharing proxy sink",
- "Sebastian Dröge <sebastian@centricular.com>",
- );
-
- let caps = gst::Caps::new_any();
-
- let sink_pad_template = gst::PadTemplate::new(
- "sink",
- gst::PadDirection::Sink,
- gst::PadPresence::Always,
- &caps,
- )
- .unwrap();
- klass.add_pad_template(sink_pad_template);
-
- klass.install_properties(&PROPERTIES_SINK);
- }
-
fn with_class(klass: &Self::Class) -> Self {
Self {
sink_pad: PadSink::new(
@@ -691,12 +595,30 @@ impl ObjectSubclass for ProxySink {
}
impl ObjectImpl for ProxySink {
- fn set_property(&self, _obj: &Self::Type, id: usize, value: &glib::Value) {
- let prop = &PROPERTIES_SINK[id];
+ fn properties() -> &'static [glib::ParamSpec] {
+ static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
+ vec![glib::ParamSpec::string(
+ "proxy-context",
+ "Proxy Context",
+ "Context name of the proxy to share with",
+ Some(DEFAULT_PROXY_CONTEXT),
+ glib::ParamFlags::READWRITE,
+ )]
+ });
+
+ PROPERTIES.as_ref()
+ }
+ fn set_property(
+ &self,
+ _obj: &Self::Type,
+ _id: usize,
+ value: &glib::Value,
+ pspec: &glib::ParamSpec,
+ ) {
let mut settings = self.settings.lock().unwrap();
- match *prop {
- subclass::Property("proxy-context", ..) => {
+ match pspec.get_name() {
+ "proxy-context" => {
settings.proxy_context = value
.get()
.expect("type checked upstream")
@@ -706,12 +628,10 @@ impl ObjectImpl for ProxySink {
}
}
- fn get_property(&self, _obj: &Self::Type, id: usize) -> glib::Value {
- let prop = &PROPERTIES_SINK[id];
-
+ fn get_property(&self, _obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
let settings = self.settings.lock().unwrap();
- match *prop {
- subclass::Property("proxy-context", ..) => settings.proxy_context.to_value(),
+ match pspec.get_name() {
+ "proxy-context" => settings.proxy_context.to_value(),
_ => unimplemented!(),
}
}
@@ -726,6 +646,37 @@ impl ObjectImpl for ProxySink {
}
impl ElementImpl for ProxySink {
+ fn metadata() -> Option<&'static gst::subclass::ElementMetadata> {
+ static ELEMENT_METADATA: Lazy<gst::subclass::ElementMetadata> = Lazy::new(|| {
+ gst::subclass::ElementMetadata::new(
+ "Thread-sharing proxy sink",
+ "Sink/Generic",
+ "Thread-sharing proxy sink",
+ "Sebastian Dröge <sebastian@centricular.com>",
+ )
+ });
+
+ Some(&*ELEMENT_METADATA)
+ }
+
+ fn pad_templates() -> &'static [gst::PadTemplate] {
+ static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| {
+ let caps = gst::Caps::new_any();
+
+ let sink_pad_template = gst::PadTemplate::new(
+ "sink",
+ gst::PadDirection::Sink,
+ gst::PadPresence::Always,
+ &caps,
+ )
+ .unwrap();
+
+ vec![sink_pad_template]
+ });
+
+ PAD_TEMPLATES.as_ref()
+ }
+
fn change_state(
&self,
element: &Self::Type,
@@ -1166,33 +1117,12 @@ impl ObjectSubclass for ProxySrc {
const NAME: &'static str = "RsTsProxySrc";
type Type = super::ProxySrc;
type ParentType = gst::Element;
+ type Interfaces = ();
type Instance = gst::subclass::ElementInstanceStruct<Self>;
type Class = subclass::simple::ClassStruct<Self>;
glib::object_subclass!();
- fn class_init(klass: &mut Self::Class) {
- klass.set_metadata(
- "Thread-sharing proxy source",
- "Source/Generic",
- "Thread-sharing proxy source",
- "Sebastian Dröge <sebastian@centricular.com>",
- );
-
- let caps = gst::Caps::new_any();
-
- let src_pad_template = gst::PadTemplate::new(
- "src",
- gst::PadDirection::Src,
- gst::PadPresence::Always,
- &caps,
- )
- .unwrap();
- klass.add_pad_template(src_pad_template);
-
- klass.install_properties(&PROPERTIES_SRC);
- }
-
fn new() -> Self {
unreachable!()
}
@@ -1212,30 +1142,93 @@ impl ObjectSubclass for ProxySrc {
}
impl ObjectImpl for ProxySrc {
- fn set_property(&self, _obj: &Self::Type, id: usize, value: &glib::Value) {
- let prop = &PROPERTIES_SRC[id];
+ fn properties() -> &'static [glib::ParamSpec] {
+ static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
+ vec![
+ glib::ParamSpec::string(
+ "context",
+ "Context",
+ "Context name to share threads with",
+ Some(DEFAULT_CONTEXT),
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::uint(
+ "context-wait",
+ "Context Wait",
+ "Throttle poll loop to run at most once every this many ms",
+ 0,
+ 1000,
+ DEFAULT_CONTEXT_WAIT,
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::string(
+ "proxy-context",
+ "Proxy Context",
+ "Context name of the proxy to share with",
+ Some(DEFAULT_PROXY_CONTEXT),
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::uint(
+ "max-size-buffers",
+ "Max Size Buffers",
+ "Maximum number of buffers to queue (0=unlimited)",
+ 0,
+ u32::MAX,
+ DEFAULT_MAX_SIZE_BUFFERS,
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::uint(
+ "max-size-bytes",
+ "Max Size Bytes",
+ "Maximum number of bytes to queue (0=unlimited)",
+ 0,
+ u32::MAX,
+ DEFAULT_MAX_SIZE_BYTES,
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::uint64(
+ "max-size-time",
+ "Max Size Time",
+ "Maximum number of nanoseconds to queue (0=unlimited)",
+ 0,
+ u64::MAX - 1,
+ DEFAULT_MAX_SIZE_TIME,
+ glib::ParamFlags::READWRITE,
+ ),
+ ]
+ });
+
+ PROPERTIES.as_ref()
+ }
+ fn set_property(
+ &self,
+ _obj: &Self::Type,
+ _id: usize,
+ value: &glib::Value,
+ pspec: &glib::ParamSpec,
+ ) {
let mut settings = self.settings.lock().unwrap();
- match *prop {
- subclass::Property("max-size-buffers", ..) => {
+ match pspec.get_name() {
+ "max-size-buffers" => {
settings.max_size_buffers = value.get_some().expect("type checked upstream");
}
- subclass::Property("max-size-bytes", ..) => {
+ "max-size-bytes" => {
settings.max_size_bytes = value.get_some().expect("type checked upstream");
}
- subclass::Property("max-size-time", ..) => {
+ "max-size-time" => {
settings.max_size_time = value.get_some().expect("type checked upstream");
}
- subclass::Property("context", ..) => {
+ "context" => {
settings.context = value
.get()
.expect("type checked upstream")
.unwrap_or_else(|| "".into());
}
- subclass::Property("context-wait", ..) => {
+ "context-wait" => {
settings.context_wait = value.get_some().expect("type checked upstream");
}
- subclass::Property("proxy-context", ..) => {
+ "proxy-context" => {
settings.proxy_context = value
.get()
.expect("type checked upstream")
@@ -1245,17 +1238,15 @@ impl ObjectImpl for ProxySrc {
}
}
- fn get_property(&self, _obj: &Self::Type, id: usize) -> glib::Value {
- let prop = &PROPERTIES_SRC[id];
-
+ fn get_property(&self, _obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
let settings = self.settings.lock().unwrap();
- match *prop {
- subclass::Property("max-size-buffers", ..) => settings.max_size_buffers.to_value(),
- subclass::Property("max-size-bytes", ..) => settings.max_size_bytes.to_value(),
- subclass::Property("max-size-time", ..) => settings.max_size_time.to_value(),
- subclass::Property("context", ..) => settings.context.to_value(),
- subclass::Property("context-wait", ..) => settings.context_wait.to_value(),
- subclass::Property("proxy-context", ..) => settings.proxy_context.to_value(),
+ match pspec.get_name() {
+ "max-size-buffers" => settings.max_size_buffers.to_value(),
+ "max-size-bytes" => settings.max_size_bytes.to_value(),
+ "max-size-time" => settings.max_size_time.to_value(),
+ "context" => settings.context.to_value(),
+ "context-wait" => settings.context_wait.to_value(),
+ "proxy-context" => settings.proxy_context.to_value(),
_ => unimplemented!(),
}
}
@@ -1270,6 +1261,37 @@ impl ObjectImpl for ProxySrc {
}
impl ElementImpl for ProxySrc {
+ fn metadata() -> Option<&'static gst::subclass::ElementMetadata> {
+ static ELEMENT_METADATA: Lazy<gst::subclass::ElementMetadata> = Lazy::new(|| {
+ gst::subclass::ElementMetadata::new(
+ "Thread-sharing proxy source",
+ "Source/Generic",
+ "Thread-sharing proxy source",
+ "Sebastian Dröge <sebastian@centricular.com>",
+ )
+ });
+
+ Some(&*ELEMENT_METADATA)
+ }
+
+ fn pad_templates() -> &'static [gst::PadTemplate] {
+ static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| {
+ let caps = gst::Caps::new_any();
+
+ let src_pad_template = gst::PadTemplate::new(
+ "src",
+ gst::PadDirection::Src,
+ gst::PadPresence::Always,
+ &caps,
+ )
+ .unwrap();
+
+ vec![src_pad_template]
+ });
+
+ PAD_TEMPLATES.as_ref()
+ }
+
fn change_state(
&self,
element: &Self::Type,
diff --git a/generic/threadshare/src/queue/imp.rs b/generic/threadshare/src/queue/imp.rs
index 8f0d98c05..dd257cadc 100644
--- a/generic/threadshare/src/queue/imp.rs
+++ b/generic/threadshare/src/queue/imp.rs
@@ -65,62 +65,6 @@ impl Default for Settings {
}
}
-static PROPERTIES: [subclass::Property; 5] = [
- subclass::Property("max-size-buffers", |name| {
- glib::ParamSpec::uint(
- name,
- "Max Size Buffers",
- "Maximum number of buffers to queue (0=unlimited)",
- 0,
- u32::MAX,
- DEFAULT_MAX_SIZE_BUFFERS,
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("max-size-bytes", |name| {
- glib::ParamSpec::uint(
- name,
- "Max Size Bytes",
- "Maximum number of bytes to queue (0=unlimited)",
- 0,
- u32::MAX,
- DEFAULT_MAX_SIZE_BYTES,
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("max-size-time", |name| {
- glib::ParamSpec::uint64(
- name,
- "Max Size Time",
- "Maximum number of nanoseconds to queue (0=unlimited)",
- 0,
- u64::MAX - 1,
- DEFAULT_MAX_SIZE_TIME,
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("context", |name| {
- glib::ParamSpec::string(
- name,
- "Context",
- "Context name to share threads with",
- Some(DEFAULT_CONTEXT),
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("context-wait", |name| {
- glib::ParamSpec::uint(
- name,
- "Context Wait",
- "Throttle poll loop to run at most once every this many ms",
- 0,
- 1000,
- DEFAULT_CONTEXT_WAIT,
- glib::ParamFlags::READWRITE,
- )
- }),
-];
-
#[derive(Debug)]
struct PendingQueue {
more_queue_space_sender: Option<oneshot::Sender<()>>,
@@ -752,42 +696,12 @@ impl ObjectSubclass for Queue {
const NAME: &'static str = "RsTsQueue";
type Type = super::Queue;
type ParentType = gst::Element;
+ type Interfaces = ();
type Instance = gst::subclass::ElementInstanceStruct<Self>;
type Class = subclass::simple::ClassStruct<Self>;
glib::object_subclass!();
- fn class_init(klass: &mut Self::Class) {
- klass.set_metadata(
- "Thread-sharing queue",
- "Generic",
- "Simple data queue",
- "Sebastian Dröge <sebastian@centricular.com>",
- );
-
- let caps = gst::Caps::new_any();
-
- let sink_pad_template = gst::PadTemplate::new(
- "sink",
- gst::PadDirection::Sink,
- gst::PadPresence::Always,
- &caps,
- )
- .unwrap();
- klass.add_pad_template(sink_pad_template);
-
- let src_pad_template = gst::PadTemplate::new(
- "src",
- gst::PadDirection::Src,
- gst::PadPresence::Always,
- &caps,
- )
- .unwrap();
- klass.add_pad_template(src_pad_template);
-
- klass.install_properties(&PROPERTIES);
- }
-
fn with_class(klass: &Self::Class) -> Self {
Self {
sink_pad: PadSink::new(
@@ -808,43 +722,97 @@ impl ObjectSubclass for Queue {
}
impl ObjectImpl for Queue {
- fn set_property(&self, _obj: &Self::Type, id: usize, value: &glib::Value) {
- let prop = &PROPERTIES[id];
+ fn properties() -> &'static [glib::ParamSpec] {
+ static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
+ vec![
+ glib::ParamSpec::string(
+ "context",
+ "Context",
+ "Context name to share threads with",
+ Some(DEFAULT_CONTEXT),
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::uint(
+ "context-wait",
+ "Context Wait",
+ "Throttle poll loop to run at most once every this many ms",
+ 0,
+ 1000,
+ DEFAULT_CONTEXT_WAIT,
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::uint(
+ "max-size-buffers",
+ "Max Size Buffers",
+ "Maximum number of buffers to queue (0=unlimited)",
+ 0,
+ u32::MAX,
+ DEFAULT_MAX_SIZE_BUFFERS,
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::uint(
+ "max-size-bytes",
+ "Max Size Bytes",
+ "Maximum number of bytes to queue (0=unlimited)",
+ 0,
+ u32::MAX,
+ DEFAULT_MAX_SIZE_BYTES,
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::uint64(
+ "max-size-time",
+ "Max Size Time",
+ "Maximum number of nanoseconds to queue (0=unlimited)",
+ 0,
+ u64::MAX - 1,
+ DEFAULT_MAX_SIZE_TIME,
+ glib::ParamFlags::READWRITE,
+ ),
+ ]
+ });
+
+ PROPERTIES.as_ref()
+ }
+ fn set_property(
+ &self,
+ _obj: &Self::Type,
+ _id: usize,
+ value: &glib::Value,
+ pspec: &glib::ParamSpec,
+ ) {
let mut settings = self.settings.lock().unwrap();
- match *prop {
- subclass::Property("max-size-buffers", ..) => {
+ match pspec.get_name() {
+ "max-size-buffers" => {
settings.max_size_buffers = value.get_some().expect("type checked upstream");
}
- subclass::Property("max-size-bytes", ..) => {
+ "max-size-bytes" => {
settings.max_size_bytes = value.get_some().expect("type checked upstream");
}
- subclass::Property("max-size-time", ..) => {
+ "max-size-time" => {
settings.max_size_time = value.get_some().expect("type checked upstream");
}
- subclass::Property("context", ..) => {
+ "context" => {
settings.context = value
.get()
.expect("type checked upstream")
.unwrap_or_else(|| "".into());
}
- subclass::Property("context-wait", ..) => {
+ "context-wait" => {
settings.context_wait = value.get_some().expect("type checked upstream");
}
_ => unimplemented!(),
}
}
- fn get_property(&self, _obj: &Self::Type, id: usize) -> glib::Value {
- let prop = &PROPERTIES[id];
-
+ fn get_property(&self, _obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
let settings = self.settings.lock().unwrap();
- match *prop {
- subclass::Property("max-size-buffers", ..) => settings.max_size_buffers.to_value(),
- subclass::Property("max-size-bytes", ..) => settings.max_size_bytes.to_value(),
- subclass::Property("max-size-time", ..) => settings.max_size_time.to_value(),
- subclass::Property("context", ..) => settings.context.to_value(),
- subclass::Property("context-wait", ..) => settings.context_wait.to_value(),
+ match pspec.get_name() {
+ "max-size-buffers" => settings.max_size_buffers.to_value(),
+ "max-size-bytes" => settings.max_size_bytes.to_value(),
+ "max-size-time" => settings.max_size_time.to_value(),
+ "context" => settings.context.to_value(),
+ "context-wait" => settings.context_wait.to_value(),
_ => unimplemented!(),
}
}
@@ -858,6 +826,45 @@ impl ObjectImpl for Queue {
}
impl ElementImpl for Queue {
+ fn metadata() -> Option<&'static gst::subclass::ElementMetadata> {
+ static ELEMENT_METADATA: Lazy<gst::subclass::ElementMetadata> = Lazy::new(|| {
+ gst::subclass::ElementMetadata::new(
+ "Thread-sharing queue",
+ "Generic",
+ "Simple data queue",
+ "Sebastian Dröge <sebastian@centricular.com>",
+ )
+ });
+
+ Some(&*ELEMENT_METADATA)
+ }
+
+ fn pad_templates() -> &'static [gst::PadTemplate] {
+ static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| {
+ let caps = gst::Caps::new_any();
+
+ let sink_pad_template = gst::PadTemplate::new(
+ "sink",
+ gst::PadDirection::Sink,
+ gst::PadPresence::Always,
+ &caps,
+ )
+ .unwrap();
+
+ let src_pad_template = gst::PadTemplate::new(
+ "src",
+ gst::PadDirection::Src,
+ gst::PadPresence::Always,
+ &caps,
+ )
+ .unwrap();
+
+ vec![sink_pad_template, src_pad_template]
+ });
+
+ PAD_TEMPLATES.as_ref()
+ }
+
fn change_state(
&self,
element: &Self::Type,
diff --git a/generic/threadshare/src/tcpclientsrc/imp.rs b/generic/threadshare/src/tcpclientsrc/imp.rs
index afd23423b..4b584b07e 100644
--- a/generic/threadshare/src/tcpclientsrc/imp.rs
+++ b/generic/threadshare/src/tcpclientsrc/imp.rs
@@ -75,69 +75,6 @@ impl Default for Settings {
}
}
-static PROPERTIES: [subclass::Property; 6] = [
- subclass::Property("host", |name| {
- glib::ParamSpec::string(
- name,
- "Host",
- "The host IP address to receive packets from",
- DEFAULT_HOST,
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("port", |name| {
- glib::ParamSpec::int(
- name,
- "Port",
- "Port to receive packets from",
- 0,
- u16::MAX as i32,
- DEFAULT_PORT,
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("caps", |name| {
- glib::ParamSpec::boxed(
- name,
- "Caps",
- "Caps to use",
- gst::Caps::static_type(),
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("blocksize", |name| {
- glib::ParamSpec::uint(
- name,
- "Blocksize",
- "Size in bytes to read per buffer (-1 = default)",
- 0,
- u32::MAX,
- DEFAULT_BLOCKSIZE,
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("context", |name| {
- glib::ParamSpec::string(
- name,
- "Context",
- "Context name to share threads with",
- Some(DEFAULT_CONTEXT),
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("context-wait", |name| {
- glib::ParamSpec::uint(
- name,
- "Context Wait",
- "Throttle poll loop to run at most once every this many ms",
- 0,
- 1000,
- DEFAULT_CONTEXT_WAIT,
- glib::ParamFlags::READWRITE,
- )
- }),
-];
-
struct TcpClientReader(tokio::net::TcpStream);
impl TcpClientReader {
@@ -612,32 +549,12 @@ impl ObjectSubclass for TcpClientSrc {
const NAME: &'static str = "RsTsTcpClientSrc";
type Type = super::TcpClientSrc;
type ParentType = gst::Element;
+ type Interfaces = ();
type Instance = gst::subclass::ElementInstanceStruct<Self>;
type Class = subclass::simple::ClassStruct<Self>;
glib::object_subclass!();
- fn class_init(klass: &mut Self::Class) {
- klass.set_metadata(
- "Thread-sharing TCP client source",
- "Source/Network",
- "Receives data over the network via TCP",
- "Sebastian Dröge <sebastian@centricular.com>, LEE Dongjun <redongjun@gmail.com>",
- );
-
- let caps = gst::Caps::new_any();
- let src_pad_template = gst::PadTemplate::new(
- "src",
- gst::PadDirection::Src,
- gst::PadPresence::Always,
- &caps,
- )
- .unwrap();
- klass.add_pad_template(src_pad_template);
-
- klass.install_properties(&PROPERTIES);
- }
-
fn with_class(klass: &Self::Class) -> Self {
let src_pad_handler = TcpClientSrcPadHandler::default();
@@ -654,47 +571,106 @@ impl ObjectSubclass for TcpClientSrc {
}
impl ObjectImpl for TcpClientSrc {
- fn set_property(&self, _obj: &Self::Type, id: usize, value: &glib::Value) {
- let prop = &PROPERTIES[id];
+ fn properties() -> &'static [glib::ParamSpec] {
+ static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
+ vec![
+ glib::ParamSpec::string(
+ "context",
+ "Context",
+ "Context name to share threads with",
+ Some(DEFAULT_CONTEXT),
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::uint(
+ "context-wait",
+ "Context Wait",
+ "Throttle poll loop to run at most once every this many ms",
+ 0,
+ 1000,
+ DEFAULT_CONTEXT_WAIT,
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::string(
+ "host",
+ "Host",
+ "The host IP address to receive packets from",
+ DEFAULT_HOST,
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::int(
+ "port",
+ "Port",
+ "Port to receive packets from",
+ 0,
+ u16::MAX as i32,
+ DEFAULT_PORT,
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::boxed(
+ "caps",
+ "Caps",
+ "Caps to use",
+ gst::Caps::static_type(),
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::uint(
+ "blocksize",
+ "Blocksize",
+ "Size in bytes to read per buffer (-1 = default)",
+ 0,
+ u32::MAX,
+ DEFAULT_BLOCKSIZE,
+ glib::ParamFlags::READWRITE,
+ ),
+ ]
+ });
+
+ PROPERTIES.as_ref()
+ }
+ fn set_property(
+ &self,
+ _obj: &Self::Type,
+ _id: usize,
+ value: &glib::Value,
+ pspec: &glib::ParamSpec,
+ ) {
let mut settings = self.settings.lock().unwrap();
- match *prop {
- subclass::Property("host", ..) => {
+ match pspec.get_name() {
+ "host" => {
settings.host = value.get().expect("type checked upstream");
}
- subclass::Property("port", ..) => {
+ "port" => {
settings.port = value.get_some().expect("type checked upstream");
}
- subclass::Property("caps", ..) => {
+ "caps" => {
settings.caps = value.get().expect("type checked upstream");
}
- subclass::Property("blocksize", ..) => {
+ "blocksize" => {
settings.blocksize = value.get_some().expect("type checked upstream");
}
- subclass::Property("context", ..) => {
+ "context" => {
settings.context = value
.get()
.expect("type checked upstream")
.unwrap_or_else(|| "".into());
}
- subclass::Property("context-wait", ..) => {
+ "context-wait" => {
settings.context_wait = value.get_some().expect("type checked upstream");
}
_ => unimplemented!(),
}
}
- fn get_property(&self, _obj: &Self::Type, id: usize) -> glib::Value {
- let prop = &PROPERTIES[id];
-
+ fn get_property(&self, _obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
let settings = self.settings.lock().unwrap();
- match *prop {
- subclass::Property("host", ..) => settings.host.to_value(),
- subclass::Property("port", ..) => settings.port.to_value(),
- subclass::Property("caps", ..) => settings.caps.to_value(),
- subclass::Property("blocksize", ..) => settings.blocksize.to_value(),
- subclass::Property("context", ..) => settings.context.to_value(),
- subclass::Property("context-wait", ..) => settings.context_wait.to_value(),
+ match pspec.get_name() {
+ "host" => settings.host.to_value(),
+ "port" => settings.port.to_value(),
+ "caps" => settings.caps.to_value(),
+ "blocksize" => settings.blocksize.to_value(),
+ "context" => settings.context.to_value(),
+ "context-wait" => settings.context_wait.to_value(),
_ => unimplemented!(),
}
}
@@ -709,6 +685,36 @@ impl ObjectImpl for TcpClientSrc {
}
impl ElementImpl for TcpClientSrc {
+ fn metadata() -> Option<&'static gst::subclass::ElementMetadata> {
+ static ELEMENT_METADATA: Lazy<gst::subclass::ElementMetadata> = Lazy::new(|| {
+ gst::subclass::ElementMetadata::new(
+ "Thread-sharing TCP client source",
+ "Source/Network",
+ "Receives data over the network via TCP",
+ "Sebastian Dröge <sebastian@centricular.com>, LEE Dongjun <redongjun@gmail.com>",
+ )
+ });
+
+ Some(&*ELEMENT_METADATA)
+ }
+
+ fn pad_templates() -> &'static [gst::PadTemplate] {
+ static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| {
+ let caps = gst::Caps::new_any();
+ let src_pad_template = gst::PadTemplate::new(
+ "src",
+ gst::PadDirection::Src,
+ gst::PadPresence::Always,
+ &caps,
+ )
+ .unwrap();
+
+ vec![src_pad_template]
+ });
+
+ PAD_TEMPLATES.as_ref()
+ }
+
fn change_state(
&self,
element: &Self::Type,
diff --git a/generic/threadshare/src/udpsink/imp.rs b/generic/threadshare/src/udpsink/imp.rs
index bd991bbc1..8b44588c1 100644
--- a/generic/threadshare/src/udpsink/imp.rs
+++ b/generic/threadshare/src/udpsink/imp.rs
@@ -118,174 +118,6 @@ static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
)
});
-static PROPERTIES: [subclass::Property; 17] = [
- subclass::Property("sync", |name| {
- glib::ParamSpec::boolean(
- name,
- "Sync",
- "Sync on the clock",
- DEFAULT_SYNC,
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("bind-address", |name| {
- glib::ParamSpec::string(
- name,
- "Bind Address",
- "Address to bind the socket to",
- Some(DEFAULT_BIND_ADDRESS),
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("bind-port", |name| {
- glib::ParamSpec::int(
- name,
- "Bind Port",
- "Port to bind the socket to",
- 0,
- u16::MAX as i32,
- DEFAULT_BIND_PORT,
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("bind-address-v6", |name| {
- glib::ParamSpec::string(
- name,
- "Bind Address V6",
- "Address to bind the V6 socket to",
- Some(DEFAULT_BIND_ADDRESS_V6),
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("bind-port-v6", |name| {
- glib::ParamSpec::int(
- name,
- "Bind Port",
- "Port to bind the V6 socket to",
- 0,
- u16::MAX as i32,
- DEFAULT_BIND_PORT_V6,
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("socket", |name| {
- glib::ParamSpec::object(
- name,
- "Socket",
- "Socket to use for UDP transmission. (None == allocate)",
- gio::Socket::static_type(),
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("used-socket", |name| {
- glib::ParamSpec::object(
- name,
- "Used Socket",
- "Socket currently in use for UDP transmission. (None = no socket)",
- gio::Socket::static_type(),
- glib::ParamFlags::READABLE,
- )
- }),
- subclass::Property("socket-v6", |name| {
- glib::ParamSpec::object(
- name,
- "Socket V6",
- "IPV6 Socket to use for UDP transmission. (None == allocate)",
- gio::Socket::static_type(),
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("used-socket-v6", |name| {
- glib::ParamSpec::object(
- name,
- "Used Socket V6",
- "V6 Socket currently in use for UDP transmission. (None = no socket)",
- gio::Socket::static_type(),
- glib::ParamFlags::READABLE,
- )
- }),
- subclass::Property("auto-multicast", |name| {
- glib::ParamSpec::boolean(
- name,
- "Auto multicast",
- "Automatically join/leave the multicast groups, FALSE means user has to do it himself",
- DEFAULT_AUTO_MULTICAST,
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("loop", |name| {
- glib::ParamSpec::boolean(
- name,
- "Loop",
- "Set the multicast loop parameter.",
- DEFAULT_LOOP,
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("ttl", |name| {
- glib::ParamSpec::uint(
- name,
- "Time To Live",
- "Used for setting the unicast TTL parameter",
- 0,
- u8::MAX as u32,
- DEFAULT_TTL,
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("ttl-mc", |name| {
- glib::ParamSpec::uint(
- name,
- "Time To Live Multicast",
- "Used for setting the multicast TTL parameter",
- 0,
- u8::MAX as u32,
- DEFAULT_TTL_MC,
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("qos-dscp", |name| {
- glib::ParamSpec::int(
- name,
- "QoS DSCP",
- "Quality of Service, differentiated services code point (-1 default)",
- -1,
- 63,
- DEFAULT_QOS_DSCP,
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("clients", |name| {
- glib::ParamSpec::string(
- name,
- "Clients",
- "A comma separated list of host:port pairs with destinations",
- Some(DEFAULT_CLIENTS),
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("context", |name| {
- glib::ParamSpec::string(
- name,
- "Context",
- "Context name to share threads with",
- Some(DEFAULT_CONTEXT),
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("context-wait", |name| {
- glib::ParamSpec::uint(
- name,
- "Context Wait",
- "Throttle poll loop to run at most once every this many ms",
- 0,
- 1000,
- DEFAULT_CONTEXT_WAIT,
- glib::ParamFlags::READWRITE,
- )
- }),
-];
-
#[derive(Debug)]
enum TaskItem {
Buffer(gst::Buffer),
@@ -1127,107 +959,12 @@ impl ObjectSubclass for UdpSink {
const NAME: &'static str = "RsTsUdpSink";
type Type = super::UdpSink;
type ParentType = gst::Element;
+ type Interfaces = ();
type Instance = gst::subclass::ElementInstanceStruct<Self>;
type Class = subclass::simple::ClassStruct<Self>;
glib::object_subclass!();
- fn class_init(klass: &mut Self::Class) {
- klass.set_metadata(
- "Thread-sharing UDP sink",
- "Sink/Network",
- "Thread-sharing UDP sink",
- "Mathieu <mathieu@centricular.com>",
- );
-
- let caps = gst::Caps::new_any();
-
- let sink_pad_template = gst::PadTemplate::new(
- "sink",
- gst::PadDirection::Sink,
- gst::PadPresence::Always,
- &caps,
- )
- .unwrap();
- klass.add_pad_template(sink_pad_template);
- klass.add_signal_with_class_handler(
- "add",
- glib::SignalFlags::RUN_LAST | glib::SignalFlags::ACTION,
- &[String::static_type(), i32::static_type()],
- glib::types::Type::Unit,
- |_, args| {
- let element = args[0]
- .get::<super::UdpSink>()
- .expect("signal arg")
- .expect("missing signal arg");
- let host = args[1]
- .get::<String>()
- .expect("signal arg")
- .expect("missing signal arg");
- let port = args[2]
- .get::<i32>()
- .expect("signal arg")
- .expect("missing signal arg");
-
- if let Ok(addr) = try_into_socket_addr(&element, &host, port) {
- let udpsink = Self::from_instance(&element);
- udpsink.add_client(addr);
- }
-
- None
- },
- );
-
- klass.add_signal_with_class_handler(
- "remove",
- glib::SignalFlags::RUN_LAST | glib::SignalFlags::ACTION,
- &[String::static_type(), i32::static_type()],
- glib::types::Type::Unit,
- |_, args| {
- let element = args[0]
- .get::<super::UdpSink>()
- .expect("signal arg")
- .expect("missing signal arg");
- let host = args[1]
- .get::<String>()
- .expect("signal arg")
- .expect("missing signal arg");
- let port = args[2]
- .get::<i32>()
- .expect("signal arg")
- .expect("missing signal arg");
-
- let udpsink = Self::from_instance(&element);
-
- if let Ok(addr) = try_into_socket_addr(&element, &host, port) {
- udpsink.remove_client(addr);
- }
-
- None
- },
- );
-
- klass.add_signal_with_class_handler(
- "clear",
- glib::SignalFlags::RUN_LAST | glib::SignalFlags::ACTION,
- &[],
- glib::types::Type::Unit,
- |_, args| {
- let element = args[0]
- .get::<super::UdpSink>()
- .expect("signal arg")
- .expect("missing signal arg");
-
- let udpsink = Self::from_instance(&element);
- udpsink.clear_clients(std::iter::empty());
-
- None
- },
- );
-
- klass.install_properties(&PROPERTIES);
- }
-
fn with_class(klass: &Self::Class) -> Self {
let settings = Arc::new(StdMutex::new(Settings::default()));
let sink_pad_handler = UdpSinkPadHandler::new(Arc::clone(&settings));
@@ -1245,66 +982,289 @@ impl ObjectSubclass for UdpSink {
}
impl ObjectImpl for UdpSink {
- fn set_property(&self, obj: &Self::Type, id: usize, value: &glib::Value) {
- let prop = &PROPERTIES[id];
+ fn properties() -> &'static [glib::ParamSpec] {
+ static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
+ vec![
+ glib::ParamSpec::string(
+ "context",
+ "Context",
+ "Context name to share threads with",
+ Some(DEFAULT_CONTEXT),
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::uint(
+ "context-wait",
+ "Context Wait",
+ "Throttle poll loop to run at most once every this many ms",
+ 0,
+ 1000,
+ DEFAULT_CONTEXT_WAIT,
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::boolean(
+ "sync",
+ "Sync",
+ "Sync on the clock",
+ DEFAULT_SYNC,
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::string(
+ "bind-address",
+ "Bind Address",
+ "Address to bind the socket to",
+ Some(DEFAULT_BIND_ADDRESS),
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::int(
+ "bind-port",
+ "Bind Port",
+ "Port to bind the socket to",
+ 0,
+ u16::MAX as i32,
+ DEFAULT_BIND_PORT,
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::string(
+ "bind-address-v6",
+ "Bind Address V6",
+ "Address to bind the V6 socket to",
+ Some(DEFAULT_BIND_ADDRESS_V6),
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::int(
+ "bind-port-v6",
+ "Bind Port",
+ "Port to bind the V6 socket to",
+ 0,
+ u16::MAX as i32,
+ DEFAULT_BIND_PORT_V6,
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::object(
+ "socket",
+ "Socket",
+ "Socket to use for UDP transmission. (None == allocate)",
+ gio::Socket::static_type(),
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::object(
+ "used-socket",
+ "Used Socket",
+ "Socket currently in use for UDP transmission. (None = no socket)",
+ gio::Socket::static_type(),
+ glib::ParamFlags::READABLE,
+ ),
+ glib::ParamSpec::object(
+ "socket-v6",
+ "Socket V6",
+ "IPV6 Socket to use for UDP transmission. (None == allocate)",
+ gio::Socket::static_type(),
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::object(
+ "used-socket-v6",
+ "Used Socket V6",
+ "V6 Socket currently in use for UDP transmission. (None = no socket)",
+ gio::Socket::static_type(),
+ glib::ParamFlags::READABLE,
+ ),
+ glib::ParamSpec::boolean(
+ "auto-multicast",
+ "Auto multicast",
+ "Automatically join/leave the multicast groups, FALSE means user has to do it himself",
+ DEFAULT_AUTO_MULTICAST,
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::boolean(
+ "loop",
+ "Loop",
+ "Set the multicast loop parameter.",
+ DEFAULT_LOOP,
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::uint(
+ "ttl",
+ "Time To Live",
+ "Used for setting the unicast TTL parameter",
+ 0,
+ u8::MAX as u32,
+ DEFAULT_TTL,
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::uint(
+ "ttl-mc",
+ "Time To Live Multicast",
+ "Used for setting the multicast TTL parameter",
+ 0,
+ u8::MAX as u32,
+ DEFAULT_TTL_MC,
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::int(
+ "qos-dscp",
+ "QoS DSCP",
+ "Quality of Service, differentiated services code point (-1 default)",
+ -1,
+ 63,
+ DEFAULT_QOS_DSCP,
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::string(
+ "clients",
+ "Clients",
+ "A comma separated list of host:port pairs with destinations",
+ Some(DEFAULT_CLIENTS),
+ glib::ParamFlags::READWRITE,
+ ),
+ ]
+ });
+
+ PROPERTIES.as_ref()
+ }
+
+ fn signals() -> &'static [glib::subclass::Signal] {
+ static SIGNALS: Lazy<Vec<glib::subclass::Signal>> = Lazy::new(|| {
+ vec![
+ glib::subclass::Signal::builder(
+ "add",
+ &[String::static_type(), i32::static_type()],
+ glib::types::Type::Unit,
+ )
+ .action()
+ .class_handler(|_, args| {
+ let element = args[0]
+ .get::<super::UdpSink>()
+ .expect("signal arg")
+ .expect("missing signal arg");
+ let host = args[1]
+ .get::<String>()
+ .expect("signal arg")
+ .expect("missing signal arg");
+ let port = args[2]
+ .get::<i32>()
+ .expect("signal arg")
+ .expect("missing signal arg");
+
+ if let Ok(addr) = try_into_socket_addr(&element, &host, port) {
+ let udpsink = UdpSink::from_instance(&element);
+ udpsink.add_client(addr);
+ }
+
+ None
+ })
+ .build(),
+ glib::subclass::Signal::builder(
+ "remove",
+ &[String::static_type(), i32::static_type()],
+ glib::types::Type::Unit,
+ )
+ .action()
+ .class_handler(|_, args| {
+ let element = args[0]
+ .get::<super::UdpSink>()
+ .expect("signal arg")
+ .expect("missing signal arg");
+ let host = args[1]
+ .get::<String>()
+ .expect("signal arg")
+ .expect("missing signal arg");
+ let port = args[2]
+ .get::<i32>()
+ .expect("signal arg")
+ .expect("missing signal arg");
+
+ if let Ok(addr) = try_into_socket_addr(&element, &host, port) {
+ let udpsink = UdpSink::from_instance(&element);
+ udpsink.remove_client(addr);
+ }
+
+ None
+ })
+ .build(),
+ glib::subclass::Signal::builder("clear", &[], glib::types::Type::Unit)
+ .action()
+ .class_handler(|_, args| {
+ let element = args[0]
+ .get::<super::UdpSink>()
+ .expect("signal arg")
+ .expect("missing signal arg");
+
+ let udpsink = UdpSink::from_instance(&element);
+ udpsink.clear_clients(std::iter::empty());
+
+ None
+ })
+ .build(),
+ ]
+ });
+ SIGNALS.as_ref()
+ }
+
+ fn set_property(
+ &self,
+ obj: &Self::Type,
+ _id: usize,
+ value: &glib::Value,
+ pspec: &glib::ParamSpec,
+ ) {
let mut settings = self.settings.lock().unwrap();
- match *prop {
- subclass::Property("sync", ..) => {
+ match pspec.get_name() {
+ "sync" => {
settings.sync = value.get_some().expect("type checked upstream");
}
- subclass::Property("bind-address", ..) => {
+ "bind-address" => {
settings.bind_address = value
.get()
.expect("type checked upstream")
.unwrap_or_else(|| "".into());
}
- subclass::Property("bind-port", ..) => {
+ "bind-port" => {
settings.bind_port = value.get_some().expect("type checked upstream");
}
- subclass::Property("bind-address-v6", ..) => {
+ "bind-address-v6" => {
settings.bind_address_v6 = value
.get()
.expect("type checked upstream")
.unwrap_or_else(|| "".into());
}
- subclass::Property("bind-port-v6", ..) => {
+ "bind-port-v6" => {
settings.bind_port_v6 = value.get_some().expect("type checked upstream");
}
- subclass::Property("socket", ..) => {
+ "socket" => {
settings.socket = value
.get::<gio::Socket>()
.expect("type checked upstream")
.map(|socket| GioSocketWrapper::new(&socket));
}
- subclass::Property("used-socket", ..) => {
+ "used-socket" => {
unreachable!();
}
- subclass::Property("socket-v6", ..) => {
+ "socket-v6" => {
settings.socket_v6 = value
.get::<gio::Socket>()
.expect("type checked upstream")
.map(|socket| GioSocketWrapper::new(&socket));
}
- subclass::Property("used-socket-v6", ..) => {
+ "used-socket-v6" => {
unreachable!();
}
- subclass::Property("auto-multicast", ..) => {
+ "auto-multicast" => {
settings.auto_multicast = value.get_some().expect("type checked upstream");
}
- subclass::Property("loop", ..) => {
+ "loop" => {
settings.multicast_loop = value.get_some().expect("type checked upstream");
}
- subclass::Property("ttl", ..) => {
+ "ttl" => {
settings.ttl = value.get_some().expect("type checked upstream");
}
- subclass::Property("ttl-mc", ..) => {
+ "ttl-mc" => {
settings.ttl_mc = value.get_some().expect("type checked upstream");
}
- subclass::Property("qos-dscp", ..) => {
+ "qos-dscp" => {
settings.qos_dscp = value.get_some().expect("type checked upstream");
}
- subclass::Property("clients", ..) => {
+ "clients" => {
let clients: String = value
.get()
.expect("type checked upstream")
@@ -1329,55 +1289,53 @@ impl ObjectImpl for UdpSink {
self.clear_clients(clients_iter);
}
- subclass::Property("context", ..) => {
+ "context" => {
settings.context = value
.get()
.expect("type checked upstream")
.unwrap_or_else(|| "".into());
}
- subclass::Property("context-wait", ..) => {
+ "context-wait" => {
settings.context_wait = value.get_some().expect("type checked upstream");
}
_ => unimplemented!(),
}
}
- fn get_property(&self, _obj: &Self::Type, id: usize) -> glib::Value {
- let prop = &PROPERTIES[id];
-
+ fn get_property(&self, _obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
let settings = self.settings.lock().unwrap();
- match *prop {
- subclass::Property("sync", ..) => settings.sync.to_value(),
- subclass::Property("bind-address", ..) => settings.bind_address.to_value(),
- subclass::Property("bind-port", ..) => settings.bind_port.to_value(),
- subclass::Property("bind-address-v6", ..) => settings.bind_address_v6.to_value(),
- subclass::Property("bind-port-v6", ..) => settings.bind_port_v6.to_value(),
- subclass::Property("socket", ..) => settings
+ match pspec.get_name() {
+ "sync" => settings.sync.to_value(),
+ "bind-address" => settings.bind_address.to_value(),
+ "bind-port" => settings.bind_port.to_value(),
+ "bind-address-v6" => settings.bind_address_v6.to_value(),
+ "bind-port-v6" => settings.bind_port_v6.to_value(),
+ "socket" => settings
.socket
.as_ref()
.map(GioSocketWrapper::as_socket)
.to_value(),
- subclass::Property("used-socket", ..) => settings
+ "used-socket" => settings
.used_socket
.as_ref()
.map(GioSocketWrapper::as_socket)
.to_value(),
- subclass::Property("socket-v6", ..) => settings
+ "socket-v6" => settings
.socket_v6
.as_ref()
.map(GioSocketWrapper::as_socket)
.to_value(),
- subclass::Property("used-socket-v6", ..) => settings
+ "used-socket-v6" => settings
.used_socket_v6
.as_ref()
.map(GioSocketWrapper::as_socket)
.to_value(),
- subclass::Property("auto-multicast", ..) => settings.sync.to_value(),
- subclass::Property("loop", ..) => settings.multicast_loop.to_value(),
- subclass::Property("ttl", ..) => settings.ttl.to_value(),
- subclass::Property("ttl-mc", ..) => settings.ttl_mc.to_value(),
- subclass::Property("qos-dscp", ..) => settings.qos_dscp.to_value(),
- subclass::Property("clients", ..) => {
+ "auto-multicast" => settings.sync.to_value(),
+ "loop" => settings.multicast_loop.to_value(),
+ "ttl" => settings.ttl.to_value(),
+ "ttl-mc" => settings.ttl_mc.to_value(),
+ "qos-dscp" => settings.qos_dscp.to_value(),
+ "clients" => {
drop(settings);
let clients: Vec<String> = self
@@ -1389,8 +1347,8 @@ impl ObjectImpl for UdpSink {
clients.join(",").to_value()
}
- subclass::Property("context", ..) => settings.context.to_value(),
- subclass::Property("context-wait", ..) => settings.context_wait.to_value(),
+ "context" => settings.context.to_value(),
+ "context-wait" => settings.context_wait.to_value(),
_ => unimplemented!(),
}
}
@@ -1405,6 +1363,37 @@ impl ObjectImpl for UdpSink {
}
impl ElementImpl for UdpSink {
+ fn metadata() -> Option<&'static gst::subclass::ElementMetadata> {
+ static ELEMENT_METADATA: Lazy<gst::subclass::ElementMetadata> = Lazy::new(|| {
+ gst::subclass::ElementMetadata::new(
+ "Thread-sharing UDP sink",
+ "Sink/Network",
+ "Thread-sharing UDP sink",
+ "Mathieu <mathieu@centricular.com>",
+ )
+ });
+
+ Some(&*ELEMENT_METADATA)
+ }
+
+ fn pad_templates() -> &'static [gst::PadTemplate] {
+ static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| {
+ let caps = gst::Caps::new_any();
+
+ let sink_pad_template = gst::PadTemplate::new(
+ "sink",
+ gst::PadDirection::Sink,
+ gst::PadPresence::Always,
+ &caps,
+ )
+ .unwrap();
+
+ vec![sink_pad_template]
+ });
+
+ PAD_TEMPLATES.as_ref()
+ }
+
fn change_state(
&self,
element: &Self::Type,
diff --git a/generic/threadshare/src/udpsrc/imp.rs b/generic/threadshare/src/udpsrc/imp.rs
index 1d42561c9..b8d92e143 100644
--- a/generic/threadshare/src/udpsrc/imp.rs
+++ b/generic/threadshare/src/udpsrc/imp.rs
@@ -84,105 +84,6 @@ impl Default for Settings {
}
}
-static PROPERTIES: [subclass::Property; 10] = [
- subclass::Property("address", |name| {
- glib::ParamSpec::string(
- name,
- "Address",
- "Address/multicast group to listen on",
- DEFAULT_ADDRESS,
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("port", |name| {
- glib::ParamSpec::int(
- name,
- "Port",
- "Port to listen on",
- 0,
- u16::MAX as i32,
- DEFAULT_PORT,
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("reuse", |name| {
- glib::ParamSpec::boolean(
- name,
- "Reuse",
- "Allow reuse of the port",
- DEFAULT_REUSE,
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("caps", |name| {
- glib::ParamSpec::boxed(
- name,
- "Caps",
- "Caps to use",
- gst::Caps::static_type(),
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("mtu", |name| {
- glib::ParamSpec::uint(
- name,
- "MTU",
- "Maximum expected packet size. This directly defines the allocation size of the receive buffer pool",
- 0,
- i32::MAX as u32,
- DEFAULT_MTU,
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("socket", |name| {
- glib::ParamSpec::object(
- name,
- "Socket",
- "Socket to use for UDP reception. (None == allocate)",
- gio::Socket::static_type(),
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("used-socket", |name| {
- glib::ParamSpec::object(
- name,
- "Used Socket",
- "Socket currently in use for UDP reception. (None = no socket)",
- gio::Socket::static_type(),
- glib::ParamFlags::READABLE,
- )
- }),
- subclass::Property("context", |name| {
- glib::ParamSpec::string(
- name,
- "Context",
- "Context name to share threads with",
- Some(DEFAULT_CONTEXT),
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("context-wait", |name| {
- glib::ParamSpec::uint(
- name,
- "Context Wait",
- "Throttle poll loop to run at most once every this many ms",
- 0,
- 1000,
- DEFAULT_CONTEXT_WAIT,
- glib::ParamFlags::READWRITE,
- )
- }),
- subclass::Property("retrieve-sender-address", |name| {
- glib::ParamSpec::boolean(
- name,
- "Retrieve sender address",
- "Whether to retrieve the sender address and add it to buffers as meta. Disabling this might result in minor performance improvements in certain scenarios",
- DEFAULT_RETRIEVE_SENDER_ADDRESS,
- glib::ParamFlags::READWRITE,
- )
- }),
-];
-
#[derive(Debug)]
struct UdpReader(tokio::net::UdpSocket);
@@ -789,48 +690,12 @@ impl ObjectSubclass for UdpSrc {
const NAME: &'static str = "RsTsUdpSrc";
type Type = super::UdpSrc;
type ParentType = gst::Element;
+ type Interfaces = ();
type Instance = gst::subclass::ElementInstanceStruct<Self>;
type Class = subclass::simple::ClassStruct<Self>;
glib::object_subclass!();
- fn class_init(klass: &mut Self::Class) {
- klass.set_metadata(
- "Thread-sharing UDP source",
- "Source/Network",
- "Receives data over the network via UDP",
- "Sebastian Dröge <sebastian@centricular.com>",
- );
-
- let caps = gst::Caps::new_any();
- let src_pad_template = gst::PadTemplate::new(
- "src",
- gst::PadDirection::Src,
- gst::PadPresence::Always,
- &caps,
- )
- .unwrap();
- klass.add_pad_template(src_pad_template);
-
- #[cfg(not(windows))]
- {
- klass.install_properties(&PROPERTIES);
- }
- #[cfg(windows)]
- {
- let properties = PROPERTIES
- .iter()
- .filter(|p| match *p {
- subclass::Property("socket", ..) | subclass::Property("used-socket", ..) => {
- false
- }
- _ => true,
- })
- .collect::<Vec<_>>();
- klass.install_properties(properties.as_slice());
- }
- }
-
fn with_class(klass: &Self::Class) -> Self {
let src_pad_handler = UdpSrcPadHandler::default();
@@ -847,76 +712,167 @@ impl ObjectSubclass for UdpSrc {
}
impl ObjectImpl for UdpSrc {
- fn set_property(&self, _obj: &Self::Type, id: usize, value: &glib::Value) {
- let prop = &PROPERTIES[id];
+ fn properties() -> &'static [glib::ParamSpec] {
+ static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
+ let mut properties = vec![
+ glib::ParamSpec::string(
+ "context",
+ "Context",
+ "Context name to share threads with",
+ Some(DEFAULT_CONTEXT),
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::uint(
+ "context-wait",
+ "Context Wait",
+ "Throttle poll loop to run at most once every this many ms",
+ 0,
+ 1000,
+ DEFAULT_CONTEXT_WAIT,
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::string(
+ "address",
+ "Address",
+ "Address/multicast group to listen on",
+ DEFAULT_ADDRESS,
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::int(
+ "port",
+ "Port",
+ "Port to listen on",
+ 0,
+ u16::MAX as i32,
+ DEFAULT_PORT,
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::boolean(
+ "reuse",
+ "Reuse",
+ "Allow reuse of the port",
+ DEFAULT_REUSE,
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::boxed(
+ "caps",
+ "Caps",
+ "Caps to use",
+ gst::Caps::static_type(),
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::uint(
+ "mtu",
+ "MTU",
+ "Maximum expected packet size. This directly defines the allocation size of the receive buffer pool",
+ 0,
+ i32::MAX as u32,
+ DEFAULT_MTU,
+ glib::ParamFlags::READWRITE,
+ ),
+ glib::ParamSpec::boolean(
+ "retrieve-sender-address",
+ "Retrieve sender address",
+ "Whether to retrieve the sender address and add it to buffers as meta. Disabling this might result in minor performance improvements in certain scenarios",
+ DEFAULT_RETRIEVE_SENDER_ADDRESS,
+ glib::ParamFlags::READWRITE,
+ ),
+ ];
+
+ #[cfg(not(windows))]
+ {
+ properties.push(glib::ParamSpec::object(
+ "socket",
+ "Socket",
+ "Socket to use for UDP reception. (None == allocate)",
+ gio::Socket::static_type(),
+ glib::ParamFlags::READWRITE,
+ ));
+ properties.push(glib::ParamSpec::object(
+ "used-socket",
+ "Used Socket",
+ "Socket currently in use for UDP reception. (None = no socket)",
+ gio::Socket::static_type(),
+ glib::ParamFlags::READABLE,
+ ));
+ }
+ properties
+ });
+
+ PROPERTIES.as_ref()
+ }
+
+ fn set_property(
+ &self,
+ _obj: &Self::Type,
+ _id: usize,
+ value: &glib::Value,
+ pspec: &glib::ParamSpec,
+ ) {
let mut settings = self.settings.lock().unwrap();
- match *prop {
- subclass::Property("address", ..) => {
+ match pspec.get_name() {
+ "address" => {
settings.address = value.get().expect("type checked upstream");
}
- subclass::Property("port", ..) => {
+ "port" => {
settings.port = value.get_some().expect("type checked upstream");
}
- subclass::Property("reuse", ..) => {
+ "reuse" => {
settings.reuse = value.get_some().expect("type checked upstream");
}
- subclass::Property("caps", ..) => {
+ "caps" => {
settings.caps = value.get().expect("type checked upstream");
}
- subclass::Property("mtu", ..) => {
+ "mtu" => {
settings.mtu = value.get_some().expect("type checked upstream");
}
- subclass::Property("socket", ..) => {
+ "socket" => {
settings.socket = value
.get::<gio::Socket>()
.expect("type checked upstream")
.map(|socket| GioSocketWrapper::new(&socket));
}
- subclass::Property("used-socket", ..) => {
+ "used-socket" => {
unreachable!();
}
- subclass::Property("context", ..) => {
+ "context" => {
settings.context = value
.get()
.expect("type checked upstream")
.unwrap_or_else(|| "".into());
}
- subclass::Property("context-wait", ..) => {
+ "context-wait" => {
settings.context_wait = value.get_some().expect("type checked upstream");
}
- subclass::Property("retrieve-sender-address", ..) => {
+ "retrieve-sender-address" => {
settings.retrieve_sender_address = value.get_some().expect("type checked upstream");
}
_ => unimplemented!(),
}
}
- fn get_property(&self, _obj: &Self::Type, id: usize) -> glib::Value {
- let prop = &PROPERTIES[id];
-
+ fn get_property(&self, _obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
let settings = self.settings.lock().unwrap();
- match *prop {
- subclass::Property("address", ..) => settings.address.to_value(),
- subclass::Property("port", ..) => settings.port.to_value(),
- subclass::Property("reuse", ..) => settings.reuse.to_value(),
- subclass::Property("caps", ..) => settings.caps.to_value(),
- subclass::Property("mtu", ..) => settings.mtu.to_value(),
- subclass::Property("socket", ..) => settings
+ match pspec.get_name() {
+ "address" => settings.address.to_value(),
+ "port" => settings.port.to_value(),
+ "reuse" => settings.reuse.to_value(),
+ "caps" => settings.caps.to_value(),
+ "mtu" => settings.mtu.to_value(),
+ "socket" => settings
.socket
.as_ref()
.map(GioSocketWrapper::as_socket)
.to_value(),
- subclass::Property("used-socket", ..) => settings
+ "used-socket" => settings
.used_socket
.as_ref()
.map(GioSocketWrapper::as_socket)
.to_value(),
- subclass::Property("context", ..) => settings.context.to_value(),
- subclass::Property("context-wait", ..) => settings.context_wait.to_value(),
- subclass::Property("retrieve-sender-address", ..) => {
- settings.retrieve_sender_address.to_value()
- }
+ "context" => settings.context.to_value(),
+ "context-wait" => settings.context_wait.to_value(),
+ "retrieve-sender-address" => settings.retrieve_sender_address.to_value(),
_ => unimplemented!(),
}
}
@@ -931,6 +887,36 @@ impl ObjectImpl for UdpSrc {
}
impl ElementImpl for UdpSrc {
+ fn metadata() -> Option<&'static gst::subclass::ElementMetadata> {
+ static ELEMENT_METADATA: Lazy<gst::subclass::ElementMetadata> = Lazy::new(|| {
+ gst::subclass::ElementMetadata::new(
+ "Thread-sharing UDP source",
+ "Source/Network",
+ "Receives data over the network via UDP",
+ "Sebastian Dröge <sebastian@centricular.com>",
+ )
+ });
+
+ Some(&*ELEMENT_METADATA)
+ }
+
+ fn pad_templates() -> &'static [gst::PadTemplate] {
+ static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| {
+ let caps = gst::Caps::new_any();
+ let src_pad_template = gst::PadTemplate::new(
+ "src",
+ gst::PadDirection::Src,
+ gst::PadPresence::Always,
+ &caps,
+ )
+ .unwrap();
+
+ vec![src_pad_template]
+ });
+
+ PAD_TEMPLATES.as_ref()
+ }
+
fn change_state(
&self,
element: &Self::Type,
diff --git a/generic/threadshare/tests/pad.rs b/generic/threadshare/tests/pad.rs
index ee8bc2457..e7d8bb960 100644
--- a/generic/threadshare/tests/pad.rs
+++ b/generic/threadshare/tests/pad.rs
@@ -69,17 +69,6 @@ struct ItemSender {
mod imp_src {
use super::*;
- static SRC_PROPERTIES: [glib::subclass::Property; 1] =
- [glib::subclass::Property("context", |name| {
- glib::ParamSpec::string(
- name,
- "Context",
- "Context name to share threads with",
- Some(DEFAULT_CONTEXT),
- glib::ParamFlags::READWRITE,
- )
- })];
-
#[derive(Clone, Debug, Default)]
struct Settings {
context: String,
@@ -316,32 +305,12 @@ mod imp_src {
const NAME: &'static str = "TsElementSrcTest";
type Type = super::ElementSrcTest;
type ParentType = gst::Element;
+ type Interfaces = ();
type Instance = gst::subclass::ElementInstanceStruct<Self>;
type Class = glib::subclass::simple::ClassStruct<Self>;
glib::object_subclass!();
- fn class_init(klass: &mut Self::Class) {
- klass.set_metadata(
- "Thread-sharing Test Src Element",
- "Generic",
- "Src Element for Pad Src Test",
- "François Laignel <fengalin@free.fr>",
- );
-
- let caps = gst::Caps::new_any();
- let src_pad_template = gst::PadTemplate::new(
- "src",
- gst::PadDirection::Src,
- gst::PadPresence::Always,
- &caps,
- )
- .unwrap();
- klass.add_pad_template(src_pad_template);
-
- klass.install_properties(&SRC_PROPERTIES);
- }
-
fn with_class(klass: &Self::Class) -> Self {
ElementSrcTest {
src_pad: PadSrc::new(
@@ -356,11 +325,29 @@ mod imp_src {
}
impl ObjectImpl for ElementSrcTest {
- fn set_property(&self, _obj: &Self::Type, id: usize, value: &glib::Value) {
- let prop = &SRC_PROPERTIES[id];
+ fn properties() -> &'static [glib::ParamSpec] {
+ static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
+ vec![glib::ParamSpec::string(
+ "context",
+ "Context",
+ "Context name to share threads with",
+ Some(DEFAULT_CONTEXT),
+ glib::ParamFlags::WRITABLE,
+ )]
+ });
+
+ PROPERTIES.as_ref()
+ }
- match *prop {
- glib::subclass::Property("context", ..) => {
+ fn set_property(
+ &self,
+ _obj: &Self::Type,
+ _id: usize,
+ value: &glib::Value,
+ pspec: &glib::ParamSpec,
+ ) {
+ match pspec.get_name() {
+ "context" => {
let context = value
.get()
.expect("type checked upstream")
@@ -380,6 +367,36 @@ mod imp_src {
}
impl ElementImpl for ElementSrcTest {
+ fn metadata() -> Option<&'static gst::subclass::ElementMetadata> {
+ static ELEMENT_METADATA: Lazy<gst::subclass::ElementMetadata> = Lazy::new(|| {
+ gst::subclass::ElementMetadata::new(
+ "Thread-sharing Test Src Element",
+ "Generic",
+ "Src Element for Pad Src Test",
+ "François Laignel <fengalin@free.fr>",
+ )
+ });
+
+ Some(&*ELEMENT_METADATA)
+ }
+
+ fn pad_templates() -> &'static [gst::PadTemplate] {
+ static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| {
+ let caps = gst::Caps::new_any();
+ let src_pad_template = gst::PadTemplate::new(
+ "src",
+ gst::PadDirection::Src,
+ gst::PadPresence::Always,
+ &caps,
+ )
+ .unwrap();
+
+ vec![src_pad_template]
+ });
+
+ PAD_TEMPLATES.as_ref()
+ }
+
fn change_state(
&self,
element: &Self::Type,
@@ -452,17 +469,6 @@ unsafe impl Sync for ElementSrcTest {}
mod imp_sink {
use super::*;
- static SINK_PROPERTIES: [glib::subclass::Property; 1] =
- [glib::subclass::Property("sender", |name| {
- glib::ParamSpec::boxed(
- name,
- "Sender",
- "Channel sender to forward the incoming items to",
- ItemSender::get_type(),
- glib::ParamFlags::WRITABLE,
- )
- })];
-
#[derive(Clone, Debug, Default)]
struct PadSinkTestHandler;
@@ -634,32 +640,12 @@ mod imp_sink {
const NAME: &'static str = "TsElementSinkTest";
type Type = super::ElementSinkTest;
type ParentType = gst::Element;
+ type Interfaces = ();
type Instance = gst::subclass::ElementInstanceStruct<Self>;
type Class = glib::subclass::simple::ClassStruct<Self>;
glib::object_subclass!();
- fn class_init(klass: &mut Self::Class) {
- klass.set_metadata(
- "Thread-sharing Test Sink Element",
- "Generic",
- "Sink Element for Pad Test",
- "François Laignel <fengalin@free.fr>",
- );
-
- let caps = gst::Caps::new_any();
- let sink_pad_template = gst::PadTemplate::new(
- "sink",
- gst::PadDirection::Sink,
- gst::PadPresence::Always,
- &caps,
- )
- .unwrap();
- klass.add_pad_template(sink_pad_template);
-
- klass.install_properties(&SINK_PROPERTIES);
- }
-
fn with_class(klass: &Self::Class) -> Self {
ElementSinkTest {
sink_pad: PadSink::new(
@@ -673,11 +659,29 @@ mod imp_sink {
}
impl ObjectImpl for ElementSinkTest {
- fn set_property(&self, _obj: &Self::Type, id: usize, value: &glib::Value) {
- let prop = &SINK_PROPERTIES[id];
+ fn properties() -> &'static [glib::ParamSpec] {
+ static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
+ vec![glib::ParamSpec::boxed(
+ "sender",
+ "Sender",
+ "Channel sender to forward the incoming items to",
+ ItemSender::get_type(),
+ glib::ParamFlags::WRITABLE,
+ )]
+ });
+
+ PROPERTIES.as_ref()
+ }
- match *prop {
- glib::subclass::Property("sender", ..) => {
+ fn set_property(
+ &self,
+ _obj: &Self::Type,
+ _id: usize,
+ value: &glib::Value,
+ pspec: &glib::ParamSpec,
+ ) {
+ match pspec.get_name() {
+ "sender" => {
let ItemSender { sender } = value
.get::<&ItemSender>()
.expect("type checked upstream")
@@ -697,6 +701,36 @@ mod imp_sink {
}
impl ElementImpl for ElementSinkTest {
+ fn metadata() -> Option<&'static gst::subclass::ElementMetadata> {
+ static ELEMENT_METADATA: Lazy<gst::subclass::ElementMetadata> = Lazy::new(|| {
+ gst::subclass::ElementMetadata::new(
+ "Thread-sharing Test Sink Element",
+ "Generic",
+ "Sink Element for Pad Test",
+ "François Laignel <fengalin@free.fr>",
+ )
+ });
+
+ Some(&*ELEMENT_METADATA)
+ }
+
+ fn pad_templates() -> &'static [gst::PadTemplate] {
+ static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| {
+ let caps = gst::Caps::new_any();
+ let sink_pad_template = gst::PadTemplate::new(
+ "sink",
+ gst::PadDirection::Sink,
+ gst::PadPresence::Always,
+ &caps,
+ )
+ .unwrap();
+
+ vec![sink_pad_template]
+ });
+
+ PAD_TEMPLATES.as_ref()
+ }
+
fn change_state(
&self,
element: &Self::Type,