plugins, examples, tutorials: Use AudioCapsBuilder and VideoCapsBuilder

Simplify caps creation code
This commit is contained in:
Vivia Nikolaidou 2022-10-13 21:02:04 +03:00
parent 862c2af1d9
commit f11b0fa5eb
20 changed files with 153 additions and 242 deletions

View file

@ -547,11 +547,9 @@ impl ElementImpl for HrtfRender {
fn pad_templates() -> &'static [gst::PadTemplate] { fn pad_templates() -> &'static [gst::PadTemplate] {
static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| { static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| {
let src_caps = gst::Caps::builder("audio/x-raw") let src_caps = gst_audio::AudioCapsBuilder::new_interleaved()
.field("format", gst_audio::AUDIO_FORMAT_F32.to_str()) .channels(2)
.field("rate", gst::IntRange::new(1, i32::MAX)) .format(gst_audio::AUDIO_FORMAT_F32)
.field("channels", 2i32)
.field("layout", "interleaved")
.build(); .build();
let src_pad_template = gst::PadTemplate::new( let src_pad_template = gst::PadTemplate::new(
@ -562,11 +560,9 @@ impl ElementImpl for HrtfRender {
) )
.unwrap(); .unwrap();
let sink_caps = gst::Caps::builder("audio/x-raw") let sink_caps = gst_audio::AudioCapsBuilder::new_interleaved()
.field("format", gst_audio::AUDIO_FORMAT_F32.to_str()) .channels_range(1..=64)
.field("rate", gst::IntRange::new(1, i32::MAX)) .format(gst_audio::AUDIO_FORMAT_F32)
.field("channels", gst::IntRange::new(1i32, 64))
.field("layout", "interleaved")
.build(); .build();
let sink_pad_template = gst::PadTemplate::new( let sink_pad_template = gst::PadTemplate::new(

View file

@ -40,19 +40,17 @@ fn build_harness(src_caps: gst::Caps, sink_caps: gst::Caps) -> (gst_check::Harne
fn test_hrtfrender_samples_in_samples_out() { fn test_hrtfrender_samples_in_samples_out() {
init(); init();
let src_caps = gst::Caps::builder("audio/x-raw") let src_caps = gst_audio::AudioCapsBuilder::new_interleaved()
.field("format", gst_audio::AUDIO_FORMAT_F32.to_str()) .format(gst_audio::AUDIO_FORMAT_F32)
.field("rate", 44_100i32) .rate(44_100)
.field("channels", 1i32) .channels(1)
.field("channel-mask", gst::Bitmask::new(0x1)) .field("channel-mask", gst::Bitmask::new(0x1))
.field("layout", "interleaved")
.build(); .build();
let sink_caps = gst::Caps::builder("audio/x-raw") let sink_caps = gst_audio::AudioCapsBuilder::new_interleaved()
.field("format", gst_audio::AUDIO_FORMAT_F32.to_str()) .format(gst_audio::AUDIO_FORMAT_F32)
.field("rate", 44_100i32) .rate(44_100)
.field("channels", 2i32) .channels(2)
.field("layout", "interleaved")
.build(); .build();
let (mut h, _) = build_harness(src_caps, sink_caps); let (mut h, _) = build_harness(src_caps, sink_caps);
@ -97,19 +95,17 @@ fn test_hrtfrender_samples_in_samples_out() {
fn test_hrtfrender_implicit_spatial_objects() { fn test_hrtfrender_implicit_spatial_objects() {
init(); init();
let src_caps = gst::Caps::builder("audio/x-raw") let src_caps = gst_audio::AudioCapsBuilder::new_interleaved()
.field("format", gst_audio::AUDIO_FORMAT_F32.to_str()) .format(gst_audio::AUDIO_FORMAT_F32)
.field("rate", 44_100i32) .rate(44_100)
.field("channels", 8i32) .channels(8)
.field("channel-mask", gst::Bitmask::new(0xc3f)) .field("channel-mask", gst::Bitmask::new(0xc3f))
.field("layout", "interleaved")
.build(); .build();
let sink_caps = gst::Caps::builder("audio/x-raw") let sink_caps = gst_audio::AudioCapsBuilder::new_interleaved()
.field("format", gst_audio::AUDIO_FORMAT_F32.to_str()) .format(gst_audio::AUDIO_FORMAT_F32)
.field("rate", 44_100i32) .rate(44_100)
.field("channels", 2i32) .channels(2)
.field("layout", "interleaved")
.build(); .build();
let (mut h, hrtf) = build_harness(src_caps, sink_caps); let (mut h, hrtf) = build_harness(src_caps, sink_caps);
@ -124,18 +120,16 @@ fn test_hrtfrender_implicit_spatial_objects() {
fn test_hrtfrender_explicit_spatial_objects() { fn test_hrtfrender_explicit_spatial_objects() {
init(); init();
let src_caps = gst::Caps::builder("audio/x-raw") let src_caps = gst_audio::AudioCapsBuilder::new_interleaved()
.field("format", gst_audio::AUDIO_FORMAT_F32.to_str()) .format(gst_audio::AUDIO_FORMAT_F32)
.field("rate", 44_100i32) .rate(44_100)
.field("channels", 8i32) .channels(8)
.field("layout", "interleaved")
.build(); .build();
let sink_caps = gst::Caps::builder("audio/x-raw") let sink_caps = gst_audio::AudioCapsBuilder::new_interleaved()
.field("format", gst_audio::AUDIO_FORMAT_F32.to_str()) .format(gst_audio::AUDIO_FORMAT_F32)
.field("rate", 44_100i32) .rate(44_100)
.field("channels", 2i32) .channels(2)
.field("layout", "interleaved")
.build(); .build();
let (mut h, hrtf) = build_harness(src_caps, sink_caps); let (mut h, hrtf) = build_harness(src_caps, sink_caps);
@ -166,18 +160,16 @@ fn test_hrtfrender_explicit_spatial_objects() {
fn test_hrtfrender_caps_negotiation_fail() { fn test_hrtfrender_caps_negotiation_fail() {
init(); init();
let src_caps = gst::Caps::builder("audio/x-raw") let src_caps = gst_audio::AudioCapsBuilder::new_interleaved()
.field("format", gst_audio::AUDIO_FORMAT_F32.to_str()) .format(gst_audio::AUDIO_FORMAT_F32)
.field("rate", 44_100i32) .rate(44_100)
.field("channels", 6i32) .channels(6)
.field("layout", "interleaved")
.build(); .build();
let sink_caps = gst::Caps::builder("audio/x-raw") let sink_caps = gst_audio::AudioCapsBuilder::new_interleaved()
.field("format", gst_audio::AUDIO_FORMAT_F32.to_str()) .format(gst_audio::AUDIO_FORMAT_F32)
.field("rate", 44_100i32) .rate(44_100)
.field("channels", 2i32) .channels(2)
.field("layout", "interleaved")
.build(); .build();
let (mut h, hrtf) = build_harness(src_caps, sink_caps); let (mut h, hrtf) = build_harness(src_caps, sink_caps);
@ -213,18 +205,16 @@ fn test_hrtfrender_caps_negotiation_fail() {
fn test_hrtfrender_multiple_instances_sharing_thread_pool() { fn test_hrtfrender_multiple_instances_sharing_thread_pool() {
init(); init();
let src_caps = gst::Caps::builder("audio/x-raw") let src_caps = gst_audio::AudioCapsBuilder::new_interleaved()
.field("format", gst_audio::AUDIO_FORMAT_F32.to_str()) .format(gst_audio::AUDIO_FORMAT_F32)
.field("rate", 44_100i32) .rate(44_100)
.field("channels", 1i32) .channels(1)
.field("layout", "interleaved")
.build(); .build();
let sink_caps = gst::Caps::builder("audio/x-raw") let sink_caps = gst_audio::AudioCapsBuilder::new_interleaved()
.field("format", gst_audio::AUDIO_FORMAT_F32.to_str()) .format(gst_audio::AUDIO_FORMAT_F32)
.field("rate", 44_100i32) .rate(44_100)
.field("channels", 2i32) .channels(2)
.field("layout", "interleaved")
.build(); .build();
let (_, hrtf) = build_harness(src_caps.clone(), sink_caps.clone()); let (_, hrtf) = build_harness(src_caps.clone(), sink_caps.clone());

View file

@ -50,11 +50,10 @@ fn test_stereo_s32() {
assert_eq!( assert_eq!(
caps, caps,
gst::Caps::builder("audio/x-raw") gst_audio::AudioCapsBuilder::new_interleaved()
.field("format", gst_audio::AUDIO_FORMAT_S2432.to_str()) .format(gst_audio::AUDIO_FORMAT_S2432)
.field("rate", 44_100i32) .rate(44100)
.field("channels", 2i32) .channels(2)
.field("layout", "interleaved")
.field("channel-mask", gst::Bitmask::new(0x3)) .field("channel-mask", gst::Bitmask::new(0x3))
.build() .build()
); );

View file

@ -91,11 +91,10 @@ fn csound_filter_eos() {
let num_channels = 1; let num_channels = 1;
let sr: i32 = 44_100; let sr: i32 = 44_100;
let caps = gst::Caps::builder("audio/x-raw") let caps = gst_audio::AudioCapsBuilder::new_interleaved()
.field("format", gst_audio::AUDIO_FORMAT_F64.to_str()) .format(gst_audio::AUDIO_FORMAT_F64)
.field("rate", sr) .rate(sr)
.field("channels", num_channels) .channels(num_channels)
.field("layout", "interleaved")
.build(); .build();
let mut h = build_harness( let mut h = build_harness(
@ -201,11 +200,10 @@ fn csound_filter_underflow() {
let num_channels = 1; let num_channels = 1;
let sr: i32 = 44_100; let sr: i32 = 44_100;
let caps = gst::Caps::builder("audio/x-raw") let caps = gst_audio::AudioCapsBuilder::new_interleaved()
.field("format", gst_audio::AUDIO_FORMAT_F64.to_str()) .format(gst_audio::AUDIO_FORMAT_F64)
.field("rate", sr) .rate(sr)
.field("channels", num_channels) .channels(num_channels)
.field("layout", "interleaved")
.build(); .build();
let mut h = build_harness( let mut h = build_harness(
@ -280,20 +278,18 @@ fn csound_filter_caps_negotiation() {
let ochannels = 1; let ochannels = 1;
let sr: i32 = 44_100; let sr: i32 = 44_100;
let src_caps = gst::Caps::builder("audio/x-raw") let src_caps = gst_audio::AudioCapsBuilder::new_interleaved()
.field("format", gst_audio::AUDIO_FORMAT_F64.to_str()) .format(gst_audio::AUDIO_FORMAT_F64)
.field("rate", sr) .rate(sr)
.field("channels", ichannels) .channels(ichannels)
.field("layout", "interleaved")
.build(); .build();
// Define the output caps which would be fixated // Define the output caps which would be fixated
// at the end of the caps negotiation // at the end of the caps negotiation
let sink_caps = gst::Caps::builder("audio/x-raw") let sink_caps = gst_audio::AudioCapsBuilder::new_interleaved()
.field("format", gst_audio::AUDIO_FORMAT_F64.to_str()) .format(gst_audio::AUDIO_FORMAT_F64)
.field("rate", gst::IntRange::new(1i32, 48000)) .rate_range(1..=48000)
.field("channels", gst::IntRange::new(1i32, 2)) .channels_range(1..=2)
.field("layout", "interleaved")
.build(); .build();
// build the harness setting its src and sink caps, // build the harness setting its src and sink caps,
@ -329,11 +325,10 @@ fn csound_filter_caps_negotiation() {
.expect("pad has no caps"); .expect("pad has no caps");
// our expected caps at the harness sinkpad // our expected caps at the harness sinkpad
let expected_caps = gst::Caps::builder("audio/x-raw") let expected_caps = gst_audio::AudioCapsBuilder::new_interleaved()
.field("format", gst_audio::AUDIO_FORMAT_F64.to_str()) .format(gst_audio::AUDIO_FORMAT_F64)
.field("rate", 44_100i32) .rate(44_100)
.field("channels", ochannels) .channels(ochannels)
.field("layout", "interleaved")
.build(); .build();
assert_eq!(harness_sink_caps, expected_caps); assert_eq!(harness_sink_caps, expected_caps);
@ -350,20 +345,18 @@ fn csound_filter_caps_negotiation_fail() {
let ichannels = 2; let ichannels = 2;
let ochannels = 1; let ochannels = 1;
let src_caps = gst::Caps::builder("audio/x-raw") let src_caps = gst_audio::AudioCapsBuilder::new_interleaved()
.field("format", gst_audio::AUDIO_FORMAT_F64.to_str()) .format(gst_audio::AUDIO_FORMAT_F64)
.field("rate", 44_100i32) .rate(44_100)
.field("channels", ichannels) .channels(ichannels)
.field("layout", "interleaved")
.build(); .build();
// instead of having a range for channels/rate fields // instead of having a range for channels/rate fields
// we fixate them to 2 and 48_000 respectively, which would cause the negotiation error // we fixate them to 2 and 48_000 respectively, which would cause the negotiation error
let sink_caps = gst::Caps::builder("audio/x-raw") let sink_caps = gst_audio::AudioCapsBuilder::new_interleaved()
.field("format", gst_audio::AUDIO_FORMAT_F64.to_str()) .format(gst_audio::AUDIO_FORMAT_F64)
.field("rate", 48_000i32) .rate(48_000)
.field("channels", ichannels) .channels(ichannels)
.field("layout", "interleaved")
.build(); .build();
let mut h = build_harness( let mut h = build_harness(

View file

@ -81,11 +81,9 @@ impl ElementImpl for LewtonDec {
) )
.unwrap(); .unwrap();
let src_caps = gst::Caps::builder("audio/x-raw") let src_caps = gst_audio::AudioCapsBuilder::new_interleaved()
.field("format", gst_audio::AUDIO_FORMAT_F32.to_str()) .format(gst_audio::AUDIO_FORMAT_F32)
.field("rate", gst::IntRange::new(1, std::i32::MAX)) .channels_range(1..=255)
.field("channels", gst::IntRange::new(1i32, 255))
.field("layout", "interleaved")
.build(); .build();
let src_pad_template = gst::PadTemplate::new( let src_pad_template = gst::PadTemplate::new(
"src", "src",

View file

@ -93,11 +93,10 @@ fn run_test(inline_headers: bool) {
.expect("pad has no caps"); .expect("pad has no caps");
assert_eq!( assert_eq!(
caps, caps,
gst::Caps::builder("audio/x-raw") gst_audio::AudioCapsBuilder::new_interleaved()
.field("format", gst_audio::AUDIO_FORMAT_F32.to_str()) .format(gst_audio::AUDIO_FORMAT_F32)
.field("rate", 44_100i32) .rate(44_100)
.field("channels", 1i32) .channels(1)
.field("layout", "interleaved")
.build() .build()
); );
} }

View file

@ -596,7 +596,7 @@
"long-name": "Transcriber", "long-name": "Transcriber",
"pad-templates": { "pad-templates": {
"sink": { "sink": {
"caps": "audio/x-raw:\n format: S16LE\n rate: [ 8000, 48000 ]\n channels: 1\n", "caps": "audio/x-raw:\n rate: [ 8000, 48000 ]\n channels: 1\n layout: { (string)interleaved, (string)non-interleaved }\n format: S16LE\n",
"direction": "sink", "direction": "sink",
"presence": "always" "presence": "always"
}, },
@ -2303,7 +2303,7 @@
"presence": "always" "presence": "always"
}, },
"src": { "src": {
"caps": "audio/x-raw:\n format: F32LE\n rate: [ 1, 2147483647 ]\n channels: [ 1, 255 ]\n layout: interleaved\n", "caps": "audio/x-raw:\n rate: [ 1, 2147483647 ]\n channels: [ 1, 255 ]\n layout: interleaved\n format: F32LE\n",
"direction": "src", "direction": "src",
"presence": "always" "presence": "always"
} }
@ -3452,12 +3452,12 @@
"long-name": "Head-Related Transfer Function (HRTF) renderer", "long-name": "Head-Related Transfer Function (HRTF) renderer",
"pad-templates": { "pad-templates": {
"sink": { "sink": {
"caps": "audio/x-raw:\n format: F32LE\n rate: [ 1, 2147483647 ]\n channels: [ 1, 64 ]\n layout: interleaved\n", "caps": "audio/x-raw:\n rate: [ 1, 2147483647 ]\n channels: [ 1, 64 ]\n layout: interleaved\n format: F32LE\n",
"direction": "sink", "direction": "sink",
"presence": "always" "presence": "always"
}, },
"src": { "src": {
"caps": "audio/x-raw:\n format: F32LE\n rate: [ 1, 2147483647 ]\n channels: 2\n layout: interleaved\n", "caps": "audio/x-raw:\n rate: [ 1, 2147483647 ]\n channels: 2\n layout: interleaved\n format: F32LE\n",
"direction": "src", "direction": "src",
"presence": "always" "presence": "always"
} }
@ -5343,7 +5343,7 @@
"presence": "always" "presence": "always"
}, },
"src": { "src": {
"caps": "video/x-raw:\n format: RGBA\n", "caps": "video/x-raw:\n format: RGBA\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n",
"direction": "src", "direction": "src",
"presence": "always" "presence": "always"
} }

View file

@ -426,11 +426,11 @@ impl VideoStream {
raw_capsfilter.set_property( raw_capsfilter.set_property(
"caps", "caps",
gst::Caps::builder("video/x-raw") gst_video::VideoCapsBuilder::new()
.field("format", "I420") .format(gst_video::VideoFormat::I420)
.field("width", self.width) .width(self.width as i32)
.field("height", self.height) .height(self.height as i32)
.field("framerate", gst::Fraction::new(30, 1)) .framerate(gst::Fraction::new(30, 1))
.build(), .build(),
); );

View file

@ -321,11 +321,11 @@ impl VideoStream {
raw_capsfilter.set_property( raw_capsfilter.set_property(
"caps", "caps",
gst::Caps::builder("video/x-raw") gst_video::VideoCapsBuilder::new()
.field("format", "I420") .format(gst_video::VideoFormat::I420)
.field("width", self.width) .width(self.width as i32)
.field("height", self.height) .height(self.height as i32)
.field("framerate", gst::Fraction::new(30, 1)) .framerate(gst::Fraction::new(30, 1))
.build(), .build(),
); );
@ -375,9 +375,7 @@ impl AudioStream {
src.set_property_from_str("wave", &self.wave); src.set_property_from_str("wave", &self.wave);
raw_capsfilter.set_property( raw_capsfilter.set_property(
"caps", "caps",
gst::Caps::builder("audio/x-raw") gst_audio::AudioCapsBuilder::new().rate(44100).build(),
.field("rate", 44100)
.build(),
); );
mux.set_property("fragment-duration", gst::ClockTime::from_mseconds(2500)); mux.set_property("fragment-duration", gst::ClockTime::from_mseconds(2500));

View file

@ -15,6 +15,7 @@ bytes = "1.0"
futures = "0.3" futures = "0.3"
gst = { package = "gstreamer", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs" } gst = { package = "gstreamer", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs" }
gst-base = { package = "gstreamer-base", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs" } gst-base = { package = "gstreamer-base", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs" }
gst-audio = { package = "gstreamer-audio", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", features = ["v1_16"] }
aws-config = "0.49.0" aws-config = "0.49.0"
aws-sdk-s3 = "0.19.0" aws-sdk-s3 = "0.19.0"
aws-sdk-transcribe = "0.19.0" aws-sdk-transcribe = "0.19.0"

View file

@ -1349,10 +1349,10 @@ impl ElementImpl for Transcriber {
) )
.unwrap(); .unwrap();
let sink_caps = gst::Caps::builder("audio/x-raw") let sink_caps = gst_audio::AudioCapsBuilder::new()
.field("format", "S16LE") .format(gst_audio::AudioFormat::S16le)
.field("rate", gst::IntRange::new(8000i32, 48000)) .rate_range(8000..=48000)
.field("channels", 1) .channels(1)
.build(); .build();
let sink_pad_template = gst::PadTemplate::new( let sink_pad_template = gst::PadTemplate::new(
"sink", "sink",

View file

@ -14,7 +14,6 @@ use gst::subclass::prelude::*;
use gst_base::subclass::prelude::*; use gst_base::subclass::prelude::*;
use gst_video::subclass::prelude::*; use gst_video::subclass::prelude::*;
use std::i32;
use std::sync::Mutex; use std::sync::Mutex;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
@ -197,23 +196,8 @@ impl ElementImpl for Rgb2Gray {
static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| { static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| {
// On the src pad, we can produce BGRx and GRAY8 of any // On the src pad, we can produce BGRx and GRAY8 of any
// width/height and with any framerate // width/height and with any framerate
let caps = gst::Caps::builder("video/x-raw") let caps = gst_video::VideoCapsBuilder::new()
.field( .format_list([gst_video::VideoFormat::Bgrx, gst_video::VideoFormat::Gray8])
"format",
gst::List::new([
gst_video::VideoFormat::Bgrx.to_str(),
gst_video::VideoFormat::Gray8.to_str(),
]),
)
.field("width", gst::IntRange::new(0, i32::MAX))
.field("height", gst::IntRange::new(0, i32::MAX))
.field(
"framerate",
gst::FractionRange::new(
gst::Fraction::new(0, 1),
gst::Fraction::new(i32::MAX, 1),
),
)
.build(); .build();
// The src pad template must be named "src" for basetransform // The src pad template must be named "src" for basetransform
// and specific a pad that is always there // and specific a pad that is always there
@ -227,17 +211,8 @@ impl ElementImpl for Rgb2Gray {
// On the sink pad, we can accept BGRx of any // On the sink pad, we can accept BGRx of any
// width/height and with any framerate // width/height and with any framerate
let caps = gst::Caps::builder("video/x-raw") let caps = gst_video::VideoCapsBuilder::new()
.field("format", gst_video::VideoFormat::Bgrx.to_str()) .format(gst_video::VideoFormat::Bgrx)
.field("width", gst::IntRange::new(0, i32::MAX))
.field("height", gst::IntRange::new(0, i32::MAX))
.field(
"framerate",
gst::FractionRange::new(
gst::Fraction::new(0, 1),
gst::Fraction::new(i32::MAX, 1),
),
)
.build(); .build();
// The sink pad template must be named "sink" for basetransform // The sink pad template must be named "sink" for basetransform
// and specific a pad that is always there // and specific a pad that is always there

View file

@ -19,7 +19,7 @@ use byte_slice_cast::*;
use std::ops::Rem; use std::ops::Rem;
use std::sync::Mutex; use std::sync::Mutex;
use std::{i32, u32}; use std::u32;
use num_traits::cast::NumCast; use num_traits::cast::NumCast;
use num_traits::float::Float; use num_traits::float::Float;
@ -352,17 +352,8 @@ impl ElementImpl for SineSrc {
static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| { static PAD_TEMPLATES: Lazy<Vec<gst::PadTemplate>> = Lazy::new(|| {
// On the src pad, we can produce F32/F64 with any sample rate // On the src pad, we can produce F32/F64 with any sample rate
// and any number of channels // and any number of channels
let caps = gst::Caps::builder("audio/x-raw") let caps = gst_audio::AudioCapsBuilder::new_interleaved()
.field( .format_list([gst_audio::AUDIO_FORMAT_F32, gst_audio::AUDIO_FORMAT_F64])
"format",
gst::List::new([
gst_audio::AUDIO_FORMAT_F32.to_str(),
gst_audio::AUDIO_FORMAT_F64.to_str(),
]),
)
.field("layout", "interleaved")
.field("rate", gst::IntRange::new(1, i32::MAX))
.field("channels", gst::IntRange::new(1, i32::MAX))
.build(); .build();
// The src pad template must be named "src" for basesrc // The src pad template must be named "src" for basesrc
// and specific a pad that is always there // and specific a pad that is always there

View file

@ -331,23 +331,10 @@ To be able to declare what kinds of pads an element can create (they are not nec
In our case we only have always pads, one sink pad called “sink”, on which we can only accept RGB (BGRx to be exact) data with any width/height/framerate and one source pad called “src”, on which we will produce either RGB (BGRx) data or GRAY8 (8-bit grayscale) data. We do this by adding the following code to the class_init function. In our case we only have always pads, one sink pad called “sink”, on which we can only accept RGB (BGRx to be exact) data with any width/height/framerate and one source pad called “src”, on which we will produce either RGB (BGRx) data or GRAY8 (8-bit grayscale) data. We do this by adding the following code to the class_init function.
```rust ```rust
let caps = gst::Caps::builder("video/x-raw") let caps = gst_video::VideoCapsBuilder::new()
.field( .format_list([gst_video::VideoFormat::Bgrx.to_str(),
"format",
gst::List::new([
gst_video::VideoFormat::Bgrx.to_str(),
gst_video::VideoFormat::Gray8.to_str(), gst_video::VideoFormat::Gray8.to_str(),
]), ])
)
.field("width", gst::IntRange::new(0, i32::MAX))
.field("height", gst::IntRange::new(0, i32::MAX))
.field(
"framerate",
gst::FractionRange::new(
gst::Fraction::new(0, 1),
gst::Fraction::new(i32::MAX, 1),
),
)
.build(); .build();
let src_pad_template = gst::PadTemplate::new( let src_pad_template = gst::PadTemplate::new(
"src", "src",
@ -359,17 +346,8 @@ In our case we only have always pads, one sink pad called “sink”, on which w
klass.add_pad_template(src_pad_template); klass.add_pad_template(src_pad_template);
let caps = gst::Caps::builder("video/x-raw") let caps = gst_video::VideoCapsBuilder::new()
.field("format", gst_video::VideoFormat::Bgrx.to_str()) .format(gst_video::VideoFormat::Bgrx)
.field("width", gst::IntRange::new(0, i32::MAX))
.field("height", gst::IntRange:::new(0, i32::MAX))
.field(
"framerate",
gst::FractionRange::new(
gst::Fraction::new(0, 1),
gst::Fraction::new(i32::MAX, 1),
),
)
.build(); .build();
let sink_pad_template = gst::PadTemplate::new( let sink_pad_template = gst::PadTemplate::new(
"sink", "sink",

View file

@ -137,18 +137,12 @@ impl ObjectSubclass for SineSrc {
// pads that could exist for this type. // pads that could exist for this type.
// On the src pad, we can produce F32/F64 with any sample rate // On the src pad, we can produce F32/F64 with any sample rate
// and any number of channels // and any number of channels (default)
let caps = gst::Caps::builder("audio/x-raw") let caps = gst_audio::AudioCapsBuilder::new_interleaved()
.field( .format_list([
"format", gst_audio::AUDIO_FORMAT_F32,
gst::List::new([ gst_audio::AUDIO_FORMAT_F64,
gst_audio::AUDIO_FORMAT_F32.to_str(), ])
gst_audio::AUDIO_FORMAT_F64.to_str(),
]),
)
.field("layout", "interleaved")
.field("rate", gst::IntRange::new(1, i32::MAX))
.field("channels", gst::IntRange::new(1, i32::MAX))
.build(); .build();
// The src pad template must be named "src" for basesrc // The src pad template must be named "src" for basesrc
// and specific a pad that is always there // and specific a pad that is always there

View file

@ -530,11 +530,11 @@ fn setup_pipeline(
src.set_property("min-latency", LATENCY.nseconds() as i64); src.set_property("min-latency", LATENCY.nseconds() as i64);
src.set_property( src.set_property(
"caps", "caps",
gst::Caps::builder("video/x-raw") gst_video::VideoCapsBuilder::new()
.field("format", "ARGB") .format(gst_video::VideoFormat::Argb)
.field("width", 320i32) .width(320)
.field("height", 240i32) .height(240)
.field("framerate", gst::Fraction::new(0, 1)) .framerate(gst::Fraction::new(0, 1))
.build(), .build(),
); );
@ -575,11 +575,11 @@ fn setup_pipeline(
fallback_src.set_property("min-latency", LATENCY.nseconds() as i64); fallback_src.set_property("min-latency", LATENCY.nseconds() as i64);
fallback_src.set_property( fallback_src.set_property(
"caps", "caps",
gst::Caps::builder("video/x-raw") gst_video::VideoCapsBuilder::new()
.field("format", "ARGB") .format(gst_video::VideoFormat::Argb)
.field("width", 160i32) .width(160)
.field("height", 120i32) .height(120)
.field("framerate", gst::Fraction::new(0, 1)) .framerate(gst::Fraction::new(0, 1))
.build(), .build(),
); );

View file

@ -101,18 +101,17 @@ fn setup_sender_receiver(
if first { if first {
assert!(sinkpad.send_event(gst::event::StreamStart::new("test"))); assert!(sinkpad.send_event(gst::event::StreamStart::new("test")));
let caps = if main_stream { let caps = if main_stream {
gst::Caps::builder("video/x-raw") gst_video::VideoCapsBuilder::new()
.field("format", "ARGB") .format(gst_video::VideoFormat::Argb)
.field("width", 320i32) .width(320)
.field("height", 240i32) .height(240)
.field("framerate", gst::Fraction::new(50, 1)) .framerate(gst::Fraction::new(50, 1))
.build() .build()
} else { } else {
gst::Caps::builder("audio/x-raw") gst_audio::AudioCapsBuilder::new_interleaved()
.field("format", "U8") .format(gst_audio::AUDIO_FORMAT_U8)
.field("layout", "interleaved") .rate(800)
.field("rate", 8000i32) .channels(1)
.field("channels", 1i32)
.build() .build()
}; };
assert!(sinkpad.send_event(gst::event::Caps::new(&caps))); assert!(sinkpad.send_event(gst::event::Caps::new(&caps)));

View file

@ -66,11 +66,11 @@ impl ElementImpl for CdgDec {
) )
.unwrap(); .unwrap();
let src_caps = gst::Caps::builder("video/x-raw") let src_caps = gst_video::VideoCapsBuilder::new()
.field("format", gst_video::VideoFormat::Rgba.to_str()) .format(gst_video::VideoFormat::Rgba)
.field("width", CDG_WIDTH as i32) .width(CDG_WIDTH as i32)
.field("height", CDG_HEIGHT as i32) .height(CDG_HEIGHT as i32)
.field("framerate", gst::Fraction::new(0, 1)) .framerate(gst::Fraction::new(0, 1))
.build(); .build();
let src_pad_template = gst::PadTemplate::new( let src_pad_template = gst::PadTemplate::new(
"src", "src",

View file

@ -18,9 +18,9 @@ fn create_ui(app: &gtk::Application) {
pipeline.add_many(&[&src, &overlay, &sink]).unwrap(); pipeline.add_many(&[&src, &overlay, &sink]).unwrap();
src.link_filtered( src.link_filtered(
&overlay, &overlay,
&gst::Caps::builder("video/x-raw") &gst_video::VideoCapsBuilder::new()
.field("width", 640) .width(640)
.field("height", 480) .height(480)
.build(), .build(),
) )
.unwrap(); .unwrap();

View file

@ -343,8 +343,8 @@ impl ElementImpl for WebPDec {
) )
.unwrap(); .unwrap();
let caps = gst::Caps::builder("video/x-raw") let caps = gst_video::VideoCapsBuilder::new()
.field("format", "RGBA") .format(gst_video::VideoFormat::Rgba)
.build(); .build();
let src_pad_template = gst::PadTemplate::new( let src_pad_template = gst::PadTemplate::new(