mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-16 23:05:42 +00:00
Backed out 2 changesets (bug 1687070) for causing failures on cubeb.drain, cubeb.tone. CLOSED TREE
Backed out changeset 65dd5e6a60fe (bug 1687070) Backed out changeset fd7fa895cdef (bug 1687070)
This commit is contained in:
parent
999d851597
commit
408a169597
@ -25,7 +25,7 @@ rev = "1bb484e96ae724309e3346968e8ffd4c25e61616"
|
|||||||
[source."https://github.com/mozilla/cubeb-pulse-rs"]
|
[source."https://github.com/mozilla/cubeb-pulse-rs"]
|
||||||
git = "https://github.com/mozilla/cubeb-pulse-rs"
|
git = "https://github.com/mozilla/cubeb-pulse-rs"
|
||||||
replace-with = "vendored-sources"
|
replace-with = "vendored-sources"
|
||||||
rev = "c3a51357f9674756311848bf1e5966a0b7c3eef9"
|
rev = "c87b50aebfa088c1ad30c74819d4e9829f88b2e3"
|
||||||
|
|
||||||
[source."https://github.com/mozilla/cubeb-coreaudio-rs"]
|
[source."https://github.com/mozilla/cubeb-coreaudio-rs"]
|
||||||
git = "https://github.com/mozilla/cubeb-coreaudio-rs"
|
git = "https://github.com/mozilla/cubeb-coreaudio-rs"
|
||||||
|
6
Cargo.lock
generated
6
Cargo.lock
generated
@ -1014,7 +1014,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "cubeb-pulse"
|
name = "cubeb-pulse"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
source = "git+https://github.com/mozilla/cubeb-pulse-rs?rev=c3a51357f9674756311848bf1e5966a0b7c3eef9#c3a51357f9674756311848bf1e5966a0b7c3eef9"
|
source = "git+https://github.com/mozilla/cubeb-pulse-rs?rev=c87b50aebfa088c1ad30c74819d4e9829f88b2e3#c87b50aebfa088c1ad30c74819d4e9829f88b2e3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cubeb-backend",
|
"cubeb-backend",
|
||||||
"pulse",
|
"pulse",
|
||||||
@ -3858,7 +3858,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "pulse"
|
name = "pulse"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
source = "git+https://github.com/mozilla/cubeb-pulse-rs?rev=c3a51357f9674756311848bf1e5966a0b7c3eef9#c3a51357f9674756311848bf1e5966a0b7c3eef9"
|
source = "git+https://github.com/mozilla/cubeb-pulse-rs?rev=c87b50aebfa088c1ad30c74819d4e9829f88b2e3#c87b50aebfa088c1ad30c74819d4e9829f88b2e3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"pulse-ffi",
|
"pulse-ffi",
|
||||||
@ -3867,7 +3867,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "pulse-ffi"
|
name = "pulse-ffi"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/mozilla/cubeb-pulse-rs?rev=c3a51357f9674756311848bf1e5966a0b7c3eef9#c3a51357f9674756311848bf1e5966a0b7c3eef9"
|
source = "git+https://github.com/mozilla/cubeb-pulse-rs?rev=c87b50aebfa088c1ad30c74819d4e9829f88b2e3#c87b50aebfa088c1ad30c74819d4e9829f88b2e3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
@ -1 +1 @@
|
|||||||
{"files":{".editorconfig":"bf047bd1da10cabb99eea666d1e57c321eba4716dccb3e4ed0e2c5fe3ca53858",".github/workflows/build.yml":"5b35f16e3fba6586f190a623ee9fc8b928f964a1c0be623f12bfb1d8f93f1bed","AUTHORS":"0e0ac930a68ce2f6b876126b195add177f0d3886facb9260f4d9b69f1988f0cc","Cargo.toml":"56e90cb82ec36ead07e551a28fc2455fa658fa8308c3d73f8d856d85bfcd2122","LICENSE":"44c6b5ae5ec3fe2fbc608b00e6f4896f4d2d5c7e525fcbaa3eaa3cf2f3d5a983","README.md":"0079450bb4b013bac065ed1750851e461a3710ebad1f323817da1cb82db0bc4f","src/backend/context.rs":"14507ac042e0d00d2d27715d523c9dfa09ff4800e5f5b5bca95d1918344dbc4a","src/backend/cork_state.rs":"4a0f1afc7d9f333dac89218cc56d7d32fbffb487cd48c1c9a4e03d79cb3b5e28","src/backend/intern.rs":"374a9a3bd79fddc47739dda1dbfc5929aea5a91946794fe65fba3c8d130fbda9","src/backend/mod.rs":"d5da05348bf1a7f65c85b14372964a49dc4849f0aee96c75e2c18b51fb03fcaf","src/backend/stream.rs":"63e13cb76df62cfc9d9909b608c3136c55f35f680fc44909aab44dfe527d4db2","src/capi.rs":"b2c1be8128cadd36caa65c80950440f9d6f2aa0c24cc7bae6a9eaf6347ac454d","src/lib.rs":"b41bbdc562cbfb130ed7c1e53fe69944774f515705341d8ce48a2f82c8c0c2c5"},"package":null}
|
{"files":{".editorconfig":"bf047bd1da10cabb99eea666d1e57c321eba4716dccb3e4ed0e2c5fe3ca53858",".travis.yml":"0394e2adb041175457685cde5ee05ff04bdab8885fd8a62551f2ff43d9e48872","AUTHORS":"0e0ac930a68ce2f6b876126b195add177f0d3886facb9260f4d9b69f1988f0cc","Cargo.toml":"56e90cb82ec36ead07e551a28fc2455fa658fa8308c3d73f8d856d85bfcd2122","LICENSE":"44c6b5ae5ec3fe2fbc608b00e6f4896f4d2d5c7e525fcbaa3eaa3cf2f3d5a983","README.md":"e6a98ee5630b9ce1a096a2907d095454f2770e298a5b0976ab552cc53ca96cfc","src/backend/context.rs":"33d9fdf1504fe1ae43d301e288daf6eaeabeb47aa0ef86efa135c6d984425fc4","src/backend/cork_state.rs":"4a0f1afc7d9f333dac89218cc56d7d32fbffb487cd48c1c9a4e03d79cb3b5e28","src/backend/intern.rs":"374a9a3bd79fddc47739dda1dbfc5929aea5a91946794fe65fba3c8d130fbda9","src/backend/mod.rs":"06ce9250865abf0ea461f215b128470636d072a6776821efef3caf5a7b992fb9","src/backend/stream.rs":"b8700fffb4d1537bc2fd3f0e26e7bbb16bc6e7cc7a803723e06704610ca1f6f5","src/capi.rs":"b2c1be8128cadd36caa65c80950440f9d6f2aa0c24cc7bae6a9eaf6347ac454d","src/lib.rs":"7282560d84b134b09acfd8d6282600982e42fb3557f72454c535637cc26c7bf6"},"package":null}
|
@ -1,40 +0,0 @@
|
|||||||
name: Build
|
|
||||||
|
|
||||||
on: [push, pull_request]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
continue-on-error: ${{ matrix.experimental }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
rust: [stable]
|
|
||||||
experimental: [false]
|
|
||||||
include:
|
|
||||||
- rust: nightly
|
|
||||||
experimental: true
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- name: Install Rust
|
|
||||||
run: rustup toolchain install ${{ matrix.rust }} --profile minimal --component rustfmt
|
|
||||||
|
|
||||||
- name: Install Dependencies (Linux)
|
|
||||||
run: sudo apt-get install libpulse-dev
|
|
||||||
|
|
||||||
# - name: Check format
|
|
||||||
# shell: bash
|
|
||||||
# run: rustup run ${{ matrix.rust }} cargo fmt --all -- --check
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
shell: bash
|
|
||||||
run: rustup run ${{ matrix.rust }} cargo build --all
|
|
||||||
|
|
||||||
- name: Test
|
|
||||||
shell: bash
|
|
||||||
run: rustup run ${{ matrix.rust }} cargo test --all
|
|
||||||
|
|
70
third_party/rust/cubeb-pulse/.travis.yml
vendored
Normal file
70
third_party/rust/cubeb-pulse/.travis.yml
vendored
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
language: rust
|
||||||
|
cache: cargo
|
||||||
|
notifications:
|
||||||
|
email:
|
||||||
|
on_success: never
|
||||||
|
|
||||||
|
rust:
|
||||||
|
# Version 1.36 is the minimum version of rust supported by Gecko.
|
||||||
|
- 1.36.0
|
||||||
|
- stable
|
||||||
|
- nightly
|
||||||
|
|
||||||
|
env:
|
||||||
|
# default jobs with and without optional features.
|
||||||
|
-
|
||||||
|
- FEATURES=pulse-dlopen
|
||||||
|
|
||||||
|
# Invoke cargo with optional target or features switches.
|
||||||
|
script: >
|
||||||
|
cargo test
|
||||||
|
${TARGET:+--target ${TARGET}}
|
||||||
|
${FEATURES:+--features ${FEATURES}}
|
||||||
|
|
||||||
|
# Install cross target if necessary.
|
||||||
|
before_install:
|
||||||
|
if test -n "${TARGET}"; then rustup target add ${TARGET}; fi
|
||||||
|
|
||||||
|
addons: &apt_64
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- libpulse-dev
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
# Add in 32-bit builds
|
||||||
|
- rust: 1.36.0
|
||||||
|
env:
|
||||||
|
- TARGET=i686-unknown-linux-gnu
|
||||||
|
addons: &apt_32
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- gcc-multilib
|
||||||
|
- g++-multilib
|
||||||
|
- libpulse-dev:i386
|
||||||
|
- libglib2.0-dev:i386
|
||||||
|
- rust: 1.36.0
|
||||||
|
env:
|
||||||
|
- TARGET=i686-unknown-linux-gnu
|
||||||
|
- FEATURES=pulse-dlopen
|
||||||
|
addons: *apt_32
|
||||||
|
- rust: stable
|
||||||
|
env:
|
||||||
|
- TARGET=i686-unknown-linux-gnu
|
||||||
|
addons: *apt_32
|
||||||
|
- rust: stable
|
||||||
|
env:
|
||||||
|
- TARGET=i686-unknown-linux-gnu
|
||||||
|
- FEATURES=pulse-dlopen
|
||||||
|
addons: *apt_32
|
||||||
|
- rust: nightly
|
||||||
|
env:
|
||||||
|
- TARGET=i686-unknown-linux-gnu
|
||||||
|
addons: *apt_32
|
||||||
|
- rust: nightly
|
||||||
|
env:
|
||||||
|
- TARGET=i686-unknown-linux-gnu
|
||||||
|
- FEATURES=pulse-dlopen
|
||||||
|
addons: *apt_32
|
||||||
|
allow_failures:
|
||||||
|
- rust: nightly
|
3
third_party/rust/cubeb-pulse/README.md
vendored
3
third_party/rust/cubeb-pulse/README.md
vendored
@ -2,4 +2,5 @@
|
|||||||
|
|
||||||
Implementation of PulseAudio backend for Cubeb written in Rust.
|
Implementation of PulseAudio backend for Cubeb written in Rust.
|
||||||
|
|
||||||
[![Build Status](https://github.com/mozilla/cubeb-pulse-rs/actions/workflows/build.yml/badge.svg)](https://github.com/mozilla/cubeb-pulse-rs/actions/workflows/build.yml)
|
[![Travis Build Status](https://travis-ci.org/djg/cubeb-pulse-rs.svg?branch=master)](https://travis-ci.org/djg/cubeb-pulse-rs)
|
||||||
|
[![Travis Build Status](https://travis-ci.org/djg/cubeb-pulse-rs.svg?branch=dev)](https://travis-ci.org/djg/cubeb-pulse-rs)
|
||||||
|
@ -4,10 +4,8 @@
|
|||||||
// accompanying file LICENSE for details.
|
// accompanying file LICENSE for details.
|
||||||
|
|
||||||
use backend::*;
|
use backend::*;
|
||||||
use cubeb_backend::{
|
use cubeb_backend::{ffi, log_enabled, Context, ContextOps, DeviceCollectionRef, DeviceId,
|
||||||
ffi, log_enabled, Context, ContextOps, DeviceCollectionRef, DeviceId, DeviceType, Error, Ops,
|
DeviceType, Error, Ops, Result, Stream, StreamParams, StreamParamsRef};
|
||||||
Result, Stream, StreamParams, StreamParamsRef,
|
|
||||||
};
|
|
||||||
use pulse::{self, ProplistExt};
|
use pulse::{self, ProplistExt};
|
||||||
use pulse_ffi::*;
|
use pulse_ffi::*;
|
||||||
use semver;
|
use semver;
|
||||||
@ -94,8 +92,17 @@ impl PulseContext {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn server_info_cb(context: &pulse::Context, info: Option<&pulse::ServerInfo>, u: *mut c_void) {
|
fn server_info_cb(
|
||||||
fn sink_info_cb(_: &pulse::Context, i: *const pulse::SinkInfo, eol: i32, u: *mut c_void) {
|
context: &pulse::Context,
|
||||||
|
info: Option<&pulse::ServerInfo>,
|
||||||
|
u: *mut c_void,
|
||||||
|
) {
|
||||||
|
fn sink_info_cb(
|
||||||
|
_: &pulse::Context,
|
||||||
|
i: *const pulse::SinkInfo,
|
||||||
|
eol: i32,
|
||||||
|
u: *mut c_void,
|
||||||
|
) {
|
||||||
let ctx = unsafe { &mut *(u as *mut PulseContext) };
|
let ctx = unsafe { &mut *(u as *mut PulseContext) };
|
||||||
if eol == 0 {
|
if eol == 0 {
|
||||||
let info = unsafe { &*i };
|
let info = unsafe { &*i };
|
||||||
@ -213,13 +220,11 @@ impl PulseContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (f == pulse::SubscriptionEventFacility::Server)
|
} else if (f == pulse::SubscriptionEventFacility::Server)
|
||||||
&& (t == pulse::SubscriptionEventType::Change)
|
&& (t == pulse::SubscriptionEventType::Change) {
|
||||||
{
|
|
||||||
cubeb_log!("Server changed {}", index as i32);
|
cubeb_log!("Server changed {}", index as i32);
|
||||||
let user_data: *mut c_void = ctx as *mut _ as *mut _;
|
let user_data: *mut c_void = ctx as *mut _ as *mut _;
|
||||||
if let Some(ref context) = ctx.context {
|
if let Some(ref context) = ctx.context {
|
||||||
if let Err(e) = context.get_server_info(PulseContext::server_info_cb, user_data)
|
if let Err(e) = context.get_server_info(PulseContext::server_info_cb, user_data) {
|
||||||
{
|
|
||||||
cubeb_log!("get_server_info ignored failure: {}", e);
|
cubeb_log!("get_server_info ignored failure: {}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
|
|
||||||
mod context;
|
mod context;
|
||||||
mod cork_state;
|
mod cork_state;
|
||||||
mod intern;
|
|
||||||
mod stream;
|
mod stream;
|
||||||
|
mod intern;
|
||||||
|
|
||||||
pub use self::context::PulseContext;
|
pub use self::context::PulseContext;
|
||||||
use self::intern::Intern;
|
use self::intern::Intern;
|
||||||
|
201
third_party/rust/cubeb-pulse/src/backend/stream.rs
vendored
201
third_party/rust/cubeb-pulse/src/backend/stream.rs
vendored
@ -3,24 +3,22 @@
|
|||||||
// This program is made available under an ISC-style license. See the
|
// This program is made available under an ISC-style license. See the
|
||||||
// accompanying file LICENSE for details.
|
// accompanying file LICENSE for details.
|
||||||
|
|
||||||
use backend::cork_state::CorkState;
|
|
||||||
use backend::*;
|
use backend::*;
|
||||||
use cubeb_backend::{
|
use backend::cork_state::CorkState;
|
||||||
ffi, log_enabled, ChannelLayout, DeviceId, DeviceRef, Error, Result, SampleFormat, StreamOps,
|
use cubeb_backend::{ffi, log_enabled, ChannelLayout, DeviceId, DeviceRef, Error, Result,
|
||||||
StreamParamsRef, StreamPrefs,
|
SampleFormat, StreamOps, StreamParamsRef, StreamPrefs};
|
||||||
};
|
|
||||||
use pulse::{self, CVolumeExt, ChannelMapExt, SampleSpecExt, StreamLatency, USecExt};
|
use pulse::{self, CVolumeExt, ChannelMapExt, SampleSpecExt, StreamLatency, USecExt};
|
||||||
use pulse_ffi::*;
|
use pulse_ffi::*;
|
||||||
use ringbuf::RingBuffer;
|
use std::{mem, ptr};
|
||||||
use std::ffi::{CStr, CString};
|
use std::ffi::{CStr, CString};
|
||||||
use std::os::raw::{c_long, c_void};
|
use std::os::raw::{c_long, c_void};
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
use std::{mem, ptr};
|
use ringbuf::RingBuffer;
|
||||||
|
|
||||||
use self::LinearInputBuffer::*;
|
|
||||||
use self::RingBufferConsumer::*;
|
use self::RingBufferConsumer::*;
|
||||||
use self::RingBufferProducer::*;
|
use self::RingBufferProducer::*;
|
||||||
|
use self::LinearInputBuffer::*;
|
||||||
|
|
||||||
const PULSE_NO_GAIN: f32 = -1.0;
|
const PULSE_NO_GAIN: f32 = -1.0;
|
||||||
|
|
||||||
@ -103,10 +101,12 @@ fn default_layout_for_channels(ch: u32) -> ChannelLayout {
|
|||||||
3 => ChannelLayout::_3F,
|
3 => ChannelLayout::_3F,
|
||||||
4 => ChannelLayout::QUAD,
|
4 => ChannelLayout::QUAD,
|
||||||
5 => ChannelLayout::_3F2,
|
5 => ChannelLayout::_3F2,
|
||||||
6 => ChannelLayout::_3F_LFE | ChannelLayout::SIDE_LEFT | ChannelLayout::SIDE_RIGHT,
|
6 => ChannelLayout::_3F_LFE
|
||||||
|
| ChannelLayout::SIDE_LEFT
|
||||||
|
| ChannelLayout::SIDE_RIGHT,
|
||||||
7 => ChannelLayout::_3F3R_LFE,
|
7 => ChannelLayout::_3F3R_LFE,
|
||||||
8 => ChannelLayout::_3F4_LFE,
|
8 => ChannelLayout::_3F4_LFE,
|
||||||
_ => panic!("channel must be between 1 to 8."),
|
_ => panic!("channel must be between 1 to 8.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,63 +127,58 @@ impl Drop for Device {
|
|||||||
|
|
||||||
enum RingBufferConsumer {
|
enum RingBufferConsumer {
|
||||||
IntegerRingBufferConsumer(ringbuf::Consumer<i16>),
|
IntegerRingBufferConsumer(ringbuf::Consumer<i16>),
|
||||||
FloatRingBufferConsumer(ringbuf::Consumer<f32>),
|
FloatRingBufferConsumer(ringbuf::Consumer<f32>)
|
||||||
}
|
}
|
||||||
|
|
||||||
enum RingBufferProducer {
|
enum RingBufferProducer {
|
||||||
IntegerRingBufferProducer(ringbuf::Producer<i16>),
|
IntegerRingBufferProducer(ringbuf::Producer<i16>),
|
||||||
FloatRingBufferProducer(ringbuf::Producer<f32>),
|
FloatRingBufferProducer(ringbuf::Producer<f32>)
|
||||||
}
|
}
|
||||||
|
|
||||||
enum LinearInputBuffer {
|
enum LinearInputBuffer {
|
||||||
IntegerLinearInputBuffer(Vec<i16>),
|
IntegerLinearInputBuffer(Vec<i16>),
|
||||||
FloatLinearInputBuffer(Vec<f32>),
|
FloatLinearInputBuffer(Vec<f32>)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BufferManager {
|
struct BufferManager {
|
||||||
consumer: RingBufferConsumer,
|
consumer: RingBufferConsumer,
|
||||||
producer: RingBufferProducer,
|
producer: RingBufferProducer,
|
||||||
linear_input_buffer: LinearInputBuffer,
|
linear_input_buffer: LinearInputBuffer
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BufferManager {
|
impl BufferManager {
|
||||||
// When opening a duplex stream, the sample-spec are guaranteed to match. It's ok to have
|
// When opening a duplex stream, the sample-spec are guaranteed to match. It's ok to have
|
||||||
// either the input or output sample-spec here.
|
// either the input or output sample-spec here.
|
||||||
fn new(input_buffer_size: usize, sample_spec: &pulse::SampleSpec) -> BufferManager {
|
fn new(input_buffer_size: usize, sample_spec: &pulse::SampleSpec) -> BufferManager {
|
||||||
if sample_spec.format == PA_SAMPLE_S16BE || sample_spec.format == PA_SAMPLE_S16LE {
|
if sample_spec.format == PA_SAMPLE_S16BE ||
|
||||||
let ring = RingBuffer::<i16>::new(input_buffer_size);
|
sample_spec.format == PA_SAMPLE_S16LE {
|
||||||
let (prod, cons) = ring.split();
|
let ring = RingBuffer::<i16>::new(input_buffer_size);
|
||||||
return BufferManager {
|
let (prod, cons) = ring.split();
|
||||||
producer: IntegerRingBufferProducer(prod),
|
return BufferManager {
|
||||||
consumer: IntegerRingBufferConsumer(cons),
|
producer: IntegerRingBufferProducer(prod),
|
||||||
linear_input_buffer: IntegerLinearInputBuffer(Vec::<i16>::with_capacity(
|
consumer: IntegerRingBufferConsumer(cons),
|
||||||
input_buffer_size,
|
linear_input_buffer: IntegerLinearInputBuffer(Vec::<i16>::with_capacity(input_buffer_size))
|
||||||
)),
|
};
|
||||||
};
|
} else {
|
||||||
} else {
|
let ring = RingBuffer::<f32>::new(input_buffer_size);
|
||||||
let ring = RingBuffer::<f32>::new(input_buffer_size);
|
let (prod, cons) = ring.split();
|
||||||
let (prod, cons) = ring.split();
|
return BufferManager {
|
||||||
return BufferManager {
|
producer: FloatRingBufferProducer(prod),
|
||||||
producer: FloatRingBufferProducer(prod),
|
consumer: FloatRingBufferConsumer(cons),
|
||||||
consumer: FloatRingBufferConsumer(cons),
|
linear_input_buffer: FloatLinearInputBuffer(Vec::<f32>::with_capacity(input_buffer_size))
|
||||||
linear_input_buffer: FloatLinearInputBuffer(Vec::<f32>::with_capacity(
|
};
|
||||||
input_buffer_size,
|
}
|
||||||
)),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_input_data(&mut self, input_data: *const c_void, read_samples: usize) {
|
fn push_input_data(&mut self, input_data: *const c_void, read_samples: usize) {
|
||||||
match &mut self.producer {
|
match &mut self.producer {
|
||||||
RingBufferProducer::FloatRingBufferProducer(p) => {
|
RingBufferProducer::FloatRingBufferProducer(p) => {
|
||||||
let input_data =
|
let input_data = unsafe { slice::from_raw_parts::<f32>(input_data as *const f32, read_samples) };
|
||||||
unsafe { slice::from_raw_parts::<f32>(input_data as *const f32, read_samples) };
|
|
||||||
// we don't do anything in particular if we can't push everything
|
// we don't do anything in particular if we can't push everything
|
||||||
p.push_slice(input_data);
|
p.push_slice(input_data);
|
||||||
}
|
}
|
||||||
RingBufferProducer::IntegerRingBufferProducer(p) => {
|
RingBufferProducer::IntegerRingBufferProducer(p) => {
|
||||||
let input_data =
|
let input_data = unsafe { slice::from_raw_parts::<i16>(input_data as *const i16, read_samples) };
|
||||||
unsafe { slice::from_raw_parts::<i16>(input_data as *const i16, read_samples) };
|
|
||||||
p.push_slice(input_data);
|
p.push_slice(input_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -192,9 +187,7 @@ impl BufferManager {
|
|||||||
fn pull_input_data(&mut self, input_data: *mut c_void, needed_samples: usize) {
|
fn pull_input_data(&mut self, input_data: *mut c_void, needed_samples: usize) {
|
||||||
match &mut self.consumer {
|
match &mut self.consumer {
|
||||||
IntegerRingBufferConsumer(p) => {
|
IntegerRingBufferConsumer(p) => {
|
||||||
let mut input: &mut [i16] = unsafe {
|
let mut input: &mut[i16] = unsafe { slice::from_raw_parts_mut::<i16>(input_data as *mut i16, needed_samples) };
|
||||||
slice::from_raw_parts_mut::<i16>(input_data as *mut i16, needed_samples)
|
|
||||||
};
|
|
||||||
let read = p.pop_slice(&mut input);
|
let read = p.pop_slice(&mut input);
|
||||||
if read < needed_samples {
|
if read < needed_samples {
|
||||||
for i in 0..(needed_samples - read) {
|
for i in 0..(needed_samples - read) {
|
||||||
@ -203,9 +196,7 @@ impl BufferManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
FloatRingBufferConsumer(p) => {
|
FloatRingBufferConsumer(p) => {
|
||||||
let mut input: &mut [f32] = unsafe {
|
let mut input: &mut[f32] = unsafe { slice::from_raw_parts_mut::<f32>(input_data as *mut f32, needed_samples) };
|
||||||
slice::from_raw_parts_mut::<f32>(input_data as *mut f32, needed_samples)
|
|
||||||
};
|
|
||||||
let read = p.pop_slice(&mut input);
|
let read = p.pop_slice(&mut input);
|
||||||
if read < needed_samples {
|
if read < needed_samples {
|
||||||
for i in 0..(needed_samples - read) {
|
for i in 0..(needed_samples - read) {
|
||||||
@ -251,8 +242,12 @@ impl BufferManager {
|
|||||||
}
|
}
|
||||||
pub fn available_samples(&mut self) -> usize {
|
pub fn available_samples(&mut self) -> usize {
|
||||||
match &self.linear_input_buffer {
|
match &self.linear_input_buffer {
|
||||||
LinearInputBuffer::IntegerLinearInputBuffer(b) => b.len(),
|
LinearInputBuffer::IntegerLinearInputBuffer(b) => {
|
||||||
LinearInputBuffer::FloatLinearInputBuffer(b) => b.len(),
|
b.len()
|
||||||
|
}
|
||||||
|
LinearInputBuffer::FloatLinearInputBuffer(b) => {
|
||||||
|
b.len()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -279,7 +274,7 @@ pub struct PulseStream<'ctx> {
|
|||||||
shutdown: bool,
|
shutdown: bool,
|
||||||
volume: f32,
|
volume: f32,
|
||||||
state: ffi::cubeb_state,
|
state: ffi::cubeb_state,
|
||||||
input_buffer_manager: Option<BufferManager>,
|
input_buffer_manager: Option<BufferManager>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ctx> PulseStream<'ctx> {
|
impl<'ctx> PulseStream<'ctx> {
|
||||||
@ -334,10 +329,7 @@ impl<'ctx> PulseStream<'ctx> {
|
|||||||
|
|
||||||
if stm.output_stream.is_some() {
|
if stm.output_stream.is_some() {
|
||||||
// duplex stream: push the input data to the ring buffer.
|
// duplex stream: push the input data to the ring buffer.
|
||||||
stm.input_buffer_manager
|
stm.input_buffer_manager.as_mut().unwrap().push_input_data(read_data, read_samples);
|
||||||
.as_mut()
|
|
||||||
.unwrap()
|
|
||||||
.push_input_data(read_data, read_samples);
|
|
||||||
} else {
|
} else {
|
||||||
// input/capture only operation. Call callback directly
|
// input/capture only operation. Call callback directly
|
||||||
let got = unsafe {
|
let got = unsafe {
|
||||||
@ -381,13 +373,11 @@ impl<'ctx> PulseStream<'ctx> {
|
|||||||
let input_buffer_manager = stm.input_buffer_manager.as_mut().unwrap();
|
let input_buffer_manager = stm.input_buffer_manager.as_mut().unwrap();
|
||||||
|
|
||||||
if stm.output_frame_count.fetch_add(nframes, Ordering::SeqCst) == 0 {
|
if stm.output_frame_count.fetch_add(nframes, Ordering::SeqCst) == 0 {
|
||||||
let buffered_input_frames = input_buffer_manager.available_samples()
|
let buffered_input_frames = input_buffer_manager.available_samples() / stm.input_sample_spec.channels as usize;
|
||||||
/ stm.input_sample_spec.channels as usize;
|
|
||||||
if buffered_input_frames > nframes {
|
if buffered_input_frames > nframes {
|
||||||
// Trim the buffer to ensure minimal roundtrip latency
|
// Trim the buffer to ensure minimal roundtrip latency
|
||||||
let popped_frames = buffered_input_frames - nframes;
|
let popped_frames = buffered_input_frames - nframes;
|
||||||
input_buffer_manager
|
input_buffer_manager.trim(nframes * stm.input_sample_spec.channels as usize);
|
||||||
.trim(nframes * stm.input_sample_spec.channels as usize);
|
|
||||||
cubeb_log!("Dropping {} frames in input buffer.", popped_frames);
|
cubeb_log!("Dropping {} frames in input buffer.", popped_frames);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -416,7 +406,7 @@ impl<'ctx> PulseStream<'ctx> {
|
|||||||
shutdown: false,
|
shutdown: false,
|
||||||
volume: PULSE_NO_GAIN,
|
volume: PULSE_NO_GAIN,
|
||||||
state: ffi::CUBEB_STATE_ERROR,
|
state: ffi::CUBEB_STATE_ERROR,
|
||||||
input_buffer_manager: None,
|
input_buffer_manager: None
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(ref context) = stm.context.context {
|
if let Some(ref context) = stm.context.context {
|
||||||
@ -431,15 +421,14 @@ impl<'ctx> PulseStream<'ctx> {
|
|||||||
s.set_state_callback(check_error, stm.as_mut() as *mut _ as *mut _);
|
s.set_state_callback(check_error, stm.as_mut() as *mut _ as *mut _);
|
||||||
s.set_write_callback(write_data, stm.as_mut() as *mut _ as *mut _);
|
s.set_write_callback(write_data, stm.as_mut() as *mut _ as *mut _);
|
||||||
|
|
||||||
let buffer_size_bytes =
|
let buffer_size_bytes = latency_frames * stm.output_sample_spec.frame_size() as u32;
|
||||||
latency_frames * stm.output_sample_spec.frame_size() as u32;
|
|
||||||
|
|
||||||
let battr = pa_buffer_attr {
|
let battr = pa_buffer_attr {
|
||||||
maxlength: u32::max_value(),
|
maxlength: u32::max_value(),
|
||||||
prebuf: 0,
|
prebuf: u32::max_value(),
|
||||||
fragsize: u32::max_value(),
|
fragsize: u32::max_value(),
|
||||||
tlength: buffer_size_bytes * 2,
|
tlength: buffer_size_bytes * 2,
|
||||||
minreq: buffer_size_bytes / 4,
|
minreq: buffer_size_bytes / 4
|
||||||
};
|
};
|
||||||
let device_name = super::try_cstr_from(output_device as *const _);
|
let device_name = super::try_cstr_from(output_device as *const _);
|
||||||
let mut stream_flags = pulse::StreamFlags::AUTO_TIMING_UPDATE
|
let mut stream_flags = pulse::StreamFlags::AUTO_TIMING_UPDATE
|
||||||
@ -449,11 +438,16 @@ impl<'ctx> PulseStream<'ctx> {
|
|||||||
if device_name.is_some()
|
if device_name.is_some()
|
||||||
|| stream_params
|
|| stream_params
|
||||||
.prefs()
|
.prefs()
|
||||||
.contains(StreamPrefs::DISABLE_DEVICE_SWITCHING)
|
.contains(StreamPrefs::DISABLE_DEVICE_SWITCHING) {
|
||||||
{
|
stream_flags |= pulse::StreamFlags::DONT_MOVE;
|
||||||
stream_flags |= pulse::StreamFlags::DONT_MOVE;
|
|
||||||
}
|
}
|
||||||
let _ = s.connect_playback(device_name, &battr, stream_flags, None, None);
|
let _ = s.connect_playback(
|
||||||
|
device_name,
|
||||||
|
&battr,
|
||||||
|
stream_flags,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
|
||||||
stm.output_stream = Some(s);
|
stm.output_stream = Some(s);
|
||||||
}
|
}
|
||||||
@ -474,14 +468,13 @@ impl<'ctx> PulseStream<'ctx> {
|
|||||||
s.set_state_callback(check_error, stm.as_mut() as *mut _ as *mut _);
|
s.set_state_callback(check_error, stm.as_mut() as *mut _ as *mut _);
|
||||||
s.set_read_callback(read_data, stm.as_mut() as *mut _ as *mut _);
|
s.set_read_callback(read_data, stm.as_mut() as *mut _ as *mut _);
|
||||||
|
|
||||||
let buffer_size_bytes =
|
let buffer_size_bytes = latency_frames * stm.input_sample_spec.frame_size() as u32;
|
||||||
latency_frames * stm.input_sample_spec.frame_size() as u32;
|
|
||||||
let battr = pa_buffer_attr {
|
let battr = pa_buffer_attr {
|
||||||
maxlength: u32::max_value(),
|
maxlength: u32::max_value(),
|
||||||
prebuf: u32::max_value(),
|
prebuf: u32::max_value(),
|
||||||
fragsize: buffer_size_bytes,
|
fragsize: buffer_size_bytes,
|
||||||
tlength: buffer_size_bytes,
|
tlength: buffer_size_bytes,
|
||||||
minreq: buffer_size_bytes,
|
minreq: buffer_size_bytes
|
||||||
};
|
};
|
||||||
let device_name = super::try_cstr_from(input_device as *const _);
|
let device_name = super::try_cstr_from(input_device as *const _);
|
||||||
let mut stream_flags = pulse::StreamFlags::AUTO_TIMING_UPDATE
|
let mut stream_flags = pulse::StreamFlags::AUTO_TIMING_UPDATE
|
||||||
@ -491,11 +484,14 @@ impl<'ctx> PulseStream<'ctx> {
|
|||||||
if device_name.is_some()
|
if device_name.is_some()
|
||||||
|| stream_params
|
|| stream_params
|
||||||
.prefs()
|
.prefs()
|
||||||
.contains(StreamPrefs::DISABLE_DEVICE_SWITCHING)
|
.contains(StreamPrefs::DISABLE_DEVICE_SWITCHING) {
|
||||||
{
|
|
||||||
stream_flags |= pulse::StreamFlags::DONT_MOVE;
|
stream_flags |= pulse::StreamFlags::DONT_MOVE;
|
||||||
}
|
}
|
||||||
let _ = s.connect_record(device_name, &battr, stream_flags);
|
let _ = s.connect_record(
|
||||||
|
device_name,
|
||||||
|
&battr,
|
||||||
|
stream_flags,
|
||||||
|
);
|
||||||
|
|
||||||
stm.input_stream = Some(s);
|
stm.input_stream = Some(s);
|
||||||
}
|
}
|
||||||
@ -510,12 +506,8 @@ impl<'ctx> PulseStream<'ctx> {
|
|||||||
// Duplex, set up the ringbuffer
|
// Duplex, set up the ringbuffer
|
||||||
if input_stream_params.is_some() && output_stream_params.is_some() {
|
if input_stream_params.is_some() && output_stream_params.is_some() {
|
||||||
// A bit more room in case of output underrun.
|
// A bit more room in case of output underrun.
|
||||||
let buffer_size_bytes =
|
let buffer_size_bytes = 2 * latency_frames * stm.input_sample_spec.frame_size() as u32;
|
||||||
2 * latency_frames * stm.input_sample_spec.frame_size() as u32;
|
stm.input_buffer_manager = Some(BufferManager::new(buffer_size_bytes as usize, &stm.input_sample_spec))
|
||||||
stm.input_buffer_manager = Some(BufferManager::new(
|
|
||||||
buffer_size_bytes as usize,
|
|
||||||
&stm.input_sample_spec,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let r = if stm.wait_until_ready() {
|
let r = if stm.wait_until_ready() {
|
||||||
@ -601,9 +593,31 @@ impl<'ctx> Drop for PulseStream<'ctx> {
|
|||||||
|
|
||||||
impl<'ctx> StreamOps for PulseStream<'ctx> {
|
impl<'ctx> StreamOps for PulseStream<'ctx> {
|
||||||
fn start(&mut self) -> Result<()> {
|
fn start(&mut self) -> Result<()> {
|
||||||
|
fn output_preroll(_: &pulse::MainloopApi, u: *mut c_void) {
|
||||||
|
let stm = unsafe { &mut *(u as *mut PulseStream) };
|
||||||
|
if !stm.shutdown {
|
||||||
|
let size = stm.output_stream
|
||||||
|
.as_ref()
|
||||||
|
.map_or(0, |s| s.writable_size().unwrap_or(0));
|
||||||
|
stm.trigger_user_callback(std::ptr::null(), size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.shutdown = false;
|
self.shutdown = false;
|
||||||
self.cork(CorkState::uncork() | CorkState::notify());
|
self.cork(CorkState::uncork() | CorkState::notify());
|
||||||
|
|
||||||
|
if self.output_stream.is_some() {
|
||||||
|
/* When doing output-only or duplex, we need to manually call user cb once in order to
|
||||||
|
* make things roll. This is done via a defer event in order to execute it from PA
|
||||||
|
* server thread. */
|
||||||
|
self.context.mainloop.lock();
|
||||||
|
self.context
|
||||||
|
.mainloop
|
||||||
|
.get_api()
|
||||||
|
.once(output_preroll, self as *const _ as *mut _);
|
||||||
|
self.context.mainloop.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -612,11 +626,9 @@ impl<'ctx> StreamOps for PulseStream<'ctx> {
|
|||||||
self.context.mainloop.lock();
|
self.context.mainloop.lock();
|
||||||
self.shutdown = true;
|
self.shutdown = true;
|
||||||
// If draining is taking place wait to finish
|
// If draining is taking place wait to finish
|
||||||
cubeb_log!("Stream stop: waiting for drain.");
|
|
||||||
while !self.drain_timer.is_null() {
|
while !self.drain_timer.is_null() {
|
||||||
self.context.mainloop.wait();
|
self.context.mainloop.wait();
|
||||||
}
|
}
|
||||||
cubeb_log!("Stream stop: waited for drain.");
|
|
||||||
self.context.mainloop.unlock();
|
self.context.mainloop.unlock();
|
||||||
}
|
}
|
||||||
self.cork(CorkState::cork() | CorkState::notify());
|
self.cork(CorkState::cork() | CorkState::notify());
|
||||||
@ -740,9 +752,13 @@ impl<'ctx> StreamOps for PulseStream<'ctx> {
|
|||||||
None => Err(Error::error()),
|
None => Err(Error::error()),
|
||||||
Some(ref stm) => {
|
Some(ref stm) => {
|
||||||
self.context.mainloop.lock();
|
self.context.mainloop.lock();
|
||||||
if let Ok(o) = stm.set_name(name, stream_success, self as *const _ as *mut _) {
|
if let Ok(o) = stm.set_name(
|
||||||
self.context.operation_wait(stm, &o);
|
name,
|
||||||
}
|
stream_success,
|
||||||
|
self as *const _ as *mut _
|
||||||
|
) {
|
||||||
|
self.context.operation_wait(stm, &o);
|
||||||
|
}
|
||||||
self.context.mainloop.unlock();
|
self.context.mainloop.unlock();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -828,23 +844,15 @@ impl<'ctx> PulseStream<'ctx> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let cm: Option<pa_channel_map> = match stream_params.layout() {
|
let cm: Option<pa_channel_map> = match stream_params.layout() {
|
||||||
ChannelLayout::UNDEFINED => {
|
ChannelLayout::UNDEFINED =>
|
||||||
if stream_params.channels() <= 8
|
if stream_params.channels() <= 8
|
||||||
&& pulse::ChannelMap::init_auto(
|
&& pulse::ChannelMap::init_auto(stream_params.channels(), PA_CHANNEL_MAP_DEFAULT).is_none() {
|
||||||
stream_params.channels(),
|
|
||||||
PA_CHANNEL_MAP_DEFAULT,
|
|
||||||
)
|
|
||||||
.is_none()
|
|
||||||
{
|
|
||||||
cubeb_log!("Layout undefined and PulseAudio's default layout has not been configured, guess one.");
|
cubeb_log!("Layout undefined and PulseAudio's default layout has not been configured, guess one.");
|
||||||
Some(layout_to_channel_map(default_layout_for_channels(
|
Some(layout_to_channel_map(default_layout_for_channels(stream_params.channels())))
|
||||||
stream_params.channels(),
|
|
||||||
)))
|
|
||||||
} else {
|
} else {
|
||||||
cubeb_log!("Layout undefined, PulseAudio will use its default.");
|
cubeb_log!("Layout undefined, PulseAudio will use its default.");
|
||||||
None
|
None
|
||||||
}
|
},
|
||||||
}
|
|
||||||
_ => Some(layout_to_channel_map(stream_params.layout())),
|
_ => Some(layout_to_channel_map(stream_params.layout())),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -956,6 +964,7 @@ impl<'ctx> PulseStream<'ctx> {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[cfg_attr(feature = "cargo-clippy", allow(cyclomatic_complexity))]
|
#[cfg_attr(feature = "cargo-clippy", allow(cyclomatic_complexity))]
|
||||||
fn trigger_user_callback(&mut self, input_data: *const c_void, nbytes: usize) {
|
fn trigger_user_callback(&mut self, input_data: *const c_void, nbytes: usize) {
|
||||||
fn drained_cb(
|
fn drained_cb(
|
||||||
@ -964,7 +973,6 @@ impl<'ctx> PulseStream<'ctx> {
|
|||||||
_tv: &pulse::TimeVal,
|
_tv: &pulse::TimeVal,
|
||||||
u: *mut c_void,
|
u: *mut c_void,
|
||||||
) {
|
) {
|
||||||
cubeb_logv!("Drain finished callback.");
|
|
||||||
let stm = unsafe { &mut *(u as *mut PulseStream) };
|
let stm = unsafe { &mut *(u as *mut PulseStream) };
|
||||||
debug_assert_eq!(stm.drain_timer, e);
|
debug_assert_eq!(stm.drain_timer, e);
|
||||||
stm.state_change_callback(ffi::CUBEB_STATE_DRAINED);
|
stm.state_change_callback(ffi::CUBEB_STATE_DRAINED);
|
||||||
@ -1045,7 +1053,6 @@ impl<'ctx> PulseStream<'ctx> {
|
|||||||
debug_assert!(r.is_ok());
|
debug_assert!(r.is_ok());
|
||||||
|
|
||||||
if (got as usize) < size / frame_size {
|
if (got as usize) < size / frame_size {
|
||||||
cubeb_logv!("Draining {} < {}", got, size / frame_size);
|
|
||||||
let latency = match stm.get_latency() {
|
let latency = match stm.get_latency() {
|
||||||
Ok(StreamLatency::Positive(l)) => l,
|
Ok(StreamLatency::Positive(l)) => l,
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
@ -1111,9 +1118,9 @@ fn not_supported() -> Error {
|
|||||||
|
|
||||||
#[cfg(all(test, not(feature = "pulse-dlopen")))]
|
#[cfg(all(test, not(feature = "pulse-dlopen")))]
|
||||||
mod test {
|
mod test {
|
||||||
use super::layout_to_channel_map;
|
|
||||||
use cubeb_backend::ChannelLayout;
|
use cubeb_backend::ChannelLayout;
|
||||||
use pulse_ffi::*;
|
use pulse_ffi::*;
|
||||||
|
use super::layout_to_channel_map;
|
||||||
|
|
||||||
macro_rules! channel_tests {
|
macro_rules! channel_tests {
|
||||||
{$($name: ident, $layout: ident => [ $($channels: ident),* ]),+} => {
|
{$($name: ident, $layout: ident => [ $($channels: ident),* ]),+} => {
|
||||||
|
4
third_party/rust/cubeb-pulse/src/lib.rs
vendored
4
third_party/rust/cubeb-pulse/src/lib.rs
vendored
@ -9,10 +9,10 @@
|
|||||||
extern crate cubeb_backend;
|
extern crate cubeb_backend;
|
||||||
extern crate pulse;
|
extern crate pulse;
|
||||||
extern crate pulse_ffi;
|
extern crate pulse_ffi;
|
||||||
extern crate ringbuf;
|
|
||||||
extern crate semver;
|
extern crate semver;
|
||||||
|
extern crate ringbuf;
|
||||||
|
|
||||||
mod backend;
|
|
||||||
mod capi;
|
mod capi;
|
||||||
|
mod backend;
|
||||||
|
|
||||||
pub use capi::pulse_rust_init;
|
pub use capi::pulse_rust_init;
|
||||||
|
@ -20,7 +20,7 @@ profiler_helper = { path = "../../../../tools/profiler/rust-helper", optional =
|
|||||||
mozurl = { path = "../../../../netwerk/base/mozurl" }
|
mozurl = { path = "../../../../netwerk/base/mozurl" }
|
||||||
webrender_bindings = { path = "../../../../gfx/webrender_bindings", optional = true }
|
webrender_bindings = { path = "../../../../gfx/webrender_bindings", optional = true }
|
||||||
cubeb-coreaudio = { git = "https://github.com/mozilla/cubeb-coreaudio-rs", rev = "ad56ea14ac915f1e7ecbcf6ac38182443b0dd29e", optional = true }
|
cubeb-coreaudio = { git = "https://github.com/mozilla/cubeb-coreaudio-rs", rev = "ad56ea14ac915f1e7ecbcf6ac38182443b0dd29e", optional = true }
|
||||||
cubeb-pulse = { git = "https://github.com/mozilla/cubeb-pulse-rs", rev="c3a51357f9674756311848bf1e5966a0b7c3eef9", optional = true, features=["pulse-dlopen"] }
|
cubeb-pulse = { git = "https://github.com/mozilla/cubeb-pulse-rs", rev="c87b50aebfa088c1ad30c74819d4e9829f88b2e3", optional = true, features=["pulse-dlopen"] }
|
||||||
cubeb-sys = { version = "0.9", optional = true, features=["gecko-in-tree"] }
|
cubeb-sys = { version = "0.9", optional = true, features=["gecko-in-tree"] }
|
||||||
encoding_glue = { path = "../../../../intl/encoding_glue" }
|
encoding_glue = { path = "../../../../intl/encoding_glue" }
|
||||||
audioipc-client = { git = "https://github.com/mozilla/audioipc-2", rev = "7537bfadad2e981577eb75e4f13662fc517e1a09", optional = true }
|
audioipc-client = { git = "https://github.com/mozilla/audioipc-2", rev = "7537bfadad2e981577eb75e4f13662fc517e1a09", optional = true }
|
||||||
|
Loading…
Reference in New Issue
Block a user