mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-12-23 02:26:35 +00:00
rtpsend: ensure only a single rtcp pad push
Otherwise, it can occur that multiple rtcp packets may be produced out of order. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1426>
This commit is contained in:
parent
525179f666
commit
df32e1ebfa
1 changed files with 31 additions and 20 deletions
|
@ -198,28 +198,39 @@ impl SendSession {
|
||||||
|
|
||||||
async fn rtcp_task(state: Arc<Mutex<State>>, session_id: usize) {
|
async fn rtcp_task(state: Arc<Mutex<State>>, session_id: usize) {
|
||||||
let mut stream = RtcpSendStream::new(state.clone(), session_id);
|
let mut stream = RtcpSendStream::new(state.clone(), session_id);
|
||||||
|
// we use a semaphore instead of mutex for ordering
|
||||||
|
// i.e. we should only allow a single pad push, but still allow other rtcp tasks to
|
||||||
|
// continue operating
|
||||||
|
let sem = Arc::new(tokio::sync::Semaphore::new(1));
|
||||||
while let Some(reply) = stream.next().await {
|
while let Some(reply) = stream.next().await {
|
||||||
let state = state.lock().unwrap();
|
let send = {
|
||||||
let Some(session) = state.session_by_id(session_id) else {
|
let state = state.lock().unwrap();
|
||||||
continue;
|
let Some(session) = state.session_by_id(session_id) else {
|
||||||
};
|
continue;
|
||||||
match reply {
|
};
|
||||||
RtcpSendReply::Data(data) => {
|
match reply {
|
||||||
let Some(rtcp_srcpad) = session.rtcp_send_srcpad.clone() else {
|
RtcpSendReply::Data(data) => {
|
||||||
continue;
|
session.rtcp_send_srcpad.clone().map(|pad| (pad, data))
|
||||||
};
|
}
|
||||||
drop(state);
|
RtcpSendReply::SsrcBye(ssrc) => {
|
||||||
RUNTIME.spawn_blocking(move || {
|
session
|
||||||
let buffer = gst::Buffer::from_mut_slice(data);
|
.internal_session
|
||||||
if let Err(e) = rtcp_srcpad.push(buffer) {
|
.config
|
||||||
gst::warning!(CAT, obj: rtcp_srcpad, "Failed to send rtcp data: flow return {e:?}");
|
.emit_by_name::<()>("bye-ssrc", &[&ssrc]);
|
||||||
}
|
None
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
RtcpSendReply::SsrcBye(ssrc) => session
|
};
|
||||||
.internal_session
|
|
||||||
.config
|
if let Some((rtcp_srcpad, data)) = send {
|
||||||
.emit_by_name::<()>("bye-ssrc", &[&ssrc]),
|
let acquired = sem.clone().acquire_owned().await;
|
||||||
|
RUNTIME.spawn_blocking(move || {
|
||||||
|
let buffer = gst::Buffer::from_mut_slice(data);
|
||||||
|
if let Err(e) = rtcp_srcpad.push(buffer) {
|
||||||
|
gst::warning!(CAT, obj: rtcp_srcpad, "Failed to send rtcp data: flow return {e:?}");
|
||||||
|
}
|
||||||
|
drop(acquired);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue