EncodingProfile: remove setters and constructors, use builders

Provide builders for the EncodingProfile so that the created objects are
imutable and can have the Send and Sync traits
This commit is contained in:
Thiago Santos 2018-05-13 11:31:10 -07:00 committed by Sebastian Dröge
parent 861f052c3d
commit f3c8dfeb9b
12 changed files with 618 additions and 456 deletions

View file

@ -149,6 +149,14 @@ status = "generate"
name = "is_equal"
ignore = true
# Ignore all setters, making it imutable. A builder will be provided.
[[object.function]]
name = "new"
ignore = true
[[object.function]]
pattern = "set_.*"
ignore = true
[[object.function]]
name = "copy"
[object.function.return]
@ -168,10 +176,14 @@ status = "generate"
name = "GstPbutils.EncodingContainerProfile"
status = "generate"
# Make it imutable, only able to be constructed for a builder
[[object.function]]
name = "new"
ignore = true
[[object.function]]
name = "add_profile"
[object.function.return]
bool_return_is_error = "Failed to add profile"
ignore = true
[[object]]
name = "GstPbutils.EncodingTarget"
@ -199,8 +211,23 @@ status = "generate"
name = "GstPbutils.EncodingAudioProfile"
status = "generate"
trait = false
# Ignore all setters, making it imutable. A builder will be provided.
[[object.function]]
name = "new"
ignore = true
[[object.function]]
pattern = "set_.*"
ignore = true
[[object]]
name = "GstPbutils.EncodingVideoProfile"
status = "generate"
trait = false
# Ignore all setters, making it imutable. A builder will be provided.
[[object.function]]
name = "new"
ignore = true
[[object.function]]
pattern = "set_.*"
ignore = true

View file

@ -3,6 +3,7 @@ extern crate gstreamer as gst;
use gst::prelude::*;
extern crate gstreamer_pbutils as pbutils;
use pbutils::EncodingProfileBuilder;
extern crate glib;

View file

@ -1,5 +1,5 @@
// This file was generated by gir (https://github.com/gtk-rs/gir @ fe7a6ff+)
// from gir-files (https://github.com/gtk-rs/gir-files @ ???)
// This file was generated by gir (https://github.com/gtk-rs/gir)
// from gir-files (https://github.com/gtk-rs/gir-files)
// DO NOT EDIT
use EncodingProfile;
@ -7,7 +7,6 @@ use ffi;
use glib::translate::*;
use glib_ffi;
use gobject_ffi;
use gst;
use std::mem;
use std::ptr;
@ -19,18 +18,7 @@ glib_wrapper! {
}
}
impl EncodingAudioProfile {
pub fn new<'a, 'b, P: Into<Option<&'a str>>, Q: Into<Option<&'b gst::Caps>>>(format: &gst::Caps, preset: P, restriction: Q, presence: u32) -> EncodingAudioProfile {
assert_initialized_main_thread!();
let preset = preset.into();
let preset = preset.to_glib_none();
let restriction = restriction.into();
let restriction = restriction.to_glib_none();
unsafe {
from_glib_full(ffi::gst_encoding_audio_profile_new(format.to_glib_none().0, preset.0, restriction.0, presence))
}
}
}
impl EncodingAudioProfile {}
unsafe impl Send for EncodingAudioProfile {}
unsafe impl Sync for EncodingAudioProfile {}

View file

