mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2025-01-03 15:58:42 +00:00
rtp: gccbwe: don't break downstream assumptions pushing buffer lists
Some elements in the RTP stack assume all buffers in a `gst::BufferList`
correspond to the same timestamp. See in [`rtpsession`] for instance.
This also had the effect that `rtpsession` did not create correct RTCP as it
only saw some of the SSRCs in the stream.
`rtpgccbwe` formed a packet group by gathering buffers in a `gst::BufferList`,
regardless of whether they corresponded to the same timestamp, which broke
synchronization under certain circonstances.
This commit makes `rtpgccbwe` push the buffers as they were received: one by one.
[`rtpsession`]: bc858976db/subprojects/gst-plugins-good/gst/rtpmanager/gstrtpsession.c (L2462)
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1502>
This commit is contained in:
parent
2b9272c7eb
commit
cc7b7d508d
1 changed files with 16 additions and 7 deletions
|
@ -19,6 +19,7 @@
|
|||
*/
|
||||
use gst::{glib, prelude::*, subclass::prelude::*};
|
||||
use once_cell::sync::Lazy;
|
||||
use smallvec::SmallVec;
|
||||
use std::{
|
||||
collections::{BTreeMap, VecDeque},
|
||||
fmt,
|
||||
|
@ -29,6 +30,7 @@ use std::{
|
|||
use time::Duration;
|
||||
|
||||
type Bitrate = u32;
|
||||
type BufferList = SmallVec<[gst::Buffer; 10]>;
|
||||
|
||||
const DEFAULT_MIN_BITRATE: Bitrate = 1000;
|
||||
const DEFAULT_ESTIMATED_BITRATE: Bitrate = 2_048_000;
|
||||
|
@ -748,7 +750,7 @@ impl Default for State {
|
|||
|
||||
impl State {
|
||||
// 4. sending engine implementing a "leaky bucket"
|
||||
fn create_buffer_list(&mut self, bwe: &super::BandwidthEstimator) -> gst::BufferList {
|
||||
fn create_buffer_list(&mut self, bwe: &super::BandwidthEstimator) -> BufferList {
|
||||
let now = time::Instant::now();
|
||||
let elapsed = now - self.last_push;
|
||||
let mut budget = (elapsed.whole_nanoseconds() as i64)
|
||||
|
@ -762,8 +764,8 @@ impl State {
|
|||
let mut remaining = self.buffers.iter().map(|b| b.size() as f64).sum::<f64>() * 8.;
|
||||
let total_size = remaining;
|
||||
|
||||
let mut list = gst::BufferList::new();
|
||||
let mutlist = list.get_mut().unwrap();
|
||||
let mut list_size = 0;
|
||||
let mut list = BufferList::new();
|
||||
|
||||
// Leak the bucket so it can hold at most 30ms of data
|
||||
let maximum_remaining_bits = 30. * self.estimated_bitrate as f64 / 1000.;
|
||||
|
@ -773,7 +775,8 @@ impl State {
|
|||
let n_bits = buf.size() * 8;
|
||||
|
||||
leaked = budget <= 0 && remaining > maximum_remaining_bits;
|
||||
mutlist.add(buf);
|
||||
list_size += buf.size();
|
||||
list.push(buf);
|
||||
budget -= n_bits as i64;
|
||||
remaining -= n_bits as f64;
|
||||
}
|
||||
|
@ -786,7 +789,7 @@ impl State {
|
|||
human_kbits(self.estimated_bitrate),
|
||||
human_kbits(budget as f64),
|
||||
human_kbits(total_budget as f64),
|
||||
human_kbits(list.calculate_size() as f64 * 8.),
|
||||
human_kbits(list_size as f64 * 8.),
|
||||
human_kbits(remaining),
|
||||
human_kbits(total_size)
|
||||
);
|
||||
|
@ -1026,8 +1029,14 @@ pub struct BandwidthEstimator {
|
|||
}
|
||||
|
||||
impl BandwidthEstimator {
|
||||
fn push_list(&self, list: gst::BufferList) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||
let res = self.srcpad.push_list(list);
|
||||
fn push_list(&self, list: BufferList) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||
let mut res = Ok(gst::FlowSuccess::Ok);
|
||||
for buf in list {
|
||||
res = self.srcpad.push(buf);
|
||||
if res.is_err() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
self.state.lock().unwrap().flow_return = res;
|
||||
|
||||
|
|
Loading…
Reference in a new issue