mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-11-22 19:41:00 +00:00
rtp: basepay: Fix header extension negotiation
Only configure header extensions from the source pad caps if they exist already in the source pad caps, otherwise the configuration will fail. Extensions that are added via the signals might not exist in the source pad caps yet and would be added later. Also, if configuring an existing extension from the new caps fails, remove it and try to request a new extension for it. Additionally don't remove extensions from the caps that can't be provided. No header extensions for them would be added to the packets, but that's not a problem. Removing them on the other hand would cause negotiation to fail. This only affects extensions that are already included in the caps. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1577>
This commit is contained in:
parent
0d33077df6
commit
dcc0b47349
1 changed files with 34 additions and 32 deletions
|
@ -897,21 +897,28 @@ impl RtpBasePay2 {
|
|||
|
||||
let mut extensions = self.extensions.lock().unwrap();
|
||||
let mut extensions_changed = false;
|
||||
for (ext_id, uri) in caps_extensions {
|
||||
if let Some(extension) = extensions.get(&ext_id) {
|
||||
if extension.uri().as_deref() == Some(&uri) {
|
||||
// Same extension, nothing to do here, we will update it with the new caps
|
||||
// later
|
||||
continue;
|
||||
for (ext_id, uri) in &caps_extensions {
|
||||
if let Some(extension) = extensions.get(ext_id) {
|
||||
if extension.uri().as_deref() == Some(uri) {
|
||||
// Same extension, update it with the new caps in case the attributes changed
|
||||
if extension.set_attributes_from_caps(src_caps) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Try to get a new one for this extension ID instead
|
||||
gst::warning!(CAT, imp: self, "Failed to configure extension {ext_id} from caps {src_caps}");
|
||||
extensions_changed |= true;
|
||||
extensions.remove(ext_id);
|
||||
} else {
|
||||
gst::debug!(
|
||||
CAT,
|
||||
imp: self,
|
||||
"Extension ID {ext_id} changed from {:?} to {uri}",
|
||||
extension.uri(),
|
||||
);
|
||||
extensions_changed |= true;
|
||||
extensions.remove(ext_id);
|
||||
}
|
||||
gst::debug!(
|
||||
CAT,
|
||||
imp: self,
|
||||
"Extension ID {ext_id} changed from {:?} to {uri}",
|
||||
extension.uri(),
|
||||
);
|
||||
extensions_changed |= true;
|
||||
extensions.remove(&ext_id);
|
||||
}
|
||||
|
||||
gst::debug!(CAT, imp: self, "Requesting extension {uri} for ID {ext_id}");
|
||||
|
@ -919,7 +926,7 @@ impl RtpBasePay2 {
|
|||
.obj()
|
||||
.emit_by_name::<Option<gst_rtp::RTPHeaderExtension>>(
|
||||
"request-extension",
|
||||
&[&(ext_id as u32), &uri],
|
||||
&[&(*ext_id as u32), &uri],
|
||||
);
|
||||
|
||||
let Some(ext) = ext else {
|
||||
|
@ -927,23 +934,23 @@ impl RtpBasePay2 {
|
|||
continue;
|
||||
};
|
||||
|
||||
if ext.id() != ext_id as u32 {
|
||||
if ext.id() != *ext_id as u32 {
|
||||
gst::warning!(CAT, imp: self, "Created extension has wrong ID");
|
||||
continue;
|
||||
}
|
||||
|
||||
extensions.insert(ext_id, ext);
|
||||
if !ext.set_attributes_from_caps(src_caps) {
|
||||
gst::warning!(CAT, imp: self, "Failed to configure extension {ext_id} from caps {src_caps}");
|
||||
continue;
|
||||
}
|
||||
|
||||
extensions.insert(*ext_id, ext);
|
||||
extensions_changed |= true;
|
||||
}
|
||||
|
||||
let sink_caps = state.sink_caps.as_ref().unwrap();
|
||||
let mut to_remove = vec![];
|
||||
for (ext_id, ext) in extensions.iter() {
|
||||
if !ext.set_attributes_from_caps(src_caps) {
|
||||
gst::warning!(CAT, imp: self, "Failed to configure extension {ext_id} from caps {src_caps}");
|
||||
to_remove.push(*ext_id);
|
||||
}
|
||||
|
||||
if !ext.set_non_rtp_sink_caps(sink_caps) {
|
||||
gst::warning!(CAT, imp: self, "Failed to configure extension {ext_id} from sink caps {sink_caps}");
|
||||
to_remove.push(*ext_id);
|
||||
|
@ -954,18 +961,13 @@ impl RtpBasePay2 {
|
|||
extensions_changed |= true;
|
||||
}
|
||||
|
||||
// First remove all header extension related fields from the caps,
|
||||
// then add them again correctly from the actually selected extensions.
|
||||
// Add extension information for all actually selected extensions to the caps.
|
||||
//
|
||||
// This will override the values for extensions that are already represented in the caps
|
||||
// but will leave extensions in the caps that couldn't be configured above and are not in
|
||||
// the extensions list anymore. This is necessary so that the created caps stay compatible.
|
||||
{
|
||||
let caps = src_caps.make_mut();
|
||||
let s = caps.structure_mut(0).unwrap();
|
||||
s.filter_map_in_place(|field, value| {
|
||||
if field.as_str().starts_with("extmap-") {
|
||||
None
|
||||
} else {
|
||||
Some(value)
|
||||
}
|
||||
});
|
||||
for (_, ext) in extensions.iter() {
|
||||
ext.set_caps_from_attributes(caps);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue