mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-11-29 23:11:01 +00:00
rtpav1pay: Don't push buffers downstream while holding mutexes
And also push all packets that can be generated as a time as a single buffer list instead of one by one.
This commit is contained in:
parent
f9a8e121e1
commit
7edc9e656f
1 changed files with 42 additions and 24 deletions
|
@ -17,7 +17,7 @@ use gst::{
|
||||||
use gst_rtp::{prelude::*, rtp_buffer::RTPBuffer, subclass::prelude::*, RTPBasePayload};
|
use gst_rtp::{prelude::*, rtp_buffer::RTPBuffer, subclass::prelude::*, RTPBasePayload};
|
||||||
use std::{
|
use std::{
|
||||||
io::{Cursor, Read, Seek, SeekFrom, Write},
|
io::{Cursor, Read, Seek, SeekFrom, Write},
|
||||||
sync::{Mutex, MutexGuard},
|
sync::Mutex,
|
||||||
};
|
};
|
||||||
|
|
||||||
use bitstream_io::{BitReader, BitWriter};
|
use bitstream_io::{BitReader, BitWriter};
|
||||||
|
@ -109,14 +109,14 @@ impl RTPAv1Pay {
|
||||||
|
|
||||||
/// Parses new OBUs, stores them in the state,
|
/// Parses new OBUs, stores them in the state,
|
||||||
/// and constructs and sends new RTP packets when appropriate.
|
/// and constructs and sends new RTP packets when appropriate.
|
||||||
fn handle_new_obus<'s>(
|
fn handle_new_obus(
|
||||||
&'s self,
|
&self,
|
||||||
element: &<Self as ObjectSubclass>::Type,
|
element: &<Self as ObjectSubclass>::Type,
|
||||||
state: &mut MutexGuard<'s, State>,
|
state: &mut State,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
dts: Option<ClockTime>,
|
dts: Option<ClockTime>,
|
||||||
pts: Option<ClockTime>,
|
pts: Option<ClockTime>,
|
||||||
) -> Result<FlowSuccess, FlowError> {
|
) -> Result<gst::BufferList, FlowError> {
|
||||||
let mut reader = Cursor::new(data);
|
let mut reader = Cursor::new(data);
|
||||||
|
|
||||||
while reader.position() < data.len() as u64 {
|
while reader.position() < data.len() as u64 {
|
||||||
|
@ -188,11 +188,16 @@ impl RTPAv1Pay {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while let Some(packet_data) = self.consider_new_packet(element, state, false) {
|
let mut list = gst::BufferList::new();
|
||||||
self.push_new_packet(element, state, packet_data)?;
|
{
|
||||||
|
let list = list.get_mut().unwrap();
|
||||||
|
while let Some(packet_data) = self.consider_new_packet(element, state, false) {
|
||||||
|
let buffer = self.generate_new_packet(element, state, packet_data)?;
|
||||||
|
list.add(buffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(FlowSuccess::Ok)
|
Ok(list)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Look at the size the currently stored OBUs would require,
|
/// Look at the size the currently stored OBUs would require,
|
||||||
|
@ -329,14 +334,14 @@ impl RTPAv1Pay {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given the information returned by consider_new_packet(), construct and push
|
/// Given the information returned by consider_new_packet(), construct and return
|
||||||
/// new RTP packet, filled with those OBUs.
|
/// new RTP packet, filled with those OBUs.
|
||||||
fn push_new_packet<'s>(
|
fn generate_new_packet(
|
||||||
&'s self,
|
&self,
|
||||||
element: &<Self as ObjectSubclass>::Type,
|
element: &<Self as ObjectSubclass>::Type,
|
||||||
state: &mut MutexGuard<'s, State>,
|
state: &mut State,
|
||||||
packet: PacketOBUData,
|
packet: PacketOBUData,
|
||||||
) -> Result<FlowSuccess, FlowError> {
|
) -> Result<gst::Buffer, FlowError> {
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj: element,
|
||||||
|
@ -461,10 +466,11 @@ impl RTPAv1Pay {
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj: element,
|
||||||
"pushing RTP packet of size {}",
|
"generated RTP packet of size {}",
|
||||||
outbuf.size()
|
outbuf.size()
|
||||||
);
|
);
|
||||||
element.push(outbuf)
|
|
||||||
|
Ok(outbuf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -590,24 +596,36 @@ impl RTPBasePayloadImpl for RTPAv1Pay {
|
||||||
FlowError::Error
|
FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
self.handle_new_obus(element, &mut state, buffer.as_slice(), dts, pts)
|
let list = self.handle_new_obus(element, &mut state, buffer.as_slice(), dts, pts)?;
|
||||||
|
drop(state);
|
||||||
|
|
||||||
|
if !list.is_empty() {
|
||||||
|
element.push_list(list)
|
||||||
|
} else {
|
||||||
|
Ok(gst::FlowSuccess::Ok)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sink_event(&self, element: &Self::Type, event: Event) -> bool {
|
fn sink_event(&self, element: &Self::Type, event: Event) -> bool {
|
||||||
gst::log!(CAT, obj: element, "sink event: {}", event.type_());
|
gst::log!(CAT, obj: element, "sink event: {}", event.type_());
|
||||||
|
|
||||||
if matches!(event.type_(), EventType::Eos) {
|
if matches!(event.type_(), EventType::Eos) {
|
||||||
let mut state = self.state.lock().unwrap();
|
|
||||||
|
|
||||||
// flush all remaining OBUs
|
// flush all remaining OBUs
|
||||||
while let Some(packet_data) = self.consider_new_packet(element, &mut state, true) {
|
let mut list = gst::BufferList::new();
|
||||||
if self
|
{
|
||||||
.push_new_packet(element, &mut state, packet_data)
|
let mut state = self.state.lock().unwrap();
|
||||||
.is_err()
|
let list = list.get_mut().unwrap();
|
||||||
{
|
|
||||||
break;
|
while let Some(packet_data) = self.consider_new_packet(element, &mut state, true) {
|
||||||
|
match self.generate_new_packet(element, &mut state, packet_data) {
|
||||||
|
Ok(buffer) => list.add(buffer),
|
||||||
|
Err(_) => break,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if !list.is_empty() {
|
||||||
|
let _ = element.push_list(list);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.parent_sink_event(element, event)
|
self.parent_sink_event(element, event)
|
||||||
|
|
Loading…
Reference in a new issue