Bug 1432869 - Update cubeb-pulse-rs to git commit deadde7. r?kamidphish draft
authorBryce Van Dyk <bvandyk@mozilla.com>
Thu, 25 Jan 2018 10:51:03 -0500
changeset 748801 f97192afce8393c0d2ef89a4e73730aaff56e0a7
parent 748800 feb08bc351a1daa43088a84773d05e897ebf46d9
child 748802 98f9131b5cb175ce1998cd2eb9932d6fee446d58
push id97241
push userbvandyk@mozilla.com
push dateTue, 30 Jan 2018 13:55:39 +0000
reviewerskamidphish
bugs1432869
milestone60.0a1
Bug 1432869 - Update cubeb-pulse-rs to git commit deadde7. r?kamidphish MozReview-Commit-ID: EdtwDx2r2Ta
media/libcubeb/cubeb-pulse-rs/README_MOZILLA
media/libcubeb/cubeb-pulse-rs/cubeb-ffi/src/ffi.rs
media/libcubeb/cubeb-pulse-rs/pulse-rs/src/lib.rs
media/libcubeb/cubeb-pulse-rs/src/backend/context.rs
media/libcubeb/cubeb-pulse-rs/src/backend/stream.rs
--- 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();