forked from mirrors/gstreamer-rs
pbutils/encoding_profile: Require passing the format caps to the builders and make construction infallible
There's no way it can fail if a format is provided and we don't pass random pointers around.
This commit is contained in:
parent
06916b23c7
commit
984ab87c79
1 changed files with 45 additions and 89 deletions
|
@ -1,7 +1,5 @@
|
||||||
// Take a look at the license at the top of the repository in the LICENSE file.
|
// Take a look at the license at the top of the repository in the LICENSE file.
|
||||||
|
|
||||||
use thiserror::Error;
|
|
||||||
|
|
||||||
use glib::prelude::*;
|
use glib::prelude::*;
|
||||||
use glib::translate::*;
|
use glib::translate::*;
|
||||||
|
|
||||||
|
@ -176,8 +174,8 @@ impl EncodingAudioProfile {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(alias = "gst_encoding_audio_profile_new")]
|
#[doc(alias = "gst_encoding_audio_profile_new")]
|
||||||
pub fn builder<'a>() -> EncodingAudioProfileBuilder<'a> {
|
pub fn builder<'a>(format: &'a gst::Caps) -> EncodingAudioProfileBuilder<'a> {
|
||||||
EncodingAudioProfileBuilder::new()
|
EncodingAudioProfileBuilder::new(format)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,8 +202,8 @@ impl EncodingVideoProfile {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(alias = "gst_encoding_video_profile_new")]
|
#[doc(alias = "gst_encoding_video_profile_new")]
|
||||||
pub fn builder<'a>() -> EncodingVideoProfileBuilder<'a> {
|
pub fn builder<'a>(format: &'a gst::Caps) -> EncodingVideoProfileBuilder<'a> {
|
||||||
EncodingVideoProfileBuilder::new()
|
EncodingVideoProfileBuilder::new(format)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_pass(&self, pass: u32) {
|
fn set_pass(&self, pass: u32) {
|
||||||
|
@ -248,35 +246,27 @@ impl EncodingContainerProfile {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(alias = "gst_encoding_container_profile_new")]
|
#[doc(alias = "gst_encoding_container_profile_new")]
|
||||||
pub fn builder<'a>() -> EncodingContainerProfileBuilder<'a> {
|
pub fn builder<'a>(format: &'a gst::Caps) -> EncodingContainerProfileBuilder<'a> {
|
||||||
EncodingContainerProfileBuilder::new()
|
EncodingContainerProfileBuilder::new(format)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_profile<P: IsA<EncodingProfile>>(
|
fn add_profile<P: IsA<EncodingProfile>>(&self, profile: &P) {
|
||||||
&self,
|
|
||||||
profile: &P,
|
|
||||||
) -> Result<(), glib::error::BoolError> {
|
|
||||||
unsafe {
|
unsafe {
|
||||||
glib::result_from_gboolean!(
|
let res = ffi::gst_encoding_container_profile_add_profile(
|
||||||
ffi::gst_encoding_container_profile_add_profile(
|
self.to_glib_none().0,
|
||||||
self.to_glib_none().0,
|
profile.as_ref().to_glib_full(),
|
||||||
profile.as_ref().to_glib_full(),
|
);
|
||||||
),
|
// Can't possibly fail unless we pass random pointers
|
||||||
"Failed to add profile",
|
assert_ne!(res, glib::ffi::GFALSE);
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Error)]
|
|
||||||
#[error("failed to build encoding profile")]
|
|
||||||
pub struct EncodingProfileBuilderError(());
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct EncodingProfileBuilderCommonData<'a> {
|
struct EncodingProfileBuilderCommonData<'a> {
|
||||||
|
format: &'a gst::Caps,
|
||||||
name: Option<&'a str>,
|
name: Option<&'a str>,
|
||||||
description: Option<&'a str>,
|
description: Option<&'a str>,
|
||||||
format: Option<&'a gst::Caps>,
|
|
||||||
preset: Option<&'a str>,
|
preset: Option<&'a str>,
|
||||||
preset_name: Option<&'a str>,
|
preset_name: Option<&'a str>,
|
||||||
presence: u32,
|
presence: u32,
|
||||||
|
@ -287,11 +277,11 @@ struct EncodingProfileBuilderCommonData<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> EncodingProfileBuilderCommonData<'a> {
|
impl<'a> EncodingProfileBuilderCommonData<'a> {
|
||||||
fn new() -> EncodingProfileBuilderCommonData<'a> {
|
fn new(format: &'a gst::Caps) -> EncodingProfileBuilderCommonData<'a> {
|
||||||
EncodingProfileBuilderCommonData {
|
EncodingProfileBuilderCommonData {
|
||||||
name: None,
|
name: None,
|
||||||
description: None,
|
description: None,
|
||||||
format: None,
|
format,
|
||||||
preset: None,
|
preset: None,
|
||||||
preset_name: None,
|
preset_name: None,
|
||||||
presence: 0,
|
presence: 0,
|
||||||
|
@ -308,8 +298,6 @@ pub trait EncodingProfileBuilder<'a>: Sized {
|
||||||
fn name(self, name: &'a str) -> Self;
|
fn name(self, name: &'a str) -> Self;
|
||||||
#[doc(alias = "gst_encoding_profile_set_description")]
|
#[doc(alias = "gst_encoding_profile_set_description")]
|
||||||
fn description(self, description: &'a str) -> Self;
|
fn description(self, description: &'a str) -> Self;
|
||||||
#[doc(alias = "gst_encoding_profile_set_format")]
|
|
||||||
fn format(self, format: &'a gst::Caps) -> Self;
|
|
||||||
#[doc(alias = "gst_encoding_profile_set_preset")]
|
#[doc(alias = "gst_encoding_profile_set_preset")]
|
||||||
fn preset(self, preset: &'a str) -> Self;
|
fn preset(self, preset: &'a str) -> Self;
|
||||||
#[doc(alias = "gst_encoding_profile_set_preset_name")]
|
#[doc(alias = "gst_encoding_profile_set_preset_name")]
|
||||||
|
@ -327,12 +315,6 @@ pub trait EncodingProfileBuilder<'a>: Sized {
|
||||||
|
|
||||||
macro_rules! declare_encoding_profile_builder_common(
|
macro_rules! declare_encoding_profile_builder_common(
|
||||||
($name:ident) => {
|
($name:ident) => {
|
||||||
impl<'a> Default for $name<'a> {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> EncodingProfileBuilder<'a> for $name<'a> {
|
impl<'a> EncodingProfileBuilder<'a> for $name<'a> {
|
||||||
fn name(mut self, name: &'a str) -> $name<'a> {
|
fn name(mut self, name: &'a str) -> $name<'a> {
|
||||||
self.base.name = Some(name);
|
self.base.name = Some(name);
|
||||||
|
@ -344,11 +326,6 @@ macro_rules! declare_encoding_profile_builder_common(
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn format(mut self, format: &'a gst::Caps) -> $name<'a> {
|
|
||||||
self.base.format = Some(format);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
fn preset(mut self, preset: &'a str) -> $name<'a> {
|
fn preset(mut self, preset: &'a str) -> $name<'a> {
|
||||||
self.base.preset = Some(preset);
|
self.base.preset = Some(preset);
|
||||||
self
|
self
|
||||||
|
@ -410,9 +387,9 @@ pub struct EncodingAudioProfileBuilder<'a> {
|
||||||
declare_encoding_profile_builder_common!(EncodingAudioProfileBuilder);
|
declare_encoding_profile_builder_common!(EncodingAudioProfileBuilder);
|
||||||
|
|
||||||
impl<'a> EncodingAudioProfileBuilder<'a> {
|
impl<'a> EncodingAudioProfileBuilder<'a> {
|
||||||
fn new() -> Self {
|
fn new(format: &'a gst::Caps) -> Self {
|
||||||
EncodingAudioProfileBuilder {
|
EncodingAudioProfileBuilder {
|
||||||
base: EncodingProfileBuilderCommonData::new(),
|
base: EncodingProfileBuilderCommonData::new(format),
|
||||||
restriction: None,
|
restriction: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -423,20 +400,17 @@ impl<'a> EncodingAudioProfileBuilder<'a> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(self) -> Result<EncodingAudioProfile, EncodingProfileBuilderError> {
|
pub fn build(self) -> EncodingAudioProfile {
|
||||||
if self.base.format.is_none() {
|
|
||||||
return Err(EncodingProfileBuilderError(()));
|
|
||||||
}
|
|
||||||
|
|
||||||
let profile = EncodingAudioProfile::new(
|
let profile = EncodingAudioProfile::new(
|
||||||
self.base.format.unwrap(),
|
self.base.format,
|
||||||
self.base.preset,
|
self.base.preset,
|
||||||
self.restriction,
|
self.restriction,
|
||||||
self.base.presence,
|
self.base.presence,
|
||||||
);
|
);
|
||||||
|
|
||||||
set_common_fields(&profile, &self.base);
|
set_common_fields(&profile, &self.base);
|
||||||
Ok(profile)
|
|
||||||
|
profile
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,9 +425,9 @@ pub struct EncodingVideoProfileBuilder<'a> {
|
||||||
declare_encoding_profile_builder_common!(EncodingVideoProfileBuilder);
|
declare_encoding_profile_builder_common!(EncodingVideoProfileBuilder);
|
||||||
|
|
||||||
impl<'a> EncodingVideoProfileBuilder<'a> {
|
impl<'a> EncodingVideoProfileBuilder<'a> {
|
||||||
fn new() -> Self {
|
fn new(format: &'a gst::Caps) -> Self {
|
||||||
EncodingVideoProfileBuilder {
|
EncodingVideoProfileBuilder {
|
||||||
base: EncodingProfileBuilderCommonData::new(),
|
base: EncodingProfileBuilderCommonData::new(format),
|
||||||
restriction: None,
|
restriction: None,
|
||||||
pass: 0,
|
pass: 0,
|
||||||
variable_framerate: false,
|
variable_framerate: false,
|
||||||
|
@ -478,13 +452,9 @@ impl<'a> EncodingVideoProfileBuilder<'a> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(self) -> Result<EncodingVideoProfile, EncodingProfileBuilderError> {
|
pub fn build(self) -> EncodingVideoProfile {
|
||||||
if self.base.format.is_none() {
|
|
||||||
return Err(EncodingProfileBuilderError(()));
|
|
||||||
}
|
|
||||||
|
|
||||||
let video_profile = EncodingVideoProfile::new(
|
let video_profile = EncodingVideoProfile::new(
|
||||||
self.base.format.unwrap(),
|
self.base.format,
|
||||||
self.base.preset,
|
self.base.preset,
|
||||||
self.restriction,
|
self.restriction,
|
||||||
self.base.presence,
|
self.base.presence,
|
||||||
|
@ -494,7 +464,8 @@ impl<'a> EncodingVideoProfileBuilder<'a> {
|
||||||
video_profile.set_variableframerate(self.variable_framerate);
|
video_profile.set_variableframerate(self.variable_framerate);
|
||||||
|
|
||||||
set_common_fields(&video_profile, &self.base);
|
set_common_fields(&video_profile, &self.base);
|
||||||
Ok(video_profile)
|
|
||||||
|
video_profile
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -507,33 +478,28 @@ pub struct EncodingContainerProfileBuilder<'a> {
|
||||||
declare_encoding_profile_builder_common!(EncodingContainerProfileBuilder);
|
declare_encoding_profile_builder_common!(EncodingContainerProfileBuilder);
|
||||||
|
|
||||||
impl<'a> EncodingContainerProfileBuilder<'a> {
|
impl<'a> EncodingContainerProfileBuilder<'a> {
|
||||||
fn new() -> Self {
|
fn new(format: &'a gst::Caps) -> Self {
|
||||||
EncodingContainerProfileBuilder {
|
EncodingContainerProfileBuilder {
|
||||||
base: EncodingProfileBuilderCommonData::new(),
|
base: EncodingProfileBuilderCommonData::new(format),
|
||||||
profiles: Vec::new(),
|
profiles: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(self) -> Result<EncodingContainerProfile, EncodingProfileBuilderError> {
|
pub fn build(self) -> EncodingContainerProfile {
|
||||||
if self.base.format.is_none() {
|
|
||||||
return Err(EncodingProfileBuilderError(()));
|
|
||||||
}
|
|
||||||
|
|
||||||
let container_profile = EncodingContainerProfile::new(
|
let container_profile = EncodingContainerProfile::new(
|
||||||
self.base.name,
|
self.base.name,
|
||||||
self.base.description,
|
self.base.description,
|
||||||
self.base.format.unwrap(),
|
self.base.format,
|
||||||
self.base.preset,
|
self.base.preset,
|
||||||
);
|
);
|
||||||
|
|
||||||
for profile in self.profiles {
|
for profile in self.profiles {
|
||||||
container_profile
|
container_profile.add_profile(&profile);
|
||||||
.add_profile(&profile)
|
|
||||||
.map_err(|_error| EncodingProfileBuilderError(()))?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set_common_fields(&container_profile, &self.base);
|
set_common_fields(&container_profile, &self.base);
|
||||||
Ok(container_profile)
|
|
||||||
|
container_profile
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(alias = "gst_encoding_container_profile_add_profile")]
|
#[doc(alias = "gst_encoding_container_profile_add_profile")]
|
||||||
|
@ -576,18 +542,16 @@ mod tests {
|
||||||
|
|
||||||
let restriction = gst::Caps::new_simple("audio/x-raw", &[("format", &"S32LE")]);
|
let restriction = gst::Caps::new_simple("audio/x-raw", &[("format", &"S32LE")]);
|
||||||
|
|
||||||
let audio_profile = EncodingAudioProfile::builder()
|
let audio_profile = EncodingAudioProfile::builder(&caps)
|
||||||
.name(AUDIO_PROFILE_NAME)
|
.name(AUDIO_PROFILE_NAME)
|
||||||
.description(AUDIO_PROFILE_DESCRIPTION)
|
.description(AUDIO_PROFILE_DESCRIPTION)
|
||||||
.format(&caps)
|
|
||||||
.preset(PRESET)
|
.preset(PRESET)
|
||||||
.preset_name(PRESET_NAME)
|
.preset_name(PRESET_NAME)
|
||||||
.restriction(&restriction)
|
.restriction(&restriction)
|
||||||
.presence(PRESENCE)
|
.presence(PRESENCE)
|
||||||
.allow_dynamic_output(ALLOW_DYNAMIC_OUTPUT)
|
.allow_dynamic_output(ALLOW_DYNAMIC_OUTPUT)
|
||||||
.enabled(ENABLED)
|
.enabled(ENABLED)
|
||||||
.build()
|
.build();
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert_eq!(audio_profile.name().unwrap(), AUDIO_PROFILE_NAME);
|
assert_eq!(audio_profile.name().unwrap(), AUDIO_PROFILE_NAME);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -615,10 +579,9 @@ mod tests {
|
||||||
|
|
||||||
let restriction = gst::Caps::new_simple("video/x-raw", &[("format", &"RGBA")]);
|
let restriction = gst::Caps::new_simple("video/x-raw", &[("format", &"RGBA")]);
|
||||||
|
|
||||||
let video_profile = EncodingVideoProfile::builder()
|
let video_profile = EncodingVideoProfile::builder(&caps)
|
||||||
.name(VIDEO_PROFILE_NAME)
|
.name(VIDEO_PROFILE_NAME)
|
||||||
.description(VIDEO_PROFILE_DESCRIPTION)
|
.description(VIDEO_PROFILE_DESCRIPTION)
|
||||||
.format(&caps)
|
|
||||||
.preset(PRESET)
|
.preset(PRESET)
|
||||||
.preset_name(PRESET_NAME)
|
.preset_name(PRESET_NAME)
|
||||||
.restriction(&restriction)
|
.restriction(&restriction)
|
||||||
|
@ -627,8 +590,7 @@ mod tests {
|
||||||
.enabled(ENABLED)
|
.enabled(ENABLED)
|
||||||
.pass(PASS)
|
.pass(PASS)
|
||||||
.variable_framerate(VARIABLE_FRAMERATE)
|
.variable_framerate(VARIABLE_FRAMERATE)
|
||||||
.build()
|
.build();
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert_eq!(video_profile.name().unwrap(), VIDEO_PROFILE_NAME);
|
assert_eq!(video_profile.name().unwrap(), VIDEO_PROFILE_NAME);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -661,23 +623,18 @@ mod tests {
|
||||||
let video_caps = gst::Caps::new_simple("video/x-raw", &[]);
|
let video_caps = gst::Caps::new_simple("video/x-raw", &[]);
|
||||||
let audio_caps = gst::Caps::new_simple("audio/x-raw", &[]);
|
let audio_caps = gst::Caps::new_simple("audio/x-raw", &[]);
|
||||||
|
|
||||||
let video_profile = EncodingVideoProfile::builder()
|
let video_profile = EncodingVideoProfile::builder(&video_caps)
|
||||||
.name(VIDEO_PROFILE_NAME)
|
.name(VIDEO_PROFILE_NAME)
|
||||||
.description(VIDEO_PROFILE_DESCRIPTION)
|
.description(VIDEO_PROFILE_DESCRIPTION)
|
||||||
.format(&video_caps)
|
.build();
|
||||||
.build()
|
let audio_profile = EncodingAudioProfile::builder(&audio_caps)
|
||||||
.unwrap();
|
|
||||||
let audio_profile = EncodingAudioProfile::builder()
|
|
||||||
.name(AUDIO_PROFILE_NAME)
|
.name(AUDIO_PROFILE_NAME)
|
||||||
.description(AUDIO_PROFILE_DESCRIPTION)
|
.description(AUDIO_PROFILE_DESCRIPTION)
|
||||||
.format(&audio_caps)
|
.build();
|
||||||
.build()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let profile = EncodingContainerProfile::builder()
|
let profile = EncodingContainerProfile::builder(&container_caps)
|
||||||
.name(CONTAINER_PROFILE_NAME)
|
.name(CONTAINER_PROFILE_NAME)
|
||||||
.description(CONTAINER_PROFILE_DESCRIPTION)
|
.description(CONTAINER_PROFILE_DESCRIPTION)
|
||||||
.format(&container_caps)
|
|
||||||
.preset(PRESET)
|
.preset(PRESET)
|
||||||
.preset_name(PRESET_NAME)
|
.preset_name(PRESET_NAME)
|
||||||
.presence(PRESENCE)
|
.presence(PRESENCE)
|
||||||
|
@ -685,8 +642,7 @@ mod tests {
|
||||||
.enabled(ENABLED)
|
.enabled(ENABLED)
|
||||||
.add_profile(&audio_profile)
|
.add_profile(&audio_profile)
|
||||||
.add_profile(&video_profile)
|
.add_profile(&video_profile)
|
||||||
.build()
|
.build();
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert_eq!(profile.name().unwrap(), CONTAINER_PROFILE_NAME);
|
assert_eq!(profile.name().unwrap(), CONTAINER_PROFILE_NAME);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|
Loading…
Reference in a new issue