examples, audio, pbutils, video: Use AudioCapsBuilder and VideoCapsBuilder

Simplify caps creation code
This commit is contained in:
Vivia Nikolaidou 2022-10-14 13:19:49 +03:00
parent 734afa998b
commit 6d4ad712c7
18 changed files with 67 additions and 93 deletions

View file

@ -16,7 +16,6 @@ use gst::prelude::*;
use byte_slice_cast::*;
use std::i16;
use std::i32;
use anyhow::Error;
use derive_more::{Display, Error};
@ -57,11 +56,9 @@ fn create_pipeline() -> Result<gst::Pipeline, Error> {
// This can be set after linking the two objects, because format negotiation between
// both elements will happen during pre-rolling of the pipeline.
appsink.set_caps(Some(
&gst::Caps::builder("audio/x-raw")
.field("format", gst_audio::AUDIO_FORMAT_S16.to_str())
.field("layout", "interleaved")
.field("channels", 1i32)
.field("rate", gst::IntRange::<i32>::new(1, i32::MAX))
&gst_audio::AudioCapsBuilder::new_interleaved()
.format(gst_audio::AUDIO_FORMAT_S16)
.channels(1)
.build(),
));

View file

@ -123,18 +123,9 @@ mod cairo_compositor {
// GStreamer about all possible pads that could exist for this type.
// On all pads we can only handle BGRx.
let caps = gst::Caps::builder("video/x-raw")
.field("format", gst_video::VideoFormat::Bgrx.to_str())
.field("width", gst::IntRange::<i32>::new(1, i32::MAX))
.field("height", gst::IntRange::<i32>::new(1, i32::MAX))
let caps = gst_video::VideoCapsBuilder::new()
.format(gst_video::VideoFormat::Bgrx)
.field("pixel-aspect-ratio", gst::Fraction::new(1, 1))
.field(
"framerate",
gst::FractionRange::new(
gst::Fraction::new(0, 1),
gst::Fraction::new(i32::MAX, 1),
),
)
.build();
vec![

View file

@ -459,8 +459,8 @@ mod video_filter {
impl ElementImpl for FdMemoryFadeInVideoFilter {
fn pad_templates() -> &'static [PadTemplate] {
static PAD_TEMPLATES: Lazy<Vec<PadTemplate>> = Lazy::new(|| {
let caps = gst::Caps::builder("video/x-raw")
.field("format", "BGRA")
let caps = gst_video::VideoCapsBuilder::new()
.format(gst_video::VideoFormat::Bgra)
.build();
vec![
PadTemplate::new("sink", PadDirection::Sink, PadPresence::Always, &caps)

View file

@ -75,10 +75,10 @@ fn create_pipeline() -> Result<gst::Pipeline, Error> {
// Plug in a capsfilter element that will force the videotestsrc and the overlay to work
// with images of the size 800x800, and framerate of 15 fps, since my laptop struggles
// rendering it at the default 30 fps
let caps = gst::Caps::builder("video/x-raw")
.field("width", 800i32)
.field("height", 800i32)
.field("framerate", gst::Fraction::new(15, 1))
let caps = gst_video::VideoCapsBuilder::new()
.width(800)
.height(800)
.framerate(gst::Fraction::new(15, 1))
.build();
capsfilter.set_property("caps", &caps);

View file

@ -77,9 +77,9 @@ fn create_pipeline() -> Result<gst::Pipeline, Error> {
// Plug in a capsfilter element that will force the videotestsrc and the cairooverlay to work
// with images of the size 800x800.
let caps = gst::Caps::builder("video/x-raw")
.field("width", 800i32)
.field("height", 800i32)
let caps = gst_video::VideoCapsBuilder::new()
.width(800)
.height(800)
.build();
capsfilter.set_property("caps", &caps);

View file

@ -222,9 +222,9 @@ fn example_main() -> Result<(), Error> {
.field("clock-rate", 90000i32)
.build();
let video_caps = gst::Caps::builder("video/x-raw")
.field("width", 1920i32)
.field("height", 1080i32)
let video_caps = gst_video::VideoCapsBuilder::new()
.width(1920)
.height(1080)
.build();
src.set_property("address", "127.0.0.1");

View file

@ -36,7 +36,6 @@ mod fir_filter {
mod imp {
use super::*;
use std::collections::VecDeque;
use std::i32;
use std::sync::Mutex;
// This is the private data of our filter
@ -86,11 +85,9 @@ mod fir_filter {
// GStreamer about all possible pads that could exist for this type.
// On both of pads we can only handle F32 mono at any sample rate.
let caps = gst::Caps::builder("audio/x-raw")
.field("format", gst_audio::AUDIO_FORMAT_F32.to_str())
.field("rate", gst::IntRange::<i32>::new(1, i32::MAX))
.field("channels", 1i32)
.field("layout", "interleaved")
let caps = gst_audio::AudioCapsBuilder::new_interleaved()
.format(gst_audio::AUDIO_FORMAT_F32)
.channels(1)
.build();
vec![

View file

@ -54,8 +54,8 @@ fn create_pipeline(uri: String, out_path: std::path::PathBuf) -> Result<gst::Pip
// This can be set after linking the two objects, because format negotiation between
// both elements will happen during pre-rolling of the pipeline.
appsink.set_caps(Some(
&gst::Caps::builder("video/x-raw")
.field("format", gst_video::VideoFormat::Rgbx.to_str())
&gst_video::VideoCapsBuilder::new()
.format(gst_video::VideoFormat::Rgbx)
.build(),
));

View file

@ -547,9 +547,9 @@ impl App {
appsink.set_property("emit-signals", false);
appsink.set_property("max-buffers", 1u32);
let caps = gst::Caps::builder("video/x-raw")
let caps = gst_video::VideoCapsBuilder::new()
.features(&[&gst_gl::CAPS_FEATURE_MEMORY_GL_MEMORY])
.field("format", gst_video::VideoFormat::Rgba.to_str())
.format(gst_video::VideoFormat::Rgba)
.field("texture-target", "2D")
.build();
appsink.set_caps(Some(&caps));

View file

@ -315,7 +315,7 @@ pub trait AudioFormatIteratorExt {
fn into_audio_caps(
self,
layout: crate::AudioLayout,
) -> Option<gst::caps::Builder<gst::caps::NoFeature>>;
) -> Option<crate::AudioCapsBuilder<gst::caps::NoFeature>>;
}
impl<T> AudioFormatIteratorExt for T
@ -325,7 +325,7 @@ where
fn into_audio_caps(
self,
layout: crate::AudioLayout,
) -> Option<gst::caps::Builder<gst::caps::NoFeature>> {
) -> Option<crate::AudioCapsBuilder<gst::caps::NoFeature>> {
let formats: Vec<crate::AudioFormat> = self.collect();
if !formats.is_empty() {
Some(crate::functions::audio_make_raw_caps(&formats, layout))
@ -339,7 +339,7 @@ pub trait AudioFormatIteratorExtRef {
fn into_audio_caps(
self,
layout: crate::AudioLayout,
) -> Option<gst::caps::Builder<gst::caps::NoFeature>>;
) -> Option<crate::AudioCapsBuilder<gst::caps::NoFeature>>;
}
impl<'a, T> AudioFormatIteratorExtRef for T
@ -349,7 +349,7 @@ where
fn into_audio_caps(
self,
layout: crate::AudioLayout,
) -> Option<gst::caps::Builder<gst::caps::NoFeature>> {
) -> Option<crate::AudioCapsBuilder<gst::caps::NoFeature>> {
let formats: Vec<crate::AudioFormat> = self.copied().collect();
if !formats.is_empty() {
Some(crate::functions::audio_make_raw_caps(&formats, layout))
@ -416,7 +416,7 @@ mod tests {
.into_audio_caps(crate::AudioLayout::Interleaved)
.unwrap()
.build();
assert_eq!(caps.to_string(), "audio/x-raw, format=(string){ S16LE, S16BE }, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ], layout=(string)interleaved");
assert_eq!(caps.to_string(), "audio/x-raw, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ], layout=(string)interleaved, format=(string){ S16LE, S16BE }");
}
#[test]

View file

@ -468,11 +468,10 @@ mod tests {
fn test_from_to_caps() {
gst::init().unwrap();
let caps = gst::Caps::builder("audio/x-raw")
.field("format", "S16LE")
.field("rate", 48000)
.field("channels", 2)
.field("layout", "interleaved")
let caps = crate::AudioCapsBuilder::new_interleaved()
.format(crate::AudioFormat::S16le)
.rate(48000)
.channels(2)
.field("channel-mask", gst::Bitmask::new(0x3))
.build();
let info = AudioInfo::from_caps(&caps).unwrap();

View file

@ -119,6 +119,7 @@ impl<T> AudioCapsBuilder<T> {
}
}
#[must_use]
pub fn build(self) -> gst::Caps {
self.builder.build()
}

View file

@ -1,7 +1,6 @@
// Take a look at the license at the top of the repository in the LICENSE file.
use glib::translate::{from_glib_full, IntoGlibPtr, ToGlibPtr};
use glib::ToSendValue;
use std::i32;
@ -48,19 +47,16 @@ pub fn audio_buffer_truncate(
pub fn audio_make_raw_caps(
formats: &[crate::AudioFormat],
layout: crate::AudioLayout,
) -> gst::caps::Builder<gst::caps::NoFeature> {
) -> crate::AudioCapsBuilder<gst::caps::NoFeature> {
assert_initialized_main_thread!();
let formats = formats.iter().map(|f| match f {
let formats = formats.iter().copied().map(|f| match f {
crate::AudioFormat::Encoded => panic!("Invalid encoded format"),
crate::AudioFormat::Unknown => panic!("Invalid unknown format"),
_ => f.to_string().to_send_value(),
_ => f,
});
let builder = gst::caps::Caps::builder("audio/x-raw")
.field("format", gst::List::from_values(formats))
.field("rate", gst::IntRange::new(1, i32::MAX))
.field("channels", gst::IntRange::new(1, i32::MAX));
let builder = crate::AudioCapsBuilder::new().format_list(formats);
match layout {
crate::AudioLayout::Interleaved => builder.field("layout", "interleaved"),
@ -82,7 +78,7 @@ mod tests {
crate::AudioLayout::Interleaved,
)
.build();
assert_eq!(caps.to_string(), "audio/x-raw, format=(string){ S16BE, S16LE }, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ], layout=(string)interleaved");
assert_eq!(caps.to_string(), "audio/x-raw, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ], layout=(string)interleaved, format=(string){ S16BE, S16LE }");
#[cfg(feature = "v1_18")]
{
@ -109,12 +105,12 @@ mod tests {
&[crate::AudioFormat::S16be, crate::AudioFormat::S16le],
crate::AudioLayout::NonInterleaved,
)
.field("rate", 16000)
.field("channels", 2)
.rate(16000)
.channels(2)
.build();
assert_eq!(
caps.to_string(),
"audio/x-raw, format=(string){ S16BE, S16LE }, rate=(int)16000, channels=(int)2, layout=(string)non-interleaved"
"audio/x-raw, rate=(int)16000, channels=(int)2, layout=(string)non-interleaved, format=(string){ S16BE, S16LE }",
);
}

View file

@ -637,8 +637,8 @@ mod tests {
let caps = gst::Caps::builder("audio/x-raw").build();
let restriction = gst::Caps::builder("audio/x-raw")
.field("format", "S32LE")
let restriction = gst_audio::AudioCapsBuilder::new()
.format(gst_audio::AudioFormat::S32le)
.build();
let audio_profile = EncodingAudioProfile::builder(&caps)
@ -665,8 +665,8 @@ mod tests {
assert_eq!(audio_profile.allows_dynamic_output(), ALLOW_DYNAMIC_OUTPUT);
assert_eq!(audio_profile.is_enabled(), ENABLED);
let restriction = gst::Caps::builder("audio/x-raw")
.field("format", "S32BE")
let restriction = gst_audio::AudioCapsBuilder::new()
.format(gst_audio::AudioFormat::S32be)
.build();
audio_profile.set_restriction(Some(&restriction));
assert_eq!(audio_profile.restriction().unwrap(), restriction);
@ -678,8 +678,8 @@ mod tests {
let caps = gst::Caps::builder("video/x-raw").build();
let restriction = gst::Caps::builder("video/x-raw")
.field("format", "RGBA")
let restriction = gst_video::VideoCapsBuilder::new()
.format(gst_video::VideoFormat::Rgba)
.build();
let video_profile = EncodingVideoProfile::builder(&caps)
@ -713,8 +713,8 @@ mod tests {
assert_eq!(video_profile.is_variableframerate(), VARIABLE_FRAMERATE);
assert_eq!(video_profile.pass(), PASS);
let restriction = gst::Caps::builder("video/x-raw")
.field("format", "NV12")
let restriction = gst_video::VideoCapsBuilder::new()
.format(gst_video::VideoFormat::Nv12)
.build();
video_profile.set_restriction(Some(&restriction));
assert_eq!(video_profile.restriction().unwrap(), restriction);

View file

@ -182,6 +182,7 @@ impl<T> VideoCapsBuilder<T> {
}
}
#[must_use]
pub fn build(self) -> gst::Caps {
self.builder.build()
}

View file

@ -1,7 +1,6 @@
// Take a look at the license at the top of the repository in the LICENSE file.
use glib::translate::{from_glib, from_glib_full, IntoGlib, ToGlibPtr};
use glib::ToSendValue;
use std::i32;
use std::mem;
@ -214,23 +213,16 @@ pub fn is_common_aspect_ratio(width: u32, height: u32, par: gst::Fraction) -> bo
pub fn video_make_raw_caps(
formats: &[crate::VideoFormat],
) -> gst::caps::Builder<gst::caps::NoFeature> {
) -> crate::VideoCapsBuilder<gst::caps::NoFeature> {
assert_initialized_main_thread!();
let formats = formats.iter().map(|f| match f {
let formats = formats.iter().copied().map(|f| match f {
crate::VideoFormat::Encoded => panic!("Invalid encoded format"),
crate::VideoFormat::Unknown => panic!("Invalid unknown format"),
_ => f.to_string().to_send_value(),
_ => f,
});
gst::caps::Caps::builder("video/x-raw")
.field("format", gst::List::from_values(formats))
.field("width", gst::IntRange::new(1, i32::MAX))
.field("height", gst::IntRange::new(1, i32::MAX))
.field(
"framerate",
gst::FractionRange::new(gst::Fraction::new(0, 1), gst::Fraction::new(i32::MAX, 1)),
)
crate::VideoCapsBuilder::new().format_list(formats)
}
#[cfg(test)]
@ -321,9 +313,9 @@ mod tests {
}
let caps = video_make_raw_caps(&[crate::VideoFormat::Nv12, crate::VideoFormat::Nv16])
.field("width", 800)
.field("height", 600)
.field("framerate", gst::Fraction::new(30, 1))
.width(800)
.height(600)
.framerate(gst::Fraction::new(30, 1))
.build();
assert_eq!(caps.to_string(), "video/x-raw, format=(string){ NV12, NV16 }, width=(int)800, height=(int)600, framerate=(fraction)30/1");
}

View file

@ -407,14 +407,14 @@ impl DoubleEndedIterator for VideoFormatIterator {
}
}
pub trait VideoFormatIteratorExt {
fn into_video_caps(self) -> Option<gst::caps::Builder<gst::caps::NoFeature>>;
fn into_video_caps(self) -> Option<crate::VideoCapsBuilder<gst::caps::NoFeature>>;
}
impl<T> VideoFormatIteratorExt for T
where
T: Iterator<Item = crate::VideoFormat>,
{
fn into_video_caps(self) -> Option<gst::caps::Builder<gst::caps::NoFeature>> {
fn into_video_caps(self) -> Option<crate::VideoCapsBuilder<gst::caps::NoFeature>> {
let formats: Vec<crate::VideoFormat> = self.collect();
if !formats.is_empty() {
Some(crate::functions::video_make_raw_caps(&formats))
@ -425,14 +425,14 @@ where
}
pub trait VideoFormatIteratorExtRef {
fn into_video_caps(self) -> Option<gst::caps::Builder<gst::caps::NoFeature>>;
fn into_video_caps(self) -> Option<crate::VideoCapsBuilder<gst::caps::NoFeature>>;
}
impl<'a, T> VideoFormatIteratorExtRef for T
where
T: Iterator<Item = &'a crate::VideoFormat>,
{
fn into_video_caps(self) -> Option<gst::caps::Builder<gst::caps::NoFeature>> {
fn into_video_caps(self) -> Option<crate::VideoCapsBuilder<gst::caps::NoFeature>> {
let formats: Vec<crate::VideoFormat> = self.copied().collect();
if !formats.is_empty() {
Some(crate::functions::video_make_raw_caps(&formats))

View file

@ -1038,11 +1038,11 @@ mod tests {
fn test_from_to_caps() {
gst::init().unwrap();
let caps = gst::Caps::builder("video/x-raw")
.field("format", "I420")
.field("width", 320)
.field("height", 240)
.field("framerate", gst::Fraction::new(30, 1))
let caps = crate::VideoCapsBuilder::new()
.format(crate::VideoFormat::I420)
.width(320)
.height(240)
.framerate(gst::Fraction::new(30, 1))
.field("pixel-aspect-ratio", gst::Fraction::new(1, 1))
.field("interlace-mode", "progressive")
.field("chroma-site", "mpeg2")