зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1399009 - Update cubeb-pulse-rs to a386d91... r=kinetik
MozReview-Commit-ID: BnJpMCuDPOf --HG-- extra : rebase_source : 37c652b29cc4732153ab5b8a45c0b02837026282
This commit is contained in:
Родитель
3d73733afa
Коммит
660a0a0bf8
|
@ -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));
|
||||
|
|
Загрузка…
Ссылка в новой задаче