@ -1,15 +1,13 @@
// This file was generated by gir (https://github.com/gtk-rs/gir @ fe7a6ff+)
// from gir-files (https://github.com/gtk-rs/gir-files @ ???)
// This file was generated by gir (https://github.com/gtk-rs/gir)
// from gir-files (https://github.com/gtk-rs/gir-files)
// DO NOT EDIT
use EncodingProfile;
use ffi;
use glib;
use glib::object::IsA;
use glib::translate::*;
use glib_ffi;
use gobject_ffi;
use gst;
use std::mem;
use std::ptr;
@ -21,39 +19,16 @@ glib_wrapper! {
}
}
impl EncodingContainerProfile {
pub fn new<'a, 'b, 'c, P: Into<Option<&'a str>>, Q: Into<Option<&'b str>>, R: Into<Option<&'c str>>>(name: P, description: Q, format: &gst::Caps, preset: R) -> EncodingContainerProfile {
assert_initialized_main_thread!();
let name = name.into();
let name = name.to_glib_none();
let description = description.into();
let description = description.to_glib_none();
let preset = preset.into();
let preset = preset.to_glib_none();
unsafe {
from_glib_full(ffi::gst_encoding_container_profile_new(name.0, description.0, format.to_glib_none().0, preset.0))
}
}
}
unsafe impl Send for EncodingContainerProfile {}
unsafe impl Sync for EncodingContainerProfile {}
pub trait EncodingContainerProfileExt {
fn add_profile<P: IsA<EncodingProfile>>(&self, profile: &P) -> Result<(), glib::error::BoolError>;
fn contains_profile<P: IsA<EncodingProfile>>(&self, profile: &P) -> bool;
fn get_profiles(&self) -> Vec<EncodingProfile>;
}
impl<O: IsA<EncodingContainerProfile>> EncodingContainerProfileExt for O {
fn add_profile<P: IsA<EncodingProfile>>(&self, profile: &P) -> Result<(), glib::error::BoolError> {
unsafe {
glib::error::BoolError::from_glib(ffi::gst_encoding_container_profile_add_profile(self.to_glib_none().0, profile.to_glib_full()), "Failed to add profile")
}
}
fn contains_profile<P: IsA<EncodingProfile>>(&self, profile: &P) -> bool {
unsafe {
from_glib(ffi::gst_encoding_container_profile_contains_profile(self.to_glib_none().0, profile.to_glib_none().0))

View file

@ -1,5 +1,5 @@
// This file was generated by gir (https://github.com/gtk-rs/gir @ fe7a6ff+)
// from gir-files (https://github.com/gtk-rs/gir-files @ ???)
// This file was generated by gir (https://github.com/gtk-rs/gir)
// from gir-files (https://github.com/gtk-rs/gir-files)
// DO NOT EDIT
use DiscovererInfo;
@ -78,24 +78,6 @@ pub trait EncodingProfileExt {
fn is_enabled(&self) -> bool;
fn set_allow_dynamic_output(&self, allow_dynamic_output: bool);
fn set_description<'a, P: Into<Option<&'a str>>>(&self, description: P);
fn set_enabled(&self, enabled: bool);
fn set_format(&self, format: &gst::Caps);
fn set_name<'a, P: Into<Option<&'a str>>>(&self, name: P);
fn set_presence(&self, presence: u32);
fn set_preset<'a, P: Into<Option<&'a str>>>(&self, preset: P);
fn set_preset_name<'a, P: Into<Option<&'a str>>>(&self, preset_name: P);
fn set_restriction<'a, P: Into<Option<&'a gst::Caps>>>(&self, restriction: P);
fn get_property_restriction_caps(&self) -> Option<gst::Caps>;
fn set_property_restriction_caps(&self, restriction_caps: Option<&gst::Caps>);
@ -182,70 +164,6 @@ impl<O: IsA<EncodingProfile> + IsA<glib::object::Object>> EncodingProfileExt for
}
}
fn set_allow_dynamic_output(&self, allow_dynamic_output: bool) {
unsafe {
ffi::gst_encoding_profile_set_allow_dynamic_output(self.to_glib_none().0, allow_dynamic_output.to_glib());
}
}
fn set_description<'a, P: Into<Option<&'a str>>>(&self, description: P) {
let description = description.into();
let description = description.to_glib_none();
unsafe {
ffi::gst_encoding_profile_set_description(self.to_glib_none().0, description.0);
}
}
fn set_enabled(&self, enabled: bool) {
unsafe {
ffi::gst_encoding_profile_set_enabled(self.to_glib_none().0, enabled.to_glib());
}
}
fn set_format(&self, format: &gst::Caps) {
unsafe {
ffi::gst_encoding_profile_set_format(self.to_glib_none().0, format.to_glib_none().0);
}
}
fn set_name<'a, P: Into<Option<&'a str>>>(&self, name: P) {
let name = name.into();
let name = name.to_glib_none();
unsafe {
ffi::gst_encoding_profile_set_name(self.to_glib_none().0, name.0);
}
}
fn set_presence(&self, presence: u32) {
unsafe {
ffi::gst_encoding_profile_set_presence(self.to_glib_none().0, presence);
}
}
fn set_preset<'a, P: Into<Option<&'a str>>>(&self, preset: P) {
let preset = preset.into();
let preset = preset.to_glib_none();
unsafe {
ffi::gst_encoding_profile_set_preset(self.to_glib_none().0, preset.0);
}
}
fn set_preset_name<'a, P: Into<Option<&'a str>>>(&self, preset_name: P) {
let preset_name = preset_name.into();
let preset_name = preset_name.to_glib_none();
unsafe {
ffi::gst_encoding_profile_set_preset_name(self.to_glib_none().0, preset_name.0);
}
}
fn set_restriction<'a, P: Into<Option<&'a gst::Caps>>>(&self, restriction: P) {
let restriction = restriction.into();
let restriction = restriction.to_glib_none();
unsafe {
ffi::gst_encoding_profile_set_restriction(self.to_glib_none().0, restriction.0);
}
}
fn get_property_restriction_caps(&self) -> Option<gst::Caps> {
unsafe {
let mut value = Value::from_type(<gst::Caps as StaticType>::static_type());
@ -271,7 +189,6 @@ impl<O: IsA<EncodingProfile> + IsA<glib::object::Object>> EncodingProfileExt for
unsafe extern "C" fn notify_restriction_caps_trampoline<P>(this: *mut ffi::GstEncodingProfile, _param_spec: glib_ffi::gpointer, f: glib_ffi::gpointer)
where P: IsA<EncodingProfile> {
callback_guard!();
let f: &&(Fn(&P) + Send + Sync + 'static) = transmute(f);
f(&EncodingProfile::from_glib_borrow(this).downcast_unchecked())
}

View file

@ -1,5 +1,5 @@
// This file was generated by gir (https://github.com/gtk-rs/gir @ fe7a6ff+)
// from gir-files (https://github.com/gtk-rs/gir-files @ ???)
// This file was generated by gir (https://github.com/gtk-rs/gir)
// from gir-files (https://github.com/gtk-rs/gir-files)
// DO NOT EDIT
use EncodingProfile;

View file

@ -1,5 +1,5 @@
// This file was generated by gir (https://github.com/gtk-rs/gir @ fe7a6ff+)
// from gir-files (https://github.com/gtk-rs/gir-files @ ???)
// This file was generated by gir (https://github.com/gtk-rs/gir)
// from gir-files (https://github.com/gtk-rs/gir-files)
// DO NOT EDIT
use EncodingProfile;
@ -7,7 +7,6 @@ use ffi;
use glib::translate::*;
use glib_ffi;
use gobject_ffi;
use gst;
use std::mem;
use std::ptr;
@ -20,17 +19,6 @@ glib_wrapper! {
}
impl EncodingVideoProfile {
pub fn new<'a, 'b, P: Into<Option<&'a str>>, Q: Into<Option<&'b gst::Caps>>>(format: &gst::Caps, preset: P, restriction: Q, presence: u32) -> EncodingVideoProfile {
assert_initialized_main_thread!();
let preset = preset.into();
let preset = preset.to_glib_none();
let restriction = restriction.into();
let restriction = restriction.to_glib_none();
unsafe {
from_glib_full(ffi::gst_encoding_video_profile_new(format.to_glib_none().0, preset.0, restriction.0, presence))
}
}
pub fn get_pass(&self) -> u32 {
unsafe {
ffi::gst_encoding_video_profile_get_pass(self.to_glib_none().0)
@ -42,18 +30,6 @@ impl EncodingVideoProfile {
from_glib(ffi::gst_encoding_video_profile_get_variableframerate(self.to_glib_none().0))
}
}
pub fn set_pass(&self, pass: u32) {
unsafe {
ffi::gst_encoding_video_profile_set_pass(self.to_glib_none().0, pass);
}
}
pub fn set_variableframerate(&self, variableframerate: bool) {
unsafe {
ffi::gst_encoding_video_profile_set_variableframerate(self.to_glib_none().0, variableframerate.to_glib());
}
}
}
unsafe impl Send for EncodingVideoProfile {}

View file

@ -1,84 +0,0 @@
use gst;
use std::error;
use std::fmt;
use auto::EncodingAudioProfile;
#[derive(Debug, Clone)]
pub struct EncodingAudioProfileBuilderError;
impl fmt::Display for EncodingAudioProfileBuilderError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "failed to build encoding audio profile")
}
}
impl error::Error for EncodingAudioProfileBuilderError {
fn description(&self) -> &str {
"invalid parameters to build encoding audio profile"
}
fn cause(&self) -> Option<&error::Error> {
None
}
}
pub struct EncodingAudioProfileBuilder<'a> {
format: Option<& 'a gst::Caps>,
preset: Option<& 'a str>,
restriction: Option<& 'a gst::Caps>,
presence: u32
}
impl<'a> EncodingAudioProfileBuilder<'a> {
pub fn new() -> Self {
EncodingAudioProfileBuilder {
format: None,
preset: None,
restriction: None,
presence: 0,
}
}
pub fn build(self) -> Result<EncodingAudioProfile, EncodingAudioProfileBuilderError> {
if self.format.is_none() {
return Err(EncodingAudioProfileBuilderError);
}
let profile = EncodingAudioProfile::new(
self.format.unwrap(), self.preset, self.restriction, self.presence);
Ok(profile)
}
pub fn format(self, format: & 'a gst::Caps) -> Self {
Self {
format: Some(format),
..self
}
}
pub fn restriction(self, restriction: & 'a gst::Caps) -> Self {
Self {
restriction: Some(restriction),
..self
}
}
pub fn preset(self, preset: & 'a str) -> Self {
Self {
preset: Some(preset),
..self
}
}
pub fn presence(self, presence: u32) -> Self {
Self {
presence: presence,
..self
}
}
}

View file

@ -1,99 +0,0 @@
use gst;
use std::error;
use std::fmt;
use auto::EncodingProfile;
use auto::EncodingContainerProfile;
use auto::EncodingContainerProfileExt;
use std::collections::LinkedList;
#[derive(Debug, Clone)]
pub struct EncodingContainerProfileBuilderError;
impl fmt::Display for EncodingContainerProfileBuilderError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "failed to build encoding video profile")
}
}
impl error::Error for EncodingContainerProfileBuilderError {
fn description(&self) -> &str {
"invalid parameters to build encoding container profile"
}
fn cause(&self) -> Option<&error::Error> {
None
}
}
pub struct EncodingContainerProfileBuilder<'a> {
name: Option<& 'a str>,
description: Option<& 'a str>,
format: Option<& 'a gst::Caps>,
preset: Option<& 'a str>,
profiles: LinkedList<& 'a EncodingProfile>
}
impl<'a> EncodingContainerProfileBuilder<'a> {
pub fn new() -> Self {
EncodingContainerProfileBuilder {
name: None,
description: None,
format: None,
preset: None,
profiles: LinkedList::new()
}
}
pub fn build(self) -> Result<EncodingContainerProfile, EncodingContainerProfileBuilderError> {
if self.format.is_none() {
return Err(EncodingContainerProfileBuilderError);
}
let container_profile = EncodingContainerProfile::new(
self.name, self.description, self.format.unwrap(), self.preset);
for profile in self.profiles {
container_profile.add_profile(profile).or_else(|_error| Err(EncodingContainerProfileBuilderError))?;
}
Ok(container_profile)
}
pub fn name(self, name: & 'a str) -> Self {
Self {
name: Some(name),
..self
}
}
pub fn description(self, description: & 'a str) -> Self {
Self {
description: Some(description),
..self
}
}
pub fn format(self, format: & 'a gst::Caps) -> Self {
Self {
format: Some(format),
..self
}
}
pub fn preset(self, preset: & 'a str) -> Self {
Self {
preset: Some(preset),
..self
}
}
pub fn add_profile(mut self, profile: & 'a EncodingProfile) -> Self {
self.profiles.push_back(profile);
self
}
}

