Bug 1399009 - Update cubeb-pulse-rs to a386d91... r=kinetik

MozReview-Commit-ID: BnJpMCuDPOf

--HG--
extra : rebase_source : 37c652b29cc4732153ab5b8a45c0b02837026282
This commit is contained in:
Dan Glastonbury 2017-09-12 15:31:18 +10:00
Родитель 3d73733afa
Коммит 660a0a0bf8
8 изменённых файлов: 96 добавлений и 21 удалений

Просмотреть файл

@ -5,4 +5,4 @@ Makefile.in build files for the Mozilla build system.
The cubeb-pulse-rs git repository is: https://github.com/djg/cubeb-pulse-rs.git
The git commit ID used was 3b8cfba161cec66bee6a755bce102466baa92ddb (2017-07-07 14:57:07 +1000)
The git commit ID used was a386d91d7f34e6d3a949ee4fa44e848e29634587 (2017-09-05 13:34:32 +1000)

Просмотреть файл

@ -2,6 +2,7 @@
use super::*;
#[cfg(feature = "dlopen")]
macro_rules! cstr {
($x:expr) => { concat!($x, "\0").as_bytes().as_ptr() as *const c_char }
}

Просмотреть файл

@ -294,6 +294,11 @@ impl Into<ffi::pa_stream_flags_t> for StreamFlags {
}
}
pub enum StreamLatency {
Positive(u64),
Negative(u64),
}
bitflags!{
pub flags SubscriptionMask : u32 {
const SUBSCRIPTION_MASK_SINK = ffi::PA_SUBSCRIPTION_MASK_SINK,

Просмотреть файл

@ -329,11 +329,18 @@ impl Stream {
error_result!(usec, r)
}
pub fn get_latency(&self) -> Result<(u64, bool)> {
pub fn get_latency(&self) -> Result<StreamLatency> {
let mut usec: u64 = 0;
let mut negative: i32 = 0;
let r = unsafe { ffi::pa_stream_get_latency(self.raw_mut(), &mut usec, &mut negative) };
error_result!((usec, negative != 0), r)
error_result!(
if negative == 0 {
StreamLatency::Positive(usec)
} else {
StreamLatency::Negative(usec)
},
r
)
}
pub fn get_sample_spec(&self) -> &SampleSpec {

Просмотреть файл

@ -14,6 +14,7 @@ use std::ffi::{CStr, CString};
use std::mem;
use std::os::raw::{c_char, c_void};
use std::ptr;
use std::cell::RefCell;
fn pa_channel_to_cubeb_channel(channel: pulse::ChannelPosition) -> cubeb::Channel {
use pulse::ChannelPosition;
@ -65,6 +66,7 @@ pub struct Context {
pub version_0_9_8: bool,
#[cfg(feature = "pulse-dlopen")]
pub libpulse: LibLoader,
devids: RefCell<Intern>,
}
impl Drop for Context {
@ -93,6 +95,7 @@ impl Context {
error: true,
version_0_9_8: false,
version_2_0_0: false,
devids: RefCell::new(Intern::new()),
});
Ok(ctx)
@ -111,6 +114,7 @@ impl Context {
error: true,
version_0_9_8: false,
version_2_0_0: false,
devids: RefCell::new(Intern::new()),
}))
}
@ -248,18 +252,17 @@ impl Context {
_ => ptr::null_mut(),
};
let info_name = unsafe { CStr::from_ptr(info.name) }.to_owned();
let info_name = unsafe { CStr::from_ptr(info.name) };
let info_description = unsafe { CStr::from_ptr(info.description) }.to_owned();
let preferred = if info_name == list_data.default_sink_name {
let preferred = if *info_name == *list_data.default_sink_name {
cubeb::DEVICE_PREF_ALL
} else {
cubeb::DevicePref::empty()
};
let ctx = &(*list_data.context);
let device_id = info_name.into_raw();
let device_id = ctx.devids.borrow_mut().add(info_name);
let friendly_name = info_description.into_raw();
let devinfo = cubeb::DeviceInfo {
device_id: device_id,
@ -305,17 +308,17 @@ impl Context {
_ => ptr::null_mut(),
};
let info_name = unsafe { CStr::from_ptr(info.name) }.to_owned();
let info_name = unsafe { CStr::from_ptr(info.name) };
let info_description = unsafe { CStr::from_ptr(info.description) }.to_owned();
let preferred = if info_name == list_data.default_source_name {
let preferred = if *info_name == *list_data.default_source_name {
cubeb::DEVICE_PREF_ALL
} else {
cubeb::DevicePref::empty()
};
let ctx = &(*list_data.context);
let device_id = info_name.into_raw();
let device_id = ctx.devids.borrow_mut().add(info_name);
let friendly_name = info_description.into_raw();
let devinfo = cubeb::DeviceInfo {
device_id: device_id,
@ -359,13 +362,13 @@ impl Context {
self.operation_wait(None, &o);
}
if devtype == cubeb::DEVICE_TYPE_OUTPUT {
if devtype.contains(cubeb::DEVICE_TYPE_OUTPUT) {
if let Ok(o) = context.get_sink_info_list(add_output_device, &mut user_data as *mut _ as *mut _) {
self.operation_wait(None, &o);
}
}
if devtype == cubeb::DEVICE_TYPE_INPUT {
if devtype.contains(cubeb::DEVICE_TYPE_INPUT) {
if let Ok(o) = context.get_source_info_list(add_input_device, &mut user_data as *mut _ as *mut _) {
self.operation_wait(None, &o);
}
@ -397,9 +400,6 @@ impl Context {
coll.count,
coll.count);
for dev in devices.iter_mut() {
if !dev.device_id.is_null() {
let _ = CString::from_raw(dev.device_id as *mut _);
}
if !dev.group_id.is_null() {
let _ = CString::from_raw(dev.group_id as *mut _);
}

Просмотреть файл

@ -0,0 +1,58 @@
// Copyright © 2017 Mozilla Foundation
//
// This program is made available under an ISC-style license. See the
// accompanying file LICENSE for details.
use std::ffi::{CStr, CString};
use std::os::raw::c_char;
#[derive(Debug)]
pub struct Intern {
vec: Vec<Box<CString>>
}
impl Intern {
pub fn new() -> Intern {
Intern {
vec: Vec::new()
}
}
pub fn add(&mut self, string: &CStr) -> *const c_char {
fn eq(s1: &CStr, s2: &CStr) -> bool { s1 == s2 }
for s in &self.vec {
if eq(s, string) {
return s.as_ptr();
}
}
self.vec.push(Box::new(string.to_owned()));
self.vec.last().unwrap().as_ptr()
}
}
#[cfg(test)]
mod tests {
use std::ffi::CStr;
use super::Intern;
#[test]
fn intern() {
fn cstr(str: &[u8]) -> &CStr {
CStr::from_bytes_with_nul(str).unwrap()
}
let mut intern = Intern::new();
let foo_ptr = intern.add(cstr(b"foo\0"));
let bar_ptr = intern.add(cstr(b"bar\0"));
assert!(!foo_ptr.is_null());
assert!(!bar_ptr.is_null());
assert!(foo_ptr != bar_ptr);
assert!(foo_ptr == intern.add(cstr(b"foo\0")));
assert!(foo_ptr != intern.add(cstr(b"fo\0")));
assert!(foo_ptr != intern.add(cstr(b"fool\0")));
assert!(foo_ptr != intern.add(cstr(b"not foo\0")));
}
}

Просмотреть файл

@ -6,6 +6,7 @@
mod context;
mod cork_state;
mod stream;
mod intern;
use std::os::raw::c_char;
use std::ffi::CStr;
@ -15,6 +16,7 @@ pub type Result<T> = ::std::result::Result<T, i32>;
pub use self::context::Context;
pub use self::stream::Device;
pub use self::stream::Stream;
use self::intern::Intern;
// helper to convert *const c_char to Option<CStr>
fn try_cstr_from<'str>(s: *const c_char) -> Option<&'str CStr> {

Просмотреть файл

@ -6,7 +6,7 @@
use backend::*;
use backend::cork_state::CorkState;
use cubeb;
use pulse::{self, CVolumeExt, ChannelMapExt, SampleSpecExt, USecExt};
use pulse::{self, CVolumeExt, ChannelMapExt, SampleSpecExt, StreamLatency, USecExt};
use pulse_ffi::*;
use std::ffi::{CStr, CString};
use std::os::raw::{c_long, c_void};
@ -415,11 +415,13 @@ impl<'ctx> Stream<'ctx> {
None => Err(cubeb::ERROR),
Some(ref stm) => {
match stm.get_latency() {
Ok((r_usec, negative)) => {
debug_assert!(negative);
Ok(StreamLatency::Positive(r_usec)) => {
let latency = (r_usec * self.output_sample_spec.rate as pa_usec_t / PA_USEC_PER_SEC) as u32;
Ok(latency)
},
Ok(_) => {
panic!("Can not handle negative latency values.");
},
Err(_) => Err(cubeb::ERROR),
}
},
@ -762,9 +764,9 @@ impl<'ctx> Stream<'ctx> {
if (got as usize) < size / frame_size {
let latency = match stm.get_latency() {
Ok((l, negative)) => {
assert_ne!(negative, true);
l
Ok(StreamLatency::Positive(l)) => l,
Ok(_) => {
panic!("Can not handle negative latency values.");
},
Err(e) => {
debug_assert_eq!(e, pulse::ErrorCode::from_error_code(PA_ERR_NODATA));