mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer-rs.git
synced 2024-11-25 02:51:10 +00:00
Update various APIs to use glib::GStr
Currently only covers what is needed to keep code compiling, plus everything caps/structure/tags related. This avoids unnecessary heap allocations for adding the NUL-terminator of C strings, and especially makes caps/structure handling as efficient as in C. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/-/merge_requests/1190>
This commit is contained in:
parent
ea136515cf
commit
003554876c
32 changed files with 602 additions and 541 deletions
|
@ -46,7 +46,7 @@ fn main_loop() -> Result<(), Error> {
|
|||
// server to require from clients.
|
||||
let auth = gst_rtsp_server::RTSPAuth::new();
|
||||
let token = gst_rtsp_server::RTSPToken::new(&[(
|
||||
*gst_rtsp_server::RTSP_TOKEN_MEDIA_FACTORY_ROLE,
|
||||
gst_rtsp_server::RTSP_TOKEN_MEDIA_FACTORY_ROLE,
|
||||
&"user",
|
||||
)]);
|
||||
let basic = gst_rtsp_server::RTSPAuth::make_basic("user", "password");
|
||||
|
|
|
@ -86,7 +86,7 @@ fn example_main() -> Result<(), Error> {
|
|||
.expect("typefinder \"have-type\" signal values[2]");
|
||||
let format_name = caps.structure(0).expect("Failed to get format name").name();
|
||||
|
||||
let demuxer = match format_name {
|
||||
let demuxer = match format_name.as_str() {
|
||||
"video/x-matroska" | "video/webm" => gst::ElementFactory::make("matroskademux")
|
||||
.build()
|
||||
.expect("matroskademux missing"),
|
||||
|
|
|
@ -541,7 +541,7 @@ impl App {
|
|||
let src = gst::ElementFactory::make("videotestsrc").build()?;
|
||||
|
||||
let caps = gst_video::VideoCapsBuilder::new()
|
||||
.features(&[&gst_gl::CAPS_FEATURE_MEMORY_GL_MEMORY])
|
||||
.features([gst_gl::CAPS_FEATURE_MEMORY_GL_MEMORY])
|
||||
.format(gst_video::VideoFormat::Rgba)
|
||||
.field("texture-target", "2D")
|
||||
.build();
|
||||
|
|
|
@ -4,4 +4,4 @@ use gst::CapsFeatures;
|
|||
use once_cell::sync::Lazy;
|
||||
|
||||
pub static CAPS_FEATURES_MEMORY_DMABUF: Lazy<CapsFeatures> =
|
||||
Lazy::new(|| CapsFeatures::new(&[*crate::CAPS_FEATURE_MEMORY_DMABUF]));
|
||||
Lazy::new(|| CapsFeatures::new([crate::CAPS_FEATURE_MEMORY_DMABUF]));
|
||||
|
|
|
@ -79,49 +79,52 @@ impl AudioConverterConfig {
|
|||
}
|
||||
|
||||
pub fn set_dither_method(&mut self, v: crate::AudioDitherMethod) {
|
||||
self.0.set("GstAudioConverter.dither-method", v);
|
||||
self.0
|
||||
.set(glib::gstr!("GstAudioConverter.dither-method"), v);
|
||||
}
|
||||
|
||||
#[doc(alias = "get_dither_method")]
|
||||
pub fn dither_method(&self) -> crate::AudioDitherMethod {
|
||||
self.0
|
||||
.get_optional("GstAudioConverter.dither-method")
|
||||
.get_optional(glib::gstr!("GstAudioConverter.dither-method"))
|
||||
.expect("Wrong type")
|
||||
.unwrap_or(crate::AudioDitherMethod::None)
|
||||
}
|
||||
|
||||
pub fn set_noise_shaping_method(&mut self, v: crate::AudioNoiseShapingMethod) {
|
||||
self.0.set("GstAudioConverter.noise-shaping-method", v);
|
||||
self.0
|
||||
.set(glib::gstr!("GstAudioConverter.noise-shaping-method"), v);
|
||||
}
|
||||
|
||||
#[doc(alias = "get_noise_shaping_method")]
|
||||
pub fn noise_shaping_method(&self) -> crate::AudioNoiseShapingMethod {
|
||||
self.0
|
||||
.get_optional("GstAudioConverter.noise-shaping-method")
|
||||
.get_optional(glib::gstr!("GstAudioConverter.noise-shaping-method"))
|
||||
.expect("Wrong type")
|
||||
.unwrap_or(crate::AudioNoiseShapingMethod::None)
|
||||
}
|
||||
|
||||
pub fn set_quantization(&mut self, v: u32) {
|
||||
self.0.set("GstAudioConverter.quantization", v);
|
||||
self.0.set(glib::gstr!("GstAudioConverter.quantization"), v);
|
||||
}
|
||||
|
||||
#[doc(alias = "get_quantization")]
|
||||
pub fn quantization(&self) -> u32 {
|
||||
self.0
|
||||
.get_optional("GstAudioConverter.quantization")
|
||||
.get_optional(glib::gstr!("GstAudioConverter.quantization"))
|
||||
.expect("Wrong type")
|
||||
.unwrap_or(1)
|
||||
}
|
||||
|
||||
pub fn set_resampler_method(&mut self, v: crate::AudioResamplerMethod) {
|
||||
self.0.set("GstAudioConverter.resampler-method", v);
|
||||
self.0
|
||||
.set(glib::gstr!("GstAudioConverter.resampler-method"), v);
|
||||
}
|
||||
|
||||
#[doc(alias = "get_resampler_method")]
|
||||
pub fn resampler_method(&self) -> crate::AudioResamplerMethod {
|
||||
self.0
|
||||
.get_optional("GstAudioConverter.resampler-method")
|
||||
.get_optional(glib::gstr!("GstAudioConverter.resampler-method"))
|
||||
.expect("Wrong type")
|
||||
.unwrap_or(crate::AudioResamplerMethod::BlackmanNuttall)
|
||||
}
|
||||
|
@ -133,13 +136,14 @@ impl AudioConverterConfig {
|
|||
assert_eq!(val.len(), length);
|
||||
gst::Array::from_values(val.iter().map(|val| val.to_send_value())).to_send_value()
|
||||
}));
|
||||
self.0.set("GstAudioConverter.mix-matrix", array);
|
||||
self.0
|
||||
.set(glib::gstr!("GstAudioConverter.mix-matrix"), array);
|
||||
}
|
||||
|
||||
#[doc(alias = "get_mix_matrix")]
|
||||
pub fn mix_matrix(&self) -> Vec<Vec<f32>> {
|
||||
self.0
|
||||
.get_optional::<gst::Array>("GstAudioConverter.mix-matrix")
|
||||
.get_optional::<gst::Array>(glib::gstr!("GstAudioConverter.mix-matrix"))
|
||||
.expect("Wrong type")
|
||||
.map(|array| {
|
||||
array
|
||||
|
@ -162,7 +166,8 @@ impl AudioConverterConfig {
|
|||
#[cfg(any(feature = "v1_22", feature = "dox"))]
|
||||
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_22")))]
|
||||
pub fn set_dither_threshold(&mut self, v: u32) {
|
||||
self.0.set("GstAudioConverter.dither-threshold", v);
|
||||
self.0
|
||||
.set(glib::gstr!("GstAudioConverter.dither-threshold"), v);
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "v1_22", feature = "dox"))]
|
||||
|
@ -170,7 +175,7 @@ impl AudioConverterConfig {
|
|||
#[doc(alias = "get_dither_threshold")]
|
||||
pub fn dither_threshold(&self) -> u32 {
|
||||
self.0
|
||||
.get_optional("GstAudioConverter.dither-threshold")
|
||||
.get_optional(glib::gstr!("GstAudioConverter.dither-threshold"))
|
||||
.expect("Wrong type")
|
||||
.unwrap_or(20)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
|
||||
use std::{ffi::CStr, str};
|
||||
use std::str;
|
||||
|
||||
use glib::translate::{from_glib, IntoGlib};
|
||||
use once_cell::sync::Lazy;
|
||||
|
@ -112,18 +112,16 @@ impl crate::AudioFormat {
|
|||
}
|
||||
|
||||
#[doc(alias = "gst_audio_format_to_string")]
|
||||
pub fn to_str<'a>(self) -> &'a str {
|
||||
pub fn to_str<'a>(self) -> &'a glib::GStr {
|
||||
if self == Self::Unknown {
|
||||
return "UNKNOWN";
|
||||
return glib::gstr!("UNKNOWN");
|
||||
}
|
||||
unsafe {
|
||||
CStr::from_ptr(
|
||||
glib::GStr::from_ptr(
|
||||
ffi::gst_audio_format_to_string(self.into_glib())
|
||||
.as_ref()
|
||||
.expect("gst_audio_format_to_string returned NULL"),
|
||||
)
|
||||
.to_str()
|
||||
.expect("gst_audio_format_to_string returned an invalid string")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
|
||||
use std::{cmp::Ordering, ffi::CStr, fmt, marker::PhantomData, str};
|
||||
use std::{cmp::Ordering, fmt, marker::PhantomData, str};
|
||||
|
||||
use glib::{
|
||||
translate::{from_glib, from_glib_none, FromGlib, IntoGlib, ToGlibPtr, ToGlibPtrMut},
|
||||
|
@ -64,13 +64,13 @@ impl AudioFormatInfo {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn name<'a>(&self) -> &'a str {
|
||||
unsafe { CStr::from_ptr(self.0.name).to_str().unwrap() }
|
||||
pub fn name<'a>(&self) -> &'a glib::GStr {
|
||||
unsafe { glib::GStr::from_ptr(self.0.name) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn description<'a>(&self) -> &'a str {
|
||||
unsafe { CStr::from_ptr(self.0.description).to_str().unwrap() }
|
||||
pub fn description<'a>(&self) -> &'a glib::GStr {
|
||||
unsafe { glib::GStr::from_ptr(self.0.description) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
@ -2,6 +2,8 @@ use std::ops::{Bound::*, RangeBounds};
|
|||
|
||||
use gst::Caps;
|
||||
|
||||
use glib::IntoGStr;
|
||||
|
||||
use crate::{AudioFormat, AudioLayout};
|
||||
|
||||
pub struct AudioCapsBuilder<T> {
|
||||
|
@ -10,7 +12,7 @@ pub struct AudioCapsBuilder<T> {
|
|||
|
||||
impl AudioCapsBuilder<gst::caps::NoFeature> {
|
||||
pub fn new() -> Self {
|
||||
let builder = Caps::builder("audio/x-raw");
|
||||
let builder = Caps::builder(glib::gstr!("audio/x-raw"));
|
||||
let builder = AudioCapsBuilder { builder };
|
||||
builder
|
||||
.rate_range(..)
|
||||
|
@ -29,7 +31,10 @@ impl AudioCapsBuilder<gst::caps::NoFeature> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn features(self, features: &[&str]) -> AudioCapsBuilder<gst::caps::HasFeatures> {
|
||||
pub fn features(
|
||||
self,
|
||||
features: impl IntoIterator<Item = impl IntoGStr>,
|
||||
) -> AudioCapsBuilder<gst::caps::HasFeatures> {
|
||||
AudioCapsBuilder {
|
||||
builder: self.builder.features(features),
|
||||
}
|
||||
|
@ -45,14 +50,14 @@ impl Default for AudioCapsBuilder<gst::caps::NoFeature> {
|
|||
impl<T> AudioCapsBuilder<T> {
|
||||
pub fn format(self, format: AudioFormat) -> Self {
|
||||
Self {
|
||||
builder: self.builder.field("format", format.to_str()),
|
||||
builder: self.builder.field(glib::gstr!("format"), format.to_str()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn format_list(self, formats: impl IntoIterator<Item = AudioFormat>) -> Self {
|
||||
Self {
|
||||
builder: self.builder.field(
|
||||
"format",
|
||||
glib::gstr!("format"),
|
||||
gst::List::new(formats.into_iter().map(|f| f.to_str())),
|
||||
),
|
||||
}
|
||||
|
@ -60,7 +65,7 @@ impl<T> AudioCapsBuilder<T> {
|
|||
|
||||
pub fn rate(self, rate: i32) -> Self {
|
||||
Self {
|
||||
builder: self.builder.field("rate", rate),
|
||||
builder: self.builder.field(glib::gstr!("rate"), rate),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,19 +73,21 @@ impl<T> AudioCapsBuilder<T> {
|
|||
let (start, end) = range_bounds_i32_start_end(rates);
|
||||
let gst_rates = gst::IntRange::<i32>::new(start, end);
|
||||
Self {
|
||||
builder: self.builder.field("rate", gst_rates),
|
||||
builder: self.builder.field(glib::gstr!("rate"), gst_rates),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn rate_list(self, rates: impl IntoIterator<Item = i32>) -> Self {
|
||||
Self {
|
||||
builder: self.builder.field("rate", gst::List::new(rates)),
|
||||
builder: self
|
||||
.builder
|
||||
.field(glib::gstr!("rate"), gst::List::new(rates)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn channels(self, channels: i32) -> Self {
|
||||
Self {
|
||||
builder: self.builder.field("channels", channels),
|
||||
builder: self.builder.field(glib::gstr!("channels"), channels),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,26 +95,30 @@ impl<T> AudioCapsBuilder<T> {
|
|||
let (start, end) = range_bounds_i32_start_end(channels);
|
||||
let gst_channels: gst::IntRange<i32> = gst::IntRange::new(start, end);
|
||||
Self {
|
||||
builder: self.builder.field("channels", gst_channels),
|
||||
builder: self.builder.field(glib::gstr!("channels"), gst_channels),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn channels_list(self, channels: impl IntoIterator<Item = i32>) -> Self {
|
||||
Self {
|
||||
builder: self.builder.field("channels", gst::List::new(channels)),
|
||||
builder: self
|
||||
.builder
|
||||
.field(glib::gstr!("channels"), gst::List::new(channels)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn layout(self, layout: AudioLayout) -> Self {
|
||||
Self {
|
||||
builder: self.builder.field("layout", layout_str(layout)),
|
||||
builder: self
|
||||
.builder
|
||||
.field(glib::gstr!("layout"), layout_str(layout)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn layout_list(self, layouts: impl IntoIterator<Item = AudioLayout>) -> Self {
|
||||
Self {
|
||||
builder: self.builder.field(
|
||||
"layout",
|
||||
glib::gstr!("layout"),
|
||||
gst::List::new(layouts.into_iter().map(layout_str)),
|
||||
),
|
||||
}
|
||||
|
@ -122,11 +133,11 @@ impl<T> AudioCapsBuilder<T> {
|
|||
}
|
||||
|
||||
pub fn fallback_channel_mask(self) -> Self {
|
||||
let channels = self.builder.structure().get::<i32>("channels");
|
||||
let channels = self.builder.structure().get::<i32>(glib::gstr!("channels"));
|
||||
match channels {
|
||||
Ok(channels) => Self {
|
||||
builder: self.builder.field(
|
||||
"channel-mask",
|
||||
glib::gstr!("channel-mask"),
|
||||
gst::Bitmask::new(crate::AudioChannelPosition::fallback_mask(channels as u32)),
|
||||
),
|
||||
},
|
||||
|
@ -161,11 +172,11 @@ fn range_bounds_i32_start_end(range: impl RangeBounds<i32>) -> (i32, i32) {
|
|||
(start, end)
|
||||
}
|
||||
|
||||
fn layout_str(layout: AudioLayout) -> &'static str {
|
||||
fn layout_str(layout: AudioLayout) -> &'static glib::GStr {
|
||||
skip_assert_initialized!();
|
||||
match layout {
|
||||
crate::AudioLayout::Interleaved => "interleaved",
|
||||
crate::AudioLayout::NonInterleaved => "non-interleaved",
|
||||
crate::AudioLayout::__Unknown(_) => "unknown",
|
||||
crate::AudioLayout::Interleaved => glib::gstr!("interleaved"),
|
||||
crate::AudioLayout::NonInterleaved => glib::gstr!("non-interleaved"),
|
||||
crate::AudioLayout::__Unknown(_) => glib::gstr!("unknown"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,4 +4,4 @@ use gst::CapsFeatures;
|
|||
use once_cell::sync::Lazy;
|
||||
|
||||
pub static CAPS_FEATURES_MEMORY_GL_MEMORY: Lazy<CapsFeatures> =
|
||||
Lazy::new(|| CapsFeatures::new(&[*crate::CAPS_FEATURE_MEMORY_GL_MEMORY]));
|
||||
Lazy::new(|| CapsFeatures::new([crate::CAPS_FEATURE_MEMORY_GL_MEMORY]));
|
||||
|
|
|
@ -1,4 +1,2 @@
|
|||
use libc::c_char;
|
||||
|
||||
// See https://gitlab.gnome.org/GNOME/gobject-introspection/issues/238
|
||||
pub const GST_GL_COLOR_CONVERT_VIDEO_CAPS: *const c_char = b"video/x-raw(memory:GLMemory), format = (string) { RGBA, RGB, RGBx, BGR, BGRx, BGRA, xRGB, xBGR, ARGB, ABGR, Y444, I420, YV12, Y42B, Y41B, NV12, NV21, YUY2, UYVY, AYUV, GRAY8, GRAY16_LE, GRAY16_BE, RGB16, BGR16 }, width = (int) [ 1, max ], height = (int) [ 1, max ], framerate = (fraction) [ 0, max ], texture-target = (string) { 2D, rectangle, external-oes } ; video/x-raw(memory:GLMemory,meta:GstVideoOverlayComposition), format = (string) { RGBA, RGB, RGBx, BGR, BGRx, BGRA, xRGB, xBGR, ARGB, ABGR, Y444, I420, YV12, Y42B, Y41B, NV12, NV21, YUY2, UYVY, AYUV, GRAY8, GRAY16_LE, GRAY16_BE, RGB16, BGR16 }, width = (int) [ 1, max ], height = (int) [ 1, max ], framerate = (fraction) [ 0, max ], texture-target = (string) { 2D, rectangle, external-oes }\0" as *const u8 as *const c_char;
|
||||
pub const GST_GL_COLOR_CONVERT_VIDEO_CAPS: &[u8] = b"video/x-raw(memory:GLMemory), format = (string) { RGBA, RGB, RGBx, BGR, BGRx, BGRA, xRGB, xBGR, ARGB, ABGR, Y444, I420, YV12, Y42B, Y41B, NV12, NV21, YUY2, UYVY, AYUV, GRAY8, GRAY16_LE, GRAY16_BE, RGB16, BGR16 }, width = (int) [ 1, max ], height = (int) [ 1, max ], framerate = (fraction) [ 0, max ], texture-target = (string) { 2D, rectangle, external-oes } ; video/x-raw(memory:GLMemory,meta:GstVideoOverlayComposition), format = (string) { RGBA, RGB, RGBx, BGR, BGRx, BGRA, xRGB, xBGR, ARGB, ABGR, Y444, I420, YV12, Y42B, Y41B, NV12, NV21, YUY2, UYVY, AYUV, GRAY8, GRAY16_LE, GRAY16_BE, RGB16, BGR16 }, width = (int) [ 1, max ], height = (int) [ 1, max ], framerate = (fraction) [ 0, max ], texture-target = (string) { 2D, rectangle, external-oes }\0";
|
||||
|
|
|
@ -17,12 +17,12 @@ pub fn pb_utils_add_codec_description_to_tag_list_for_tag<'a, T: CodecTag<'a>>(
|
|||
caps: &gst::CapsRef,
|
||||
) -> Result<(), glib::BoolError> {
|
||||
assert_initialized_main_thread!();
|
||||
let codec_tag = T::tag_name();
|
||||
let codec_tag = T::TAG_NAME;
|
||||
unsafe {
|
||||
glib::result_from_gboolean!(
|
||||
ffi::gst_pb_utils_add_codec_description_to_tag_list(
|
||||
taglist.as_mut_ptr(),
|
||||
codec_tag.to_glib_none().0,
|
||||
codec_tag.as_ptr(),
|
||||
caps.as_ptr(),
|
||||
),
|
||||
"Failed to find codec description",
|
||||
|
|
|
@ -53,67 +53,34 @@ mod rtsp_token;
|
|||
|
||||
pub mod subclass;
|
||||
|
||||
use std::ffi::CStr;
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
pub use crate::{rtsp_context::*, rtsp_thread::*, rtsp_token::*};
|
||||
|
||||
pub static RTSP_ADDRESS_POOL_ANY_IPV4: Lazy<&'static str> = Lazy::new(|| unsafe {
|
||||
CStr::from_ptr(ffi::GST_RTSP_ADDRESS_POOL_ANY_IPV4)
|
||||
.to_str()
|
||||
.unwrap()
|
||||
});
|
||||
pub static RTSP_ADDRESS_POOL_ANY_IPV6: Lazy<&'static str> = Lazy::new(|| unsafe {
|
||||
CStr::from_ptr(ffi::GST_RTSP_ADDRESS_POOL_ANY_IPV6)
|
||||
.to_str()
|
||||
.unwrap()
|
||||
});
|
||||
pub static RTSP_AUTH_CHECK_CONNECT: Lazy<&'static str> = Lazy::new(|| unsafe {
|
||||
CStr::from_ptr(ffi::GST_RTSP_AUTH_CHECK_CONNECT)
|
||||
.to_str()
|
||||
.unwrap()
|
||||
});
|
||||
pub static RTSP_AUTH_CHECK_MEDIA_FACTORY_ACCESS: Lazy<&'static str> = Lazy::new(|| unsafe {
|
||||
CStr::from_ptr(ffi::GST_RTSP_AUTH_CHECK_MEDIA_FACTORY_ACCESS)
|
||||
.to_str()
|
||||
.unwrap()
|
||||
});
|
||||
pub static RTSP_AUTH_CHECK_MEDIA_FACTORY_CONSTRUCT: Lazy<&'static str> = Lazy::new(|| unsafe {
|
||||
CStr::from_ptr(ffi::GST_RTSP_AUTH_CHECK_MEDIA_FACTORY_CONSTRUCT)
|
||||
.to_str()
|
||||
.unwrap()
|
||||
});
|
||||
pub static RTSP_AUTH_CHECK_TRANSPORT_CLIENT_SETTINGS: Lazy<&'static str> = Lazy::new(|| unsafe {
|
||||
CStr::from_ptr(ffi::GST_RTSP_AUTH_CHECK_TRANSPORT_CLIENT_SETTINGS)
|
||||
.to_str()
|
||||
.unwrap()
|
||||
});
|
||||
pub static RTSP_AUTH_CHECK_URL: Lazy<&'static str> = Lazy::new(|| unsafe {
|
||||
CStr::from_ptr(ffi::GST_RTSP_AUTH_CHECK_URL)
|
||||
.to_str()
|
||||
.unwrap()
|
||||
});
|
||||
pub static RTSP_PERM_MEDIA_FACTORY_ACCESS: Lazy<&'static str> = Lazy::new(|| unsafe {
|
||||
CStr::from_ptr(ffi::GST_RTSP_PERM_MEDIA_FACTORY_ACCESS)
|
||||
.to_str()
|
||||
.unwrap()
|
||||
});
|
||||
pub static RTSP_PERM_MEDIA_FACTORY_CONSTRUCT: Lazy<&'static str> = Lazy::new(|| unsafe {
|
||||
CStr::from_ptr(ffi::GST_RTSP_PERM_MEDIA_FACTORY_CONSTRUCT)
|
||||
.to_str()
|
||||
.unwrap()
|
||||
});
|
||||
pub static RTSP_TOKEN_MEDIA_FACTORY_ROLE: Lazy<&'static str> = Lazy::new(|| unsafe {
|
||||
CStr::from_ptr(ffi::GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE)
|
||||
.to_str()
|
||||
.unwrap()
|
||||
});
|
||||
pub static RTSP_TOKEN_TRANSPORT_CLIENT_SETTINGS: Lazy<&'static str> = Lazy::new(|| unsafe {
|
||||
CStr::from_ptr(ffi::GST_RTSP_TOKEN_TRANSPORT_CLIENT_SETTINGS)
|
||||
.to_str()
|
||||
.unwrap()
|
||||
});
|
||||
pub static RTSP_ADDRESS_POOL_ANY_IPV4: &glib::GStr =
|
||||
unsafe { glib::GStr::from_utf8_with_nul_unchecked(ffi::GST_RTSP_ADDRESS_POOL_ANY_IPV4) };
|
||||
pub static RTSP_ADDRESS_POOL_ANY_IPV6: &glib::GStr =
|
||||
unsafe { glib::GStr::from_utf8_with_nul_unchecked(ffi::GST_RTSP_ADDRESS_POOL_ANY_IPV6) };
|
||||
pub static RTSP_AUTH_CHECK_CONNECT: &glib::GStr =
|
||||
unsafe { glib::GStr::from_utf8_with_nul_unchecked(ffi::GST_RTSP_AUTH_CHECK_CONNECT) };
|
||||
pub static RTSP_AUTH_CHECK_MEDIA_FACTORY_ACCESS: &glib::GStr = unsafe {
|
||||
glib::GStr::from_utf8_with_nul_unchecked(ffi::GST_RTSP_AUTH_CHECK_MEDIA_FACTORY_ACCESS)
|
||||
};
|
||||
pub static RTSP_AUTH_CHECK_MEDIA_FACTORY_CONSTRUCT: &glib::GStr = unsafe {
|
||||
glib::GStr::from_utf8_with_nul_unchecked(ffi::GST_RTSP_AUTH_CHECK_MEDIA_FACTORY_CONSTRUCT)
|
||||
};
|
||||
pub static RTSP_AUTH_CHECK_TRANSPORT_CLIENT_SETTINGS: &glib::GStr = unsafe {
|
||||
glib::GStr::from_utf8_with_nul_unchecked(ffi::GST_RTSP_AUTH_CHECK_TRANSPORT_CLIENT_SETTINGS)
|
||||
};
|
||||
pub static RTSP_AUTH_CHECK_URL: &glib::GStr =
|
||||
unsafe { glib::GStr::from_utf8_with_nul_unchecked(ffi::GST_RTSP_AUTH_CHECK_URL) };
|
||||
pub static RTSP_PERM_MEDIA_FACTORY_ACCESS: &glib::GStr =
|
||||
unsafe { glib::GStr::from_utf8_with_nul_unchecked(ffi::GST_RTSP_PERM_MEDIA_FACTORY_ACCESS) };
|
||||
pub static RTSP_PERM_MEDIA_FACTORY_CONSTRUCT: &glib::GStr =
|
||||
unsafe { glib::GStr::from_utf8_with_nul_unchecked(ffi::GST_RTSP_PERM_MEDIA_FACTORY_CONSTRUCT) };
|
||||
pub static RTSP_TOKEN_MEDIA_FACTORY_ROLE: &glib::GStr =
|
||||
unsafe { glib::GStr::from_utf8_with_nul_unchecked(ffi::GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE) };
|
||||
pub static RTSP_TOKEN_TRANSPORT_CLIENT_SETTINGS: &glib::GStr = unsafe {
|
||||
glib::GStr::from_utf8_with_nul_unchecked(ffi::GST_RTSP_TOKEN_TRANSPORT_CLIENT_SETTINGS)
|
||||
};
|
||||
|
||||
// Re-export all the traits in a prelude module, so that applications
|
||||
// can always "use gst_rtsp_server::prelude::*" without getting conflicts
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use std::ops::{Bound::*, RangeBounds};
|
||||
|
||||
use glib::IntoGStr;
|
||||
use gst::Caps;
|
||||
|
||||
use crate::VideoFormat;
|
||||
|
@ -10,7 +11,7 @@ pub struct VideoCapsBuilder<T> {
|
|||
|
||||
impl VideoCapsBuilder<gst::caps::NoFeature> {
|
||||
pub fn new() -> Self {
|
||||
let builder = Caps::builder("video/x-raw");
|
||||
let builder = Caps::builder(glib::gstr!("video/x-raw"));
|
||||
let builder = VideoCapsBuilder { builder };
|
||||
builder
|
||||
.format_list(VideoFormat::iter_raw())
|
||||
|
@ -25,7 +26,10 @@ impl VideoCapsBuilder<gst::caps::NoFeature> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn features(self, features: &[&str]) -> VideoCapsBuilder<gst::caps::HasFeatures> {
|
||||
pub fn features(
|
||||
self,
|
||||
features: impl IntoIterator<Item = impl IntoGStr>,
|
||||
) -> VideoCapsBuilder<gst::caps::HasFeatures> {
|
||||
VideoCapsBuilder {
|
||||
builder: self.builder.features(features),
|
||||
}
|
||||
|
@ -41,14 +45,14 @@ impl Default for VideoCapsBuilder<gst::caps::NoFeature> {
|
|||
impl<T> VideoCapsBuilder<T> {
|
||||
pub fn format(self, format: VideoFormat) -> Self {
|
||||
Self {
|
||||
builder: self.builder.field("format", format.to_str()),
|
||||
builder: self.builder.field(glib::gstr!("format"), format.to_str()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn format_list(self, formats: impl IntoIterator<Item = VideoFormat>) -> Self {
|
||||
Self {
|
||||
builder: self.builder.field(
|
||||
"format",
|
||||
glib::gstr!("format"),
|
||||
gst::List::new(formats.into_iter().map(|f| f.to_str())),
|
||||
),
|
||||
}
|
||||
|
@ -56,7 +60,7 @@ impl<T> VideoCapsBuilder<T> {
|
|||
|
||||
pub fn width(self, width: i32) -> Self {
|
||||
Self {
|
||||
builder: self.builder.field("width", width),
|
||||
builder: self.builder.field(glib::gstr!("width"), width),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,19 +68,21 @@ impl<T> VideoCapsBuilder<T> {
|
|||
let (start, end) = range_bounds_i32_start_end(widths);
|
||||
let gst_widths: gst::IntRange<i32> = gst::IntRange::new(start, end);
|
||||
Self {
|
||||
builder: self.builder.field("width", gst_widths),
|
||||
builder: self.builder.field(glib::gstr!("width"), gst_widths),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn width_list(self, widths: impl IntoIterator<Item = i32>) -> Self {
|
||||
Self {
|
||||
builder: self.builder.field("width", gst::List::new(widths)),
|
||||
builder: self
|
||||
.builder
|
||||
.field(glib::gstr!("width"), gst::List::new(widths)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn height(self, height: i32) -> Self {
|
||||
Self {
|
||||
builder: self.builder.field("height", height),
|
||||
builder: self.builder.field(glib::gstr!("height"), height),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,19 +90,21 @@ impl<T> VideoCapsBuilder<T> {
|
|||
let (start, end) = range_bounds_i32_start_end(heights);
|
||||
let gst_heights: gst::IntRange<i32> = gst::IntRange::new(start, end);
|
||||
Self {
|
||||
builder: self.builder.field("height", gst_heights),
|
||||
builder: self.builder.field(glib::gstr!("height"), gst_heights),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn height_list(self, heights: impl IntoIterator<Item = i32>) -> Self {
|
||||
Self {
|
||||
builder: self.builder.field("height", gst::List::new(heights)),
|
||||
builder: self
|
||||
.builder
|
||||
.field(glib::gstr!("height"), gst::List::new(heights)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn framerate(self, framerate: gst::Fraction) -> Self {
|
||||
Self {
|
||||
builder: self.builder.field("framerate", framerate),
|
||||
builder: self.builder.field(glib::gstr!("framerate"), framerate),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -120,13 +128,15 @@ impl<T> VideoCapsBuilder<T> {
|
|||
assert!(start <= end);
|
||||
let framerates: gst::FractionRange = gst::FractionRange::new(start, end);
|
||||
Self {
|
||||
builder: self.builder.field("framerate", framerates),
|
||||
builder: self.builder.field(glib::gstr!("framerate"), framerates),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn framerate_list(self, framerates: impl IntoIterator<Item = gst::Fraction>) -> Self {
|
||||
Self {
|
||||
builder: self.builder.field("framerate", gst::List::new(framerates)),
|
||||
builder: self
|
||||
.builder
|
||||
.field(glib::gstr!("framerate"), gst::List::new(framerates)),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,53 +1,42 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
|
||||
use std::ffi::CStr;
|
||||
|
||||
use gst::CapsFeatures;
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
#[cfg(any(feature = "v1_16", feature = "dox"))]
|
||||
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_16")))]
|
||||
pub static CAPS_FEATURE_FORMAT_INTERLACED: Lazy<&'static str> = Lazy::new(|| unsafe {
|
||||
CStr::from_ptr(ffi::GST_CAPS_FEATURE_FORMAT_INTERLACED)
|
||||
.to_str()
|
||||
.unwrap()
|
||||
});
|
||||
pub static CAPS_FEATURE_FORMAT_INTERLACED: &glib::GStr =
|
||||
unsafe { glib::GStr::from_utf8_with_nul_unchecked(ffi::GST_CAPS_FEATURE_FORMAT_INTERLACED) };
|
||||
#[cfg(any(feature = "v1_16", feature = "dox"))]
|
||||
#[cfg_attr(feature = "dox", doc(cfg(feature = "v1_16")))]
|
||||
pub static CAPS_FEATURES_FORMAT_INTERLACED: Lazy<CapsFeatures> =
|
||||
Lazy::new(|| CapsFeatures::new(&[*CAPS_FEATURE_FORMAT_INTERLACED]));
|
||||
Lazy::new(|| CapsFeatures::new([CAPS_FEATURE_FORMAT_INTERLACED]));
|
||||
|
||||
pub static CAPS_FEATURE_META_GST_VIDEO_AFFINE_TRANSFORMATION_META: Lazy<&'static str> =
|
||||
Lazy::new(|| unsafe {
|
||||
CStr::from_ptr(ffi::GST_CAPS_FEATURE_META_GST_VIDEO_AFFINE_TRANSFORMATION_META)
|
||||
.to_str()
|
||||
.unwrap()
|
||||
});
|
||||
pub static CAPS_FEATURE_META_GST_VIDEO_AFFINE_TRANSFORMATION_META: &glib::GStr = unsafe {
|
||||
glib::GStr::from_utf8_with_nul_unchecked(
|
||||
ffi::GST_CAPS_FEATURE_META_GST_VIDEO_AFFINE_TRANSFORMATION_META,
|
||||
)
|
||||
};
|
||||
pub static CAPS_FEATURES_META_GST_VIDEO_AFFINE_TRANSFORMATION_META: Lazy<CapsFeatures> =
|
||||
Lazy::new(|| CapsFeatures::new(&[*CAPS_FEATURE_META_GST_VIDEO_AFFINE_TRANSFORMATION_META]));
|
||||
Lazy::new(|| CapsFeatures::new([CAPS_FEATURE_META_GST_VIDEO_AFFINE_TRANSFORMATION_META]));
|
||||
|
||||
pub static CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META: Lazy<&'static str> =
|
||||
Lazy::new(|| unsafe {
|
||||
CStr::from_ptr(ffi::GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META)
|
||||
.to_str()
|
||||
.unwrap()
|
||||
});
|
||||
pub static CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META: &glib::GStr = unsafe {
|
||||
glib::GStr::from_utf8_with_nul_unchecked(
|
||||
ffi::GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META,
|
||||
)
|
||||
};
|
||||
pub static CAPS_FEATURES_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META: Lazy<CapsFeatures> =
|
||||
Lazy::new(|| CapsFeatures::new(&[*CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META]));
|
||||
Lazy::new(|| CapsFeatures::new([CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META]));
|
||||
|
||||
pub static CAPS_FEATURE_META_GST_VIDEO_META: Lazy<&'static str> = Lazy::new(|| unsafe {
|
||||
CStr::from_ptr(ffi::GST_CAPS_FEATURE_META_GST_VIDEO_META)
|
||||
.to_str()
|
||||
.unwrap()
|
||||
});
|
||||
pub static CAPS_FEATURE_META_GST_VIDEO_META: &glib::GStr =
|
||||
unsafe { glib::GStr::from_utf8_with_nul_unchecked(ffi::GST_CAPS_FEATURE_META_GST_VIDEO_META) };
|
||||
pub static CAPS_FEATURES_META_GST_VIDEO_META: Lazy<CapsFeatures> =
|
||||
Lazy::new(|| CapsFeatures::new(&[*CAPS_FEATURE_META_GST_VIDEO_META]));
|
||||
Lazy::new(|| CapsFeatures::new([CAPS_FEATURE_META_GST_VIDEO_META]));
|
||||
|
||||
pub static CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION: Lazy<&'static str> =
|
||||
Lazy::new(|| unsafe {
|
||||
CStr::from_ptr(ffi::GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION)
|
||||
.to_str()
|
||||
.unwrap()
|
||||
});
|
||||
pub static CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION: &glib::GStr = unsafe {
|
||||
glib::GStr::from_utf8_with_nul_unchecked(
|
||||
ffi::GST_CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION,
|
||||
)
|
||||
};
|
||||
pub static CAPS_FEATURES_META_GST_VIDEO_OVERLAY_COMPOSITION: Lazy<CapsFeatures> =
|
||||
Lazy::new(|| CapsFeatures::new(&[*CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION]));
|
||||
Lazy::new(|| CapsFeatures::new([CAPS_FEATURE_META_GST_VIDEO_OVERLAY_COMPOSITION]));
|
||||
|
|
|
@ -1,32 +1,24 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
|
||||
use std::{ffi::CStr, marker::PhantomData, mem};
|
||||
use std::{marker::PhantomData, mem};
|
||||
|
||||
use glib::translate::*;
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
pub static BUFFER_POOL_OPTION_VIDEO_AFFINE_TRANSFORMATION_META: Lazy<&'static str> =
|
||||
Lazy::new(|| unsafe {
|
||||
CStr::from_ptr(ffi::GST_BUFFER_POOL_OPTION_VIDEO_AFFINE_TRANSFORMATION_META)
|
||||
.to_str()
|
||||
.unwrap()
|
||||
});
|
||||
pub static BUFFER_POOL_OPTION_VIDEO_ALIGNMENT: Lazy<&'static str> = Lazy::new(|| unsafe {
|
||||
CStr::from_ptr(ffi::GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT)
|
||||
.to_str()
|
||||
.unwrap()
|
||||
});
|
||||
pub static BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META: Lazy<&'static str> =
|
||||
Lazy::new(|| unsafe {
|
||||
CStr::from_ptr(ffi::GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META)
|
||||
.to_str()
|
||||
.unwrap()
|
||||
});
|
||||
pub static BUFFER_POOL_OPTION_VIDEO_META: Lazy<&'static str> = Lazy::new(|| unsafe {
|
||||
CStr::from_ptr(ffi::GST_BUFFER_POOL_OPTION_VIDEO_META)
|
||||
.to_str()
|
||||
.unwrap()
|
||||
});
|
||||
pub static BUFFER_POOL_OPTION_VIDEO_AFFINE_TRANSFORMATION_META: &glib::GStr = unsafe {
|
||||
glib::GStr::from_utf8_with_nul_unchecked(
|
||||
ffi::GST_BUFFER_POOL_OPTION_VIDEO_AFFINE_TRANSFORMATION_META,
|
||||
)
|
||||
};
|
||||
pub static BUFFER_POOL_OPTION_VIDEO_ALIGNMENT: &glib::GStr = unsafe {
|
||||
glib::GStr::from_utf8_with_nul_unchecked(ffi::GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT)
|
||||
};
|
||||
pub static BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META: &glib::GStr = unsafe {
|
||||
glib::GStr::from_utf8_with_nul_unchecked(
|
||||
ffi::GST_BUFFER_POOL_OPTION_VIDEO_GL_TEXTURE_UPLOAD_META,
|
||||
)
|
||||
};
|
||||
pub static BUFFER_POOL_OPTION_VIDEO_META: &glib::GStr =
|
||||
unsafe { glib::GStr::from_utf8_with_nul_unchecked(ffi::GST_BUFFER_POOL_OPTION_VIDEO_META) };
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[doc(alias = "GstVideoAlignment")]
|
||||
|
|
|
@ -184,277 +184,287 @@ impl VideoConverterConfig {
|
|||
}
|
||||
|
||||
pub fn set_resampler_method(&mut self, v: crate::VideoResamplerMethod) {
|
||||
self.0.set("GstVideoConverter.resampler-method", v);
|
||||
self.0
|
||||
.set(glib::gstr!("GstVideoConverter.resampler-method"), v);
|
||||
}
|
||||
|
||||
#[doc(alias = "get_resampler_method")]
|
||||
pub fn resampler_method(&self) -> crate::VideoResamplerMethod {
|
||||
self.0
|
||||
.get_optional("GstVideoConverter.resampler-method")
|
||||
.get_optional(glib::gstr!("GstVideoConverter.resampler-method"))
|
||||
.expect("Wrong type")
|
||||
.unwrap_or(crate::VideoResamplerMethod::Cubic)
|
||||
}
|
||||
|
||||
pub fn set_chroma_resampler_method(&mut self, v: crate::VideoResamplerMethod) {
|
||||
self.0.set("GstVideoConverter.chroma-resampler-method", v);
|
||||
self.0
|
||||
.set(glib::gstr!("GstVideoConverter.chroma-resampler-method"), v);
|
||||
}
|
||||
|
||||
#[doc(alias = "get_chroma_resampler_method")]
|
||||
pub fn chroma_resampler_method(&self) -> crate::VideoResamplerMethod {
|
||||
self.0
|
||||
.get_optional("GstVideoConverter.chroma-resampler-method")
|
||||
.get_optional(glib::gstr!("GstVideoConverter.chroma-resampler-method"))
|
||||
.expect("Wrong type")
|
||||
.unwrap_or(crate::VideoResamplerMethod::Linear)
|
||||
}
|
||||
|
||||
pub fn set_resampler_taps(&mut self, v: u32) {
|
||||
self.0.set("GstVideoConverter.resampler-taps", v);
|
||||
self.0
|
||||
.set(glib::gstr!("GstVideoConverter.resampler-taps"), v);
|
||||
}
|
||||
|
||||
#[doc(alias = "get_resampler_taps")]
|
||||
pub fn resampler_taps(&self) -> u32 {
|
||||
self.0
|
||||
.get_optional("GstVideoConverter.resampler-taps")
|
||||
.get_optional(glib::gstr!("GstVideoConverter.resampler-taps"))
|
||||
.expect("Wrong type")
|
||||
.unwrap_or(0)
|
||||
}
|
||||
|
||||
pub fn set_dither_method(&mut self, v: crate::VideoDitherMethod) {
|
||||
self.0.set("GstVideoConverter.dither-method", v);
|
||||
self.0
|
||||
.set(glib::gstr!("GstVideoConverter.dither-method"), v);
|
||||
}
|
||||
|
||||
#[doc(alias = "get_dither_method")]
|
||||
pub fn dither_method(&self) -> crate::VideoDitherMethod {
|
||||
self.0
|
||||
.get_optional("GstVideoConverter.dither-method")
|
||||
.get_optional(glib::gstr!("GstVideoConverter.dither-method"))
|
||||
.expect("Wrong type")
|
||||
.unwrap_or(crate::VideoDitherMethod::Bayer)
|
||||
}
|
||||
|
||||
pub fn set_dither_quantization(&mut self, v: u32) {
|
||||
self.0.set("GstVideoConverter.dither-quantization", v);
|
||||
self.0
|
||||
.set(glib::gstr!("GstVideoConverter.dither-quantization"), v);
|
||||
}
|
||||
|
||||
#[doc(alias = "get_dither_quantization")]
|
||||
pub fn dither_quantization(&self) -> u32 {
|
||||
self.0
|
||||
.get_optional("GstVideoConverter.dither-quantization")
|
||||
.get_optional(glib::gstr!("GstVideoConverter.dither-quantization"))
|
||||
.expect("Wrong type")
|
||||
.unwrap_or(1)
|
||||
}
|
||||
|
||||
pub fn set_src_x(&mut self, v: i32) {
|
||||
self.0.set("GstVideoConverter.src-x", v);
|
||||
self.0.set(glib::gstr!("GstVideoConverter.src-x"), v);
|
||||
}
|
||||
|
||||
#[doc(alias = "get_src_x")]
|
||||
pub fn src_x(&self) -> i32 {
|
||||
self.0
|
||||
.get_optional("GstVideoConverter.src-x")
|
||||
.get_optional(glib::gstr!("GstVideoConverter.src-x"))
|
||||
.expect("Wrong type")
|
||||
.unwrap_or(0)
|
||||
}
|
||||
|
||||
pub fn set_src_y(&mut self, v: i32) {
|
||||
self.0.set("GstVideoConverter.src-y", v);
|
||||
self.0.set(glib::gstr!("GstVideoConverter.src-y"), v);
|
||||
}
|
||||
|
||||
#[doc(alias = "get_src_y")]
|
||||
pub fn src_y(&self) -> i32 {
|
||||
self.0
|
||||
.get_optional("GstVideoConverter.src-y")
|
||||
.get_optional(glib::gstr!("GstVideoConverter.src-y"))
|
||||
.expect("Wrong type")
|
||||
.unwrap_or(0)
|
||||
}
|
||||
|
||||
pub fn set_src_width(&mut self, v: Option<i32>) {
|
||||
if let Some(v) = v {
|
||||
self.0.set("GstVideoConverter.src-width", v);
|
||||
self.0.set(glib::gstr!("GstVideoConverter.src-width"), v);
|
||||
} else {
|
||||
self.0.remove_field("GstVideoConverter.src-width");
|
||||
self.0
|
||||
.remove_field(glib::gstr!("GstVideoConverter.src-width"));
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "get_src_width")]
|
||||
pub fn src_width(&self) -> Option<i32> {
|
||||
self.0
|
||||
.get_optional("GstVideoConverter.src-width")
|
||||
.get_optional(glib::gstr!("GstVideoConverter.src-width"))
|
||||
.expect("Wrong type")
|
||||
}
|
||||
|
||||
pub fn set_src_height(&mut self, v: Option<i32>) {
|
||||
if let Some(v) = v {
|
||||
self.0.set("GstVideoConverter.src-height", v);
|
||||
self.0.set(glib::gstr!("GstVideoConverter.src-height"), v);
|
||||
} else {
|
||||
self.0.remove_field("GstVideoConverter.src-height");
|
||||
self.0
|
||||
.remove_field(glib::gstr!("GstVideoConverter.src-height"));
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "get_src_height")]
|
||||
pub fn src_height(&self) -> Option<i32> {
|
||||
self.0
|
||||
.get_optional("GstVideoConverter.src-height")
|
||||
.get_optional(glib::gstr!("GstVideoConverter.src-height"))
|
||||
.expect("Wrong type")
|
||||
}
|
||||
|
||||
pub fn set_dest_x(&mut self, v: i32) {
|
||||
self.0.set("GstVideoConverter.dest-x", v);
|
||||
self.0.set(glib::gstr!("GstVideoConverter.dest-x"), v);
|
||||
}
|
||||
|
||||
#[doc(alias = "get_dest_x")]
|
||||
pub fn dest_x(&self) -> i32 {
|
||||
self.0
|
||||
.get_optional("GstVideoConverter.dest-x")
|
||||
.get_optional(glib::gstr!("GstVideoConverter.dest-x"))
|
||||
.expect("Wrong type")
|
||||
.unwrap_or(0)
|
||||
}
|
||||
|
||||
pub fn set_dest_y(&mut self, v: i32) {
|
||||
self.0.set("GstVideoConverter.dest-y", v);
|
||||
self.0.set(glib::gstr!("GstVideoConverter.dest-y"), v);
|
||||
}
|
||||
|
||||
#[doc(alias = "get_dest_y")]
|
||||
pub fn dest_y(&self) -> i32 {
|
||||
self.0
|
||||
.get_optional("GstVideoConverter.dest-y")
|
||||
.get_optional(glib::gstr!("GstVideoConverter.dest-y"))
|
||||
.expect("Wrong type")
|
||||
.unwrap_or(0)
|
||||
}
|
||||
|
||||
pub fn set_dest_width(&mut self, v: Option<i32>) {
|
||||
if let Some(v) = v {
|
||||
self.0.set("GstVideoConverter.dest-width", v);
|
||||
self.0.set(glib::gstr!("GstVideoConverter.dest-width"), v);
|
||||
} else {
|
||||
self.0.remove_field("GstVideoConverter.dest-width");
|
||||
self.0
|
||||
.remove_field(glib::gstr!("GstVideoConverter.dest-width"));
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "get_dest_width")]
|
||||
pub fn dest_width(&self) -> Option<i32> {
|
||||
self.0
|
||||
.get_optional("GstVideoConverter.dest-width")
|
||||
.get_optional(glib::gstr!("GstVideoConverter.dest-width"))
|
||||
.expect("Wrong type")
|
||||
}
|
||||
|
||||
pub fn set_dest_height(&mut self, v: Option<i32>) {
|
||||
if let Some(v) = v {
|
||||
self.0.set("GstVideoConverter.dest-height", v);
|
||||
self.0.set(glib::gstr!("GstVideoConverter.dest-height"), v);
|
||||
} else {
|
||||
self.0.remove_field("GstVideoConverter.dest-height");
|
||||
self.0
|
||||
.remove_field(glib::gstr!("GstVideoConverter.dest-height"));
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "get_dest_height")]
|
||||
pub fn dest_height(&self) -> Option<i32> {
|
||||
self.0
|
||||
.get_optional("GstVideoConverter.dest-height")
|
||||
.get_optional(glib::gstr!("GstVideoConverter.dest-height"))
|
||||
.expect("Wrong type")
|
||||
}
|
||||
|
||||
pub fn set_fill_border(&mut self, v: bool) {
|
||||
self.0.set("GstVideoConverter.fill-border", v);
|
||||
self.0.set(glib::gstr!("GstVideoConverter.fill-border"), v);
|
||||
}
|
||||
|
||||
#[doc(alias = "get_fill_border")]
|
||||
pub fn fills_border(&self) -> bool {
|
||||
self.0
|
||||
.get_optional("GstVideoConverter.fill-border")
|
||||
.get_optional(glib::gstr!("GstVideoConverter.fill-border"))
|
||||
.expect("Wrong type")
|
||||
.unwrap_or(true)
|
||||
}
|
||||
|
||||
pub fn set_alpha_value(&mut self, v: f64) {
|
||||
self.0.set("GstVideoConverter.alpha-value", v);
|
||||
self.0.set(glib::gstr!("GstVideoConverter.alpha-value"), v);
|
||||
}
|
||||
|
||||
#[doc(alias = "get_alpha_value")]
|
||||
pub fn alpha_value(&self) -> f64 {
|
||||
self.0
|
||||
.get_optional("GstVideoConverter.alpha-value")
|
||||
.get_optional(glib::gstr!("GstVideoConverter.alpha-value"))
|
||||
.expect("Wrong type")
|
||||
.unwrap_or(1.0)
|
||||
}
|
||||
|
||||
pub fn set_alpha_mode(&mut self, v: crate::VideoAlphaMode) {
|
||||
self.0.set("GstVideoConverter.alpha-mode", v);
|
||||
self.0.set(glib::gstr!("GstVideoConverter.alpha-mode"), v);
|
||||
}
|
||||
|
||||
#[doc(alias = "get_alpha_mode")]
|
||||
pub fn alpha_mode(&self) -> crate::VideoAlphaMode {
|
||||
self.0
|
||||
.get_optional("GstVideoConverter.alpha-mode")
|
||||
.get_optional(glib::gstr!("GstVideoConverter.alpha-mode"))
|
||||
.expect("Wrong type")
|
||||
.unwrap_or(crate::VideoAlphaMode::Copy)
|
||||
}
|
||||
|
||||
pub fn set_border_argb(&mut self, v: u32) {
|
||||
self.0.set("GstVideoConverter.border-argb", v);
|
||||
self.0.set(glib::gstr!("GstVideoConverter.border-argb"), v);
|
||||
}
|
||||
|
||||
#[doc(alias = "get_border_argb")]
|
||||
pub fn border_argb(&self) -> u32 {
|
||||
self.0
|
||||
.get_optional("GstVideoConverter.border-argb")
|
||||
.get_optional(glib::gstr!("GstVideoConverter.border-argb"))
|
||||
.expect("Wrong type")
|
||||
.unwrap_or(0xff_00_00_00)
|
||||
}
|
||||
|
||||
pub fn set_chroma_mode(&mut self, v: crate::VideoChromaMode) {
|
||||
self.0.set("GstVideoConverter.chroma-mode", v);
|
||||
self.0.set(glib::gstr!("GstVideoConverter.chroma-mode"), v);
|
||||
}
|
||||
|
||||
#[doc(alias = "get_chroma_mode")]
|
||||
pub fn chroma_mode(&self) -> crate::VideoChromaMode {
|
||||
self.0
|
||||
.get_optional("GstVideoConverter.chroma-mode")
|
||||
.get_optional(glib::gstr!("GstVideoConverter.chroma-mode"))
|
||||
.expect("Wrong type")
|
||||
.unwrap_or(crate::VideoChromaMode::Full)
|
||||
}
|
||||
|
||||
pub fn set_matrix_mode(&mut self, v: crate::VideoMatrixMode) {
|
||||
self.0.set("GstVideoConverter.matrix-mode", v);
|
||||
self.0.set(glib::gstr!("GstVideoConverter.matrix-mode"), v);
|
||||
}
|
||||
|
||||
#[doc(alias = "get_matrix_mode")]
|
||||
pub fn matrix_mode(&self) -> crate::VideoMatrixMode {
|
||||
self.0
|
||||
.get_optional("GstVideoConverter.matrix-mode")
|
||||
.get_optional(glib::gstr!("GstVideoConverter.matrix-mode"))
|
||||
.expect("Wrong type")
|
||||
.unwrap_or(crate::VideoMatrixMode::Full)
|
||||
}
|
||||
|
||||
pub fn set_gamma_mode(&mut self, v: crate::VideoGammaMode) {
|
||||
self.0.set("GstVideoConverter.gamma-mode", v);
|
||||
self.0.set(glib::gstr!("GstVideoConverter.gamma-mode"), v);
|
||||
}
|
||||
|
||||
#[doc(alias = "get_gamma_mode")]
|
||||
pub fn gamma_mode(&self) -> crate::VideoGammaMode {
|
||||
self.0
|
||||
.get_optional("GstVideoConverter.gamma-mode")
|
||||
.get_optional(glib::gstr!("GstVideoConverter.gamma-mode"))
|
||||
.expect("Wrong type")
|
||||
.unwrap_or(crate::VideoGammaMode::None)
|
||||
}
|
||||
|
||||
pub fn set_primaries_mode(&mut self, v: crate::VideoPrimariesMode) {
|
||||
self.0.set("GstVideoConverter.primaries-mode", v);
|
||||
self.0
|
||||
.set(glib::gstr!("GstVideoConverter.primaries-mode"), v);
|
||||
}
|
||||
|
||||
#[doc(alias = "get_primaries_mode")]
|
||||
pub fn primaries_mode(&self) -> crate::VideoPrimariesMode {
|
||||
self.0
|
||||
.get_optional("GstVideoConverter.primaries-mode")
|
||||
.get_optional(glib::gstr!("GstVideoConverter.primaries-mode"))
|
||||
.expect("Wrong type")
|
||||
.unwrap_or(crate::VideoPrimariesMode::None)
|
||||
}
|
||||
|
||||
pub fn set_threads(&mut self, v: u32) {
|
||||
self.0.set("GstVideoConverter.threads", v);
|
||||
self.0.set(glib::gstr!("GstVideoConverter.threads"), v);
|
||||
}
|
||||
|
||||
#[doc(alias = "get_threads")]
|
||||
pub fn threads(&self) -> u32 {
|
||||
self.0
|
||||
.get_optional("GstVideoConverter.threads")
|
||||
.get_optional(glib::gstr!("GstVideoConverter.threads"))
|
||||
.expect("Wrong type")
|
||||
.unwrap_or(1)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
|
||||
use std::{ffi::CStr, str};
|
||||
use std::str;
|
||||
|
||||
use glib::translate::{from_glib, FromGlib, IntoGlib};
|
||||
use once_cell::sync::Lazy;
|
||||
|
@ -269,18 +269,16 @@ impl crate::VideoFormat {
|
|||
}
|
||||
|
||||
#[doc(alias = "gst_video_format_to_string")]
|
||||
pub fn to_str<'a>(self) -> &'a str {
|
||||
pub fn to_str<'a>(self) -> &'a glib::GStr {
|
||||
if self == Self::Unknown {
|
||||
return "UNKNOWN";
|
||||
return glib::gstr!("UNKNOWN");
|
||||
}
|
||||
unsafe {
|
||||
CStr::from_ptr(
|
||||
glib::GStr::from_ptr(
|
||||
ffi::gst_video_format_to_string(self.into_glib())
|
||||
.as_ref()
|
||||
.expect("gst_video_format_to_string returned NULL"),
|
||||
)
|
||||
.to_str()
|
||||
.expect("gst_video_format_to_string returned an invalid string")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
|
||||
use std::{cmp::Ordering, ffi::CStr, fmt, marker::PhantomData, str};
|
||||
use std::{cmp::Ordering, fmt, marker::PhantomData, str};
|
||||
|
||||
use glib::translate::{from_glib, IntoGlib, ToGlibPtr};
|
||||
|
||||
|
@ -32,13 +32,13 @@ impl VideoFormatInfo {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn name<'a>(&self) -> &'a str {
|
||||
unsafe { CStr::from_ptr(self.0.name).to_str().unwrap() }
|
||||
pub fn name<'a>(&self) -> &'a glib::GStr {
|
||||
unsafe { glib::GStr::from_ptr(self.0.name) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn description<'a>(&self) -> &'a str {
|
||||
unsafe { CStr::from_ptr(self.0.description).to_str().unwrap() }
|
||||
pub fn description<'a>(&self) -> &'a glib::GStr {
|
||||
unsafe { glib::GStr::from_ptr(self.0.description) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
@ -5,7 +5,7 @@ use std::{fmt, marker::PhantomData, ptr, str};
|
|||
use glib::{
|
||||
translate::{from_glib, from_glib_full, FromGlibPtrFull, IntoGlib, IntoGlibPtr, ToGlibPtr},
|
||||
value::ToSendValue,
|
||||
StaticType,
|
||||
IntoGStr, StaticType,
|
||||
};
|
||||
|
||||
use crate::{caps_features::*, structure::*, CapsIntersectMode};
|
||||
|
@ -14,7 +14,7 @@ mini_object_wrapper!(Caps, CapsRef, ffi::GstCaps, || { ffi::gst_caps_get_type()
|
|||
|
||||
impl Caps {
|
||||
#[doc(alias = "gst_caps_new_simple")]
|
||||
pub fn builder(name: &str) -> Builder<NoFeature> {
|
||||
pub fn builder(name: impl IntoGStr) -> Builder<NoFeature> {
|
||||
assert_initialized_main_thread!();
|
||||
Builder::new(name)
|
||||
}
|
||||
|
@ -50,7 +50,9 @@ impl Caps {
|
|||
}
|
||||
|
||||
#[doc(alias = "gst_caps_new_simple")]
|
||||
pub fn new_simple(name: &str, values: &[(&str, &(dyn ToSendValue + Sync))]) -> Self {
|
||||
#[deprecated = "Use `Caps::builder()` or `Caps::new_empty()`"]
|
||||
#[allow(deprecated)]
|
||||
pub fn new_simple(name: impl IntoGStr, values: &[(&str, &(dyn ToSendValue + Sync))]) -> Self {
|
||||
skip_assert_initialized!();
|
||||
let mut caps = Caps::new_empty();
|
||||
|
||||
|
@ -61,9 +63,14 @@ impl Caps {
|
|||
}
|
||||
|
||||
#[doc(alias = "gst_caps_new_empty_simple")]
|
||||
pub fn new_empty_simple(name: &str) -> Self {
|
||||
pub fn new_empty_simple(name: impl IntoGStr) -> Self {
|
||||
skip_assert_initialized!();
|
||||
Self::new_simple(name, &[])
|
||||
let mut caps = Caps::new_empty();
|
||||
|
||||
let structure = Structure::new_empty(name);
|
||||
caps.get_mut().unwrap().append_structure(structure);
|
||||
|
||||
caps
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_caps_fixate")]
|
||||
|
@ -142,8 +149,10 @@ impl str::FromStr for Caps {
|
|||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
assert_initialized_main_thread!();
|
||||
unsafe {
|
||||
Option::<_>::from_glib_full(ffi::gst_caps_from_string(s.to_glib_none().0))
|
||||
s.run_with_gstr(|s| {
|
||||
Option::<_>::from_glib_full(ffi::gst_caps_from_string(s.as_ptr()))
|
||||
.ok_or_else(|| glib::bool_error!("Failed to parse caps from string"))
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -234,7 +243,23 @@ impl std::iter::Extend<Caps> for CapsRef {
|
|||
}
|
||||
|
||||
impl CapsRef {
|
||||
#[doc(alias = "gst_caps_set_value")]
|
||||
pub fn set(&mut self, name: impl IntoGStr, value: impl ToSendValue + Sync) {
|
||||
let value = value.to_send_value();
|
||||
self.set_value(name, value);
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_caps_set_value")]
|
||||
pub fn set_value(&mut self, name: impl IntoGStr, value: glib::SendValue) {
|
||||
unsafe {
|
||||
name.run_with_gstr(|name| {
|
||||
ffi::gst_caps_set_value(self.as_mut_ptr(), name.as_ptr(), value.to_glib_none().0)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_caps_set_simple")]
|
||||
#[deprecated = "Use `CapsRef::set()`"]
|
||||
pub fn set_simple(&mut self, values: &[(&str, &(dyn ToSendValue + Sync))]) {
|
||||
for &(name, value) in values {
|
||||
let value = value.to_value();
|
||||
|
@ -913,7 +938,7 @@ impl<T> fmt::Debug for Builder<T> {
|
|||
}
|
||||
|
||||
impl Builder<NoFeature> {
|
||||
fn new(name: &str) -> Builder<NoFeature> {
|
||||
fn new(name: impl IntoGStr) -> Builder<NoFeature> {
|
||||
skip_assert_initialized!();
|
||||
Builder {
|
||||
s: crate::Structure::new_empty(name),
|
||||
|
@ -922,7 +947,10 @@ impl Builder<NoFeature> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn features(self, features: &[&str]) -> Builder<HasFeatures> {
|
||||
pub fn features(
|
||||
self,
|
||||
features: impl IntoIterator<Item = impl IntoGStr>,
|
||||
) -> Builder<HasFeatures> {
|
||||
Builder {
|
||||
s: self.s,
|
||||
features: Some(CapsFeatures::new(features)),
|
||||
|
@ -940,7 +968,7 @@ impl Builder<NoFeature> {
|
|||
}
|
||||
|
||||
impl<T> Builder<T> {
|
||||
pub fn field(mut self, name: &str, value: impl Into<glib::Value> + Send) -> Self {
|
||||
pub fn field(mut self, name: impl IntoGStr, value: impl Into<glib::Value> + Send) -> Self {
|
||||
self.s.set(name, value);
|
||||
self
|
||||
}
|
||||
|
@ -1058,6 +1086,7 @@ mod tests {
|
|||
use crate::{Array, Fraction};
|
||||
|
||||
#[test]
|
||||
#[allow(deprecated)]
|
||||
fn test_simple() {
|
||||
crate::init().unwrap();
|
||||
|
||||
|
@ -1100,12 +1129,12 @@ mod tests {
|
|||
|
||||
{
|
||||
let caps = caps.get_mut().unwrap();
|
||||
caps.set_features(0, Some(CapsFeatures::new(&["foo:bla"])));
|
||||
caps.set_features(0, Some(CapsFeatures::new(["foo:bla"])));
|
||||
}
|
||||
assert!(caps
|
||||
.features(0)
|
||||
.unwrap()
|
||||
.is_equal(CapsFeatures::new(&["foo:bla"]).as_ref()));
|
||||
.is_equal(CapsFeatures::new(["foo:bla"]).as_ref()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1132,7 +1161,7 @@ mod tests {
|
|||
|
||||
let caps = Caps::builder("foo/bar")
|
||||
.field("int", 12)
|
||||
.features(&["foo:bla", "foo:baz"])
|
||||
.features(["foo:bla", "foo:baz"])
|
||||
.build();
|
||||
assert_eq!(caps.to_string(), "foo/bar(foo:bla, foo:baz), int=(int)12");
|
||||
}
|
||||
|
@ -1172,7 +1201,7 @@ mod tests {
|
|||
.structure_with_any_features(Structure::builder("audio/x-raw").build())
|
||||
.structure_with_features(
|
||||
Structure::builder("video/x-raw").build(),
|
||||
CapsFeatures::new(&["foo:bla", "foo:baz"]),
|
||||
CapsFeatures::new(["foo:bla", "foo:baz"]),
|
||||
)
|
||||
.build();
|
||||
assert_eq!(
|
||||
|
@ -1185,11 +1214,11 @@ mod tests {
|
|||
fn test_builder_full_with_features() {
|
||||
crate::init().unwrap();
|
||||
|
||||
let caps = Caps::builder_full_with_features(CapsFeatures::new(&["foo:bla"]))
|
||||
let caps = Caps::builder_full_with_features(CapsFeatures::new(["foo:bla"]))
|
||||
.structure(Structure::builder("audio/x-raw").build())
|
||||
.structure_with_features(
|
||||
Structure::builder("video/x-raw").build(),
|
||||
CapsFeatures::new(&["foo:baz"]),
|
||||
CapsFeatures::new(["foo:baz"]),
|
||||
)
|
||||
.build();
|
||||
assert_eq!(
|
||||
|
@ -1253,7 +1282,7 @@ mod tests {
|
|||
.build();
|
||||
assert_eq!(format!("{:?}", caps), "Caps(audio/x-raw(ANY))");
|
||||
|
||||
let caps = Caps::builder_full_with_features(CapsFeatures::new(&["foo:bla"]))
|
||||
let caps = Caps::builder_full_with_features(CapsFeatures::new(["foo:bla"]))
|
||||
.structure(
|
||||
Structure::builder("audio/x-raw")
|
||||
.field(
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
use std::{
|
||||
borrow::{Borrow, BorrowMut, ToOwned},
|
||||
ffi::CStr,
|
||||
fmt,
|
||||
marker::PhantomData,
|
||||
mem,
|
||||
|
@ -10,7 +9,7 @@ use std::{
|
|||
ptr, str,
|
||||
};
|
||||
|
||||
use glib::{translate::*, StaticType};
|
||||
use glib::{translate::*, IntoGStr, StaticType};
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
#[doc(alias = "GstCapsFeatures")]
|
||||
|
@ -21,7 +20,7 @@ unsafe impl Sync for CapsFeatures {}
|
|||
|
||||
impl CapsFeatures {
|
||||
#[doc(alias = "gst_caps_features_new")]
|
||||
pub fn new(features: &[&str]) -> Self {
|
||||
pub fn new(features: impl IntoIterator<Item = impl IntoGStr>) -> Self {
|
||||
skip_assert_initialized!();
|
||||
let mut f = Self::new_empty();
|
||||
|
||||
|
@ -33,12 +32,12 @@ impl CapsFeatures {
|
|||
}
|
||||
|
||||
#[doc(alias = "gst_caps_features_new_id")]
|
||||
pub fn from_quarks(features: &[glib::Quark]) -> Self {
|
||||
pub fn from_quarks(features: impl IntoIterator<Item = glib::Quark>) -> Self {
|
||||
skip_assert_initialized!();
|
||||
let mut f = Self::new_empty();
|
||||
|
||||
for feature in features {
|
||||
f.add_from_quark(*feature);
|
||||
for feature in features.into_iter() {
|
||||
f.add_from_quark(feature);
|
||||
}
|
||||
|
||||
f
|
||||
|
@ -140,7 +139,7 @@ impl str::FromStr for CapsFeatures {
|
|||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
assert_initialized_main_thread!();
|
||||
unsafe {
|
||||
let ptr = ffi::gst_caps_features_from_string(s.to_glib_none().0);
|
||||
let ptr = s.run_with_gstr(|s| ffi::gst_caps_features_from_string(s.as_ptr()));
|
||||
if ptr.is_null() {
|
||||
return Err(glib::bool_error!(
|
||||
"Failed to parse caps features from string"
|
||||
|
@ -361,12 +360,14 @@ impl CapsFeaturesRef {
|
|||
}
|
||||
|
||||
#[doc(alias = "gst_caps_features_contains")]
|
||||
pub fn contains(&self, feature: &str) -> bool {
|
||||
pub fn contains(&self, feature: impl IntoGStr) -> bool {
|
||||
unsafe {
|
||||
feature.run_with_gstr(|feature| {
|
||||
from_glib(ffi::gst_caps_features_contains(
|
||||
self.as_ptr(),
|
||||
feature.to_glib_none().0,
|
||||
feature.as_ptr(),
|
||||
))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -388,7 +389,7 @@ impl CapsFeaturesRef {
|
|||
|
||||
#[doc(alias = "get_nth")]
|
||||
#[doc(alias = "gst_caps_features_get_nth")]
|
||||
pub fn nth(&self, idx: u32) -> Option<&str> {
|
||||
pub fn nth(&self, idx: u32) -> Option<&glib::GStr> {
|
||||
if idx >= self.size() {
|
||||
return None;
|
||||
}
|
||||
|
@ -399,7 +400,7 @@ impl CapsFeaturesRef {
|
|||
return None;
|
||||
}
|
||||
|
||||
Some(CStr::from_ptr(feature).to_str().unwrap())
|
||||
Some(glib::GStr::from_ptr(feature))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -416,13 +417,21 @@ impl CapsFeaturesRef {
|
|||
}
|
||||
|
||||
#[doc(alias = "gst_caps_features_add")]
|
||||
pub fn add(&mut self, feature: &str) {
|
||||
unsafe { ffi::gst_caps_features_add(self.as_mut_ptr(), feature.to_glib_none().0) }
|
||||
pub fn add(&mut self, feature: impl IntoGStr) {
|
||||
unsafe {
|
||||
feature.run_with_gstr(|feature| {
|
||||
ffi::gst_caps_features_add(self.as_mut_ptr(), feature.as_ptr())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_caps_features_remove")]
|
||||
pub fn remove(&mut self, feature: &str) {
|
||||
unsafe { ffi::gst_caps_features_remove(self.as_mut_ptr(), feature.to_glib_none().0) }
|
||||
pub fn remove(&mut self, feature: impl IntoGStr) {
|
||||
unsafe {
|
||||
feature.run_with_gstr(|feature| {
|
||||
ffi::gst_caps_features_remove(self.as_mut_ptr(), feature.as_ptr())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_caps_features_add_id")]
|
||||
|
@ -464,12 +473,24 @@ impl<'a> std::iter::Extend<&'a str> for CapsFeaturesRef {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> std::iter::Extend<&'a glib::GStr> for CapsFeaturesRef {
|
||||
fn extend<T: IntoIterator<Item = &'a glib::GStr>>(&mut self, iter: T) {
|
||||
iter.into_iter().for_each(|f| self.add(f));
|
||||
}
|
||||
}
|
||||
|
||||
impl std::iter::Extend<String> for CapsFeaturesRef {
|
||||
fn extend<T: IntoIterator<Item = String>>(&mut self, iter: T) {
|
||||
iter.into_iter().for_each(|f| self.add(&f));
|
||||
}
|
||||
}
|
||||
|
||||
impl std::iter::Extend<glib::GString> for CapsFeaturesRef {
|
||||
fn extend<T: IntoIterator<Item = glib::GString>>(&mut self, iter: T) {
|
||||
iter.into_iter().for_each(|f| self.add(&f));
|
||||
}
|
||||
}
|
||||
|
||||
impl std::iter::Extend<glib::Quark> for CapsFeaturesRef {
|
||||
fn extend<T: IntoIterator<Item = glib::Quark>>(&mut self, iter: T) {
|
||||
iter.into_iter().for_each(|f| self.add_from_quark(f));
|
||||
|
@ -537,7 +558,7 @@ impl<'a> Iter<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Iterator for Iter<'a> {
|
||||
type Item = &'a str;
|
||||
type Item = &'a glib::GStr;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.idx >= self.n_features {
|
||||
|
@ -551,7 +572,7 @@ impl<'a> Iterator for Iter<'a> {
|
|||
|
||||
self.idx += 1;
|
||||
|
||||
Some(CStr::from_ptr(feature).to_str().unwrap())
|
||||
Some(glib::GStr::from_ptr(feature))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -577,7 +598,7 @@ impl<'a> Iterator for Iter<'a> {
|
|||
let feature =
|
||||
ffi::gst_caps_features_get_nth(self.caps_features.as_ptr(), end as u32);
|
||||
debug_assert!(!feature.is_null());
|
||||
Some(CStr::from_ptr(feature).to_str().unwrap())
|
||||
Some(glib::GStr::from_ptr(feature))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -592,7 +613,7 @@ impl<'a> Iterator for Iter<'a> {
|
|||
self.n_features as u32 - 1,
|
||||
);
|
||||
debug_assert!(!feature.is_null());
|
||||
Some(CStr::from_ptr(feature).to_str().unwrap())
|
||||
Some(glib::GStr::from_ptr(feature))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -611,7 +632,7 @@ impl<'a> DoubleEndedIterator for Iter<'a> {
|
|||
ffi::gst_caps_features_get_nth(self.caps_features.as_ptr(), self.n_features as u32);
|
||||
debug_assert!(!feature.is_null());
|
||||
|
||||
Some(CStr::from_ptr(feature).to_str().unwrap())
|
||||
Some(glib::GStr::from_ptr(feature))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -629,7 +650,7 @@ impl<'a> DoubleEndedIterator for Iter<'a> {
|
|||
);
|
||||
debug_assert!(!feature.is_null());
|
||||
|
||||
Some(CStr::from_ptr(feature).to_str().unwrap())
|
||||
Some(glib::GStr::from_ptr(feature))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -641,7 +662,7 @@ impl<'a> std::iter::FusedIterator for Iter<'a> {}
|
|||
|
||||
impl<'a> IntoIterator for &'a CapsFeaturesRef {
|
||||
type IntoIter = Iter<'a>;
|
||||
type Item = &'a str;
|
||||
type Item = &'a glib::GStr;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.iter()
|
||||
|
@ -659,6 +680,18 @@ impl<'a> std::iter::FromIterator<&'a str> for CapsFeatures {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> std::iter::FromIterator<&'a glib::GStr> for CapsFeatures {
|
||||
fn from_iter<T: IntoIterator<Item = &'a glib::GStr>>(iter: T) -> Self {
|
||||
assert_initialized_main_thread!();
|
||||
|
||||
let mut features = CapsFeatures::new_empty();
|
||||
|
||||
iter.into_iter().for_each(|f| features.add(f));
|
||||
|
||||
features
|
||||
}
|
||||
}
|
||||
|
||||
impl std::iter::FromIterator<String> for CapsFeatures {
|
||||
fn from_iter<T: IntoIterator<Item = String>>(iter: T) -> Self {
|
||||
skip_assert_initialized!();
|
||||
|
@ -670,6 +703,18 @@ impl std::iter::FromIterator<String> for CapsFeatures {
|
|||
}
|
||||
}
|
||||
|
||||
impl std::iter::FromIterator<glib::GString> for CapsFeatures {
|
||||
fn from_iter<T: IntoIterator<Item = glib::GString>>(iter: T) -> Self {
|
||||
assert_initialized_main_thread!();
|
||||
|
||||
let mut features = CapsFeatures::new_empty();
|
||||
|
||||
iter.into_iter().for_each(|f| features.add(&f));
|
||||
|
||||
features
|
||||
}
|
||||
}
|
||||
|
||||
impl std::iter::FromIterator<glib::Quark> for CapsFeatures {
|
||||
fn from_iter<T: IntoIterator<Item = glib::Quark>>(iter: T) -> Self {
|
||||
skip_assert_initialized!();
|
||||
|
@ -710,13 +755,10 @@ impl ToOwned for CapsFeaturesRef {
|
|||
unsafe impl Sync for CapsFeaturesRef {}
|
||||
unsafe impl Send for CapsFeaturesRef {}
|
||||
|
||||
pub static CAPS_FEATURE_MEMORY_SYSTEM_MEMORY: Lazy<&'static str> = Lazy::new(|| unsafe {
|
||||
CStr::from_ptr(ffi::GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY)
|
||||
.to_str()
|
||||
.unwrap()
|
||||
});
|
||||
pub static CAPS_FEATURE_MEMORY_SYSTEM_MEMORY: &glib::GStr =
|
||||
unsafe { glib::GStr::from_utf8_with_nul_unchecked(ffi::GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY) };
|
||||
pub static CAPS_FEATURES_MEMORY_SYSTEM_MEMORY: Lazy<CapsFeatures> =
|
||||
Lazy::new(|| CapsFeatures::new(&[*CAPS_FEATURE_MEMORY_SYSTEM_MEMORY]));
|
||||
Lazy::new(|| CapsFeatures::new([CAPS_FEATURE_MEMORY_SYSTEM_MEMORY]));
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
|
|
@ -33,7 +33,7 @@ impl<'a> Serialize for CapsFeaturesForIterSe<'a> {
|
|||
if size > 0 {
|
||||
let mut seq = serializer.serialize_seq(Some(size))?;
|
||||
for feature in iter {
|
||||
seq.serialize_element(feature)?;
|
||||
seq.serialize_element(feature.as_str())?;
|
||||
}
|
||||
seq.end()
|
||||
} else {
|
||||
|
@ -81,7 +81,7 @@ impl<'de> Visitor<'de> for CapsFeaturesSomeVisitor {
|
|||
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
|
||||
let mut features = CapsFeatures::new_empty();
|
||||
while let Some(feature) = seq.next_element::<String>()? {
|
||||
features.add(feature.as_ref());
|
||||
features.add(feature.as_str());
|
||||
}
|
||||
Ok(CapsFeaturesSome(features))
|
||||
}
|
||||
|
|
|
@ -262,7 +262,7 @@ mod tests {
|
|||
.field("string", "bla")
|
||||
.field("fraction", Fraction::new(1, 2))
|
||||
.field("array", Array::new([1, 2]))
|
||||
.features(&["foo:bar", "foo:baz"])
|
||||
.features(["foo:bar", "foo:baz"])
|
||||
.build();
|
||||
|
||||
let pretty_config = ron::ser::PrettyConfig::new().new_line("".to_string());
|
||||
|
@ -405,7 +405,7 @@ mod tests {
|
|||
.as_ref()
|
||||
);
|
||||
let f = caps.features(0).unwrap();
|
||||
assert!(f.is_equal(CapsFeatures::new(&["foo:bar", "foo:baz"]).as_ref()));
|
||||
assert!(f.is_equal(CapsFeatures::new(["foo:bar", "foo:baz"]).as_ref()));
|
||||
|
||||
let caps_ron = r#"
|
||||
Some([
|
||||
|
@ -471,7 +471,7 @@ mod tests {
|
|||
.field("string", "bla")
|
||||
.field("fraction", Fraction::new(1, 2))
|
||||
.field("array", Array::new([1, 2]))
|
||||
.features(&["foo:bar", "foo:baz"])
|
||||
.features(["foo:bar", "foo:baz"])
|
||||
.build();
|
||||
let caps_ser = ron::ser::to_string(&caps).unwrap();
|
||||
let caps_de: Caps = ron::de::from_str(caps_ser.as_str()).unwrap();
|
||||
|
|
|
@ -41,36 +41,36 @@ impl DeviceProviderFactory {
|
|||
#[doc(alias = "get_longname")]
|
||||
#[doc(alias = "gst_device_provider_factory_get_longname")]
|
||||
pub fn longname(&self) -> &str {
|
||||
self.metadata(&ELEMENT_METADATA_LONGNAME).unwrap()
|
||||
self.metadata(ELEMENT_METADATA_LONGNAME).unwrap()
|
||||
}
|
||||
|
||||
#[doc(alias = "get_klass")]
|
||||
#[doc(alias = "gst_device_provider_factory_get_klass")]
|
||||
pub fn klass(&self) -> &str {
|
||||
self.metadata(&ELEMENT_METADATA_KLASS).unwrap()
|
||||
self.metadata(ELEMENT_METADATA_KLASS).unwrap()
|
||||
}
|
||||
|
||||
#[doc(alias = "get_description")]
|
||||
#[doc(alias = "gst_device_provider_factory_get_description")]
|
||||
pub fn description(&self) -> &str {
|
||||
self.metadata(&ELEMENT_METADATA_DESCRIPTION).unwrap()
|
||||
self.metadata(ELEMENT_METADATA_DESCRIPTION).unwrap()
|
||||
}
|
||||
|
||||
#[doc(alias = "get_author")]
|
||||
#[doc(alias = "gst_device_provider_factory_get_author")]
|
||||
pub fn author(&self) -> &str {
|
||||
self.metadata(&ELEMENT_METADATA_AUTHOR).unwrap()
|
||||
self.metadata(ELEMENT_METADATA_AUTHOR).unwrap()
|
||||
}
|
||||
|
||||
#[doc(alias = "get_documentation_uri")]
|
||||
#[doc(alias = "gst_device_provider_factory_get_documentation_uri")]
|
||||
pub fn documentation_uri(&self) -> Option<&str> {
|
||||
self.metadata(&ELEMENT_METADATA_DOC_URI)
|
||||
self.metadata(ELEMENT_METADATA_DOC_URI)
|
||||
}
|
||||
|
||||
#[doc(alias = "get_icon_name")]
|
||||
#[doc(alias = "gst_device_provider_factory_get_icon_name")]
|
||||
pub fn icon_name(&self) -> Option<&str> {
|
||||
self.metadata(&ELEMENT_METADATA_ICON_NAME)
|
||||
self.metadata(ELEMENT_METADATA_ICON_NAME)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
use std::{ffi::CStr, future::Future, mem, num::NonZeroU64, pin::Pin};
|
||||
|
||||
use glib::translate::*;
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
use crate::{
|
||||
format::{
|
||||
|
@ -982,41 +981,23 @@ pub unsafe trait ElementClassExt {
|
|||
unsafe impl<T: IsA<Element> + glib::object::IsClass> ElementClassExt for glib::object::Class<T> {}
|
||||
|
||||
#[doc(alias = "GST_ELEMENT_METADATA_AUTHOR")]
|
||||
pub static ELEMENT_METADATA_AUTHOR: Lazy<&'static str> = Lazy::new(|| unsafe {
|
||||
CStr::from_ptr(ffi::GST_ELEMENT_METADATA_AUTHOR)
|
||||
.to_str()
|
||||
.unwrap()
|
||||
});
|
||||
pub static ELEMENT_METADATA_AUTHOR: &glib::GStr =
|
||||
unsafe { glib::GStr::from_utf8_with_nul_unchecked(ffi::GST_ELEMENT_METADATA_AUTHOR) };
|
||||
#[doc(alias = "GST_ELEMENT_METADATA_DESCRIPTION")]
|
||||
pub static ELEMENT_METADATA_DESCRIPTION: Lazy<&'static str> = Lazy::new(|| unsafe {
|
||||
CStr::from_ptr(ffi::GST_ELEMENT_METADATA_DESCRIPTION)
|
||||
.to_str()
|
||||
.unwrap()
|
||||
});
|
||||
pub static ELEMENT_METADATA_DESCRIPTION: &glib::GStr =
|
||||
unsafe { glib::GStr::from_utf8_with_nul_unchecked(ffi::GST_ELEMENT_METADATA_DESCRIPTION) };
|
||||
#[doc(alias = "GST_ELEMENT_METADATA_DOC_URI")]
|
||||
pub static ELEMENT_METADATA_DOC_URI: Lazy<&'static str> = Lazy::new(|| unsafe {
|
||||
CStr::from_ptr(ffi::GST_ELEMENT_METADATA_DOC_URI)
|
||||
.to_str()
|
||||
.unwrap()
|
||||
});
|
||||
pub static ELEMENT_METADATA_DOC_URI: &glib::GStr =
|
||||
unsafe { glib::GStr::from_utf8_with_nul_unchecked(ffi::GST_ELEMENT_METADATA_DOC_URI) };
|
||||
#[doc(alias = "GST_ELEMENT_METADATA_ICON_NAME")]
|
||||
pub static ELEMENT_METADATA_ICON_NAME: Lazy<&'static str> = Lazy::new(|| unsafe {
|
||||
CStr::from_ptr(ffi::GST_ELEMENT_METADATA_ICON_NAME)
|
||||
.to_str()
|
||||
.unwrap()
|
||||
});
|
||||
pub static ELEMENT_METADATA_ICON_NAME: &glib::GStr =
|
||||
unsafe { glib::GStr::from_utf8_with_nul_unchecked(ffi::GST_ELEMENT_METADATA_ICON_NAME) };
|
||||
#[doc(alias = "GST_ELEMENT_METADATA_KLASS")]
|
||||
pub static ELEMENT_METADATA_KLASS: Lazy<&'static str> = Lazy::new(|| unsafe {
|
||||
CStr::from_ptr(ffi::GST_ELEMENT_METADATA_KLASS)
|
||||
.to_str()
|
||||
.unwrap()
|
||||
});
|
||||
pub static ELEMENT_METADATA_KLASS: &glib::GStr =
|
||||
unsafe { glib::GStr::from_utf8_with_nul_unchecked(ffi::GST_ELEMENT_METADATA_KLASS) };
|
||||
#[doc(alias = "GST_ELEMENT_METADATA_LONGNAME")]
|
||||
pub static ELEMENT_METADATA_LONGNAME: Lazy<&'static str> = Lazy::new(|| unsafe {
|
||||
CStr::from_ptr(ffi::GST_ELEMENT_METADATA_LONGNAME)
|
||||
.to_str()
|
||||
.unwrap()
|
||||
});
|
||||
pub static ELEMENT_METADATA_LONGNAME: &glib::GStr =
|
||||
unsafe { glib::GStr::from_utf8_with_nul_unchecked(ffi::GST_ELEMENT_METADATA_LONGNAME) };
|
||||
|
||||
#[doc(alias = "GST_ELEMENT_ERROR")]
|
||||
#[doc(alias = "GST_ELEMENT_ERROR_WITH_DETAILS")]
|
||||
|
|
|
@ -140,37 +140,37 @@ impl ElementFactory {
|
|||
#[doc(alias = "get_longname")]
|
||||
#[doc(alias = "gst_element_factory_get_longname")]
|
||||
pub fn longname(&self) -> &str {
|
||||
self.metadata(&ELEMENT_METADATA_LONGNAME).unwrap()
|
||||
self.metadata(ELEMENT_METADATA_LONGNAME).unwrap()
|
||||
}
|
||||
|
||||
#[doc(alias = "get_klass")]
|
||||
#[doc(alias = "gst_element_factory_get_klass")]
|
||||
pub fn klass(&self) -> &str {
|
||||
self.metadata(&ELEMENT_METADATA_KLASS).unwrap()
|
||||
self.metadata(ELEMENT_METADATA_KLASS).unwrap()
|
||||
}
|
||||
|
||||
#[doc(alias = "get_description")]
|
||||
#[doc(alias = "gst_element_factory_get_description")]
|
||||
pub fn description(&self) -> &str {
|
||||
self.metadata(&ELEMENT_METADATA_DESCRIPTION).unwrap()
|
||||
self.metadata(ELEMENT_METADATA_DESCRIPTION).unwrap()
|
||||
}
|
||||
|
||||
#[doc(alias = "get_author")]
|
||||
#[doc(alias = "gst_element_factory_get_author")]
|
||||
pub fn author(&self) -> &str {
|
||||
self.metadata(&ELEMENT_METADATA_AUTHOR).unwrap()
|
||||
self.metadata(ELEMENT_METADATA_AUTHOR).unwrap()
|
||||
}
|
||||
|
||||
#[doc(alias = "get_documentation_uri")]
|
||||
#[doc(alias = "gst_element_factory_get_documentation_uri")]
|
||||
pub fn documentation_uri(&self) -> Option<&str> {
|
||||
self.metadata(&ELEMENT_METADATA_DOC_URI)
|
||||
self.metadata(ELEMENT_METADATA_DOC_URI)
|
||||
}
|
||||
|
||||
#[doc(alias = "get_icon_name")]
|
||||
#[doc(alias = "gst_element_factory_get_icon_name")]
|
||||
pub fn icon_name(&self) -> Option<&str> {
|
||||
self.metadata(&ELEMENT_METADATA_ICON_NAME)
|
||||
self.metadata(ELEMENT_METADATA_ICON_NAME)
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_element_factory_can_sink_all_caps")]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
|
||||
use std::{ffi::CStr, fmt, marker::PhantomData, ptr};
|
||||
use std::{fmt, marker::PhantomData, ptr};
|
||||
|
||||
use glib::{translate::*, StaticType};
|
||||
|
||||
|
@ -25,7 +25,7 @@ impl fmt::Debug for StaticCaps {
|
|||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_struct("StaticCaps")
|
||||
.field("str", &unsafe {
|
||||
CStr::from_ptr(self.0.as_ref().string).to_str()
|
||||
glib::GStr::from_ptr(self.0.as_ref().string)
|
||||
})
|
||||
.finish()
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
use std::{
|
||||
borrow::{Borrow, BorrowMut, ToOwned},
|
||||
ffi::CStr,
|
||||
fmt,
|
||||
marker::PhantomData,
|
||||
mem,
|
||||
|
@ -11,9 +10,10 @@ use std::{
|
|||
};
|
||||
|
||||
use glib::{
|
||||
prelude::*,
|
||||
translate::*,
|
||||
value::{FromValue, SendValue, ToSendValue},
|
||||
StaticType,
|
||||
IntoGStr,
|
||||
};
|
||||
|
||||
use crate::Fraction;
|
||||
|
@ -50,23 +50,24 @@ unsafe impl Sync for Structure {}
|
|||
|
||||
impl Structure {
|
||||
#[doc(alias = "gst_structure_new")]
|
||||
pub fn builder(name: &str) -> Builder {
|
||||
pub fn builder(name: impl IntoGStr) -> Builder {
|
||||
skip_assert_initialized!();
|
||||
Builder::new(name)
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_structure_new_empty")]
|
||||
pub fn new_empty(name: &str) -> Structure {
|
||||
pub fn new_empty(name: impl IntoGStr) -> Structure {
|
||||
assert_initialized_main_thread!();
|
||||
unsafe {
|
||||
let ptr = ffi::gst_structure_new_empty(name.to_glib_none().0);
|
||||
let ptr = name.run_with_gstr(|name| ffi::gst_structure_new_empty(name.as_ptr()));
|
||||
debug_assert!(!ptr.is_null());
|
||||
Structure(ptr::NonNull::new_unchecked(ptr))
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_structure_new")]
|
||||
pub fn new(name: &str, values: &[(&str, &(dyn ToSendValue + Sync))]) -> Structure {
|
||||
#[deprecated = "Use `Structure::builder()` or `Structure::new_empty()`"]
|
||||
pub fn new(name: impl IntoGStr, values: &[(&str, &(dyn ToSendValue + Sync))]) -> Structure {
|
||||
skip_assert_initialized!();
|
||||
let mut structure = Structure::new_empty(name);
|
||||
|
||||
|
@ -79,8 +80,8 @@ impl Structure {
|
|||
|
||||
#[allow(clippy::should_implement_trait)]
|
||||
pub fn from_iter<'a>(
|
||||
name: &str,
|
||||
iter: impl IntoIterator<Item = (&'a str, SendValue)>,
|
||||
name: impl IntoGStr,
|
||||
iter: impl IntoIterator<Item = (&'a glib::GStr, SendValue)>,
|
||||
) -> Structure {
|
||||
skip_assert_initialized!();
|
||||
let mut structure = Structure::new_empty(name);
|
||||
|
@ -189,7 +190,8 @@ impl str::FromStr for Structure {
|
|||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
assert_initialized_main_thread!();
|
||||
unsafe {
|
||||
let structure = ffi::gst_structure_from_string(s.to_glib_none().0, ptr::null_mut());
|
||||
let structure =
|
||||
s.run_with_gstr(|s| ffi::gst_structure_from_string(s.as_ptr(), ptr::null_mut()));
|
||||
if structure.is_null() {
|
||||
Err(glib::bool_error!("Failed to parse structure from string"))
|
||||
} else {
|
||||
|
@ -429,7 +431,7 @@ impl StructureRef {
|
|||
#[doc(alias = "gst_structure_get")]
|
||||
pub fn get<'a, T: FromValue<'a>>(
|
||||
&'a self,
|
||||
name: &str,
|
||||
name: impl IntoGStr,
|
||||
) -> Result<T, GetError<<<T as FromValue<'a>>::Checker as glib::value::ValueTypeChecker>::Error>>
|
||||
{
|
||||
let name = glib::Quark::from_str(name);
|
||||
|
@ -439,7 +441,7 @@ impl StructureRef {
|
|||
#[doc(alias = "gst_structure_get")]
|
||||
pub fn get_optional<'a, T: FromValue<'a>>(
|
||||
&'a self,
|
||||
name: &str,
|
||||
name: impl IntoGStr,
|
||||
) -> Result<
|
||||
Option<T>,
|
||||
GetError<<<T as FromValue<'a>>::Checker as glib::value::ValueTypeChecker>::Error>,
|
||||
|
@ -450,7 +452,10 @@ impl StructureRef {
|
|||
|
||||
#[doc(alias = "get_value")]
|
||||
#[doc(alias = "gst_structure_get_value")]
|
||||
pub fn value(&self, name: &str) -> Result<&SendValue, GetError<std::convert::Infallible>> {
|
||||
pub fn value(
|
||||
&self,
|
||||
name: impl IntoGStr,
|
||||
) -> Result<&SendValue, GetError<std::convert::Infallible>> {
|
||||
let name = glib::Quark::from_str(name);
|
||||
self.value_by_quark(name)
|
||||
}
|
||||
|
@ -502,19 +507,17 @@ impl StructureRef {
|
|||
}
|
||||
|
||||
#[doc(alias = "gst_structure_set")]
|
||||
pub fn set(&mut self, name: &str, value: impl Into<glib::Value> + Send) {
|
||||
pub fn set(&mut self, name: impl IntoGStr, value: impl Into<glib::Value> + Send) {
|
||||
let value = glib::SendValue::from_owned(value);
|
||||
self.set_value(name, value);
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_structure_set_value")]
|
||||
pub fn set_value(&mut self, name: &str, value: SendValue) {
|
||||
pub fn set_value(&mut self, name: impl IntoGStr, value: SendValue) {
|
||||
unsafe {
|
||||
ffi::gst_structure_take_value(
|
||||
&mut self.0,
|
||||
name.to_glib_none().0,
|
||||
&mut value.into_raw(),
|
||||
);
|
||||
name.run_with_gstr(|name| {
|
||||
ffi::gst_structure_take_value(&mut self.0, name.as_ptr(), &mut value.into_raw())
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -533,12 +536,8 @@ impl StructureRef {
|
|||
|
||||
#[doc(alias = "get_name")]
|
||||
#[doc(alias = "gst_structure_get_name")]
|
||||
pub fn name<'a>(&self) -> &'a str {
|
||||
unsafe {
|
||||
CStr::from_ptr(ffi::gst_structure_get_name(&self.0))
|
||||
.to_str()
|
||||
.unwrap()
|
||||
}
|
||||
pub fn name<'a>(&self) -> &'a glib::GStr {
|
||||
unsafe { glib::GStr::from_ptr(ffi::gst_structure_get_name(&self.0)) }
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_structure_get_name_id")]
|
||||
|
@ -547,8 +546,10 @@ impl StructureRef {
|
|||
}
|
||||
|
||||
#[doc(alias = "gst_structure_set_name")]
|
||||
pub fn set_name(&mut self, name: &str) {
|
||||
unsafe { ffi::gst_structure_set_name(&mut self.0, name.to_glib_none().0) }
|
||||
pub fn set_name(&mut self, name: impl IntoGStr) {
|
||||
unsafe {
|
||||
name.run_with_gstr(|name| ffi::gst_structure_set_name(&mut self.0, name.as_ptr()))
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_structure_has_name")]
|
||||
|
@ -557,23 +558,24 @@ impl StructureRef {
|
|||
}
|
||||
|
||||
#[doc(alias = "gst_structure_has_field")]
|
||||
pub fn has_field(&self, field: &str) -> bool {
|
||||
pub fn has_field(&self, field: impl IntoGStr) -> bool {
|
||||
unsafe {
|
||||
from_glib(ffi::gst_structure_has_field(
|
||||
&self.0,
|
||||
field.to_glib_none().0,
|
||||
))
|
||||
field.run_with_gstr(|field| {
|
||||
from_glib(ffi::gst_structure_has_field(&self.0, field.as_ptr()))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_structure_has_field_typed")]
|
||||
pub fn has_field_with_type(&self, field: &str, type_: glib::Type) -> bool {
|
||||
pub fn has_field_with_type(&self, field: impl IntoGStr, type_: glib::Type) -> bool {
|
||||
unsafe {
|
||||
field.run_with_gstr(|field| {
|
||||
from_glib(ffi::gst_structure_has_field_typed(
|
||||
&self.0,
|
||||
field.to_glib_none().0,
|
||||
field.as_ptr(),
|
||||
type_.into_glib(),
|
||||
))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -594,15 +596,17 @@ impl StructureRef {
|
|||
}
|
||||
|
||||
#[doc(alias = "gst_structure_remove_field")]
|
||||
pub fn remove_field(&mut self, field: &str) {
|
||||
pub fn remove_field(&mut self, field: impl IntoGStr) {
|
||||
unsafe {
|
||||
ffi::gst_structure_remove_field(&mut self.0, field.to_glib_none().0);
|
||||
field.run_with_gstr(|field| {
|
||||
ffi::gst_structure_remove_field(&mut self.0, field.as_ptr())
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_structure_remove_fields")]
|
||||
pub fn remove_fields(&mut self, fields: &[&str]) {
|
||||
for f in fields {
|
||||
pub fn remove_fields(&mut self, fields: impl IntoIterator<Item = impl IntoGStr>) {
|
||||
for f in fields.into_iter() {
|
||||
self.remove_field(f)
|
||||
}
|
||||
}
|
||||
|
@ -624,7 +628,7 @@ impl StructureRef {
|
|||
|
||||
#[doc(alias = "get_nth_field_name")]
|
||||
#[doc(alias = "gst_structure_nth_field_name")]
|
||||
pub fn nth_field_name<'a>(&self, idx: u32) -> Option<&'a str> {
|
||||
pub fn nth_field_name<'a>(&self, idx: u32) -> Option<&'a glib::GStr> {
|
||||
if idx >= self.n_fields() {
|
||||
return None;
|
||||
}
|
||||
|
@ -633,7 +637,7 @@ impl StructureRef {
|
|||
let field_name = ffi::gst_structure_nth_field_name(&self.0, idx);
|
||||
debug_assert!(!field_name.is_null());
|
||||
|
||||
Some(CStr::from_ptr(field_name).to_str().unwrap())
|
||||
Some(glib::GStr::from_ptr(field_name))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -663,75 +667,86 @@ impl StructureRef {
|
|||
}
|
||||
|
||||
#[doc(alias = "gst_structure_fixate_field")]
|
||||
pub fn fixate_field(&mut self, name: &str) -> bool {
|
||||
pub fn fixate_field(&mut self, name: impl IntoGStr) -> bool {
|
||||
unsafe {
|
||||
from_glib(ffi::gst_structure_fixate_field(
|
||||
&mut self.0,
|
||||
name.to_glib_none().0,
|
||||
))
|
||||
name.run_with_gstr(|name| {
|
||||
from_glib(ffi::gst_structure_fixate_field(&mut self.0, name.as_ptr()))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_structure_fixate_field_boolean")]
|
||||
pub fn fixate_field_bool(&mut self, name: &str, target: bool) -> bool {
|
||||
pub fn fixate_field_bool(&mut self, name: impl IntoGStr, target: bool) -> bool {
|
||||
unsafe {
|
||||
name.run_with_gstr(|name| {
|
||||
from_glib(ffi::gst_structure_fixate_field_boolean(
|
||||
&mut self.0,
|
||||
name.to_glib_none().0,
|
||||
name.as_ptr(),
|
||||
target.into_glib(),
|
||||
))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_structure_fixate_field_string")]
|
||||
pub fn fixate_field_str(&mut self, name: &str, target: &str) -> bool {
|
||||
pub fn fixate_field_str(&mut self, name: impl IntoGStr, target: impl IntoGStr) -> bool {
|
||||
unsafe {
|
||||
name.run_with_gstr(|name| {
|
||||
target.run_with_gstr(|target| {
|
||||
from_glib(ffi::gst_structure_fixate_field_string(
|
||||
&mut self.0,
|
||||
name.to_glib_none().0,
|
||||
target.to_glib_none().0,
|
||||
name.as_ptr(),
|
||||
target.as_ptr(),
|
||||
))
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_structure_fixate_field_nearest_double")]
|
||||
pub fn fixate_field_nearest_double(&mut self, name: &str, target: f64) -> bool {
|
||||
pub fn fixate_field_nearest_double(&mut self, name: impl IntoGStr, target: f64) -> bool {
|
||||
unsafe {
|
||||
name.run_with_gstr(|name| {
|
||||
from_glib(ffi::gst_structure_fixate_field_nearest_double(
|
||||
&mut self.0,
|
||||
name.to_glib_none().0,
|
||||
name.as_ptr(),
|
||||
target,
|
||||
))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_structure_fixate_field_nearest_fraction")]
|
||||
pub fn fixate_field_nearest_fraction<T: Into<Fraction>>(
|
||||
pub fn fixate_field_nearest_fraction(
|
||||
&mut self,
|
||||
name: &str,
|
||||
target: T,
|
||||
name: impl IntoGStr,
|
||||
target: impl Into<Fraction>,
|
||||
) -> bool {
|
||||
skip_assert_initialized!();
|
||||
|
||||
let target = target.into();
|
||||
unsafe {
|
||||
name.run_with_gstr(|name| {
|
||||
from_glib(ffi::gst_structure_fixate_field_nearest_fraction(
|
||||
&mut self.0,
|
||||
name.to_glib_none().0,
|
||||
name.as_ptr(),
|
||||
target.numer(),
|
||||
target.denom(),
|
||||
))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_structure_fixate_field_nearest_int")]
|
||||
pub fn fixate_field_nearest_int(&mut self, name: &str, target: i32) -> bool {
|
||||
pub fn fixate_field_nearest_int(&mut self, name: impl IntoGStr, target: i32) -> bool {
|
||||
unsafe {
|
||||
name.run_with_gstr(|name| {
|
||||
from_glib(ffi::gst_structure_fixate_field_nearest_int(
|
||||
&mut self.0,
|
||||
name.to_glib_none().0,
|
||||
name.as_ptr(),
|
||||
target,
|
||||
))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -941,7 +956,7 @@ impl<'a> FieldIterator<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Iterator for FieldIterator<'a> {
|
||||
type Item = &'static str;
|
||||
type Item = &'static glib::GStr;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.idx >= self.n_fields {
|
||||
|
@ -991,7 +1006,7 @@ impl<'a> Iter<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Iterator for Iter<'a> {
|
||||
type Item = (&'static str, &'a SendValue);
|
||||
type Item = (&'static glib::GStr, &'a SendValue);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let f = self.iter.next()?;
|
||||
|
@ -1041,7 +1056,7 @@ impl<'a> std::iter::FusedIterator for Iter<'a> {}
|
|||
|
||||
impl<'a> IntoIterator for &'a StructureRef {
|
||||
type IntoIter = Iter<'a>;
|
||||
type Item = (&'static str, &'a SendValue);
|
||||
type Item = (&'static glib::GStr, &'a SendValue);
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.iter()
|
||||
|
@ -1054,12 +1069,24 @@ impl<'a> std::iter::Extend<(&'a str, SendValue)> for StructureRef {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> std::iter::Extend<(&'a glib::GStr, SendValue)> for StructureRef {
|
||||
fn extend<T: IntoIterator<Item = (&'a glib::GStr, SendValue)>>(&mut self, iter: T) {
|
||||
iter.into_iter().for_each(|(f, v)| self.set_value(f, v));
|
||||
}
|
||||
}
|
||||
|
||||
impl std::iter::Extend<(String, SendValue)> for StructureRef {
|
||||
fn extend<T: IntoIterator<Item = (String, SendValue)>>(&mut self, iter: T) {
|
||||
iter.into_iter().for_each(|(f, v)| self.set_value(&f, v));
|
||||
}
|
||||
}
|
||||
|
||||
impl std::iter::Extend<(glib::GString, SendValue)> for StructureRef {
|
||||
fn extend<T: IntoIterator<Item = (glib::GString, SendValue)>>(&mut self, iter: T) {
|
||||
iter.into_iter().for_each(|(f, v)| self.set_value(&f, v));
|
||||
}
|
||||
}
|
||||
|
||||
impl std::iter::Extend<(glib::Quark, SendValue)> for StructureRef {
|
||||
fn extend<T: IntoIterator<Item = (glib::Quark, SendValue)>>(&mut self, iter: T) {
|
||||
iter.into_iter()
|
||||
|
@ -1074,14 +1101,14 @@ pub struct Builder {
|
|||
}
|
||||
|
||||
impl Builder {
|
||||
fn new(name: &str) -> Self {
|
||||
fn new(name: impl IntoGStr) -> Self {
|
||||
skip_assert_initialized!();
|
||||
Builder {
|
||||
s: Structure::new_empty(name),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn field(mut self, name: &str, value: impl Into<glib::Value> + Send) -> Self {
|
||||
pub fn field(mut self, name: impl IntoGStr, value: impl Into<glib::Value> + Send) -> Self {
|
||||
self.s.set(name, value);
|
||||
self
|
||||
}
|
||||
|
@ -1097,6 +1124,7 @@ mod tests {
|
|||
use super::*;
|
||||
|
||||
#[test]
|
||||
#[allow(deprecated)]
|
||||
fn new_set_get() {
|
||||
use glib::{value, Type};
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ impl<'a> Serialize for StructureForIter<'a> {
|
|||
impl Serialize for StructureRef {
|
||||
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
let mut tup = serializer.serialize_tuple(2)?;
|
||||
tup.serialize_element(self.name())?;
|
||||
tup.serialize_element(self.name().as_str())?;
|
||||
tup.serialize_element(&StructureForIter(self))?;
|
||||
tup.end()
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ impl<'de> Visitor<'de> for StructureVisitor {
|
|||
let name = seq
|
||||
.next_element::<String>()?
|
||||
.ok_or_else(|| de::Error::custom("Expected a name for the `Structure`"))?;
|
||||
let mut structure = Structure::new_empty(&name);
|
||||
let mut structure = Structure::new_empty(name);
|
||||
seq.next_element_seed(FieldsDe(structure.as_mut()))?
|
||||
.ok_or_else(|| de::Error::custom("Expected a sequence of `Field`s"))?;
|
||||
|
||||
|
|
|
@ -720,7 +720,7 @@ mod tests {
|
|||
assert_eq!(element.name(), "test");
|
||||
|
||||
assert_eq!(
|
||||
element.metadata(&crate::ELEMENT_METADATA_LONGNAME),
|
||||
element.metadata(crate::ELEMENT_METADATA_LONGNAME),
|
||||
Some("Test Element")
|
||||
);
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ impl<O: IsA<TagSetter>> TagSetterExtManual for O {
|
|||
ffi::gst_tag_setter_add_tag_value(
|
||||
self.as_ref().to_glib_none().0,
|
||||
mode.into_glib(),
|
||||
T::tag_name().to_glib_none().0,
|
||||
T::TAG_NAME.as_ptr(),
|
||||
v.to_glib_none().0,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||
|
||||
use std::{ffi::CStr, fmt, marker::PhantomData, mem};
|
||||
use std::{fmt, marker::PhantomData, mem};
|
||||
|
||||
use glib::{
|
||||
translate::*,
|
||||
value::{FromValue, SendValue, ToSendValue, Value},
|
||||
StaticType,
|
||||
IntoGStr, StaticType,
|
||||
};
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
use crate::{Sample, TagError, TagMergeMode, TagScope};
|
||||
|
||||
pub trait Tag<'a> {
|
||||
type TagType: StaticType + FromValue<'a> + ToSendValue + Send + Sync;
|
||||
fn tag_name<'b>() -> &'b str;
|
||||
const TAG_NAME: &'static glib::GStr;
|
||||
}
|
||||
|
||||
macro_rules! impl_tag(
|
||||
|
@ -21,14 +20,8 @@ macro_rules! impl_tag(
|
|||
pub enum $name {}
|
||||
impl<'a> Tag<'a> for $name {
|
||||
type TagType = $t;
|
||||
|
||||
fn tag_name<'b>() -> &'b str {
|
||||
*$rust_tag
|
||||
const TAG_NAME: &'static glib::GStr = unsafe { glib::GStr::from_utf8_with_nul_unchecked(ffi::$gst_tag) };
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) static $rust_tag: Lazy<&'static str> = Lazy::new(||
|
||||
unsafe { CStr::from_ptr(ffi::$gst_tag).to_str().unwrap() });
|
||||
};
|
||||
);
|
||||
|
||||
|
@ -363,15 +356,15 @@ impl<T> TagValue<T> {
|
|||
impl TagListRef {
|
||||
#[doc(alias = "gst_tag_list_add")]
|
||||
pub fn add<'a, T: Tag<'a>>(&mut self, value: &T::TagType, mode: TagMergeMode) {
|
||||
// result can be safely ignored here as `value`'s type is tied to `T::tag_name()`
|
||||
// result can be safely ignored here as `value`'s type is tied to `T::TAG_NAME`
|
||||
let v = <T::TagType as ToSendValue>::to_send_value(value);
|
||||
let _res = self.add_value(T::tag_name(), &v, mode);
|
||||
let _res = self.add_value(T::TAG_NAME, &v, mode);
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_tag_list_add")]
|
||||
pub fn add_generic(
|
||||
&mut self,
|
||||
tag_name: &str,
|
||||
tag_name: impl IntoGStr,
|
||||
value: impl ToSendValue,
|
||||
mode: TagMergeMode,
|
||||
) -> Result<(), TagError> {
|
||||
|
@ -381,14 +374,13 @@ impl TagListRef {
|
|||
#[doc(alias = "gst_tag_list_add_value")]
|
||||
pub fn add_value(
|
||||
&mut self,
|
||||
tag_name: &str,
|
||||
tag_name: impl IntoGStr,
|
||||
value: &glib::SendValue,
|
||||
mode: TagMergeMode,
|
||||
) -> Result<(), TagError> {
|
||||
unsafe {
|
||||
let tag_name = tag_name.to_glib_none();
|
||||
|
||||
let tag_type: glib::Type = from_glib(ffi::gst_tag_get_type(tag_name.0));
|
||||
tag_name.run_with_gstr(|tag_name| {
|
||||
let tag_type: glib::Type = from_glib(ffi::gst_tag_get_type(tag_name.as_ptr()));
|
||||
if tag_type != value.type_() {
|
||||
return Err(TagError::TypeMismatch);
|
||||
}
|
||||
|
@ -396,35 +388,35 @@ impl TagListRef {
|
|||
ffi::gst_tag_list_add_value(
|
||||
self.as_mut_ptr(),
|
||||
mode.into_glib(),
|
||||
tag_name.0,
|
||||
tag_name.as_ptr(),
|
||||
value.to_glib_none().0,
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_tag_list_remove_tag")]
|
||||
pub fn remove<'a, T: Tag<'a>>(&mut self) {
|
||||
self.remove_generic(T::tag_name());
|
||||
self.remove_generic(T::TAG_NAME);
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_tag_list_remove_tag")]
|
||||
pub fn remove_generic(&mut self, tag_name: &str) {
|
||||
pub fn remove_generic(&mut self, tag_name: impl IntoGStr) {
|
||||
unsafe {
|
||||
let tag_name = tag_name.to_glib_none();
|
||||
|
||||
ffi::gst_tag_list_remove_tag(self.as_mut_ptr(), tag_name.0);
|
||||
tag_name.run_with_gstr(|tag_name| {
|
||||
ffi::gst_tag_list_remove_tag(self.as_mut_ptr(), tag_name.as_ptr());
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_tag_list_get")]
|
||||
pub fn get<'a, T: Tag<'a>>(&self) -> Option<TagValue<T::TagType>> {
|
||||
self.generic(T::tag_name()).map(|value| {
|
||||
self.generic(T::TAG_NAME).map(|value| {
|
||||
if !value.is::<T::TagType>() {
|
||||
panic!(
|
||||
"TagListRef::get type mismatch for tag {}: {}",
|
||||
T::tag_name(),
|
||||
T::TAG_NAME,
|
||||
value.type_()
|
||||
);
|
||||
}
|
||||
|
@ -434,23 +426,25 @@ impl TagListRef {
|
|||
|
||||
#[doc(alias = "gst_tag_list_get")]
|
||||
#[doc(alias = "get_generic")]
|
||||
pub fn generic(&self, tag_name: &str) -> Option<SendValue> {
|
||||
pub fn generic(&self, tag_name: impl IntoGStr) -> Option<SendValue> {
|
||||
unsafe {
|
||||
let mut value: mem::MaybeUninit<SendValue> = mem::MaybeUninit::zeroed();
|
||||
|
||||
let found: bool = from_glib(ffi::gst_tag_list_copy_value(
|
||||
let found: bool = tag_name.run_with_gstr(|tag_name| {
|
||||
from_glib(ffi::gst_tag_list_copy_value(
|
||||
(*value.as_mut_ptr()).to_glib_none_mut().0,
|
||||
self.as_ptr(),
|
||||
tag_name.to_glib_none().0,
|
||||
));
|
||||
tag_name.as_ptr(),
|
||||
))
|
||||
});
|
||||
|
||||
if !found {
|
||||
return None;
|
||||
}
|
||||
|
||||
None
|
||||
} else {
|
||||
Some(value.assume_init())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_tag_list_n_tags")]
|
||||
pub fn n_tags(&self) -> u32 {
|
||||
|
@ -458,7 +452,7 @@ impl TagListRef {
|
|||
}
|
||||
|
||||
#[doc(alias = "gst_tag_list_nth_tag_name")]
|
||||
pub fn nth_tag_name(&self, idx: u32) -> Option<&str> {
|
||||
pub fn nth_tag_name(&self, idx: u32) -> Option<&glib::GStr> {
|
||||
if idx >= self.n_tags() {
|
||||
return None;
|
||||
}
|
||||
|
@ -466,18 +460,18 @@ impl TagListRef {
|
|||
unsafe {
|
||||
let name = ffi::gst_tag_list_nth_tag_name(self.as_ptr(), idx);
|
||||
debug_assert!(!name.is_null());
|
||||
Some(CStr::from_ptr(name).to_str().unwrap())
|
||||
Some(glib::GStr::from_ptr(name))
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "get_index")]
|
||||
#[doc(alias = "gst_tag_list_get_index")]
|
||||
pub fn index<'a, T: Tag<'a>>(&self, idx: u32) -> Option<&'a TagValue<T::TagType>> {
|
||||
self.index_generic(T::tag_name(), idx).map(|value| {
|
||||
self.index_generic(T::TAG_NAME, idx).map(|value| {
|
||||
if !value.is::<T::TagType>() {
|
||||
panic!(
|
||||
"TagListRef::get_index type mismatch for tag {}: {}",
|
||||
T::tag_name(),
|
||||
T::TAG_NAME,
|
||||
value.type_()
|
||||
);
|
||||
}
|
||||
|
@ -487,36 +481,42 @@ impl TagListRef {
|
|||
|
||||
#[doc(alias = "get_index_generic")]
|
||||
#[doc(alias = "gst_tag_list_get_index")]
|
||||
pub fn index_generic<'a>(&'a self, tag_name: &str, idx: u32) -> Option<&'a SendValue> {
|
||||
pub fn index_generic(&self, tag_name: impl IntoGStr, idx: u32) -> Option<&SendValue> {
|
||||
unsafe {
|
||||
let value =
|
||||
ffi::gst_tag_list_get_value_index(self.as_ptr(), tag_name.to_glib_none().0, idx);
|
||||
let value = tag_name.run_with_gstr(|tag_name| {
|
||||
ffi::gst_tag_list_get_value_index(self.as_ptr(), tag_name.as_ptr(), idx)
|
||||
});
|
||||
|
||||
if value.is_null() {
|
||||
return None;
|
||||
}
|
||||
|
||||
None
|
||||
} else {
|
||||
Some(&*(value as *const SendValue))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "get_size")]
|
||||
#[doc(alias = "gst_tag_list_get_tag_size")]
|
||||
pub fn size<'a, T: Tag<'a>>(&self) -> u32 {
|
||||
self.size_by_name(T::tag_name())
|
||||
self.size_by_name(T::TAG_NAME)
|
||||
}
|
||||
|
||||
#[doc(alias = "get_size_by_name")]
|
||||
#[doc(alias = "gst_tag_list_get_tag_size")]
|
||||
pub fn size_by_name(&self, tag_name: &str) -> u32 {
|
||||
unsafe { ffi::gst_tag_list_get_tag_size(self.as_ptr(), tag_name.to_glib_none().0) }
|
||||
pub fn size_by_name(&self, tag_name: impl IntoGStr) -> u32 {
|
||||
unsafe {
|
||||
tag_name.run_with_gstr(|tag_name| {
|
||||
ffi::gst_tag_list_get_tag_size(self.as_ptr(), tag_name.as_ptr())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn iter_tag<'a, T: Tag<'a>>(&'a self) -> TagIter<'a, T> {
|
||||
TagIter::new(self)
|
||||
}
|
||||
|
||||
pub fn iter_tag_generic<'a>(&'a self, tag_name: &'a str) -> GenericTagIter<'a> {
|
||||
pub fn iter_tag_generic(&self, tag_name: impl IntoGStr) -> GenericTagIter {
|
||||
let tag_name = glib::Quark::from_str(tag_name).as_str();
|
||||
GenericTagIter::new(self, tag_name)
|
||||
}
|
||||
|
||||
|
@ -728,13 +728,13 @@ where
|
|||
#[derive(Debug)]
|
||||
pub struct GenericTagIter<'a> {
|
||||
taglist: &'a TagListRef,
|
||||
name: &'a str,
|
||||
name: &'static glib::GStr,
|
||||
idx: usize,
|
||||
size: usize,
|
||||
}
|
||||
|
||||
impl<'a> GenericTagIter<'a> {
|
||||
fn new(taglist: &'a TagListRef, name: &'a str) -> GenericTagIter<'a> {
|
||||
fn new(taglist: &'a TagListRef, name: &'static glib::GStr) -> GenericTagIter<'a> {
|
||||
skip_assert_initialized!();
|
||||
GenericTagIter {
|
||||
taglist,
|
||||
|
@ -850,7 +850,7 @@ impl<'a> GenericIter<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Iterator for GenericIter<'a> {
|
||||
type Item = (&'a str, GenericTagIter<'a>);
|
||||
type Item = (&'a glib::GStr, GenericTagIter<'a>);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.idx >= self.size {
|
||||
|
@ -944,7 +944,7 @@ impl<'a> Iter<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Iterator for Iter<'a> {
|
||||
type Item = (&'a str, glib::SendValue);
|
||||
type Item = (&'a glib::GStr, glib::SendValue);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.idx >= self.size {
|
||||
|
@ -1019,50 +1019,50 @@ impl<'a> ExactSizeIterator for Iter<'a> {}
|
|||
impl<'a> std::iter::FusedIterator for Iter<'a> {}
|
||||
|
||||
#[doc(alias = "gst_tag_exists")]
|
||||
pub fn tag_exists(name: &str) -> bool {
|
||||
pub fn tag_exists(name: impl IntoGStr) -> bool {
|
||||
skip_assert_initialized!();
|
||||
unsafe { from_glib(ffi::gst_tag_exists(name.to_glib_none().0)) }
|
||||
unsafe { name.run_with_gstr(|name| from_glib(ffi::gst_tag_exists(name.as_ptr()))) }
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_tag_get_type")]
|
||||
pub fn tag_get_type(name: &str) -> glib::Type {
|
||||
pub fn tag_get_type(name: impl IntoGStr) -> glib::Type {
|
||||
skip_assert_initialized!();
|
||||
unsafe { from_glib(ffi::gst_tag_get_type(name.to_glib_none().0)) }
|
||||
unsafe { name.run_with_gstr(|name| from_glib(ffi::gst_tag_get_type(name.as_ptr()))) }
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_tag_get_nick")]
|
||||
pub fn tag_get_nick(name: &str) -> &str {
|
||||
pub fn tag_get_nick<'b>(name: impl IntoGStr) -> &'b glib::GStr {
|
||||
skip_assert_initialized!();
|
||||
unsafe {
|
||||
let ptr = ffi::gst_tag_get_nick(name.to_glib_none().0);
|
||||
CStr::from_ptr(ptr).to_str().unwrap()
|
||||
let ptr = name.run_with_gstr(|name| ffi::gst_tag_get_nick(name.as_ptr()));
|
||||
glib::GStr::from_ptr(ptr)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_tag_get_description")]
|
||||
pub fn tag_get_description<'b>(name: &str) -> Option<&'b str> {
|
||||
pub fn tag_get_description<'b>(name: impl IntoGStr) -> Option<&'b glib::GStr> {
|
||||
skip_assert_initialized!();
|
||||
unsafe {
|
||||
let ptr = ffi::gst_tag_get_description(name.to_glib_none().0);
|
||||
let ptr = name.run_with_gstr(|name| ffi::gst_tag_get_description(name.as_ptr()));
|
||||
|
||||
if ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(CStr::from_ptr(ptr).to_str().unwrap())
|
||||
Some(glib::GStr::from_ptr(ptr))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(alias = "gst_tag_get_flag")]
|
||||
pub fn tag_get_flag(name: &str) -> crate::TagFlag {
|
||||
pub fn tag_get_flag(name: impl IntoGStr) -> crate::TagFlag {
|
||||
skip_assert_initialized!();
|
||||
unsafe { from_glib(ffi::gst_tag_get_flag(name.to_glib_none().0)) }
|
||||
unsafe { name.run_with_gstr(|name| from_glib(ffi::gst_tag_get_flag(name.as_ptr()))) }
|
||||
}
|
||||
|
||||
pub trait CustomTag<'a>: Tag<'a> {
|
||||
const FLAG: crate::TagFlag;
|
||||
const NICK: &'static str;
|
||||
const DESCRIPTION: &'static str;
|
||||
const NICK: &'static glib::GStr;
|
||||
const DESCRIPTION: &'static glib::GStr;
|
||||
|
||||
fn merge_func(src: &Value) -> Value {
|
||||
skip_assert_initialized!();
|
||||
|
@ -1072,7 +1072,7 @@ pub trait CustomTag<'a>: Tag<'a> {
|
|||
|
||||
#[doc(alias = "gst_tag_register")]
|
||||
pub fn register<T: for<'a> CustomTag<'a>>() {
|
||||
assert!(!tag_exists(T::tag_name()));
|
||||
assert!(!tag_exists(T::TAG_NAME));
|
||||
|
||||
unsafe extern "C" fn merge_func_trampoline<T: for<'a> CustomTag<'a>>(
|
||||
dest: *mut glib::gobject_ffi::GValue,
|
||||
|
@ -1083,11 +1083,11 @@ pub fn register<T: for<'a> CustomTag<'a>>() {
|
|||
|
||||
unsafe {
|
||||
ffi::gst_tag_register(
|
||||
T::tag_name().to_glib_none().0,
|
||||
T::TAG_NAME.as_ptr(),
|
||||
T::FLAG.into_glib(),
|
||||
T::TagType::static_type().into_glib(),
|
||||
T::NICK.to_glib_none().0,
|
||||
T::DESCRIPTION.to_glib_none().0,
|
||||
T::NICK.as_ptr(),
|
||||
T::DESCRIPTION.as_ptr(),
|
||||
Some(merge_func_trampoline::<T>),
|
||||
)
|
||||
}
|
||||
|
@ -1186,21 +1186,25 @@ mod tests {
|
|||
{
|
||||
let tags = tags.get_mut().unwrap();
|
||||
assert!(tags
|
||||
.add_generic(&TAG_TITLE, "some title", TagMergeMode::Append)
|
||||
.add_generic(Title::TAG_NAME, "some title", TagMergeMode::Append)
|
||||
.is_ok());
|
||||
assert!(tags
|
||||
.add_generic(&TAG_TITLE, "second title", TagMergeMode::Append)
|
||||
.add_generic(Title::TAG_NAME, "second title", TagMergeMode::Append)
|
||||
.is_ok());
|
||||
assert!(tags
|
||||
.add_generic(&TAG_DURATION, ClockTime::SECOND * 120, TagMergeMode::Append)
|
||||
.add_generic(
|
||||
Duration::TAG_NAME,
|
||||
ClockTime::SECOND * 120,
|
||||
TagMergeMode::Append
|
||||
)
|
||||
.is_ok());
|
||||
assert!(tags
|
||||
.add_generic(&TAG_TITLE, "third title", TagMergeMode::Append)
|
||||
.add_generic(Title::TAG_NAME, "third title", TagMergeMode::Append)
|
||||
.is_ok());
|
||||
|
||||
assert_eq!(
|
||||
tags.add_generic(
|
||||
&TAG_IMAGE,
|
||||
Image::TAG_NAME,
|
||||
"`&[str] instead of `Sample`",
|
||||
TagMergeMode::Append
|
||||
),
|
||||
|
@ -1209,35 +1213,35 @@ mod tests {
|
|||
}
|
||||
|
||||
assert_eq!(
|
||||
tags.index_generic(&TAG_TITLE, 0).unwrap().get(),
|
||||
tags.index_generic(Title::TAG_NAME, 0).unwrap().get(),
|
||||
Ok(Some("some title"))
|
||||
);
|
||||
assert_eq!(
|
||||
tags.index_generic(&TAG_TITLE, 1).unwrap().get(),
|
||||
tags.index_generic(Title::TAG_NAME, 1).unwrap().get(),
|
||||
Ok(Some("second title"))
|
||||
);
|
||||
assert_eq!(
|
||||
tags.index_generic(&TAG_DURATION, 0).unwrap().get(),
|
||||
tags.index_generic(Duration::TAG_NAME, 0).unwrap().get(),
|
||||
Ok(Some(ClockTime::SECOND * 120))
|
||||
);
|
||||
assert_eq!(
|
||||
tags.index_generic(&TAG_TITLE, 2).unwrap().get(),
|
||||
tags.index_generic(Title::TAG_NAME, 2).unwrap().get(),
|
||||
Ok(Some("third title"))
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
tags.generic(&TAG_TITLE).unwrap().get(),
|
||||
tags.generic(Title::TAG_NAME).unwrap().get(),
|
||||
Ok(Some("some title, second title, third title"))
|
||||
);
|
||||
|
||||
assert_eq!(tags.n_tags(), 2);
|
||||
assert_eq!(tags.nth_tag_name(0), Some(*TAG_TITLE));
|
||||
assert_eq!(tags.size_by_name(&TAG_TITLE), 3);
|
||||
assert_eq!(tags.nth_tag_name(1), Some(*TAG_DURATION));
|
||||
assert_eq!(tags.size_by_name(&TAG_DURATION), 1);
|
||||
assert_eq!(tags.nth_tag_name(0), Some(Title::TAG_NAME));
|
||||
assert_eq!(tags.size_by_name(Title::TAG_NAME), 3);
|
||||
assert_eq!(tags.nth_tag_name(1), Some(Duration::TAG_NAME));
|
||||
assert_eq!(tags.size_by_name(Duration::TAG_NAME), 1);
|
||||
|
||||
// GenericTagIter
|
||||
let mut title_iter = tags.iter_tag_generic(&TAG_TITLE);
|
||||
let mut title_iter = tags.iter_tag_generic(Title::TAG_NAME);
|
||||
assert_eq!(title_iter.size_hint(), (3, Some(3)));
|
||||
let first_title = title_iter.next().unwrap();
|
||||
assert_eq!(first_title.get(), Ok(Some("some title")));
|
||||
|
@ -1252,7 +1256,7 @@ mod tests {
|
|||
assert_eq!(tag_list_iter.size_hint(), (2, Some(2)));
|
||||
|
||||
let (tag_name, mut tag_iter) = tag_list_iter.next().unwrap();
|
||||
assert_eq!(tag_name, *TAG_TITLE);
|
||||
assert_eq!(tag_name, Title::TAG_NAME);
|
||||
let first_title = tag_iter.next().unwrap();
|
||||
assert_eq!(first_title.get(), Ok(Some("some title")));
|
||||
let second_title = tag_iter.next().unwrap();
|
||||
|
@ -1262,7 +1266,7 @@ mod tests {
|
|||
assert!(tag_iter.next().is_none());
|
||||
|
||||
let (tag_name, mut tag_iter) = tag_list_iter.next().unwrap();
|
||||
assert_eq!(tag_name, *TAG_DURATION);
|
||||
assert_eq!(tag_name, Duration::TAG_NAME);
|
||||
let first_duration = tag_iter.next().unwrap();
|
||||
assert_eq!(first_duration.get(), Ok(Some(ClockTime::SECOND * 120)));
|
||||
assert!(tag_iter.next().is_none());
|
||||
|
@ -1272,14 +1276,14 @@ mod tests {
|
|||
assert_eq!(tag_list_iter.size_hint(), (2, Some(2)));
|
||||
|
||||
let (tag_name, tag_value) = tag_list_iter.next().unwrap();
|
||||
assert_eq!(tag_name, *TAG_TITLE);
|
||||
assert_eq!(tag_name, Title::TAG_NAME);
|
||||
assert_eq!(
|
||||
tag_value.get(),
|
||||
Ok(Some("some title, second title, third title"))
|
||||
);
|
||||
|
||||
let (tag_name, tag_value) = tag_list_iter.next().unwrap();
|
||||
assert_eq!(tag_name, *TAG_DURATION);
|
||||
assert_eq!(tag_name, Duration::TAG_NAME);
|
||||
assert_eq!(tag_value.get(), Ok(Some(ClockTime::SECOND * 120)));
|
||||
assert!(tag_iter.next().is_none());
|
||||
}
|
||||
|
@ -1292,15 +1296,14 @@ mod tests {
|
|||
|
||||
impl<'a> Tag<'a> for MyCustomTag {
|
||||
type TagType = &'a str;
|
||||
fn tag_name<'b>() -> &'b str {
|
||||
"my-custom-tag"
|
||||
}
|
||||
const TAG_NAME: &'static glib::GStr = glib::gstr!("my-custom-tag");
|
||||
}
|
||||
|
||||
impl<'a> CustomTag<'a> for MyCustomTag {
|
||||
const FLAG: crate::TagFlag = crate::TagFlag::Meta;
|
||||
const NICK: &'static str = "my custom tag";
|
||||
const DESCRIPTION: &'static str = "My own custom tag type for testing";
|
||||
const NICK: &'static glib::GStr = glib::gstr!("my custom tag");
|
||||
const DESCRIPTION: &'static glib::GStr =
|
||||
glib::gstr!("My own custom tag type for testing");
|
||||
|
||||
fn merge_func(src: &Value) -> Value {
|
||||
skip_assert_initialized!();
|
||||
|
@ -1310,17 +1313,17 @@ mod tests {
|
|||
|
||||
register::<MyCustomTag>();
|
||||
|
||||
assert!(tag_exists(MyCustomTag::tag_name()));
|
||||
assert!(tag_exists(MyCustomTag::TAG_NAME));
|
||||
assert_eq!(
|
||||
tag_get_type(MyCustomTag::tag_name()),
|
||||
tag_get_type(MyCustomTag::TAG_NAME),
|
||||
<MyCustomTag as Tag>::TagType::static_type()
|
||||
);
|
||||
assert_eq!(tag_get_nick(MyCustomTag::tag_name()), MyCustomTag::NICK);
|
||||
assert_eq!(tag_get_nick(MyCustomTag::TAG_NAME), MyCustomTag::NICK);
|
||||
assert_eq!(
|
||||
tag_get_description(MyCustomTag::tag_name()),
|
||||
tag_get_description(MyCustomTag::TAG_NAME),
|
||||
Some(MyCustomTag::DESCRIPTION)
|
||||
);
|
||||
assert_eq!(tag_get_flag(MyCustomTag::tag_name()), MyCustomTag::FLAG);
|
||||
assert_eq!(tag_get_flag(MyCustomTag::TAG_NAME), MyCustomTag::FLAG);
|
||||
|
||||
let mut tags = TagList::new();
|
||||
{
|
||||
|
|
|
@ -234,7 +234,7 @@ mod tutorial5 {
|
|||
None => return,
|
||||
};
|
||||
|
||||
if application.structure().map(|s| s.name()) == Some("tags-changed") {
|
||||
if application.structure().map(|s| s.name().as_str()) == Some("tags-changed") {
|
||||
let textbuf = streams_list
|
||||
.buffer()
|
||||
.expect("Couldn't get buffer from text_view");
|
||||
|
|
Loading…
Reference in a new issue