View file

@ -0,0 +1,574 @@
use gst;
use glib;
use ffi;
use std::error;
use std::fmt;
use std::collections::LinkedList;
use glib::Cast;
use glib::object::IsA;
use glib::translate::*;
use auto::EncodingProfile;
use auto::EncodingAudioProfile;
use auto::EncodingVideoProfile;
use auto::EncodingContainerProfile;
trait EncodingProfileEdit {
fn set_allow_dynamic_output(&self, allow_dynamic_output: bool);
fn set_description<'a, P: Into<Option<&'a str>>>(&self, description: P);
fn set_enabled(&self, enabled: bool);
fn set_format(&self, format: &gst::Caps);
fn set_name<'a, P: Into<Option<&'a str>>>(&self, name: P);
fn set_presence(&self, presence: u32);
fn set_preset<'a, P: Into<Option<&'a str>>>(&self, preset: P);
fn set_preset_name<'a, P: Into<Option<&'a str>>>(&self, preset_name: P);
fn set_restriction<'a, P: Into<Option<&'a gst::Caps>>>(&self, restriction: P);
}
impl<O: IsA<EncodingProfile> + IsA<glib::object::Object>> EncodingProfileEdit for O {
fn set_allow_dynamic_output(&self, allow_dynamic_output: bool) {
unsafe {
ffi::gst_encoding_profile_set_allow_dynamic_output(self.to_glib_none().0, allow_dynamic_output.to_glib());
}
}
fn set_description<'a, P: Into<Option<&'a str>>>(&self, description: P) {
let description = description.into();
let description = description.to_glib_none();
unsafe {
ffi::gst_encoding_profile_set_description(self.to_glib_none().0, description.0);
}
}
fn set_enabled(&self, enabled: bool) {
unsafe {
ffi::gst_encoding_profile_set_enabled(self.to_glib_none().0, enabled.to_glib());
}
}
fn set_format(&self, format: &gst::Caps) {
unsafe {
ffi::gst_encoding_profile_set_format(self.to_glib_none().0, format.to_glib_none().0);
}
}
fn set_name<'a, P: Into<Option<&'a str>>>(&self, name: P) {
let name = name.into();
let name = name.to_glib_none();
unsafe {
ffi::gst_encoding_profile_set_name(self.to_glib_none().0, name.0);
}
}
fn set_presence(&self, presence: u32) {
unsafe {
ffi::gst_encoding_profile_set_presence(self.to_glib_none().0, presence);
}
}
fn set_preset<'a, P: Into<Option<&'a str>>>(&self, preset: P) {
let preset = preset.into();
let preset = preset.to_glib_none();
unsafe {
ffi::gst_encoding_profile_set_preset(self.to_glib_none().0, preset.0);
}
}
fn set_preset_name<'a, P: Into<Option<&'a str>>>(&self, preset_name: P) {
let preset_name = preset_name.into();
let preset_name = preset_name.to_glib_none();
unsafe {
ffi::gst_encoding_profile_set_preset_name(self.to_glib_none().0, preset_name.0);
}
}
fn set_restriction<'a, P: Into<Option<&'a gst::Caps>>>(&self, restriction: P) {
let restriction = restriction.into();
let restriction = restriction.to_glib_none();
unsafe {
ffi::gst_encoding_profile_set_restriction(self.to_glib_none().0, restriction.0);
}
}
}
impl EncodingAudioProfile {
fn new<'a, 'b, P: Into<Option<&'a str>>, Q: Into<Option<&'b gst::Caps>>>(format: &gst::Caps, preset: P, restriction: Q, presence: u32) -> EncodingAudioProfile {
assert_initialized_main_thread!();
let preset = preset.into();
let preset = preset.to_glib_none();
let restriction = restriction.into();
let restriction = restriction.to_glib_none();
unsafe {
from_glib_full(ffi::gst_encoding_audio_profile_new(format.to_glib_none().0, preset.0, restriction.0, presence))
}
}
}
impl EncodingVideoProfile {
fn new<'a, 'b, P: Into<Option<&'a str>>, Q: Into<Option<&'b gst::Caps>>>(format: &gst::Caps, preset: P, restriction: Q, presence: u32) -> EncodingVideoProfile {
assert_initialized_main_thread!();
let preset = preset.into();
let preset = preset.to_glib_none();
let restriction = restriction.into();
let restriction = restriction.to_glib_none();
unsafe {
from_glib_full(ffi::gst_encoding_video_profile_new(format.to_glib_none().0, preset.0, restriction.0, presence))
}
}
fn set_pass(&self, pass: u32) {
unsafe {
ffi::gst_encoding_video_profile_set_pass(self.to_glib_none().0, pass);
}
}
fn set_variableframerate(&self, variableframerate: bool) {
unsafe {
ffi::gst_encoding_video_profile_set_variableframerate(self.to_glib_none().0, variableframerate.to_glib());
}
}
}
impl EncodingContainerProfile {
fn new<'a, 'b, 'c, P: Into<Option<&'a str>>, Q: Into<Option<&'b str>>, R: Into<Option<&'c str>>>(name: P, description: Q, format: &gst::Caps, preset: R) -> EncodingContainerProfile {
assert_initialized_main_thread!();
let name = name.into();
let name = name.to_glib_none();
let description = description.into();
let description = description.to_glib_none();
let preset = preset.into();
let preset = preset.to_glib_none();
unsafe {
from_glib_full(ffi::gst_encoding_container_profile_new(name.0, description.0, format.to_glib_none().0, preset.0))
}
}
fn add_profile<P: IsA<EncodingProfile>>(&self, profile: &P) -> Result<(), glib::error::BoolError> {
unsafe {
glib::error::BoolError::from_glib(ffi::gst_encoding_container_profile_add_profile(self.to_glib_none().0, profile.to_glib_full()), "Failed to add profile")
}
}
}
#[derive(Debug, Clone)]
pub struct EncodingProfileBuilderError;
impl fmt::Display for EncodingProfileBuilderError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "failed to build encoding profile")
}
}
impl error::Error for EncodingProfileBuilderError {
fn description(&self) -> &str {
"invalid parameters to build encoding profile"
}
fn cause(&self) -> Option<&error::Error> {
None
}
}
struct EncodingProfileBuilderData<'a> {
name: Option<& 'a str>,
description: Option<& 'a str>,
format: Option<& 'a gst::Caps>,
preset: Option<& 'a str>,
preset_name: Option<& 'a str>,
restriction: Option<& 'a gst::Caps>,
presence: u32,
allow_dynamic_output: bool,
enabled: bool
}
impl<'a> EncodingProfileBuilderData<'a> {
fn new() -> EncodingProfileBuilderData<'a> {
EncodingProfileBuilderData {
name: None,
description: None,
format: None,
preset: None,
preset_name : None,
restriction: None,
presence: 0,
allow_dynamic_output: true,
enabled: true
}
}
}
pub trait EncodingProfileBuilder<'a>: Sized {
fn name(self, name: & 'a str) -> Self;
fn description(self, description: & 'a str) -> Self;
fn format(self, format: & 'a gst::Caps) -> Self;
fn preset(self, preset: & 'a str) -> Self;
fn preset_name(self, preset_name: & 'a str) -> Self;
fn restriction(self, format: & 'a gst::Caps) -> Self;
fn presence(self, presence: u32) -> Self;
fn allow_dynamic_output(self, allow: bool) -> Self;
fn enabled(self, enabled: bool) -> Self;
}
macro_rules! declare_encoding_profile_builder(
($name:ident) => {
impl<'a> EncodingProfileBuilder<'a> for $name<'a> {
fn name(mut self, name: &'a str) -> $name<'a> {
self.base.name = Some(name);
self
}
fn description(mut self, description: &'a str) -> $name<'a> {
self.base.description = Some(description);
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> {
self.base.preset = Some(preset);
self
}
fn preset_name(mut self, preset_name: &'a str) -> $name<'a> {
self.base.preset_name = Some(preset_name);
self
}
fn restriction(mut self, restriction: &'a gst::Caps) -> $name<'a> {
self.base.restriction = Some(restriction);
self
}
fn presence(mut self, presence: u32) -> $name<'a> {
self.base.presence = presence;
self
}
fn allow_dynamic_output(mut self, allow: bool) -> $name<'a> {
self.base.allow_dynamic_output = allow;
self
}
fn enabled(mut self, enabled: bool) -> $name<'a> {
self.base.enabled = enabled;
self
}
}
}
);
fn set_common_fields<T: EncodingProfileEdit>(profile: &mut T, base_data: &EncodingProfileBuilderData) {
profile.set_name(base_data.name);
profile.set_description(base_data.description);
profile.set_preset(base_data.preset);
profile.set_preset_name(base_data.preset_name);
profile.set_allow_dynamic_output(base_data.allow_dynamic_output);
profile.set_enabled(base_data.enabled);
profile.set_restriction(base_data.restriction);
profile.set_presence(base_data.presence);
}
pub struct EncodingAudioProfileBuilder<'a> {
base : EncodingProfileBuilderData<'a>
}
declare_encoding_profile_builder!(EncodingAudioProfileBuilder);
impl<'a> EncodingAudioProfileBuilder<'a> {
pub fn new() -> Self {
EncodingAudioProfileBuilder {
base: EncodingProfileBuilderData::new(),
}
}
pub fn build(self) -> Result<EncodingProfile, EncodingProfileBuilderError> {
if self.base.format.is_none() {
return Err(EncodingProfileBuilderError);
}
let profile = EncodingAudioProfile::new(
self.base.format.unwrap(), self.base.preset,
self.base.restriction, self.base.presence);
let mut profile = profile.upcast();
set_common_fields(&mut profile, &self.base);
Ok(profile)
}
}
pub struct EncodingVideoProfileBuilder<'a> {
base : EncodingProfileBuilderData<'a>,
pass: u32,
variable_framerate: bool,
}
declare_encoding_profile_builder!(EncodingVideoProfileBuilder);
impl<'a> EncodingVideoProfileBuilder<'a> {
pub fn new() -> Self {
EncodingVideoProfileBuilder {
base: EncodingProfileBuilderData::new(),
pass: 0,
variable_framerate: false
}
}
pub fn pass(mut self, pass: u32) -> Self {
self.pass = pass;
self
}
pub fn variable_framerate(mut self, variable_framerate: bool) -> Self {
self.variable_framerate = variable_framerate;
self
}
pub fn build(self) -> Result<EncodingProfile, EncodingProfileBuilderError> {
if self.base.format.is_none() {
return Err(EncodingProfileBuilderError);
}
let video_profile = EncodingVideoProfile::new(
self.base.format.unwrap(), self.base.preset, self.base.restriction, self.base.presence);
video_profile.set_pass(self.pass);
video_profile.set_variableframerate(self.variable_framerate);
let mut profile = video_profile.upcast();
set_common_fields(&mut profile, &self.base);
Ok(profile)
}
}
pub struct EncodingContainerProfileBuilder<'a> {
base : EncodingProfileBuilderData<'a>,
profiles: LinkedList<& 'a EncodingProfile>
}
declare_encoding_profile_builder!(EncodingContainerProfileBuilder);
impl<'a> EncodingContainerProfileBuilder<'a> {
pub fn new() -> Self {
EncodingContainerProfileBuilder {
base: EncodingProfileBuilderData::new(),
profiles: LinkedList::new()
}
}
pub fn build(self) -> Result<EncodingProfile, EncodingProfileBuilderError> {
if self.base.format.is_none() {
return Err(EncodingProfileBuilderError);
}
let container_profile = EncodingContainerProfile::new(
self.base.name, self.base.description, self.base.format.unwrap(), self.base.preset);
for profile in self.profiles {
container_profile.add_profile(profile).or_else(|_error| Err(EncodingProfileBuilderError))?;
}
let mut profile = container_profile.upcast();
set_common_fields(&mut profile, &self.base);
Ok(profile)
}
pub fn add_profile(mut self, profile: & 'a EncodingProfile) -> Self {
self.profiles.push_back(profile);
self
}
}
#[cfg(test)]
mod tests {
use super::*;
use gst;
use auto::EncodingProfileExt;
use auto::EncodingVideoProfile;
use auto::EncodingContainerProfile;
use auto::EncodingContainerProfileExt;
const AUDIO_PROFILE_NAME: &'static str = "audio-profile";
const AUDIO_PROFILE_DESCRIPTION: &'static str = "audio-profile-description";
const PRESET: &'static str = "preset";
const PRESET_NAME: &'static str = "preset-name";
const PRESENCE: u32 = 5;
const ALLOW_DYNAMIC_OUTPUT: bool = false;
const ENABLED: bool = false;
const VIDEO_PROFILE_NAME: &'static str = "video-profile";
const VIDEO_PROFILE_DESCRIPTION: &'static str = "video-profile-description";
const CONTAINER_PROFILE_NAME: &'static str = "container-profile";
const CONTAINER_PROFILE_DESCRIPTION: &'static str = "container-profile-description";
// Video profile exclusive attributes
const PASS: u32 = 8;
const VARIABLE_FRAMERATE: bool = true;
#[test]
fn test_encoding_audio_profile_builder() {
gst::init().unwrap();
let caps = gst::Caps::new_simple(
"audio/x-raw",
&[],
);
let restriction = gst::Caps::new_simple(
"audio/x-raw",
&[
("format", &"S32LE"),
],
);
let audio_profile = EncodingAudioProfileBuilder::new()
.name(AUDIO_PROFILE_NAME)
.description(AUDIO_PROFILE_DESCRIPTION)
.format(&caps)
.preset(PRESET)
.preset_name(PRESET_NAME)
.restriction(&restriction)
.presence(PRESENCE)
.allow_dynamic_output(ALLOW_DYNAMIC_OUTPUT)
.enabled(ENABLED)
.build().unwrap();
assert_eq!(audio_profile.get_name().unwrap(), AUDIO_PROFILE_NAME);
assert_eq!(audio_profile.get_description().unwrap(), AUDIO_PROFILE_DESCRIPTION);
assert_eq!(audio_profile.get_format(), caps);
assert_eq!(audio_profile.get_preset().unwrap(), PRESET);
assert_eq!(audio_profile.get_preset_name().unwrap(), PRESET_NAME);
assert_eq!(audio_profile.get_restriction().unwrap(), restriction);
assert_eq!(audio_profile.get_presence(), PRESENCE);
assert_eq!(audio_profile.get_allow_dynamic_output(), ALLOW_DYNAMIC_OUTPUT);
assert_eq!(audio_profile.is_enabled(), ENABLED);
}
#[test]
fn test_encoding_video_profile_builder() {
gst::init().unwrap();
let caps = gst::Caps::new_simple(
"video/x-raw",
&[],
);
let restriction = gst::Caps::new_simple(
"video/x-raw",
&[
("format", &"RGBA"),
],
);
let video_profile = EncodingVideoProfileBuilder::new()
.name(VIDEO_PROFILE_NAME)
.description(VIDEO_PROFILE_DESCRIPTION)
.format(&caps)
.preset(PRESET)
.preset_name(PRESET_NAME)
.restriction(&restriction)
.presence(PRESENCE)
.allow_dynamic_output(ALLOW_DYNAMIC_OUTPUT)
.enabled(ENABLED)
.pass(PASS)
.variable_framerate(VARIABLE_FRAMERATE)
.build().unwrap();
assert_eq!(video_profile.get_name().unwrap(), VIDEO_PROFILE_NAME);
assert_eq!(video_profile.get_description().unwrap(), VIDEO_PROFILE_DESCRIPTION);
assert_eq!(video_profile.get_format(), caps);
assert_eq!(video_profile.get_preset().unwrap(), PRESET);
assert_eq!(video_profile.get_preset_name().unwrap(), PRESET_NAME);
assert_eq!(video_profile.get_restriction().unwrap(), restriction);
assert_eq!(video_profile.get_presence(), PRESENCE);
assert_eq!(video_profile.get_allow_dynamic_output(), ALLOW_DYNAMIC_OUTPUT);
assert_eq!(video_profile.is_enabled(), ENABLED);
let video_profile: EncodingVideoProfile =
glib::object::Downcast::downcast(video_profile).ok().unwrap();
assert_eq!(video_profile.get_variableframerate(), VARIABLE_FRAMERATE);
assert_eq!(video_profile.get_pass(), PASS);
}
#[test]
fn test_encoding_container_profile_builder() {
gst::init().unwrap();
let container_caps = gst::Caps::new_simple(
"container/x-caps",
&[],
);
let restriction = gst::Caps::new_simple(
"container/x-caps",
&[
("field", &"somevalue")
],
);
let video_caps = gst::Caps::new_simple(
"video/x-raw",
&[],
);
let audio_caps = gst::Caps::new_simple(
"audio/x-raw",
&[],
);
let video_profile = EncodingVideoProfileBuilder::new()
.name(VIDEO_PROFILE_NAME)
.description(VIDEO_PROFILE_DESCRIPTION)
.format(&video_caps)
.build().unwrap();
let audio_profile = EncodingAudioProfileBuilder::new()
.name(AUDIO_PROFILE_NAME)
.description(AUDIO_PROFILE_DESCRIPTION)
.format(&audio_caps)
.build().unwrap();
let profile = EncodingContainerProfileBuilder::new()
.name(CONTAINER_PROFILE_NAME)
.description(CONTAINER_PROFILE_DESCRIPTION)
.format(&container_caps)
.preset(PRESET)
.preset_name(PRESET_NAME)
.restriction(&restriction)
.presence(PRESENCE)
.allow_dynamic_output(ALLOW_DYNAMIC_OUTPUT)
.enabled(ENABLED)
.add_profile(&audio_profile)
.add_profile(&video_profile)
.build().unwrap();
assert_eq!(profile.get_name().unwrap(), CONTAINER_PROFILE_NAME);
assert_eq!(profile.get_description().unwrap(), CONTAINER_PROFILE_DESCRIPTION);
assert_eq!(profile.get_format(), container_caps);
assert_eq!(profile.get_preset().unwrap(), PRESET);
assert_eq!(profile.get_preset_name().unwrap(), PRESET_NAME);
assert_eq!(profile.get_restriction().unwrap(), restriction);
assert_eq!(profile.get_presence(), PRESENCE);
assert_eq!(profile.get_allow_dynamic_output(), ALLOW_DYNAMIC_OUTPUT);
assert_eq!(profile.is_enabled(), ENABLED);
let container_profile: EncodingContainerProfile =
glib::object::Downcast::downcast(profile).ok().unwrap();
assert!(container_profile.contains_profile(&video_profile));
assert!(container_profile.contains_profile(&audio_profile));
}
}

View file

@ -1,105 +0,0 @@
use gst;
use std::error;
use std::fmt;
use auto::EncodingVideoProfile;
#[derive(Debug, Clone)]
pub struct EncodingVideoProfileBuilderError;
impl fmt::Display for EncodingVideoProfileBuilderError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "failed to build encoding video profile")
}
}
impl error::Error for EncodingVideoProfileBuilderError {
fn description(&self) -> &str {
"invalid parameters to build encoding video profile"
}
fn cause(&self) -> Option<&error::Error> {
None
}
}
pub struct EncodingVideoProfileBuilder<'a> {
format: Option<& 'a gst::Caps>,
preset: Option<& 'a str>,
restriction: Option<& 'a gst::Caps>,
presence: u32,
pass: u32,
variable_framerate: bool,
}
impl<'a> EncodingVideoProfileBuilder<'a> {
pub fn new() -> Self {
EncodingVideoProfileBuilder {
format: None,
preset: None,
restriction: None,
presence: 0,
pass: 0,
variable_framerate: false,
}
}
pub fn build(self) -> Result<EncodingVideoProfile, EncodingVideoProfileBuilderError> {
if self.format.is_none() {
return Err(EncodingVideoProfileBuilderError);
}
let profile = EncodingVideoProfile::new(
self.format.unwrap(), self.preset, self.restriction, self.presence);
profile.set_pass(self.pass);
profile.set_variableframerate(self.variable_framerate);
Ok(profile)
}
pub fn format(self, format: & 'a gst::Caps) -> Self {
Self {
format: Some(format),
..self
}
}
pub fn restriction(self, restriction: & 'a gst::Caps) -> Self {
Self {
restriction: Some(restriction),
..self
}
}
pub fn preset(self, preset: & 'a str) -> Self {
Self {
preset: Some(preset),
..self
}
}
pub fn presence(self, presence: u32) -> Self {
Self {
presence: presence,
..self
}
}
pub fn pass(self, pass: u32) -> Self {
Self {
pass: pass,
..self
}
}
pub fn variable_framerate(self, variable_framerate: bool) -> Self {
Self {
variable_framerate: variable_framerate,
..self
}
}
}

View file

@ -55,14 +55,8 @@ pub mod discoverer_stream_info;
mod discoverer_video_info;
pub use discoverer_video_info::*;
mod encoding_container_profile;
pub use encoding_container_profile::*;
mod encoding_audio_profile;
pub use encoding_audio_profile::*;
mod encoding_video_profile;
pub use encoding_video_profile::*;
mod encoding_profile;
pub use encoding_profile::*;
// Re-export all the traits in a prelude module, so that applications
// can always "use gst::prelude::*" without getting conflicts
@ -74,9 +68,7 @@ pub mod prelude {
pub use discoverer_stream_info::*;
pub use discoverer_video_info::*;
pub use encoding_container_profile::*;
pub use encoding_video_profile::*;
pub use encoding_audio_profile::*;
pub use encoding_profile::*;
pub use auto::traits::*;
}