2018-10-08 06:22:32 +00:00
|
|
|
// Copyright (C) 2018 Thiago Santos <thiagossantos@gmail.com>
|
|
|
|
// Sebastian Dröge <sebastian@centricular.com>
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2018-05-13 18:31:10 +00:00
|
|
|
use ffi;
|
2018-10-08 04:44:17 +00:00
|
|
|
use glib;
|
|
|
|
use gst;
|
2018-10-02 00:25:50 +00:00
|
|
|
use gst_ffi;
|
2018-05-13 18:31:10 +00:00
|
|
|
|
|
|
|
use std::error;
|
|
|
|
use std::fmt;
|
|
|
|
|
|
|
|
use glib::object::IsA;
|
|
|
|
use glib::translate::*;
|
|
|
|
|
|
|
|
use auto::EncodingAudioProfile;
|
|
|
|
use auto::EncodingContainerProfile;
|
2018-10-08 04:44:17 +00:00
|
|
|
use auto::EncodingProfile;
|
|
|
|
use auto::EncodingVideoProfile;
|
2018-05-13 18:31:10 +00:00
|
|
|
|
2018-10-08 04:44:17 +00:00
|
|
|
trait EncodingProfileBuilderCommon {
|
2018-05-13 18:31:10 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2018-10-08 04:44:17 +00:00
|
|
|
impl<O: IsA<EncodingProfile> + IsA<glib::object::Object>> EncodingProfileBuilderCommon for O {
|
2018-05-13 18:31:10 +00:00
|
|
|
fn set_allow_dynamic_output(&self, allow_dynamic_output: bool) {
|
|
|
|
unsafe {
|
2018-10-08 04:44:17 +00:00
|
|
|
ffi::gst_encoding_profile_set_allow_dynamic_output(
|
|
|
|
self.to_glib_none().0,
|
|
|
|
allow_dynamic_output.to_glib(),
|
|
|
|
);
|
2018-05-13 18:31:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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();
|
|
|
|
unsafe {
|
2018-10-02 00:25:50 +00:00
|
|
|
let restriction = match restriction {
|
|
|
|
Some(restriction) => restriction.to_glib_full(),
|
|
|
|
None => gst_ffi::gst_caps_new_any(),
|
|
|
|
};
|
|
|
|
|
|
|
|
ffi::gst_encoding_profile_set_restriction(self.to_glib_none().0, restriction);
|
2018-05-13 18:31:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl EncodingAudioProfile {
|
2018-10-08 04:44:17 +00:00
|
|
|
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 {
|
2018-05-13 18:31:10 +00:00
|
|
|
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 {
|
2018-10-08 04:44:17 +00:00
|
|
|
from_glib_full(ffi::gst_encoding_audio_profile_new(
|
|
|
|
format.to_glib_none().0,
|
|
|
|
preset.0,
|
|
|
|
restriction.0,
|
|
|
|
presence,
|
|
|
|
))
|
2018-05-13 18:31:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl EncodingVideoProfile {
|
2018-10-08 04:44:17 +00:00
|
|
|
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 {
|
2018-05-13 18:31:10 +00:00
|
|
|
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 {
|
2018-10-08 04:44:17 +00:00
|
|
|
from_glib_full(ffi::gst_encoding_video_profile_new(
|
|
|
|
format.to_glib_none().0,
|
|
|
|
preset.0,
|
|
|
|
restriction.0,
|
|
|
|
presence,
|
|
|
|
))
|
2018-05-13 18:31:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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 {
|
2018-10-08 04:44:17 +00:00
|
|
|
ffi::gst_encoding_video_profile_set_variableframerate(
|
|
|
|
self.to_glib_none().0,
|
|
|
|
variableframerate.to_glib(),
|
|
|
|
);
|
2018-05-13 18:31:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl EncodingContainerProfile {
|
2018-10-08 04:44:17 +00:00
|
|
|
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 {
|
2018-05-13 18:31:10 +00:00
|
|
|
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 {
|
2018-10-08 04:44:17 +00:00
|
|
|
from_glib_full(ffi::gst_encoding_container_profile_new(
|
|
|
|
name.0,
|
|
|
|
description.0,
|
|
|
|
format.to_glib_none().0,
|
|
|
|
preset.0,
|
|
|
|
))
|
2018-05-13 18:31:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-08 04:44:17 +00:00
|
|
|
fn add_profile<P: IsA<EncodingProfile>>(
|
|
|
|
&self,
|
|
|
|
profile: &P,
|
|
|
|
) -> Result<(), glib::error::BoolError> {
|
2018-05-13 18:31:10 +00:00
|
|
|
unsafe {
|
2018-10-08 04:44:17 +00:00
|
|
|
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",
|
|
|
|
)
|
2018-05-13 18:31:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-08 04:44:17 +00:00
|
|
|
struct EncodingProfileBuilderCommonData<'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>,
|
2018-05-13 18:31:10 +00:00
|
|
|
presence: u32,
|
|
|
|
allow_dynamic_output: bool,
|
2018-10-08 04:44:17 +00:00
|
|
|
enabled: bool,
|
2018-05-13 18:31:10 +00:00
|
|
|
}
|
|
|
|
|
2018-10-08 04:44:17 +00:00
|
|
|
impl<'a> EncodingProfileBuilderCommonData<'a> {
|
|
|
|
fn new() -> EncodingProfileBuilderCommonData<'a> {
|
|
|
|
EncodingProfileBuilderCommonData {
|
2018-05-13 18:31:10 +00:00
|
|
|
name: None,
|
|
|
|
description: None,
|
|
|
|
format: None,
|
|
|
|
preset: None,
|
2018-10-08 04:44:17 +00:00
|
|
|
preset_name: None,
|
2018-05-13 18:31:10 +00:00
|
|
|
restriction: None,
|
|
|
|
presence: 0,
|
|
|
|
allow_dynamic_output: true,
|
2018-10-08 04:44:17 +00:00
|
|
|
enabled: true,
|
2018-05-13 18:31:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub trait EncodingProfileBuilder<'a>: Sized {
|
2018-10-08 04:44:17 +00:00
|
|
|
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;
|
2018-05-13 18:31:10 +00:00
|
|
|
fn presence(self, presence: u32) -> Self;
|
|
|
|
fn allow_dynamic_output(self, allow: bool) -> Self;
|
|
|
|
fn enabled(self, enabled: bool) -> Self;
|
|
|
|
}
|
|
|
|
|
2018-10-08 04:44:17 +00:00
|
|
|
macro_rules! declare_encoding_profile_builder_common(
|
2018-05-13 18:31:10 +00:00
|
|
|
($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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
2018-10-08 04:44:17 +00:00
|
|
|
fn set_common_fields<T: EncodingProfileBuilderCommon>(
|
|
|
|
profile: &T,
|
|
|
|
base_data: &EncodingProfileBuilderCommonData,
|
|
|
|
) {
|
2018-05-13 18:31:10 +00:00
|
|
|
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> {
|
2018-10-08 04:44:17 +00:00
|
|
|
base: EncodingProfileBuilderCommonData<'a>,
|
2018-05-13 18:31:10 +00:00
|
|
|
}
|
|
|
|
|
2018-10-08 04:44:17 +00:00
|
|
|
declare_encoding_profile_builder_common!(EncodingAudioProfileBuilder);
|
2018-05-13 18:31:10 +00:00
|
|
|
|
|
|
|
impl<'a> EncodingAudioProfileBuilder<'a> {
|
|
|
|
pub fn new() -> Self {
|
|
|
|
EncodingAudioProfileBuilder {
|
2018-10-08 04:44:17 +00:00
|
|
|
base: EncodingProfileBuilderCommonData::new(),
|
2018-05-13 18:31:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-08 04:44:17 +00:00
|
|
|
pub fn build(self) -> Result<EncodingAudioProfile, EncodingProfileBuilderError> {
|
2018-05-13 18:31:10 +00:00
|
|
|
if self.base.format.is_none() {
|
|
|
|
return Err(EncodingProfileBuilderError);
|
|
|
|
}
|
|
|
|
|
|
|
|
let profile = EncodingAudioProfile::new(
|
2018-10-08 04:44:17 +00:00
|
|
|
self.base.format.unwrap(),
|
|
|
|
self.base.preset,
|
|
|
|
self.base.restriction,
|
|
|
|
self.base.presence,
|
|
|
|
);
|
2018-05-13 18:31:10 +00:00
|
|
|
|
2018-10-08 04:44:17 +00:00
|
|
|
set_common_fields(&profile, &self.base);
|
2018-05-13 18:31:10 +00:00
|
|
|
Ok(profile)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct EncodingVideoProfileBuilder<'a> {
|
2018-10-08 04:44:17 +00:00
|
|
|
base: EncodingProfileBuilderCommonData<'a>,
|
2018-05-13 18:31:10 +00:00
|
|
|
pass: u32,
|
|
|
|
variable_framerate: bool,
|
|
|
|
}
|
|
|
|
|
2018-10-08 04:44:17 +00:00
|
|
|
declare_encoding_profile_builder_common!(EncodingVideoProfileBuilder);
|
2018-05-13 18:31:10 +00:00
|
|
|
|
|
|
|
impl<'a> EncodingVideoProfileBuilder<'a> {
|
|
|
|
pub fn new() -> Self {
|
|
|
|
EncodingVideoProfileBuilder {
|
2018-10-08 04:44:17 +00:00
|
|
|
base: EncodingProfileBuilderCommonData::new(),
|
2018-05-13 18:31:10 +00:00
|
|
|
pass: 0,
|
2018-10-08 04:44:17 +00:00
|
|
|
variable_framerate: false,
|
2018-05-13 18:31:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2018-10-08 04:44:17 +00:00
|
|
|
pub fn build(self) -> Result<EncodingVideoProfile, EncodingProfileBuilderError> {
|
2018-05-13 18:31:10 +00:00
|
|
|
if self.base.format.is_none() {
|
|
|
|
return Err(EncodingProfileBuilderError);
|
|
|
|
}
|
|
|
|
|
|
|
|
let video_profile = EncodingVideoProfile::new(
|
2018-10-08 04:44:17 +00:00
|
|
|
self.base.format.unwrap(),
|
|
|
|
self.base.preset,
|
|
|
|
self.base.restriction,
|
|
|
|
self.base.presence,
|
|
|
|
);
|
2018-05-13 18:31:10 +00:00
|
|
|
|
|
|
|
video_profile.set_pass(self.pass);
|
|
|
|
video_profile.set_variableframerate(self.variable_framerate);
|
|
|
|
|
2018-10-08 04:44:17 +00:00
|
|
|
set_common_fields(&video_profile, &self.base);
|
|
|
|
Ok(video_profile)
|
2018-05-13 18:31:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct EncodingContainerProfileBuilder<'a> {
|
2018-10-08 04:44:17 +00:00
|
|
|
base: EncodingProfileBuilderCommonData<'a>,
|
2018-10-08 06:17:26 +00:00
|
|
|
profiles: Vec<EncodingProfile>,
|
2018-05-13 18:31:10 +00:00
|
|
|
}
|
|
|
|
|
2018-10-08 04:44:17 +00:00
|
|
|
declare_encoding_profile_builder_common!(EncodingContainerProfileBuilder);
|
2018-05-13 18:31:10 +00:00
|
|
|
|
|
|
|
impl<'a> EncodingContainerProfileBuilder<'a> {
|
|
|
|
pub fn new() -> Self {
|
|
|
|
EncodingContainerProfileBuilder {
|
2018-10-08 04:44:17 +00:00
|
|
|
base: EncodingProfileBuilderCommonData::new(),
|
2018-10-08 06:17:26 +00:00
|
|
|
profiles: Vec::new(),
|
2018-05-13 18:31:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-08 04:44:17 +00:00
|
|
|
pub fn build(self) -> Result<EncodingContainerProfile, EncodingProfileBuilderError> {
|
2018-05-13 18:31:10 +00:00
|
|
|
if self.base.format.is_none() {
|
|
|
|
return Err(EncodingProfileBuilderError);
|
|
|
|
}
|
|
|
|
|
|
|
|
let container_profile = EncodingContainerProfile::new(
|
2018-10-08 04:44:17 +00:00
|
|
|
self.base.name,
|
|
|
|
self.base.description,
|
|
|
|
self.base.format.unwrap(),
|
|
|
|
self.base.preset,
|
|
|
|
);
|
2018-05-13 18:31:10 +00:00
|
|
|
|
2018-10-08 06:17:26 +00:00
|
|
|
for profile in self.profiles {
|
2018-10-08 04:44:17 +00:00
|
|
|
container_profile
|
|
|
|
.add_profile(&profile)
|
|
|
|
.or_else(|_error| Err(EncodingProfileBuilderError))?;
|
2018-05-13 18:31:10 +00:00
|
|
|
}
|
|
|
|
|
2018-10-08 04:44:17 +00:00
|
|
|
set_common_fields(&container_profile, &self.base);
|
|
|
|
Ok(container_profile)
|
2018-05-13 18:31:10 +00:00
|
|
|
}
|
|
|
|
|
2018-10-08 06:17:26 +00:00
|
|
|
pub fn add_profile<P: IsA<EncodingProfile>>(mut self, profile: &P) -> Self {
|
|
|
|
unsafe {
|
|
|
|
self.profiles.push(from_glib_none(profile.to_glib_none().0));
|
|
|
|
}
|
2018-05-13 18:31:10 +00:00
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
|
|
|
use auto::EncodingContainerProfile;
|
|
|
|
use auto::EncodingContainerProfileExt;
|
2018-10-08 04:44:17 +00:00
|
|
|
use auto::EncodingProfileExt;
|
|
|
|
use auto::EncodingVideoProfile;
|
|
|
|
use gst;
|
2018-05-13 18:31:10 +00:00
|
|
|
|
|
|
|
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();
|
|
|
|
|
2018-10-08 04:44:17 +00:00
|
|
|
let caps = gst::Caps::new_simple("audio/x-raw", &[]);
|
2018-05-13 18:31:10 +00:00
|
|
|
|
2018-10-08 04:44:17 +00:00
|
|
|
let restriction = gst::Caps::new_simple("audio/x-raw", &[("format", &"S32LE")]);
|
2018-05-13 18:31:10 +00:00
|
|
|
|
|
|
|
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)
|
2018-10-08 04:44:17 +00:00
|
|
|
.build()
|
|
|
|
.unwrap();
|
2018-05-13 18:31:10 +00:00
|
|
|
|
|
|
|
assert_eq!(audio_profile.get_name().unwrap(), AUDIO_PROFILE_NAME);
|
2018-10-08 04:44:17 +00:00
|
|
|
assert_eq!(
|
|
|
|
audio_profile.get_description().unwrap(),
|
|
|
|
AUDIO_PROFILE_DESCRIPTION
|
|
|
|
);
|
2018-05-13 18:31:10 +00:00
|
|
|
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);
|
2018-10-08 04:44:17 +00:00
|
|
|
assert_eq!(
|
|
|
|
audio_profile.get_allow_dynamic_output(),
|
|
|
|
ALLOW_DYNAMIC_OUTPUT
|
|
|
|
);
|
2018-05-13 18:31:10 +00:00
|
|
|
assert_eq!(audio_profile.is_enabled(), ENABLED);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_encoding_video_profile_builder() {
|
|
|
|
gst::init().unwrap();
|
|
|
|
|
2018-10-08 04:44:17 +00:00
|
|
|
let caps = gst::Caps::new_simple("video/x-raw", &[]);
|
2018-05-13 18:31:10 +00:00
|
|
|
|
2018-10-08 04:44:17 +00:00
|
|
|
let restriction = gst::Caps::new_simple("video/x-raw", &[("format", &"RGBA")]);
|
2018-05-13 18:31:10 +00:00
|
|
|
|
|
|
|
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)
|
2018-10-08 04:44:17 +00:00
|
|
|
.build()
|
|
|
|
.unwrap();
|
2018-05-13 18:31:10 +00:00
|
|
|
|
|
|
|
assert_eq!(video_profile.get_name().unwrap(), VIDEO_PROFILE_NAME);
|
2018-10-08 04:44:17 +00:00
|
|
|
assert_eq!(
|
|
|
|
video_profile.get_description().unwrap(),
|
|
|
|
VIDEO_PROFILE_DESCRIPTION
|
|
|
|
);
|
2018-05-13 18:31:10 +00:00
|
|
|
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);
|
2018-10-08 04:44:17 +00:00
|
|
|
assert_eq!(
|
|
|
|
video_profile.get_allow_dynamic_output(),
|
|
|
|
ALLOW_DYNAMIC_OUTPUT
|
|
|
|
);
|
2018-05-13 18:31:10 +00:00
|
|
|
assert_eq!(video_profile.is_enabled(), ENABLED);
|
|
|
|
|
2018-10-08 04:44:17 +00:00
|
|
|
let video_profile: EncodingVideoProfile = glib::object::Downcast::downcast(video_profile)
|
|
|
|
.ok()
|
|
|
|
.unwrap();
|
2018-05-13 18:31:10 +00:00
|
|
|
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();
|
|
|
|
|
2018-10-08 04:44:17 +00:00
|
|
|
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", &[]);
|
2018-05-13 18:31:10 +00:00
|
|
|
|
|
|
|
let video_profile = EncodingVideoProfileBuilder::new()
|
|
|
|
.name(VIDEO_PROFILE_NAME)
|
|
|
|
.description(VIDEO_PROFILE_DESCRIPTION)
|
|
|
|
.format(&video_caps)
|
2018-10-08 04:44:17 +00:00
|
|
|
.build()
|
|
|
|
.unwrap();
|
2018-05-13 18:31:10 +00:00
|
|
|
let audio_profile = EncodingAudioProfileBuilder::new()
|
|
|
|
.name(AUDIO_PROFILE_NAME)
|
|
|
|
.description(AUDIO_PROFILE_DESCRIPTION)
|
|
|
|
.format(&audio_caps)
|
2018-10-08 04:44:17 +00:00
|
|
|
.build()
|
|
|
|
.unwrap();
|
2018-05-13 18:31:10 +00:00
|
|
|
|
|
|
|
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)
|
2018-10-08 04:44:17 +00:00
|
|
|
.build()
|
|
|
|
.unwrap();
|
2018-05-13 18:31:10 +00:00
|
|
|
|
|
|
|
assert_eq!(profile.get_name().unwrap(), CONTAINER_PROFILE_NAME);
|
2018-10-08 04:44:17 +00:00
|
|
|
assert_eq!(
|
|
|
|
profile.get_description().unwrap(),
|
|
|
|
CONTAINER_PROFILE_DESCRIPTION
|
|
|
|
);
|
2018-05-13 18:31:10 +00:00
|
|
|
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));
|
|
|
|
}
|
|
|
|
}
|