Use num_rational instead of home-baked (u32, u32) fractions

This commit is contained in:
Sebastian Dröge 2017-01-15 20:56:20 +01:00
parent 620cf7c5f7
commit aa54f1a4e6
5 changed files with 34 additions and 25 deletions

View file

@ -31,7 +31,7 @@ use gst_plugin::utils;
use gst_plugin::utils::Element;
use gst_plugin::log::*;
use gst_plugin::caps::Caps;
use gst_plugin::value;
use gst_plugin::value::Rational32;
use gst_plugin::bytes::*;
use slog::*;
@ -261,8 +261,8 @@ struct VideoFormat {
format: flavors::CodecId,
width: Option<u32>,
height: Option<u32>,
pixel_aspect_ratio: Option<(u32, u32)>,
framerate: Option<(u32, u32)>,
pixel_aspect_ratio: Option<Rational32>,
framerate: Option<Rational32>,
bitrate: Option<u32>,
avc_sequence_header: Option<Buffer>,
}
@ -354,17 +354,15 @@ impl VideoFormat {
}
if let Some(par) = self.pixel_aspect_ratio {
if par.0 != 0 && par.1 != 0 {
caps.as_mut().map(|c| {
c.set_simple(&[("pixel-aspect-ratio", &(par.0 as i32, par.1 as i32).into())])
});
if *par.numer() != 0 && par.numer() != par.denom() {
caps.as_mut().map(|c| c.set_simple(&[("pixel-aspect-ratio", &par.into())]));
}
}
if let Some(fps) = self.framerate {
if fps.1 != 0 {
if *fps.numer() != 0 {
caps.as_mut()
.map(|c| c.set_simple(&[("framerate", &(fps.0 as i32, fps.1 as i32).into())]));
.map(|c| c.set_simple(&[("framerate", &fps.into())]));
}
}
@ -397,8 +395,8 @@ struct Metadata {
video_width: Option<u32>,
video_height: Option<u32>,
video_pixel_aspect_ratio: Option<(u32, u32)>,
video_framerate: Option<(u32, u32)>,
video_pixel_aspect_ratio: Option<Rational32>,
video_framerate: Option<Rational32>,
video_bitrate: Option<u32>,
}
@ -456,15 +454,15 @@ impl Metadata {
metadata.video_height = Some(height as u32);
}
("framerate", &flavors::ScriptDataValue::Number(framerate)) if framerate >= 0.0 => {
if let Some((n, d)) = utils::f64_to_fraction(framerate) {
metadata.video_framerate = Some((n as u32, d as u32));
if let Some(framerate) = utils::f64_to_fraction(framerate) {
metadata.video_framerate = Some(framerate);
}
}
("AspectRatioX", &flavors::ScriptDataValue::Number(par_x)) => {
par_n = Some(par_x as u32);
("AspectRatioX", &flavors::ScriptDataValue::Number(par_x)) if par_x > 0.0 => {
par_n = Some(par_x as i32);
}
("AspectRatioY", &flavors::ScriptDataValue::Number(par_y)) => {
par_d = Some(par_y as u32);
("AspectRatioY", &flavors::ScriptDataValue::Number(par_y)) if par_y > 0.0 => {
par_d = Some(par_y as i32);
}
("videodatarate", &flavors::ScriptDataValue::Number(datarate)) => {
metadata.video_bitrate = Some((datarate * 1024.0) as u32);
@ -474,7 +472,7 @@ impl Metadata {
}
if let (Some(par_n), Some(par_d)) = (par_n, par_d) {
metadata.video_pixel_aspect_ratio = Some((par_n, par_d));
metadata.video_pixel_aspect_ratio = Some(Rational32::new(par_n, par_d));
}
metadata

View file

@ -13,6 +13,7 @@ bitflags = "0.7"
slog = { version = "1.3", features = ["max_level_trace"] }
lazy_static = "0.2"
byteorder = "1.0"
num-rational = { version = "0.1", default-features = false, features = [] }
[build-dependencies]
gcc = "0.3"

View file

@ -25,6 +25,7 @@ extern crate slog;
#[macro_use]
extern crate lazy_static;
extern crate byteorder;
extern crate num_rational;
#[macro_use]
pub mod utils;

View file

@ -20,6 +20,7 @@ use libc::c_char;
use std::os::raw::c_void;
use std::ffi::CString;
use std::i32;
use num_rational::Rational32;
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
@ -94,7 +95,7 @@ pub unsafe extern "C" fn cstring_drop(ptr: *mut c_char) {
let _ = CString::from_raw(ptr);
}
pub fn f64_to_fraction(val: f64) -> Option<(i32, i32)> {
pub fn f64_to_fraction(val: f64) -> Option<Rational32> {
// Continued fractions algorithm
// http://mathforum.org/dr.math/faq/faq.fractions.html#decfrac
@ -168,9 +169,9 @@ pub fn f64_to_fraction(val: f64) -> Option<(i32, i32)> {
// Make negative again if needed
if negative {
Some((-(n1 as i32), d1 as i32))
Some(Rational32::new(-(n1 as i32), d1 as i32))
} else {
Some((n1 as i32, d1 as i32))
Some(Rational32::new(n1 as i32, d1 as i32))
}
}

View file

@ -20,6 +20,8 @@ use std::os::raw::c_void;
use std::ffi::CString;
use std::mem;
pub use num_rational::Rational32;
use buffer::*;
#[derive(Debug, PartialEq, Eq, Clone)]
@ -27,7 +29,7 @@ pub enum Value {
Bool(bool),
Int(i32),
String(String),
Fraction(i32, i32),
Fraction(Rational32),
Buffer(Buffer),
Array(Vec<Value>),
}
@ -75,9 +77,9 @@ impl Value {
g_value_init(&mut gvalue as *mut GValue, TYPE_STRING);
g_value_set_string(&mut gvalue as *mut GValue, v_cstr.as_ptr());
},
Value::Fraction(v_n, v_d) => unsafe {
Value::Fraction(ref v) => unsafe {
g_value_init(&mut gvalue as *mut GValue, gst_fraction_get_type());
gst_value_set_fraction(&mut gvalue as *mut GValue, v_n, v_d);
gst_value_set_fraction(&mut gvalue as *mut GValue, *v.numer(), *v.denom());
},
Value::Buffer(ref buffer) => unsafe {
g_value_init(&mut gvalue as *mut GValue, gst_buffer_get_type());
@ -136,9 +138,15 @@ impl<'a> From<&'a str> for Value {
}
}
impl From<Rational32> for Value {
fn from(f: Rational32) -> Value {
Value::Fraction(f)
}
}
impl From<(i32, i32)> for Value {
fn from((f_n, f_d): (i32, i32)) -> Value {
Value::Fraction(f_n, f_d)
Value::Fraction(Rational32::new(f_n, f_d))
}
}