mirror of
https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs.git
synced 2025-02-18 05:45:14 +00:00
rtp: opus: add test for payloader dtx packet handling
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1571>
This commit is contained in:
parent
2585639054
commit
92c0cf1285
3 changed files with 148 additions and 0 deletions
|
@ -2,3 +2,7 @@
|
||||||
|
|
||||||
pub mod depay;
|
pub mod depay;
|
||||||
pub mod pay;
|
pub mod pay;
|
||||||
|
|
||||||
|
#[allow(clippy::module_inception)]
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests;
|
||||||
|
|
3
net/rtp/src/opus/tests/mod.rs
Normal file
3
net/rtp/src/opus/tests/mod.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
|
mod tests;
|
141
net/rtp/src/opus/tests/tests.rs
Normal file
141
net/rtp/src/opus/tests/tests.rs
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
// GStreamer RTP Opus Payloader / Depayloader - unit tests
|
||||||
|
//
|
||||||
|
// Copyright (C) 2024 Tim-Philipp Müller <tim centricular com>
|
||||||
|
//
|
||||||
|
// This Source Code Form is subject to the terms of the Mozilla Public License, v2.0.
|
||||||
|
// If a copy of the MPL was not distributed with this file, You can obtain one at
|
||||||
|
// <https://mozilla.org/MPL/2.0/>.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
|
|
||||||
|
use crate::tests::{run_test_pipeline, ExpectedBuffer, ExpectedPacket, Source};
|
||||||
|
|
||||||
|
fn init() {
|
||||||
|
use std::sync::Once;
|
||||||
|
static INIT: Once = Once::new();
|
||||||
|
|
||||||
|
INIT.call_once(|| {
|
||||||
|
gst::init().unwrap();
|
||||||
|
crate::plugin_register_static().expect("rtpopus test");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// test_opus_pay_dtx
|
||||||
|
//
|
||||||
|
// Make sure payloader drops any DTX packets by the encoder (if so requested via the property)
|
||||||
|
//
|
||||||
|
#[test]
|
||||||
|
fn test_opus_pay_dtx() {
|
||||||
|
// gst-launch-1.0 audiotestsrc wave=silence
|
||||||
|
// ! opusenc dtx=true bitrate-type=vbr
|
||||||
|
// ! fakesink silent=false dump=true
|
||||||
|
const OPUS_BUFFER_SILENCE: &[u8] = &[0xf8, 0xff, 0xfe];
|
||||||
|
const OPUS_BUFFER_SILENCE_DTX: &[u8] = &[0xf8];
|
||||||
|
|
||||||
|
fn make_buffer(
|
||||||
|
data: &'static [u8],
|
||||||
|
pts: gst::ClockTime,
|
||||||
|
duration: gst::ClockTime,
|
||||||
|
flags: gst::BufferFlags,
|
||||||
|
) -> gst::Buffer {
|
||||||
|
let mut buf = gst::Buffer::from_slice(data);
|
||||||
|
|
||||||
|
let buf_ref = buf.get_mut().unwrap();
|
||||||
|
buf_ref.set_pts(pts);
|
||||||
|
buf_ref.set_duration(duration);
|
||||||
|
buf_ref.set_flags(flags);
|
||||||
|
|
||||||
|
buf
|
||||||
|
}
|
||||||
|
|
||||||
|
init();
|
||||||
|
|
||||||
|
for dtx_prop in [false, true] {
|
||||||
|
eprintln!("Testing rtpopuspay2 dtx={dtx_prop} ..");
|
||||||
|
|
||||||
|
let input_caps = gst::Caps::builder("audio/x-opus")
|
||||||
|
.field("rate", 48000i32)
|
||||||
|
.field("channels", 1i32)
|
||||||
|
.field("channel-mapping-family", 0i32)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let input_buffers = vec![
|
||||||
|
make_buffer(
|
||||||
|
OPUS_BUFFER_SILENCE,
|
||||||
|
gst::ClockTime::ZERO,
|
||||||
|
gst::ClockTime::from_useconds(13500),
|
||||||
|
gst::BufferFlags::DISCONT,
|
||||||
|
),
|
||||||
|
make_buffer(
|
||||||
|
OPUS_BUFFER_SILENCE,
|
||||||
|
gst::ClockTime::from_useconds(13500),
|
||||||
|
gst::ClockTime::from_mseconds(20),
|
||||||
|
gst::BufferFlags::empty(),
|
||||||
|
),
|
||||||
|
make_buffer(
|
||||||
|
OPUS_BUFFER_SILENCE_DTX,
|
||||||
|
gst::ClockTime::from_useconds(33500),
|
||||||
|
gst::ClockTime::from_mseconds(20),
|
||||||
|
gst::BufferFlags::empty(),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
// TODO: check durations?
|
||||||
|
let mut expected_pay = vec![
|
||||||
|
vec![ExpectedPacket::builder()
|
||||||
|
.pts(gst::ClockTime::ZERO)
|
||||||
|
.flags(gst::BufferFlags::DISCONT | gst::BufferFlags::MARKER)
|
||||||
|
.pt(96)
|
||||||
|
.rtp_time(0)
|
||||||
|
.marker_bit(true)
|
||||||
|
.build()],
|
||||||
|
vec![ExpectedPacket::builder()
|
||||||
|
.pts(gst::ClockTime::from_useconds(13500))
|
||||||
|
.flags(gst::BufferFlags::empty())
|
||||||
|
.pt(96)
|
||||||
|
.rtp_time(648)
|
||||||
|
.marker_bit(false)
|
||||||
|
.build()],
|
||||||
|
vec![ExpectedPacket::builder()
|
||||||
|
.pts(gst::ClockTime::from_useconds(33500))
|
||||||
|
.flags(gst::BufferFlags::empty())
|
||||||
|
.pt(96)
|
||||||
|
.rtp_time(648 + 960)
|
||||||
|
.marker_bit(false)
|
||||||
|
.build()],
|
||||||
|
];
|
||||||
|
|
||||||
|
// TODO: check durations?
|
||||||
|
let mut expected_depay = vec![
|
||||||
|
vec![ExpectedBuffer::builder()
|
||||||
|
.pts(gst::ClockTime::ZERO)
|
||||||
|
.size(3)
|
||||||
|
.flags(gst::BufferFlags::DISCONT | gst::BufferFlags::RESYNC)
|
||||||
|
.build()],
|
||||||
|
vec![ExpectedBuffer::builder()
|
||||||
|
.pts(gst::ClockTime::from_useconds(13500))
|
||||||
|
.size(3)
|
||||||
|
.flags(gst::BufferFlags::empty())
|
||||||
|
.build()],
|
||||||
|
vec![ExpectedBuffer::builder()
|
||||||
|
.pts(gst::ClockTime::from_useconds(33500))
|
||||||
|
.size(1)
|
||||||
|
.flags(gst::BufferFlags::empty())
|
||||||
|
.build()],
|
||||||
|
];
|
||||||
|
|
||||||
|
if dtx_prop {
|
||||||
|
// Payloader should drop DTX buffer if dtx=true and not output it
|
||||||
|
expected_pay.pop();
|
||||||
|
expected_depay.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
run_test_pipeline(
|
||||||
|
Source::Buffers(input_caps, input_buffers),
|
||||||
|
&format!("rtpopuspay2 dtx={dtx_prop}"),
|
||||||
|
"rtpopusdepay2",
|
||||||
|
expected_pay,
|
||||||
|
expected_depay,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue