mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2024-11-25 21:11:00 +00:00
rtpav1: Use GStreamer types by namespace instead of importing dozens of types directly into the scope
For consistency with other plugins and to reduce confusion of where types actually come from.
This commit is contained in:
parent
5774d9c9ee
commit
0b81ed2e34
5 changed files with 94 additions and 110 deletions
|
@ -10,14 +10,14 @@
|
||||||
macro_rules! err_flow {
|
macro_rules! err_flow {
|
||||||
($element:ident, read, $msg:literal) => {
|
($element:ident, read, $msg:literal) => {
|
||||||
|err| {
|
|err| {
|
||||||
gst::element_error!($element, ResourceError::Read, [$msg, err]);
|
gst::element_error!($element, gst::ResourceError::Read, [$msg, err]);
|
||||||
FlowError::Error
|
gst::FlowError::Error
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
($element:ident, write, $msg:literal) => {
|
($element:ident, write, $msg:literal) => {
|
||||||
|err| {
|
|err| {
|
||||||
gst::element_error!($element, ResourceError::Write, [$msg, err]);
|
gst::element_error!($element, gst::ResourceError::Write, [$msg, err]);
|
||||||
FlowError::Error
|
gst::FlowError::Error
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -53,13 +53,13 @@ macro_rules! err_flow {
|
||||||
macro_rules! err_opt {
|
macro_rules! err_opt {
|
||||||
($element:ident, read, $msg:literal) => {
|
($element:ident, read, $msg:literal) => {
|
||||||
|err| {
|
|err| {
|
||||||
gst::element_error!($element, ResourceError::Read, [$msg, err]);
|
gst::element_error!($element, gst::ResourceError::Read, [$msg, err]);
|
||||||
Option::<()>::None
|
Option::<()>::None
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
($element:ident, write, $msg:literal) => {
|
($element:ident, write, $msg:literal) => {
|
||||||
|err| {
|
|err| {
|
||||||
gst::element_error!($element, ResourceError::Write, [$msg, err]);
|
gst::element_error!($element, gst::ResourceError::Write, [$msg, err]);
|
||||||
Option::<()>::None
|
Option::<()>::None
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,17 +7,8 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use gst::{
|
use gst::{glib, subclass::prelude::*};
|
||||||
glib,
|
use gst_rtp::subclass::prelude::*;
|
||||||
subclass::{prelude::*, ElementMetadata},
|
|
||||||
Buffer, BufferFlags, Caps, DebugCategory, DebugColorFlags, IntRange, Memory, PadDirection,
|
|
||||||
PadPresence, PadTemplate, ResourceError, StateChange, StateChangeError, StateChangeSuccess,
|
|
||||||
};
|
|
||||||
use gst_base::UniqueAdapter;
|
|
||||||
use gst_rtp::{
|
|
||||||
rtp_buffer::{RTPBuffer, Readable},
|
|
||||||
subclass::prelude::*,
|
|
||||||
};
|
|
||||||
use std::{
|
use std::{
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
io::{Cursor, Read, Seek, SeekFrom},
|
io::{Cursor, Read, Seek, SeekFrom},
|
||||||
|
@ -37,7 +28,7 @@ use crate::common::{
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
struct State {
|
struct State {
|
||||||
/// used to store outgoing OBUs until the TU is complete
|
/// used to store outgoing OBUs until the TU is complete
|
||||||
adapter: UniqueAdapter,
|
adapter: gst_base::UniqueAdapter,
|
||||||
|
|
||||||
last_timestamp: Option<u32>,
|
last_timestamp: Option<u32>,
|
||||||
/// if true, the last packet of a temporal unit has been received
|
/// if true, the last packet of a temporal unit has been received
|
||||||
|
@ -51,15 +42,16 @@ pub struct RTPAv1Depay {
|
||||||
state: Mutex<State>,
|
state: Mutex<State>,
|
||||||
}
|
}
|
||||||
|
|
||||||
static CAT: Lazy<DebugCategory> = Lazy::new(|| {
|
static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
|
||||||
DebugCategory::new(
|
gst::DebugCategory::new(
|
||||||
"rtpav1depay",
|
"rtpav1depay",
|
||||||
DebugColorFlags::empty(),
|
gst::DebugColorFlags::empty(),
|
||||||
Some("RTP AV1 Depayloader"),
|
Some("RTP AV1 Depayloader"),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
static TEMPORAL_DELIMITER: Lazy<Memory> = Lazy::new(|| Memory::from_slice(&[0b0001_0010, 0]));
|
static TEMPORAL_DELIMITER: Lazy<gst::Memory> =
|
||||||
|
Lazy::new(|| gst::Memory::from_slice(&[0b0001_0010, 0]));
|
||||||
|
|
||||||
impl RTPAv1Depay {
|
impl RTPAv1Depay {
|
||||||
fn reset(&self, element: &<Self as ObjectSubclass>::Type, state: &mut State) {
|
fn reset(&self, element: &<Self as ObjectSubclass>::Type, state: &mut State) {
|
||||||
|
@ -81,8 +73,8 @@ impl ObjectImpl for RTPAv1Depay {}
|
||||||
impl GstObjectImpl for RTPAv1Depay {}
|
impl GstObjectImpl for RTPAv1Depay {}
|
||||||
|
|
||||||
impl ElementImpl for RTPAv1Depay {
|
impl ElementImpl for RTPAv1Depay {
|
||||||
fn metadata() -> Option<&'static ElementMetadata> {
|
fn metadata() -> Option<&'static gst::subclass::ElementMetadata> {
|
||||||
static ELEMENT_METADATA: Lazy<ElementMetadata> = Lazy::new(|| {
|
static ELEMENT_METADATA: Lazy<gst::subclass::ElementMetadata> = Lazy::new(|| {
|
||||||
gst::subclass::ElementMetadata::new(
|
gst::subclass::ElementMetadata::new(
|
||||||
"RTP AV1 Depayloader",
|
"RTP AV1 Depayloader",
|
||||||
"Codec/Depayloader/Network/RTP",
|
"Codec/Depayloader/Network/RTP",
|
||||||
|
@ -94,26 +86,26 @@ impl ElementImpl for RTPAv1Depay {
|
||||||
Some(&*ELEMENT_METADATA)
|
Some(&*ELEMENT_METADATA)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pad_templates() -> &'static [PadTemplate] {
|
fn pad_templates() -> &'static [gst::PadTemplate] {
|
||||||
static PAD_TEMPLATES: Lazy<Vec<PadTemplate>> = Lazy::new(|| {
|
static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| {
|
||||||
let sink_pad_template = PadTemplate::new(
|
let sink_pad_template = gst::PadTemplate::new(
|
||||||
"sink",
|
"sink",
|
||||||
PadDirection::Sink,
|
gst::PadDirection::Sink,
|
||||||
PadPresence::Always,
|
gst::PadPresence::Always,
|
||||||
&Caps::builder("application/x-rtp")
|
&gst::Caps::builder("application/x-rtp")
|
||||||
.field("media", "video")
|
.field("media", "video")
|
||||||
.field("payload", IntRange::new(96, 127))
|
.field("payload", gst::IntRange::new(96, 127))
|
||||||
.field("clock-rate", CLOCK_RATE as i32)
|
.field("clock-rate", CLOCK_RATE as i32)
|
||||||
.field("encoding-name", "AV1")
|
.field("encoding-name", "AV1")
|
||||||
.build(),
|
.build(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let src_pad_template = PadTemplate::new(
|
let src_pad_template = gst::PadTemplate::new(
|
||||||
"src",
|
"src",
|
||||||
PadDirection::Src,
|
gst::PadDirection::Src,
|
||||||
PadPresence::Always,
|
gst::PadPresence::Always,
|
||||||
&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", "tu")
|
.field("alignment", "tu")
|
||||||
|
@ -130,18 +122,18 @@ impl ElementImpl for RTPAv1Depay {
|
||||||
fn change_state(
|
fn change_state(
|
||||||
&self,
|
&self,
|
||||||
element: &Self::Type,
|
element: &Self::Type,
|
||||||
transition: StateChange,
|
transition: gst::StateChange,
|
||||||
) -> Result<StateChangeSuccess, StateChangeError> {
|
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
gst::debug!(CAT, obj: element, "changing state: {}", transition);
|
gst::debug!(CAT, obj: element, "changing state: {}", transition);
|
||||||
|
|
||||||
if matches!(transition, StateChange::ReadyToPaused) {
|
if matches!(transition, gst::StateChange::ReadyToPaused) {
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
self.reset(element, &mut state);
|
self.reset(element, &mut state);
|
||||||
}
|
}
|
||||||
|
|
||||||
let ret = self.parent_change_state(element, transition);
|
let ret = self.parent_change_state(element, transition);
|
||||||
|
|
||||||
if matches!(transition, StateChange::PausedToReady) {
|
if matches!(transition, gst::StateChange::PausedToReady) {
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
self.reset(element, &mut state);
|
self.reset(element, &mut state);
|
||||||
}
|
}
|
||||||
|
@ -166,8 +158,8 @@ impl RTPBaseDepayloadImpl for RTPAv1Depay {
|
||||||
fn process_rtp_packet(
|
fn process_rtp_packet(
|
||||||
&self,
|
&self,
|
||||||
element: &Self::Type,
|
element: &Self::Type,
|
||||||
rtp: &RTPBuffer<Readable>,
|
rtp: &gst_rtp::RTPBuffer<gst_rtp::rtp_buffer::Readable>,
|
||||||
) -> Option<Buffer> {
|
) -> Option<gst::Buffer> {
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj: element,
|
||||||
|
@ -180,7 +172,7 @@ impl RTPBaseDepayloadImpl for RTPAv1Depay {
|
||||||
|
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
|
|
||||||
if rtp.buffer().flags().contains(BufferFlags::DISCONT) {
|
if rtp.buffer().flags().contains(gst::BufferFlags::DISCONT) {
|
||||||
gst::debug!(CAT, obj: element, "buffer discontinuity");
|
gst::debug!(CAT, obj: element, "buffer discontinuity");
|
||||||
self.reset(element, &mut state);
|
self.reset(element, &mut state);
|
||||||
}
|
}
|
||||||
|
@ -188,7 +180,7 @@ impl RTPBaseDepayloadImpl for RTPAv1Depay {
|
||||||
// number of bytes that can be used in the next outgoing buffer
|
// number of bytes that can be used in the next outgoing buffer
|
||||||
let mut bytes_ready = 0;
|
let mut bytes_ready = 0;
|
||||||
let mut reader = Cursor::new(payload);
|
let mut reader = Cursor::new(payload);
|
||||||
let mut ready_obus = Buffer::new();
|
let mut ready_obus = gst::Buffer::new();
|
||||||
|
|
||||||
let aggr_header = {
|
let aggr_header = {
|
||||||
let mut byte = [0; 1];
|
let mut byte = [0; 1];
|
||||||
|
@ -363,7 +355,7 @@ impl RTPBaseDepayloadImpl for RTPAv1Depay {
|
||||||
/// and will be at the first byte past the element's size field afterwards.
|
/// and will be at the first byte past the element's size field afterwards.
|
||||||
fn find_element_info(
|
fn find_element_info(
|
||||||
element: &<RTPAv1Depay as ObjectSubclass>::Type,
|
element: &<RTPAv1Depay as ObjectSubclass>::Type,
|
||||||
rtp: &RTPBuffer<Readable>,
|
rtp: &gst_rtp::RTPBuffer<gst_rtp::rtp_buffer::Readable>,
|
||||||
reader: &mut Cursor<&[u8]>,
|
reader: &mut Cursor<&[u8]>,
|
||||||
aggr_header: &AggregationHeader,
|
aggr_header: &AggregationHeader,
|
||||||
index: u32,
|
index: u32,
|
||||||
|
@ -410,8 +402,8 @@ fn translate_obu(
|
||||||
element: &<RTPAv1Depay as ObjectSubclass>::Type,
|
element: &<RTPAv1Depay as ObjectSubclass>::Type,
|
||||||
reader: &mut Cursor<&[u8]>,
|
reader: &mut Cursor<&[u8]>,
|
||||||
obu: &SizedObu,
|
obu: &SizedObu,
|
||||||
) -> Option<Buffer> {
|
) -> Option<gst::Buffer> {
|
||||||
let mut bytes = Buffer::with_size(obu.full_size() as usize)
|
let mut bytes = gst::Buffer::with_size(obu.full_size() as usize)
|
||||||
.map_err(err_opt!(element, buf_alloc))
|
.map_err(err_opt!(element, buf_alloc))
|
||||||
.ok()?
|
.ok()?
|
||||||
.into_mapped_buffer_writable()
|
.into_mapped_buffer_writable()
|
||||||
|
@ -457,9 +449,8 @@ fn translate_obu(
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use gst_rtp::prelude::*;
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
use gst::buffer::Buffer;
|
|
||||||
use gst_rtp::rtp_buffer::RTPBufferExt;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_translate_obu() {
|
fn test_translate_obu() {
|
||||||
|
@ -565,8 +556,8 @@ mod tests {
|
||||||
aggr_header,
|
aggr_header,
|
||||||
)) in test_data.into_iter().enumerate() {
|
)) in test_data.into_iter().enumerate() {
|
||||||
println!("running test {}...", idx);
|
println!("running test {}...", idx);
|
||||||
let buffer = Buffer::new_rtp_with_sizes(payload_size, 0, 0).unwrap();
|
let buffer = gst::Buffer::new_rtp_with_sizes(payload_size, 0, 0).unwrap();
|
||||||
let rtp = RTPBuffer::from_buffer_readable(&buffer).unwrap();
|
let rtp = gst_rtp::RTPBuffer::from_buffer_readable(&buffer).unwrap();
|
||||||
let mut reader = Cursor::new(rtp_bytes.as_slice());
|
let mut reader = Cursor::new(rtp_bytes.as_slice());
|
||||||
|
|
||||||
let mut element_size = 0;
|
let mut element_size = 0;
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
#![allow(clippy::new_without_default)]
|
#![allow(clippy::new_without_default)]
|
||||||
|
|
||||||
use glib::Object;
|
|
||||||
use gst::glib;
|
use gst::glib;
|
||||||
use gst::prelude::*;
|
use gst::prelude::*;
|
||||||
|
|
||||||
|
@ -21,7 +20,7 @@ glib::wrapper! {
|
||||||
|
|
||||||
impl RTPAv1Depay {
|
impl RTPAv1Depay {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Object::new(&[]).expect("Failed to create AV1 depayloader")
|
glib::Object::new(&[]).expect("Failed to create AV1 depayloader")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,14 +7,8 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
use gst::{
|
use gst::{glib, subclass::prelude::*};
|
||||||
glib,
|
use gst_rtp::{prelude::*, subclass::prelude::*};
|
||||||
subclass::{prelude::*, ElementMetadata},
|
|
||||||
Buffer, BufferFlags, Caps, ClockTime, DebugCategory, DebugColorFlags, Event, FlowError,
|
|
||||||
FlowSuccess, IntRange, LoggableError, PadDirection, PadPresence, PadTemplate, ResourceError,
|
|
||||||
StateChange, StateChangeError, StateChangeSuccess,
|
|
||||||
};
|
|
||||||
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,
|
sync::Mutex,
|
||||||
|
@ -27,10 +21,10 @@ use crate::common::{
|
||||||
err_flow, leb128_size, write_leb128, ObuType, SizedObu, CLOCK_RATE, ENDIANNESS,
|
err_flow, leb128_size, write_leb128, ObuType, SizedObu, CLOCK_RATE, ENDIANNESS,
|
||||||
};
|
};
|
||||||
|
|
||||||
static CAT: Lazy<DebugCategory> = Lazy::new(|| {
|
static CAT: Lazy<gst::DebugCategory> = Lazy::new(|| {
|
||||||
DebugCategory::new(
|
gst::DebugCategory::new(
|
||||||
"rtpav1pay",
|
"rtpav1pay",
|
||||||
DebugColorFlags::empty(),
|
gst::DebugColorFlags::empty(),
|
||||||
Some("RTP AV1 Payloader"),
|
Some("RTP AV1 Payloader"),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
@ -62,8 +56,8 @@ struct TempPacketData {
|
||||||
struct ObuData {
|
struct ObuData {
|
||||||
info: SizedObu,
|
info: SizedObu,
|
||||||
bytes: Vec<u8>,
|
bytes: Vec<u8>,
|
||||||
dts: Option<ClockTime>,
|
dts: Option<gst::ClockTime>,
|
||||||
pts: Option<ClockTime>,
|
pts: Option<gst::ClockTime>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
|
@ -114,9 +108,9 @@ impl RTPAv1Pay {
|
||||||
element: &<Self as ObjectSubclass>::Type,
|
element: &<Self as ObjectSubclass>::Type,
|
||||||
state: &mut State,
|
state: &mut State,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
dts: Option<ClockTime>,
|
dts: Option<gst::ClockTime>,
|
||||||
pts: Option<ClockTime>,
|
pts: Option<gst::ClockTime>,
|
||||||
) -> Result<gst::BufferList, FlowError> {
|
) -> Result<gst::BufferList, gst::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 {
|
||||||
|
@ -142,10 +136,10 @@ impl RTPAv1Pay {
|
||||||
if obu.size != 0 {
|
if obu.size != 0 {
|
||||||
gst::element_error!(
|
gst::element_error!(
|
||||||
element,
|
element,
|
||||||
ResourceError::Read,
|
gst::ResourceError::Read,
|
||||||
["temporal delimiter OBUs should have empty payload"]
|
["temporal delimiter OBUs should have empty payload"]
|
||||||
);
|
);
|
||||||
return Err(FlowError::Error);
|
return Err(gst::FlowError::Error);
|
||||||
}
|
}
|
||||||
state.obus.push(ObuData {
|
state.obus.push(ObuData {
|
||||||
info: obu,
|
info: obu,
|
||||||
|
@ -222,7 +216,7 @@ impl RTPAv1Pay {
|
||||||
|
|
||||||
let mut data = state.temp_packet_data.take().unwrap_or_else(|| {
|
let mut data = state.temp_packet_data.take().unwrap_or_else(|| {
|
||||||
TempPacketData {
|
TempPacketData {
|
||||||
payload_limit: RTPBuffer::calc_payload_len(element.mtu(), 0, 0),
|
payload_limit: gst_rtp::RTPBuffer::calc_payload_len(element.mtu(), 0, 0),
|
||||||
packet: PacketOBUData {
|
packet: PacketOBUData {
|
||||||
payload_size: 1, // 1 byte is used for the aggregation header
|
payload_size: 1, // 1 byte is used for the aggregation header
|
||||||
omit_last_size_field: true,
|
omit_last_size_field: true,
|
||||||
|
@ -341,7 +335,7 @@ impl RTPAv1Pay {
|
||||||
element: &<Self as ObjectSubclass>::Type,
|
element: &<Self as ObjectSubclass>::Type,
|
||||||
state: &mut State,
|
state: &mut State,
|
||||||
packet: PacketOBUData,
|
packet: PacketOBUData,
|
||||||
) -> Result<gst::Buffer, FlowError> {
|
) -> Result<gst::Buffer, gst::FlowError> {
|
||||||
gst::log!(
|
gst::log!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj: element,
|
||||||
|
@ -350,15 +344,16 @@ impl RTPAv1Pay {
|
||||||
);
|
);
|
||||||
|
|
||||||
// prepare the outgoing buffer
|
// prepare the outgoing buffer
|
||||||
let mut outbuf = Buffer::new_rtp_with_sizes(packet.payload_size, 0, 0).map_err(|err| {
|
let mut outbuf =
|
||||||
gst::element_error!(
|
gst::Buffer::new_rtp_with_sizes(packet.payload_size, 0, 0).map_err(|err| {
|
||||||
element,
|
gst::element_error!(
|
||||||
ResourceError::Write,
|
element,
|
||||||
["Failed to allocate output buffer: {}", err]
|
gst::ResourceError::Write,
|
||||||
);
|
["Failed to allocate output buffer: {}", err]
|
||||||
|
);
|
||||||
|
|
||||||
FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
{
|
{
|
||||||
// this block enforces that outbuf_mut is dropped before pushing outbuf
|
// this block enforces that outbuf_mut is dropped before pushing outbuf
|
||||||
|
@ -368,8 +363,8 @@ impl RTPAv1Pay {
|
||||||
outbuf_mut.set_dts(state.obus[0].dts);
|
outbuf_mut.set_dts(state.obus[0].dts);
|
||||||
outbuf_mut.set_pts(state.obus[0].pts);
|
outbuf_mut.set_pts(state.obus[0].pts);
|
||||||
|
|
||||||
let mut rtp =
|
let mut rtp = gst_rtp::RTPBuffer::from_buffer_writable(outbuf_mut)
|
||||||
RTPBuffer::from_buffer_writable(outbuf_mut).expect("Failed to create RTPBuffer");
|
.expect("Failed to create RTPBuffer");
|
||||||
rtp.set_marker(packet.ends_temporal_unit);
|
rtp.set_marker(packet.ends_temporal_unit);
|
||||||
|
|
||||||
let payload = rtp
|
let payload = rtp
|
||||||
|
@ -478,7 +473,7 @@ impl RTPAv1Pay {
|
||||||
impl ObjectSubclass for RTPAv1Pay {
|
impl ObjectSubclass for RTPAv1Pay {
|
||||||
const NAME: &'static str = "GstRtpAv1Pay";
|
const NAME: &'static str = "GstRtpAv1Pay";
|
||||||
type Type = super::RTPAv1Pay;
|
type Type = super::RTPAv1Pay;
|
||||||
type ParentType = RTPBasePayload;
|
type ParentType = gst_rtp::RTPBasePayload;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObjectImpl for RTPAv1Pay {}
|
impl ObjectImpl for RTPAv1Pay {}
|
||||||
|
@ -486,9 +481,9 @@ impl ObjectImpl for RTPAv1Pay {}
|
||||||
impl GstObjectImpl for RTPAv1Pay {}
|
impl GstObjectImpl for RTPAv1Pay {}
|
||||||
|
|
||||||
impl ElementImpl for RTPAv1Pay {
|
impl ElementImpl for RTPAv1Pay {
|
||||||
fn metadata() -> Option<&'static ElementMetadata> {
|
fn metadata() -> Option<&'static gst::subclass::ElementMetadata> {
|
||||||
static ELEMENT_METADATA: Lazy<ElementMetadata> = Lazy::new(|| {
|
static ELEMENT_METADATA: Lazy<gst::subclass::ElementMetadata> = Lazy::new(|| {
|
||||||
ElementMetadata::new(
|
gst::subclass::ElementMetadata::new(
|
||||||
"RTP AV1 payloader",
|
"RTP AV1 payloader",
|
||||||
"Codec/Payloader/Network/RTP",
|
"Codec/Payloader/Network/RTP",
|
||||||
"Payload AV1 as RTP packets",
|
"Payload AV1 as RTP packets",
|
||||||
|
@ -499,13 +494,13 @@ impl ElementImpl for RTPAv1Pay {
|
||||||
Some(&*ELEMENT_METADATA)
|
Some(&*ELEMENT_METADATA)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pad_templates() -> &'static [PadTemplate] {
|
fn pad_templates() -> &'static [gst::PadTemplate] {
|
||||||
static PAD_TEMPLATES: Lazy<Vec<PadTemplate>> = Lazy::new(|| {
|
static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| {
|
||||||
let sink_pad_template = PadTemplate::new(
|
let sink_pad_template = gst::PadTemplate::new(
|
||||||
"sink",
|
"sink",
|
||||||
PadDirection::Sink,
|
gst::PadDirection::Sink,
|
||||||
PadPresence::Always,
|
gst::PadPresence::Always,
|
||||||
&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", "obu")
|
||||||
|
@ -513,13 +508,13 @@ impl ElementImpl for RTPAv1Pay {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let src_pad_template = PadTemplate::new(
|
let src_pad_template = gst::PadTemplate::new(
|
||||||
"src",
|
"src",
|
||||||
PadDirection::Src,
|
gst::PadDirection::Src,
|
||||||
PadPresence::Always,
|
gst::PadPresence::Always,
|
||||||
&Caps::builder("application/x-rtp")
|
&gst::Caps::builder("application/x-rtp")
|
||||||
.field("media", "video")
|
.field("media", "video")
|
||||||
.field("payload", IntRange::new(96, 127))
|
.field("payload", gst::IntRange::new(96, 127))
|
||||||
.field("clock-rate", CLOCK_RATE as i32)
|
.field("clock-rate", CLOCK_RATE as i32)
|
||||||
.field("encoding-name", "AV1")
|
.field("encoding-name", "AV1")
|
||||||
.build(),
|
.build(),
|
||||||
|
@ -535,18 +530,18 @@ impl ElementImpl for RTPAv1Pay {
|
||||||
fn change_state(
|
fn change_state(
|
||||||
&self,
|
&self,
|
||||||
element: &Self::Type,
|
element: &Self::Type,
|
||||||
transition: StateChange,
|
transition: gst::StateChange,
|
||||||
) -> Result<StateChangeSuccess, StateChangeError> {
|
) -> Result<gst::StateChangeSuccess, gst::StateChangeError> {
|
||||||
gst::debug!(CAT, obj: element, "changing state: {}", transition);
|
gst::debug!(CAT, obj: element, "changing state: {}", transition);
|
||||||
|
|
||||||
if matches!(transition, StateChange::ReadyToPaused) {
|
if matches!(transition, gst::StateChange::ReadyToPaused) {
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
self.reset(element, &mut state);
|
self.reset(element, &mut state);
|
||||||
}
|
}
|
||||||
|
|
||||||
let ret = self.parent_change_state(element, transition);
|
let ret = self.parent_change_state(element, transition);
|
||||||
|
|
||||||
if matches!(transition, StateChange::PausedToReady) {
|
if matches!(transition, gst::StateChange::PausedToReady) {
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
self.reset(element, &mut state);
|
self.reset(element, &mut state);
|
||||||
}
|
}
|
||||||
|
@ -556,7 +551,7 @@ impl ElementImpl for RTPAv1Pay {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RTPBasePayloadImpl for RTPAv1Pay {
|
impl RTPBasePayloadImpl for RTPAv1Pay {
|
||||||
fn set_caps(&self, element: &Self::Type, _caps: &Caps) -> Result<(), LoggableError> {
|
fn set_caps(&self, element: &Self::Type, _caps: &gst::Caps) -> Result<(), gst::LoggableError> {
|
||||||
element.set_options("video", true, "AV1", CLOCK_RATE);
|
element.set_options("video", true, "AV1", CLOCK_RATE);
|
||||||
|
|
||||||
gst::debug!(CAT, obj: element, "setting caps");
|
gst::debug!(CAT, obj: element, "setting caps");
|
||||||
|
@ -567,8 +562,8 @@ impl RTPBasePayloadImpl for RTPAv1Pay {
|
||||||
fn handle_buffer(
|
fn handle_buffer(
|
||||||
&self,
|
&self,
|
||||||
element: &Self::Type,
|
element: &Self::Type,
|
||||||
buffer: Buffer,
|
buffer: gst::Buffer,
|
||||||
) -> Result<FlowSuccess, FlowError> {
|
) -> Result<gst::FlowSuccess, gst::FlowError> {
|
||||||
gst::trace!(
|
gst::trace!(
|
||||||
CAT,
|
CAT,
|
||||||
obj: element,
|
obj: element,
|
||||||
|
@ -578,7 +573,7 @@ impl RTPBasePayloadImpl for RTPAv1Pay {
|
||||||
|
|
||||||
let mut state = self.state.lock().unwrap();
|
let mut state = self.state.lock().unwrap();
|
||||||
|
|
||||||
if buffer.flags().contains(BufferFlags::DISCONT) {
|
if buffer.flags().contains(gst::BufferFlags::DISCONT) {
|
||||||
gst::debug!(CAT, obj: element, "buffer discontinuity");
|
gst::debug!(CAT, obj: element, "buffer discontinuity");
|
||||||
self.reset(element, &mut state);
|
self.reset(element, &mut state);
|
||||||
}
|
}
|
||||||
|
@ -589,11 +584,11 @@ impl RTPBasePayloadImpl for RTPAv1Pay {
|
||||||
let buffer = buffer.into_mapped_buffer_readable().map_err(|_| {
|
let buffer = buffer.into_mapped_buffer_readable().map_err(|_| {
|
||||||
gst::element_error!(
|
gst::element_error!(
|
||||||
element,
|
element,
|
||||||
ResourceError::Read,
|
gst::ResourceError::Read,
|
||||||
["Failed to map buffer readable"]
|
["Failed to map buffer readable"]
|
||||||
);
|
);
|
||||||
|
|
||||||
FlowError::Error
|
gst::FlowError::Error
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let list = 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)?;
|
||||||
|
@ -606,7 +601,7 @@ impl RTPBasePayloadImpl for RTPAv1Pay {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sink_event(&self, element: &Self::Type, event: Event) -> bool {
|
fn sink_event(&self, element: &Self::Type, event: gst::Event) -> bool {
|
||||||
gst::log!(CAT, obj: element, "sink event: {}", event.type_());
|
gst::log!(CAT, obj: element, "sink event: {}", event.type_());
|
||||||
|
|
||||||
match event.view() {
|
match event.view() {
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
#![allow(clippy::new_without_default)]
|
#![allow(clippy::new_without_default)]
|
||||||
|
|
||||||
use glib::Object;
|
|
||||||
use gst::glib;
|
use gst::glib;
|
||||||
use gst::prelude::*;
|
use gst::prelude::*;
|
||||||
|
|
||||||
|
@ -21,7 +20,7 @@ glib::wrapper! {
|
||||||
|
|
||||||
impl RTPAv1Pay {
|
impl RTPAv1Pay {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Object::new(&[]).expect("Failed to create AV1 payloader")
|
glib::Object::new(&[]).expect("Failed to create AV1 payloader")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue