mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2025-02-02 22:22:24 +00:00
rtpav1pay: Add support for tu/frame aligned input
In this case every buffer can be sent out immediately and makes up a whole frame. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1086>
This commit is contained in:
parent
ba0904630d
commit
17dec1cb26
2 changed files with 37 additions and 13 deletions
|
@ -5517,7 +5517,7 @@
|
||||||
"long-name": "RTP AV1 payloader",
|
"long-name": "RTP AV1 payloader",
|
||||||
"pad-templates": {
|
"pad-templates": {
|
||||||
"sink": {
|
"sink": {
|
||||||
"caps": "video/x-av1:\n parsed: true\n stream-format: obu-stream\n alignment: obu\n",
|
"caps": "video/x-av1:\n parsed: true\n stream-format: obu-stream\n alignment: { (string)tu, (string)frame, (string)obu }\n",
|
||||||
"direction": "sink",
|
"direction": "sink",
|
||||||
"presence": "always"
|
"presence": "always"
|
||||||
},
|
},
|
||||||
|
|
|
@ -82,6 +82,9 @@ struct State {
|
||||||
last_dts: Option<gst::ClockTime>,
|
last_dts: Option<gst::ClockTime>,
|
||||||
/// The last observed PTS if upstream does not provide PTS for each OBU
|
/// The last observed PTS if upstream does not provide PTS for each OBU
|
||||||
last_pts: Option<gst::ClockTime>,
|
last_pts: Option<gst::ClockTime>,
|
||||||
|
|
||||||
|
/// If the input is TU or frame aligned.
|
||||||
|
framed: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
|
@ -97,15 +100,23 @@ impl Default for State {
|
||||||
first_packet_in_seq: true,
|
first_packet_in_seq: true,
|
||||||
last_dts: None,
|
last_dts: None,
|
||||||
last_pts: None,
|
last_pts: None,
|
||||||
|
framed: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RTPAv1Pay {
|
impl RTPAv1Pay {
|
||||||
fn reset(&self, state: &mut State) {
|
fn reset(&self, state: &mut State, full: bool) {
|
||||||
gst::debug!(CAT, imp: self, "resetting state");
|
gst::debug!(CAT, imp: self, "resetting state");
|
||||||
|
|
||||||
*state = State::default();
|
if full {
|
||||||
|
*state = State::default();
|
||||||
|
} else {
|
||||||
|
*state = State {
|
||||||
|
framed: state.framed,
|
||||||
|
..State::default()
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses new OBUs, stores them in the state,
|
/// Parses new OBUs, stores them in the state,
|
||||||
|
@ -576,7 +587,7 @@ impl ElementImpl for RTPAv1Pay {
|
||||||
&gst::Caps::builder("video/x-av1")
|
&gst::Caps::builder("video/x-av1")
|
||||||
.field("parsed", true)
|
.field("parsed", true)
|
||||||
.field("stream-format", "obu-stream")
|
.field("stream-format", "obu-stream")
|
||||||
.field("alignment", "obu")
|
.field("alignment", gst::List::new(["tu", "frame", "obu"]))
|
||||||
.build(),
|
.build(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -608,14 +619,14 @@ impl ElementImpl for RTPAv1Pay {
|
||||||
|
|
||||||
if matches!(transition, gst::StateChange::ReadyToPaused) {
|
if matches!(transition, gst::StateChange::ReadyToPaused) {
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
self.reset(&mut state);
|
self.reset(&mut state, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
let ret = self.parent_change_state(transition);
|
let ret = self.parent_change_state(transition);
|
||||||
|
|
||||||
if matches!(transition, gst::StateChange::PausedToReady) {
|
if matches!(transition, gst::StateChange::PausedToReady) {
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
self.reset(&mut state);
|
self.reset(&mut state, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
@ -623,10 +634,23 @@ impl ElementImpl for RTPAv1Pay {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RTPBasePayloadImpl for RTPAv1Pay {
|
impl RTPBasePayloadImpl for RTPAv1Pay {
|
||||||
fn set_caps(&self, _caps: &gst::Caps) -> Result<(), gst::LoggableError> {
|
fn set_caps(&self, caps: &gst::Caps) -> Result<(), gst::LoggableError> {
|
||||||
self.obj().set_options("video", true, "AV1", CLOCK_RATE);
|
gst::debug!(CAT, imp: self, "received caps {caps:?}");
|
||||||
|
|
||||||
gst::debug!(CAT, imp: self, "setting caps");
|
{
|
||||||
|
let mut state = self.state.lock().unwrap();
|
||||||
|
let s = caps.structure(0).unwrap();
|
||||||
|
match s.get::<&str>("alignment").unwrap() {
|
||||||
|
"tu" | "frame" => {
|
||||||
|
state.framed = true;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
state.framed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.obj().set_options("video", true, "AV1", CLOCK_RATE);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -638,7 +662,7 @@ impl RTPBasePayloadImpl for RTPAv1Pay {
|
||||||
|
|
||||||
if buffer.flags().contains(gst::BufferFlags::DISCONT) {
|
if buffer.flags().contains(gst::BufferFlags::DISCONT) {
|
||||||
gst::debug!(CAT, imp: self, "buffer discontinuity");
|
gst::debug!(CAT, imp: self, "buffer discontinuity");
|
||||||
self.reset(&mut state);
|
self.reset(&mut state, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
let dts = buffer.dts();
|
let dts = buffer.dts();
|
||||||
|
@ -655,7 +679,7 @@ impl RTPBasePayloadImpl for RTPAv1Pay {
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Does the buffer finished a full TU?
|
// Does the buffer finished a full TU?
|
||||||
let marker = buffer.flags().contains(gst::BufferFlags::MARKER);
|
let marker = buffer.flags().contains(gst::BufferFlags::MARKER) || state.framed;
|
||||||
let list = self.handle_new_obus(&mut state, map.as_slice(), marker, dts, pts)?;
|
let list = self.handle_new_obus(&mut state, map.as_slice(), marker, dts, pts)?;
|
||||||
drop(map);
|
drop(map);
|
||||||
drop(state);
|
drop(state);
|
||||||
|
@ -685,7 +709,7 @@ impl RTPBasePayloadImpl for RTPAv1Pay {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.reset(&mut state);
|
self.reset(&mut state, false);
|
||||||
}
|
}
|
||||||
if !list.is_empty() {
|
if !list.is_empty() {
|
||||||
let _ = self.obj().push_list(list);
|
let _ = self.obj().push_list(list);
|
||||||
|
@ -693,7 +717,7 @@ impl RTPBasePayloadImpl for RTPAv1Pay {
|
||||||
}
|
}
|
||||||
gst::EventView::FlushStop(_) => {
|
gst::EventView::FlushStop(_) => {
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
self.reset(&mut state);
|
self.reset(&mut state, false);
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue