--- a/media/libcubeb/cubeb-pulse-rs/README_MOZILLA
+++ b/media/libcubeb/cubeb-pulse-rs/README_MOZILLA
@@ -1,8 +1,8 @@
The source from this directory was copied from the cubeb-pulse-rs
git repository using the update.sh script. The only changes
made were those applied by update.sh and the addition of
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 cb7141e3aae5471b3a8ac1e4524f35d04edcdf4e (2018-01-17 13:10:58 +1000)
+The git commit ID used was deadde7d14e0010628471e33a538a0a1e59765ff (2018-01-25 10:00:16 +1000)
--- a/media/libcubeb/cubeb-pulse-rs/cubeb-ffi/src/ffi.rs
+++ b/media/libcubeb/cubeb-pulse-rs/cubeb-ffi/src/ffi.rs
@@ -46,23 +46,34 @@ pub const LAYOUT_3F1_LFE: ChannelLayout
pub const LAYOUT_2F2: ChannelLayout = 13;
pub const LAYOUT_2F2_LFE: ChannelLayout = 14;
pub const LAYOUT_3F2: ChannelLayout = 15;
pub const LAYOUT_3F2_LFE: ChannelLayout = 16;
pub const LAYOUT_3F3R_LFE: ChannelLayout = 17;
pub const LAYOUT_3F4_LFE: ChannelLayout = 18;
pub const LAYOUT_MAX: ChannelLayout = 256;
+
+// These need to match cubeb_device_type
+bitflags! {
+ #[repr(C)]
+ pub struct StreamPrefs : u32 {
+ const STREAM_PREF_NONE = 0x00;
+ const STREAM_PREF_LOOPBACK = 0x01;
+ }
+}
+
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct StreamParams {
pub format: SampleFormat,
pub rate: u32,
pub channels: u32,
pub layout: ChannelLayout,
+ pub prefs: StreamPrefs,
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct Device {
pub output_name: *mut c_char,
pub input_name: *mut c_char,
}
@@ -303,17 +314,17 @@ extern "C" {
output: *mut f32,
in_channels: u32,
out_channels: u32);
}
#[test]
fn bindgen_test_layout_stream_params() {
assert_eq!(::std::mem::size_of::<StreamParams>(),
- 16usize,
+ 20usize,
concat!("Size of: ", stringify!(StreamParams)));
assert_eq!(::std::mem::align_of::<StreamParams>(),
4usize,
concat!("Alignment of ", stringify!(StreamParams)));
assert_eq!(unsafe { &(*(0 as *const StreamParams)).format as *const _ as usize },
0usize,
concat!("Alignment of field: ",
stringify!(StreamParams),
@@ -332,16 +343,22 @@ fn bindgen_test_layout_stream_params() {
"::",
stringify!(channels)));
assert_eq!(unsafe { &(*(0 as *const StreamParams)).layout as *const _ as usize },
12usize,
concat!("Alignment of field: ",
stringify!(StreamParams),
"::",
stringify!(layout)));
+ assert_eq!(unsafe { &(*(0 as *const StreamParams)).prefs as *const _ as usize },
+ 16usize,
+ concat!("Alignment of field: ",
+ stringify!(StreamParams),
+ "::",
+ stringify!(layout)));
}
#[test]
fn bindgen_test_layout_cubeb_device() {
assert_eq!(::std::mem::size_of::<Device>(),
16usize,
concat!("Size of: ", stringify!(Device)));
assert_eq!(::std::mem::align_of::<Device>(),
--- a/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/lib.rs
+++ b/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/lib.rs
@@ -365,17 +365,17 @@ impl SubscriptionEvent {
}
}
pub fn event_facility(self) -> SubscriptionEventFacility {
unsafe { ::std::mem::transmute(self.0 & ffi::PA_SUBSCRIPTION_EVENT_FACILITY_MASK) }
}
pub fn event_type(self) -> SubscriptionEventType {
- unsafe { ::std::mem::transmute(((self.0 & ffi::PA_SUBSCRIPTION_EVENT_TYPE_MASK) >> 4)) }
+ unsafe { ::std::mem::transmute((self.0 & ffi::PA_SUBSCRIPTION_EVENT_TYPE_MASK) >> 4) }
}
}
#[repr(i32)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum SeekMode {
Relative = ffi::PA_SEEK_RELATIVE,
Absolute = ffi::PA_SEEK_ABSOLUTE,
--- a/media/libcubeb/cubeb-pulse-rs/src/backend/context.rs
+++ b/media/libcubeb/cubeb-pulse-rs/src/backend/context.rs
@@ -32,17 +32,17 @@ fn pa_channel_to_cubeb_channel(channel:
ChannelPosition::LowFreqEffects => cubeb::CHANNEL_LFE,
_ => cubeb::CHANNEL_INVALID,
}
}
fn channel_map_to_layout(cm: &pulse::ChannelMap) -> cubeb::ChannelLayout {
use pulse::ChannelPosition;
let mut cubeb_map: cubeb::ChannelMap = Default::default();
- cubeb_map.channels = cm.channels as u32;
+ cubeb_map.channels = u32::from(cm.channels);
for i in 0usize..cm.channels as usize {
cubeb_map.map[i] = pa_channel_to_cubeb_channel(ChannelPosition::try_from(cm.map[i])
.unwrap_or(ChannelPosition::Invalid));
}
unsafe { cubeb::cubeb_channel_map_to_layout(&cubeb_map) }
}
#[derive(Debug)]
@@ -171,16 +171,17 @@ impl Context {
pub fn destroy(&mut self) {
self.context_destroy();
if !self.mainloop.is_null() {
self.mainloop.stop();
}
}
+ #[cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))]
pub fn new_stream(&mut self,
stream_name: &CStr,
input_device: cubeb::DeviceId,
input_stream_params: Option<cubeb::StreamParams>,
output_device: cubeb::DeviceId,
output_stream_params: Option<cubeb::StreamParams>,
latency_frames: u32,
data_callback: cubeb::DataCallback,
@@ -200,17 +201,17 @@ impl Context {
latency_frames,
data_callback,
state_callback,
user_ptr)
}
pub fn max_channel_count(&self) -> Result<u32> {
match self.default_sink_info {
- Some(ref info) => Ok(info.channel_map.channels as u32),
+ Some(ref info) => Ok(u32::from(info.channel_map.channels)),
None => Err(cubeb::ERROR),
}
}
pub fn preferred_sample_rate(&self) -> Result<u32> {
match self.default_sink_info {
Some(ref info) => Ok(info.sample_spec.rate),
None => Err(cubeb::ERROR),
@@ -271,17 +272,17 @@ impl Context {
friendly_name: friendly_name,
group_id: group_id,
vendor_name: vendor_name,
devtype: cubeb::DeviceType::OUTPUT,
state: ctx.state_from_port(info.active_port),
preferred: preferred,
format: cubeb::DeviceFmt::all(),
default_format: pulse_format_to_cubeb_format(info.sample_spec.format),
- max_channels: info.channel_map.channels as u32,
+ max_channels: u32::from(info.channel_map.channels),
min_rate: 1,
max_rate: PA_RATE_MAX,
default_rate: info.sample_spec.rate,
latency_lo: 0,
latency_hi: 0,
};
list_data.devinfo.push(devinfo);
}
@@ -327,26 +328,25 @@ impl Context {
friendly_name: friendly_name,
group_id: group_id,
vendor_name: vendor_name,
devtype: cubeb::DeviceType::INPUT,
state: ctx.state_from_port(info.active_port),
preferred: preferred,
format: cubeb::DeviceFmt::all(),
default_format: pulse_format_to_cubeb_format(info.sample_spec.format),
- max_channels: info.channel_map.channels as u32,
+ max_channels: u32::from(info.channel_map.channels),
min_rate: 1,
max_rate: PA_RATE_MAX,
default_rate: info.sample_spec.rate,
latency_lo: 0,
latency_hi: 0,
};
list_data.devinfo.push(devinfo);
-
}
fn default_device_names(_: &pulse::Context, info: &pulse::ServerInfo, user_data: *mut c_void) {
let list_data = unsafe { &mut *(user_data as *mut PulseDevListData) };
list_data.default_sink_name = super::try_cstr_from(info.default_sink_name)
.map(|s| s.to_owned())
.unwrap_or_default();
@@ -398,17 +398,17 @@ impl Context {
pub fn device_collection_destroy(&self, collection: *mut cubeb::DeviceCollection) {
debug_assert!(!collection.is_null());
unsafe {
let coll = *collection;
let mut devices = Vec::from_raw_parts(coll.device as *mut cubeb::DeviceInfo,
coll.count,
coll.count);
- for dev in devices.iter_mut() {
+ for dev in &mut devices {
if !dev.group_id.is_null() {
let _ = CString::from_raw(dev.group_id as *mut _);
}
if !dev.vendor_name.is_null() {
let _ = CString::from_raw(dev.vendor_name as *mut _);
}
if !dev.friendly_name.is_null() {
let _ = CString::from_raw(dev.friendly_name as *mut _);
@@ -553,28 +553,25 @@ impl Context {
fn context_destroy(&mut self) {
fn drain_complete(_: &pulse::Context, u: *mut c_void) {
let ctx = unsafe { &*(u as *mut Context) };
ctx.mainloop.signal();
}
let context_ptr: *mut c_void = self as *mut _ as *mut _;
- match self.context.take() {
- Some(ctx) => {
- self.mainloop.lock();
- if let Ok(o) = ctx.drain(drain_complete, context_ptr) {
- self.operation_wait(None, &o);
- }
- ctx.clear_state_callback();
- ctx.disconnect();
- ctx.unref();
- self.mainloop.unlock();
- },
- _ => {},
+ if let Some(ctx) = self.context.take() {
+ self.mainloop.lock();
+ if let Ok(o) = ctx.drain(drain_complete, context_ptr) {
+ self.operation_wait(None, &o);
+ }
+ ctx.clear_state_callback();
+ ctx.disconnect();
+ ctx.unref();
+ self.mainloop.unlock();
}
}
pub fn operation_wait<'a, S>(&self, s: S, o: &pulse::Operation) -> bool
where S: Into<Option<&'a pulse::Stream>>
{
let stream = s.into();
while o.get_state() == PA_OPERATION_RUNNING {
--- a/media/libcubeb/cubeb-pulse-rs/src/backend/stream.rs
+++ b/media/libcubeb/cubeb-pulse-rs/src/backend/stream.rs
@@ -29,17 +29,17 @@ fn cubeb_channel_to_pa_channel(channel:
PA_CHANNEL_POSITION_SIDE_LEFT, // CHANNEL_LS
PA_CHANNEL_POSITION_SIDE_RIGHT, // CHANNEL_RS
PA_CHANNEL_POSITION_REAR_LEFT, // CHANNEL_RLS
PA_CHANNEL_POSITION_REAR_CENTER, // CHANNEL_RCENTER
PA_CHANNEL_POSITION_REAR_RIGHT, // CHANNEL_RRS
PA_CHANNEL_POSITION_LFE // CHANNEL_LFE
];
- let idx: i32 = channel.into();
+ let idx: i32 = channel;
MAP[idx as usize]
}
fn layout_to_channel_map(layout: cubeb::ChannelLayout) -> pulse::ChannelMap {
assert_ne!(layout, cubeb::LAYOUT_UNDEFINED);
let order = cubeb::mixer::channel_index_to_order(layout);
@@ -84,16 +84,17 @@ pub struct Stream<'ctx> {
impl<'ctx> Drop for Stream<'ctx> {
fn drop(&mut self) {
self.destroy();
}
}
impl<'ctx> Stream<'ctx> {
+ #[cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))]
pub fn new(context: &'ctx Context,
stream_name: &CStr,
input_device: cubeb::DeviceId,
input_stream_params: Option<cubeb::StreamParams>,
output_device: cubeb::DeviceId,
output_stream_params: Option<cubeb::StreamParams>,
latency_frames: u32,
data_callback: cubeb::DataCallback,
@@ -109,20 +110,18 @@ impl<'ctx> Stream<'ctx> {
stm.context.mainloop.signal();
}
fn read_data(s: &pulse::Stream, nbytes: usize, u: *mut c_void) {
fn read_from_input(s: &pulse::Stream, buffer: *mut *const c_void, size: *mut usize) -> i32 {
let readable_size: i32 = s.readable_size()
.and_then(|s| Ok(s as i32))
.unwrap_or(-1);
- if readable_size > 0 {
- if unsafe { s.peek(buffer, size).is_err() } {
- return -1;
- }
+ if readable_size > 0 && unsafe { s.peek(buffer, size).is_err() } {
+ return -1;
}
readable_size
}
logv!("Input callback buffer size {}", nbytes);
let stm = unsafe { &mut *(u as *mut Stream) };
if stm.shutdown {
return;
@@ -225,17 +224,16 @@ impl<'ctx> Stream<'ctx> {
stm.output_stream = Some(s);
},
Err(e) => {
stm.context.mainloop.unlock();
stm.destroy();
return Err(e);
},
}
-
}
// Set up input stream
if let Some(ref stream_params) = input_stream_params {
match Stream::stream_init(context, stream_params, stream_name) {
Ok(s) => {
stm.input_sample_spec = *s.get_sample_spec();
@@ -253,17 +251,16 @@ impl<'ctx> Stream<'ctx> {
stm.input_stream = Some(s);
},
Err(e) => {
stm.context.mainloop.unlock();
stm.destroy();
return Err(e);
},
}
-
}
let r = if stm.wait_until_ready() {
/* force a timing update now, otherwise timing info does not become valid
until some point after initialization has completed. */
stm.update_timing_info()
} else {
false
@@ -304,41 +301,35 @@ impl<'ctx> Stream<'ctx> {
Ok(stm)
}
fn destroy(&mut self) {
self.cork(CorkState::cork());
self.context.mainloop.lock();
{
- match self.output_stream.take() {
- Some(stm) => {
- if !self.drain_timer.is_null() {
- /* there's no pa_rttime_free, so use this instead. */
- self.context
- .mainloop
- .get_api()
- .time_free(self.drain_timer);
- }
- stm.clear_state_callback();
- stm.clear_write_callback();
- let _ = stm.disconnect();
- stm.unref();
- },
- _ => {},
+ if let Some(stm) = self.output_stream.take() {
+ if !self.drain_timer.is_null() {
+ /* there's no pa_rttime_free, so use this instead. */
+ self.context
+ .mainloop
+ .get_api()
+ .time_free(self.drain_timer);
+ }
+ stm.clear_state_callback();
+ stm.clear_write_callback();
+ let _ = stm.disconnect();
+ stm.unref();
}
- match self.input_stream.take() {
- Some(stm) => {
- stm.clear_state_callback();
- stm.clear_read_callback();
- let _ = stm.disconnect();
- stm.unref();
- },
- _ => {},
+ if let Some(stm) = self.input_stream.take() {
+ stm.clear_state_callback();
+ stm.clear_read_callback();
+ let _ = stm.disconnect();
+ stm.unref();
}
}
self.context.mainloop.unlock();
}
pub fn start(&mut self) -> i32 {
fn output_preroll(_: &pulse::MainloopApi, u: *mut c_void) {
let stm = unsafe { &mut *(u as *mut Stream) };
@@ -411,17 +402,17 @@ impl<'ctx> Stream<'ctx> {
}
pub fn latency(&self) -> Result<u32> {
match self.output_stream {
None => Err(cubeb::ERROR),
Some(ref stm) => {
match stm.get_latency() {
Ok(StreamLatency::Positive(r_usec)) => {
- let latency = (r_usec * self.output_sample_spec.rate as pa_usec_t / PA_USEC_PER_SEC) as u32;
+ let latency = (r_usec * pa_usec_t::from(self.output_sample_spec.rate) / PA_USEC_PER_SEC) as u32;
Ok(latency)
},
Ok(_) => {
panic!("Can not handle negative latency values.");
},
Err(_) => Err(cubeb::ERROR),
}
},
@@ -446,18 +437,18 @@ impl<'ctx> Stream<'ctx> {
_ => pulse::SinkFlags::empty(),
}
};
if flags.contains(pulse::SinkFlags::FLAT_VOLUME) {
self.volume = volume;
} else {
let channels = stm.get_sample_spec().channels;
- let vol = pulse::sw_volume_from_linear(volume as f64);
- cvol.set(channels as u32, vol);
+ let vol = pulse::sw_volume_from_linear(f64::from(volume));
+ cvol.set(u32::from(channels), vol);
let index = stm.get_index();
let context_ptr = self.context as *const _ as *mut _;
if let Ok(o) = context.set_sink_input_volume(index, &cvol, context_success, context_ptr) {
self.context.operation_wait(stm, &o);
}
}
@@ -559,16 +550,20 @@ impl<'ctx> Stream<'ctx> {
}
}
fn stream_init(context: &pulse::Context,
stream_params: &cubeb::StreamParams,
stream_name: &CStr)
-> Result<pulse::Stream> {
+ if stream_params.prefs == cubeb::StreamPrefs::STREAM_PREF_LOOPBACK {
+ return Err(cubeb::ERROR_NOT_SUPPORTED);
+ }
+
fn to_pulse_format(format: cubeb::SampleFormat) -> pulse::SampleFormat {
match format {
cubeb::SAMPLE_S16LE => pulse::SampleFormat::Signed16LE,
cubeb::SAMPLE_S16BE => pulse::SampleFormat::Signed16BE,
cubeb::SAMPLE_FLOAT32LE => pulse::SampleFormat::Float32LE,
cubeb::SAMPLE_FLOAT32BE => pulse::SampleFormat::Float32BE,
_ => pulse::SampleFormat::Invalid,
}
@@ -684,16 +679,17 @@ impl<'ctx> Stream<'ctx> {
if !wait_until_io_stream_ready(stm, &self.context.mainloop) {
return false;
}
}
true
}
+ #[cfg_attr(feature = "cargo-clippy", allow(cyclomatic_complexity))]
fn trigger_user_callback(&mut self, input_data: *const c_void, nbytes: usize) {
fn drained_cb(a: &pulse::MainloopApi, e: *mut pa_time_event, _tv: &pulse::TimeVal, u: *mut c_void) {
let stm = unsafe { &mut *(u as *mut Stream) };
debug_assert_eq!(stm.drain_timer, e);
stm.state_change_callback(cubeb::STATE_DRAINED);
/* there's no pa_rttime_free, so use this instead. */
a.time_free(stm.drain_timer);
stm.drain_timer = ptr::null_mut();