mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer-rs.git
synced 2024-11-26 11:31:06 +00:00
Fix building argument-less messages
Building an argument-less message such as eos yields an assertion failure due to the inner structure being null. The short term solution consists in checking that the inner `structure` is not `null` before attempting to insert `other_fields`. The consequence is that `others_fields` defined for argument-less messages will be ignored. A correction will be applied when GStreamer 1.14 is released thank to the introduction of `gst_message_writable_structure` (see https://bugzilla.gnome.org/show_bug.cgi?id=792928). Due to the dependency on GStreamer 1.14, the correction will be only available under the activation of a feature "v1_14". Events are not affected as the build method the availability of `gst_event_writable_structure` and this function "will never return NULL". However, we can avoid a `structure` allocation for argument-less messages without `other_fields`.
This commit is contained in:
parent
7fe2216daf
commit
658be807c1
2 changed files with 95 additions and 7 deletions
|
@ -895,7 +895,7 @@ macro_rules! event_builder_generic_impl {
|
||||||
ffi::gst_event_set_running_time_offset(event, running_time_offset);
|
ffi::gst_event_set_running_time_offset(event, running_time_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
if !self.other_fields.is_empty() {
|
||||||
let s = StructureRef::from_glib_borrow_mut(
|
let s = StructureRef::from_glib_borrow_mut(
|
||||||
ffi::gst_event_writable_structure(event)
|
ffi::gst_event_writable_structure(event)
|
||||||
);
|
);
|
||||||
|
@ -1667,3 +1667,49 @@ impl<'a> CustomBothOobBuilder<'a> {
|
||||||
ev
|
ev
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_simple() {
|
||||||
|
::init().unwrap();
|
||||||
|
|
||||||
|
// Event without arguments
|
||||||
|
let flush_start_evt = Event::new_flush_start().build();
|
||||||
|
match flush_start_evt.view() {
|
||||||
|
EventView::FlushStart(flush_start_evt) => {
|
||||||
|
assert!(flush_start_evt.0.get_structure().is_none());
|
||||||
|
},
|
||||||
|
_ => panic!("flush_start_evt.view() is not an EventView::FlushStart(_)"),
|
||||||
|
}
|
||||||
|
|
||||||
|
let flush_start_evt = Event::new_flush_start()
|
||||||
|
.other_fields(&[("extra-field", &true)])
|
||||||
|
.build();
|
||||||
|
match flush_start_evt.view() {
|
||||||
|
EventView::FlushStart(flush_start_evt) => {
|
||||||
|
assert!(flush_start_evt.0.get_structure().is_some());
|
||||||
|
if let Some(other_fields) = flush_start_evt.0.get_structure() {
|
||||||
|
assert!(other_fields.has_field("extra-field"));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => panic!("flush_start_evt.view() is not an EventView::FlushStart(_)"),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event with arguments
|
||||||
|
let flush_stop_evt = Event::new_flush_stop(true)
|
||||||
|
.other_fields(&[("extra-field", &true)])
|
||||||
|
.build();
|
||||||
|
match flush_stop_evt.view() {
|
||||||
|
EventView::FlushStop(flush_stop_evt) => {
|
||||||
|
assert_eq!(flush_stop_evt.get_reset_time(), true);
|
||||||
|
assert!(flush_stop_evt.0.get_structure().is_some());
|
||||||
|
if let Some(other_fields) = flush_stop_evt.0.get_structure() {
|
||||||
|
assert!(other_fields.has_field("extra-field"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => panic!("flush_stop_evt.view() is not an EventView::FlushStop(_)"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1165,6 +1165,8 @@ macro_rules! message_builder_generic_impl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warning: other_fields are ignored with argument-less messages
|
||||||
|
// until GStreamer 1.14 is released
|
||||||
pub fn other_fields(self, other_fields: &[(&'a str, &'a ToSendValue)]) -> Self {
|
pub fn other_fields(self, other_fields: &[(&'a str, &'a ToSendValue)]) -> Self {
|
||||||
Self {
|
Self {
|
||||||
other_fields: self.other_fields.iter().cloned()
|
other_fields: self.other_fields.iter().cloned()
|
||||||
|
@ -1183,13 +1185,19 @@ macro_rules! message_builder_generic_impl {
|
||||||
ffi::gst_message_set_seqnum(msg, seqnum.to_glib());
|
ffi::gst_message_set_seqnum(msg, seqnum.to_glib());
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
if !self.other_fields.is_empty() {
|
||||||
let s = StructureRef::from_glib_borrow_mut(
|
// issue with argument-less messages. We need the function
|
||||||
ffi::gst_message_get_structure(msg) as *mut _
|
// ffi::gst_message_writable_structure to sort this out
|
||||||
);
|
// and this function will be available in GStreamer 1.14
|
||||||
|
// See https://github.com/sdroege/gstreamer-rs/pull/75
|
||||||
|
// and https://bugzilla.gnome.org/show_bug.cgi?id=792928
|
||||||
|
let structure = ffi::gst_message_get_structure(msg);
|
||||||
|
if !structure.is_null() {
|
||||||
|
let structure = StructureRef::from_glib_borrow_mut(structure as *mut _);
|
||||||
|
|
||||||
for (k, v) in self.other_fields {
|
for (k, v) in self.other_fields {
|
||||||
s.set_value(k, v.to_send_value());
|
structure.set_value(k, v.to_send_value());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2442,3 +2450,37 @@ impl<'a> RedirectBuilder<'a> {
|
||||||
msg
|
msg
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_simple() {
|
||||||
|
::init().unwrap();
|
||||||
|
|
||||||
|
// Message without arguments
|
||||||
|
let eos_msg = Message::new_eos().build();
|
||||||
|
match eos_msg.view() {
|
||||||
|
MessageView::Eos(eos_msg) => {
|
||||||
|
assert!(eos_msg.0.get_structure().is_none());
|
||||||
|
},
|
||||||
|
_ => panic!("eos_msg.view() is not a MessageView::Eos(_)"),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: can't define other_fields for argument-less messages before GStreamer 1.14
|
||||||
|
|
||||||
|
// Message with arguments
|
||||||
|
let buffering_msg = Message::new_buffering(42)
|
||||||
|
.other_fields(&[("extra-field", &true)])
|
||||||
|
.build();
|
||||||
|
match buffering_msg.view() {
|
||||||
|
MessageView::Buffering(buffering_msg) => {
|
||||||
|
assert_eq!(buffering_msg.get_percent(), 42);
|
||||||
|
assert!(buffering_msg.0.get_structure().is_some());
|
||||||
|
assert!(buffering_msg.0.get_structure().unwrap().has_field("extra-field"));
|
||||||
|
}
|
||||||
|
_ => panic!("buffering_msg.view() is not a MessageView::Buffering(_)"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue