Add support for Fractions

This commit is contained in:
Sebastian Dröge 2017-07-12 13:25:11 +03:00
parent 8421cec1ee
commit 9c357abf1a
6 changed files with 259 additions and 5 deletions

26
Cargo.lock generated
View file

@ -8,6 +8,7 @@ dependencies = [
"gobject-sys 0.3.4 (git+https://github.com/gtk-rs/sys)",
"gstreamer-sys 0.1.1 (git+https://github.com/sdroege/gstreamer-sys)",
"libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)",
"num-rational 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -78,6 +79,28 @@ name = "libc"
version = "0.2.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "num-integer"
version = "0.1.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-traits 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-rational"
version = "0.1.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-integer 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-traits"
version = "0.1.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "pkg-config"
version = "0.3.9"
@ -91,4 +114,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum gstreamer-sys 0.1.1 (git+https://github.com/sdroege/gstreamer-sys)" = "<none>"
"checksum lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf"
"checksum libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)" = "30885bcb161cf67054244d10d4a7f4835ffd58773bc72e07d35fecf472295503"
"checksum num-integer 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "ef1a4bf6f9174aa5783a9b4cc892cacd11aebad6c69ad027a0b65c6ca5f8aa37"
"checksum num-rational 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "33c881e104a26e1accc09449374c095ff2312c8e0c27fab7bbefe16eac7c776d"
"checksum num-traits 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "1708c0628602a98b52fad936cf3edb9a107af06e52e49fdf0707e884456a6af6"
"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"

View file

@ -10,6 +10,7 @@ glib-sys = { version = "0.3.4", git = "https://github.com/gtk-rs/sys" }
gobject-sys = { version = "0.3.4", git = "https://github.com/gtk-rs/sys" }
gstreamer-sys = { version = "0.1.1", git = "https://github.com/sdroege/gstreamer-sys", features = ["v1_8"] }
glib = { version = "0.1.3", git = "https://github.com/gtk-rs/glib" }
num-rational = { version = "0.1.38", default-features = false, features = [] }
[features]
v1_10 = ["gstreamer-sys/v1_10", "v1_8"]

View file

@ -225,6 +225,7 @@ unsafe impl Send for CapsRef {}
mod tests {
use super::*;
use glib::ToValue;
use Fraction;
#[test]
fn test_simple() {
@ -236,15 +237,15 @@ mod tests {
("int", &12.to_value()),
("bool", &true.to_value()),
("string", &"bla".to_value()),
//("fraction", (1, 2).into()),
("fraction", &Fraction::new(1, 2).to_value()),
//("array", vec![1.into(), 2.into()].into()),
],
);
assert_eq!(
caps.to_string(),
"foo/bar, int=(int)12, bool=(boolean)true, string=(string)bla"
"foo/bar, int=(int)12, bool=(boolean)true, string=(string)bla, fraction=(fraction)1/2"
); //, \
// fraction=(fraction)1/2, array=(int)< 1, 2 >"
// array=(int)< 1, 2 >"
//);
let s = caps.get_structure(0).unwrap();
@ -256,7 +257,7 @@ mod tests {
("int", &12.to_value()),
("bool", &true.to_value()),
("string", &"bla".to_value()),
//("fraction", (1, 2).into()),
("fraction", &Fraction::new(1, 2).to_value()),
//("array", vec![1.into(), 2.into()].into()),
],
).as_ref()

View file

@ -17,6 +17,8 @@ extern crate gstreamer_sys as ffi;
#[macro_use]
extern crate glib;
extern crate num_rational;
use glib::translate::{from_glib, from_glib_full};
macro_rules! callback_guard {
@ -60,6 +62,9 @@ mod bin;
mod bus;
pub use bin::BinExtManual;
mod value;
pub use value::*;
use std::ptr;
pub fn init() -> Result<(), glib::Error> {

View file

@ -1951,7 +1951,10 @@ impl<'a> RedirectBuilder<'a> {
}
}
pub fn entries(self, entries: &'a [(&'a str, Option<&'a TagList>, Option<&'a Structure>)]) -> Self {
pub fn entries(
self,
entries: &'a [(&'a str, Option<&'a TagList>, Option<&'a Structure>)],
) -> Self {
Self {
entries: Some(entries),
..self

218
gstreamer/src/value.rs Normal file
View file

@ -0,0 +1,218 @@
// Copyright (C) 2017 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.
use num_rational::Rational32;
use std::fmt;
use std::ops;
use std::mem;
use glib;
use glib::value::{Value, FromValue, FromValueOptional, ToValue, SetValue, SetValueOptional};
use glib::translate::{from_glib, ToGlibPtr, ToGlibPtrMut};
use ffi;
use gobject_ffi;
#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub struct Fraction(pub Rational32);
impl Fraction {
pub fn new(num: i32, den: i32) -> Fraction {
(num, den).into()
}
pub fn approximate_f32(x: f32) -> Option<Fraction> {
Rational32::approximate_float(x).map(|r| r.into())
}
pub fn approximate_f64(x: f64) -> Option<Fraction> {
Rational32::approximate_float(x).map(|r| r.into())
}
}
impl fmt::Display for Fraction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)
}
}
impl ops::Deref for Fraction {
type Target = Rational32;
fn deref(&self) -> &Rational32 {
&self.0
}
}
impl ops::DerefMut for Fraction {
fn deref_mut(&mut self) -> &mut Rational32 {
&mut self.0
}
}
impl AsRef<Rational32> for Fraction {
fn as_ref(&self) -> &Rational32 {
&self.0
}
}
impl ops::Mul<Fraction> for Fraction {
type Output = Fraction;
fn mul(self, other: Fraction) -> Fraction {
Fraction(self.0.mul(other.0))
}
}
impl ops::Mul<i32> for Fraction {
type Output = Fraction;
fn mul(self, other: i32) -> Fraction {
self.mul(Fraction::from(other))
}
}
impl ops::Div<Fraction> for Fraction {
type Output = Fraction;
fn div(self, other: Fraction) -> Fraction {
Fraction(self.0.div(other.0))
}
}
impl ops::Div<i32> for Fraction {
type Output = Fraction;
fn div(self, other: i32) -> Fraction {
self.div(Fraction::from(other))
}
}
impl ops::Add<Fraction> for Fraction {
type Output = Fraction;
fn add(self, other: Fraction) -> Fraction {
Fraction(self.0.add(other.0))
}
}
impl ops::Add<i32> for Fraction {
type Output = Fraction;
fn add(self, other: i32) -> Fraction {
self.add(Fraction::from(other))
}
}
impl ops::Sub<Fraction> for Fraction {
type Output = Fraction;
fn sub(self, other: Fraction) -> Fraction {
Fraction(self.0.sub(other.0))
}
}
impl ops::Sub<i32> for Fraction {
type Output = Fraction;
fn sub(self, other: i32) -> Fraction {
self.sub(Fraction::from(other))
}
}
impl ops::Rem<Fraction> for Fraction {
type Output = Fraction;
fn rem(self, other: Fraction) -> Fraction {
Fraction(self.0.rem(other.0))
}
}
impl ops::Rem<i32> for Fraction {
type Output = Fraction;
fn rem(self, other: i32) -> Fraction {
self.rem(Fraction::from(other))
}
}
impl ops::Neg for Fraction {
type Output = Fraction;
fn neg(self) -> Fraction {
Fraction(self.0.neg())
}
}
impl From<i32> for Fraction {
fn from(x: i32) -> Fraction {
Fraction(x.into())
}
}
impl From<(i32, i32)> for Fraction {
fn from(x: (i32, i32)) -> Fraction {
Fraction(x.into())
}
}
impl Into<(i32, i32)> for Fraction {
fn into(self) -> (i32, i32) {
self.0.into()
}
}
impl From<Rational32> for Fraction {
fn from(x: Rational32) -> Fraction {
Fraction(x)
}
}
impl From<Fraction> for Rational32 {
fn from(x: Fraction) -> Rational32 {
x.0
}
}
impl glib::types::StaticType for Fraction {
fn static_type() -> glib::types::Type {
unsafe { from_glib(ffi::gst_fraction_get_type()) }
}
}
impl<'a> FromValue<'a> for Fraction {
unsafe fn from_value(v: &'a Value) -> Fraction {
let n = ffi::gst_value_get_fraction_numerator(v.to_glib_none().0);
let d = ffi::gst_value_get_fraction_denominator(v.to_glib_none().0);
Fraction::new(n, d)
}
}
impl<'a> FromValueOptional<'a> for Fraction {
unsafe fn from_value_optional(v: &'a Value) -> Option<Fraction> {
Some(Fraction::from_value(v))
}
}
impl SetValue for Fraction {
unsafe fn set_value(v: &mut Value, f: &Self) {
ffi::gst_value_set_fraction(v.to_glib_none_mut().0, *f.numer(), *f.denom());
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_simple() {
let f: Fraction = (1, 2).into();
println!("{}", f * 2);
}
}