Backed out 3 changesets (bug 1876526) for causing crashes due to CubebDeviceEnumerator.cpp. CLOSED TREE

Backed out changeset 2d60a4692649 (bug 1876526)
Backed out changeset cd358cbc7365 (bug 1876526)
Backed out changeset 60c24f7a2294 (bug 1876526)
This commit is contained in:
Natalia Csoregi 2024-02-07 21:29:11 +02:00
parent f345d74fee
commit ed8168123f
10 changed files with 91 additions and 167 deletions

View File

@ -1700,7 +1700,7 @@ mozilla::ipc::IPCResult ContentChild::RecvSetProcessSandbox(
if (sandboxEnabled && !StaticPrefs::media_cubeb_sandbox()) {
// Pre-start audio before sandboxing; see bug 1443612.
Unused << CubebUtils::GetCubeb();
Unused << CubebUtils::GetCubebContext();
}
if (sandboxEnabled) {

View File

@ -245,15 +245,14 @@ nsresult AudioStream::Init(AudioDeviceInfo* aSinkInfo)
// This is noop if MOZ_DUMP_AUDIO is not set.
mDumpFile.Open("AudioStream", mOutChannels, mAudioClock.GetInputRate());
RefPtr<CubebUtils::CubebHandle> handle = CubebUtils::GetCubeb();
if (!handle) {
cubeb* cubebContext = CubebUtils::GetCubebContext();
if (!cubebContext) {
LOGE("Can't get cubeb context!");
CubebUtils::ReportCubebStreamInitFailure(true);
return NS_ERROR_DOM_MEDIA_CUBEB_INITIALIZATION_ERR;
}
mCubeb = handle;
return OpenCubeb(handle->Context(), params, startTime,
return OpenCubeb(cubebContext, params, startTime,
CubebUtils::GetFirstStream());
}

View File

@ -337,8 +337,6 @@ class AudioStream final {
const uint32_t mOutChannels;
// mCubebStream holds a bare pointer to cubeb, so we hold a ref on its behalf
RefPtr<CubebUtils::CubebHandle> mCubeb;
// Owning reference to a cubeb_stream. Set in Init(), cleared in ShutDown, so
// no lock is needed to access.
UniquePtr<cubeb_stream, CubebDestroyPolicy> mCubebStream;

View File

@ -83,8 +83,8 @@ UniquePtr<CubebInputStream> CubebInputStream::Create(cubeb_devid aDeviceId,
return nullptr;
}
RefPtr<CubebUtils::CubebHandle> handle = CubebUtils::GetCubeb();
if (!handle) {
cubeb* context = CubebUtils::GetCubebContext();
if (!context) {
LOGE("No valid cubeb context");
CubebUtils::ReportCubebStreamInitFailure(CubebUtils::GetFirstStream());
return nullptr;
@ -98,9 +98,9 @@ UniquePtr<CubebInputStream> CubebInputStream::Create(cubeb_devid aDeviceId,
RefPtr<Listener> listener(aListener);
if (int r = CubebUtils::CubebStreamInit(
handle->Context(), &cubebStream, "input-only stream", aDeviceId,
&params, nullptr, nullptr, latencyFrames, DataCallback_s,
StateCallback_s, listener.get());
context, &cubebStream, "input-only stream", aDeviceId, &params,
nullptr, nullptr, latencyFrames, DataCallback_s, StateCallback_s,
listener.get());
r != CUBEB_OK) {
CubebUtils::ReportCubebStreamInitFailure(CubebUtils::GetFirstStream());
LOGE("Fail to create a cubeb stream. Error %d", r);
@ -120,9 +120,7 @@ UniquePtr<CubebInputStream> CubebInputStream::Create(cubeb_devid aDeviceId,
CubebInputStream::CubebInputStream(
already_AddRefed<Listener>&& aListener,
UniquePtr<cubeb_stream, CubebDestroyPolicy>&& aStream)
: mListener(aListener),
mCubeb(CubebUtils::GetCubeb()),
mStream(std::move(aStream)) {
: mListener(aListener), mStream(std::move(aStream)) {
MOZ_ASSERT(mListener);
MOZ_ASSERT(mStream);
}

View File

@ -76,8 +76,6 @@ class CubebInputStream final {
// mListener must outlive the life time of the mStream.
const RefPtr<Listener> mListener;
// So must mCubeb (mStream has a bare pointer to cubeb).
const RefPtr<CubebUtils::CubebHandle> mCubeb;
const UniquePtr<cubeb_stream, CubebDestroyPolicy> mStream;
};

View File

@ -87,7 +87,7 @@ enum class CubebState {
Initialized,
Shutdown
} sCubebState = CubebState::Uninitialized;
StaticRefPtr<CubebUtils::CubebHandle> sCubebHandle;
cubeb* sCubebContext;
double sVolumeScale = 1.0;
uint32_t sCubebPlaybackLatencyInMilliseconds = 100;
uint32_t sCubebMTGLatencyInFrames = 512;
@ -185,7 +185,7 @@ static const uint32_t CUBEB_NORMAL_LATENCY_MS = 100;
static const uint32_t CUBEB_NORMAL_LATENCY_FRAMES = 1024;
namespace CubebUtils {
RefPtr<CubebHandle> GetCubebUnlocked();
cubeb* GetCubebContextUnlocked();
void GetPrefAndSetString(const char* aPref, StaticAutoPtr<char>& aStorage) {
nsAutoCString value;
@ -292,19 +292,18 @@ double GetVolumeScale() {
return sVolumeScale;
}
RefPtr<CubebHandle> GetCubeb() {
cubeb* GetCubebContext() {
StaticMutexAutoLock lock(sMutex);
return GetCubebUnlocked();
return GetCubebContextUnlocked();
}
// This is only exported when running tests.
void ForceSetCubebContext(cubeb* aCubebContext) {
StaticMutexAutoLock lock(sMutex);
if (aCubebContext) {
sCubebHandle = new CubebHandle(aCubebContext);
} else {
sCubebHandle = nullptr;
if (sCubebContext) {
cubeb_destroy(sCubebContext);
}
sCubebContext = aCubebContext;
sCubebState = CubebState::Initialized;
}
@ -327,7 +326,7 @@ void SetInCommunication(bool aInCommunication) {
}
bool InitPreferredSampleRate() {
sMutex.AssertCurrentThreadOwns();
StaticMutexAutoLock lock(sMutex);
if (sPreferredSampleRate != 0) {
return true;
}
@ -340,16 +339,13 @@ bool InitPreferredSampleRate() {
return false;
}
#else
RefPtr<CubebHandle> handle = GetCubebUnlocked();
if (!handle) {
cubeb* context = GetCubebContextUnlocked();
if (!context) {
return false;
}
uint32_t rate;
{
StaticMutexAutoUnlock unlock(sMutex);
if (cubeb_get_preferred_sample_rate(handle->Context(), &rate) != CUBEB_OK) {
return false;
}
if (cubeb_get_preferred_sample_rate(context, &rate) != CUBEB_OK) {
return false;
}
sPreferredSampleRate = rate;
#endif
@ -358,7 +354,6 @@ bool InitPreferredSampleRate() {
}
uint32_t PreferredSampleRate(bool aShouldResistFingerprinting) {
StaticMutexAutoLock lock(sMutex);
if (sCubebForcedSampleRate) {
return sCubebForcedSampleRate;
}
@ -478,7 +473,7 @@ ipc::FileDescriptor CreateAudioIPCConnection() {
#endif
}
RefPtr<CubebHandle> GetCubebUnlocked() {
cubeb* GetCubebContextUnlocked() {
sMutex.AssertCurrentThreadOwns();
if (sCubebForceNullContext) {
// Pref set such that we should return a null context
@ -490,7 +485,7 @@ RefPtr<CubebHandle> GetCubebUnlocked() {
if (sCubebState != CubebState::Uninitialized) {
// If we have already passed the initialization point (below), just return
// the current context, which may be null (e.g., after error or shutdown.)
return sCubebHandle;
return sCubebContext;
}
if (!sBrandName && NS_IsMainThread()) {
@ -532,21 +527,14 @@ RefPtr<CubebHandle> GetCubebUnlocked() {
};
initParams.mThreadDestroyCallback = []() { PROFILER_UNREGISTER_THREAD(); };
cubeb* temp = nullptr;
rv = audioipc2::audioipc2_client_init(&temp, sBrandName, &initParams);
if (temp) {
sCubebHandle = new CubebHandle(temp);
}
rv = audioipc2::audioipc2_client_init(&sCubebContext, sBrandName,
&initParams);
} else {
#endif // MOZ_CUBEB_REMOTING
#ifdef XP_WIN
mozilla::mscom::EnsureMTA([&]() -> void {
#endif
cubeb* temp = nullptr;
rv = cubeb_init(&temp, sBrandName, sCubebBackendName);
if (temp) {
sCubebHandle = new CubebHandle(temp);
}
rv = cubeb_init(&sCubebContext, sBrandName, sCubebBackendName);
#ifdef XP_WIN
});
#endif
@ -558,22 +546,17 @@ RefPtr<CubebHandle> GetCubebUnlocked() {
sCubebState =
(rv == CUBEB_OK) ? CubebState::Initialized : CubebState::Uninitialized;
return sCubebHandle;
return sCubebContext;
}
void ReportCubebBackendUsed() {
RefPtr<CubebHandle> handle;
{
StaticMutexAutoLock lock(sMutex);
sAudioStreamInitEverSucceeded = true;
handle = sCubebHandle;
}
StaticMutexAutoLock lock(sMutex);
MOZ_RELEASE_ASSERT(handle.get());
sAudioStreamInitEverSucceeded = true;
LABELS_MEDIA_AUDIO_BACKEND label = LABELS_MEDIA_AUDIO_BACKEND::unknown;
auto backend =
kTelemetryBackendLabel.find(cubeb_get_backend_id(handle->Context()));
kTelemetryBackendLabel.find(cubeb_get_backend_id(sCubebContext));
if (backend != kTelemetryBackendLabel.end()) {
label = backend->second;
}
@ -622,20 +605,12 @@ uint32_t GetCubebMTGLatencyInFrames(cubeb_stream_params* params) {
return 512;
}
#else
RefPtr<CubebHandle> handle = GetCubebUnlocked();
if (!handle) {
cubeb* context = GetCubebContextUnlocked();
if (!context) {
return sCubebMTGLatencyInFrames; // default 512
}
uint32_t latency_frames = 0;
int cubeb_result = CUBEB_OK;
{
StaticMutexAutoUnlock unlock(sMutex);
cubeb_result =
cubeb_get_min_latency(handle->Context(), params, &latency_frames);
}
if (cubeb_result != CUBEB_OK) {
if (cubeb_get_min_latency(context, params, &latency_frames) != CUBEB_OK) {
NS_WARNING("Could not get minimal latency from cubeb.");
return sCubebMTGLatencyInFrames; // default 512
}
@ -696,23 +671,17 @@ void ShutdownLibrary() {
Preferences::UnregisterCallbacks(PrefChanged, gInitCallbackPrefs);
Preferences::UnregisterCallbacks(PrefChanged, gCallbackPrefs);
cubeb_set_log_callback(CUBEB_LOG_DISABLED, nullptr);
RefPtr<CubebHandle> trash;
StaticMutexAutoLock lock(sMutex);
trash = sCubebHandle.forget();
cubeb_set_log_callback(CUBEB_LOG_DISABLED, nullptr);
if (sCubebContext) {
cubeb_destroy(sCubebContext);
sCubebContext = nullptr;
}
sBrandName = nullptr;
sCubebBackendName = nullptr;
// This will ensure we don't try to re-create a context.
sCubebState = CubebState::Shutdown;
if (trash) {
StaticMutexAutoUnlock unlock(sMutex);
nsrefcnt count = trash.forget().take()->Release();
MOZ_RELEASE_ASSERT(!count,
"ShutdownLibrary should be releasing the last reference "
"to the cubeb ctx!");
}
#ifdef MOZ_CUBEB_REMOTING
sIPCConnection = nullptr;
ShutdownAudioIPCServer();
@ -729,10 +698,10 @@ bool SandboxEnabled() {
}
uint32_t MaxNumberOfChannels() {
RefPtr<CubebHandle> handle = GetCubeb();
cubeb* cubebContext = GetCubebContext();
uint32_t maxNumberOfChannels;
if (handle && cubeb_get_max_channel_count(handle->Context(),
&maxNumberOfChannels) == CUBEB_OK) {
if (cubebContext && cubeb_get_max_channel_count(
cubebContext, &maxNumberOfChannels) == CUBEB_OK) {
return maxNumberOfChannels;
}
@ -740,9 +709,9 @@ uint32_t MaxNumberOfChannels() {
}
void GetCurrentBackend(nsAString& aBackend) {
RefPtr<CubebHandle> handle = GetCubeb();
if (handle) {
const char* backend = cubeb_get_backend_id(handle->Context());
cubeb* cubebContext = GetCubebContext();
if (cubebContext) {
const char* backend = cubeb_get_backend_id(cubebContext);
if (backend) {
aBackend.AssignASCII(backend);
return;
@ -776,7 +745,6 @@ long datacb(cubeb_stream*, void*, const void*, void* out_buffer, long nframes) {
void statecb(cubeb_stream*, void*, cubeb_state) {}
bool EstimatedRoundTripLatencyDefaultDevices(double* aMean, double* aStdDev) {
RefPtr<CubebHandle> handle = GetCubeb();
nsTArray<double> roundtripLatencies;
// Create a cubeb stream with the correct latency and default input/output
// devices (mono/stereo channels). Wait for two seconds, get the latency a few
@ -784,7 +752,7 @@ bool EstimatedRoundTripLatencyDefaultDevices(double* aMean, double* aStdDev) {
int rv;
uint32_t rate;
uint32_t latencyFrames;
rv = cubeb_get_preferred_sample_rate(handle->Context(), &rate);
rv = cubeb_get_preferred_sample_rate(GetCubebContext(), &rate);
if (rv != CUBEB_OK) {
MOZ_LOG(gCubebLog, LogLevel::Error, ("Could not get preferred rate"));
return false;
@ -807,7 +775,7 @@ bool EstimatedRoundTripLatencyDefaultDevices(double* aMean, double* aStdDev) {
input_params.prefs = GetDefaultStreamPrefs(CUBEB_DEVICE_TYPE_INPUT);
cubeb_stream* stm;
rv = cubeb_stream_init(handle->Context(), &stm,
rv = cubeb_stream_init(GetCubebContext(), &stm,
"about:support latency estimation", NULL,
&input_params, NULL, &output_params, latencyFrames,
datacb, statecb, NULL);

View File

@ -11,7 +11,6 @@
# include "AudioSampleFormat.h"
# include "nsString.h"
# include "nsISupportsImpl.h"
class AudioDeviceInfo;
@ -35,23 +34,6 @@ struct ToCubebFormat<AUDIO_FORMAT_S16> {
static const cubeb_sample_format value = CUBEB_SAMPLE_S16NE;
};
class CubebHandle {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CubebHandle)
explicit CubebHandle(cubeb* aCubeb) : mCubeb(aCubeb) {
MOZ_RELEASE_ASSERT(mCubeb);
};
CubebHandle(const CubebHandle&) = delete;
cubeb* Context() const { return mCubeb.get(); }
private:
struct CubebDeletePolicy {
void operator()(cubeb* aCubeb) { cubeb_destroy(aCubeb); }
};
const UniquePtr<cubeb, CubebDeletePolicy> mCubeb;
~CubebHandle() = default;
};
// Initialize Audio Library. Some Audio backends require initializing the
// library before using it.
void InitLibrary();
@ -83,7 +65,7 @@ enum Side { Input, Output };
double GetVolumeScale();
bool GetFirstStream();
RefPtr<CubebHandle> GetCubeb();
cubeb* GetCubebContext();
void ReportCubebStreamInitFailure(bool aIsFirstStream);
void ReportCubebBackendUsed();
uint32_t GetCubebPlaybackLatencyInMilliseconds();

View File

@ -128,12 +128,12 @@ class MediaTrackGraphInitThreadRunnable : public Runnable {
MOZ_ASSERT(!mDriver->AsAudioCallbackDriver());
AudioCallbackDriver* audioCallbackDriver =
previousDriver->AsAudioCallbackDriver();
MOZ_ALWAYS_SUCCEEDS(audioCallbackDriver->mCubebOperationThread->Dispatch(
audioCallbackDriver->mCubebOperationThread->Dispatch(
NS_NewRunnableFunction(
"ThreadedDriver previousDriver::Stop()",
[audioCallbackDriver = RefPtr{audioCallbackDriver}] {
audioCallbackDriver->Stop();
})));
}));
mDriver->SetPreviousDriver(nullptr);
}
@ -428,17 +428,6 @@ class AudioCallbackDriver::FallbackWrapper : public GraphInterface {
NS_IMPL_ISUPPORTS0(AudioCallbackDriver::FallbackWrapper)
/* static */
already_AddRefed<TaskQueue> AudioCallbackDriver::CreateTaskQueue() {
RefPtr<SharedThreadPool> pool = CUBEB_TASK_THREAD;
const uint32_t kIdleThreadTimeoutMs = 2000;
pool->SetIdleThreadTimeout(PR_MillisecondsToInterval(kIdleThreadTimeoutMs));
RefPtr<TaskQueue> queue =
TaskQueue::Create(pool.forget(), "AudioCallbackDriver cubeb task queue");
return queue.forget();
}
AudioCallbackDriver::AudioCallbackDriver(
GraphInterface* aGraphInterface, GraphDriver* aPreviousDriver,
uint32_t aSampleRate, uint32_t aOutputChannelCount,
@ -450,7 +439,7 @@ AudioCallbackDriver::AudioCallbackDriver(
mOutputDeviceID(aOutputDeviceID),
mInputDeviceID(aInputDeviceID),
mIterationDurationMS(MEDIA_GRAPH_TARGET_PERIOD_MS),
mCubebOperationThread(CreateTaskQueue()),
mCubebOperationThread(CUBEB_TASK_THREAD),
mAudioThreadId(ProfilerThreadId{}),
mAudioThreadIdInCb(std::thread::id()),
mFallback("AudioCallbackDriver::mFallback"),
@ -464,6 +453,10 @@ AudioCallbackDriver::AudioCallbackDriver(
"Invalid output channel count");
MOZ_ASSERT(mOutputChannelCount <= 8);
const uint32_t kIdleThreadTimeoutMs = 2000;
mCubebOperationThread->SetIdleThreadTimeout(
PR_MillisecondsToInterval(kIdleThreadTimeoutMs));
bool allowVoice = true;
#ifdef MOZ_WIDGET_COCOA
// Using the VoiceProcessingIO audio unit on MacOS 12 causes crashes in
@ -521,8 +514,8 @@ void AudioCallbackDriver::Init(const nsCString& aStreamName) {
return;
}
bool fromFallback = fallbackState == FallbackDriverState::Running;
RefPtr<CubebUtils::CubebHandle> handle = CubebUtils::GetCubeb();
if (!handle) {
cubeb* cubebContext = CubebUtils::GetCubebContext();
if (!cubebContext) {
NS_WARNING("Could not get cubeb context.");
LOG(LogLevel::Warning, ("%s: Could not get cubeb context", __func__));
mAudioStreamState = AudioStreamState::None;
@ -631,11 +624,10 @@ void AudioCallbackDriver::Init(const nsCString& aStreamName) {
CubebUtils::AudioDeviceID inputId = mInputDeviceID;
if (CubebUtils::CubebStreamInit(
handle->Context(), &stream, streamName, inputId,
cubebContext, &stream, streamName, inputId,
inputWanted ? &input : nullptr,
forcedOutputDeviceId ? forcedOutputDeviceId : outputId, &output,
latencyFrames, DataCallback_s, StateCallback_s, this) == CUBEB_OK) {
mCubeb = handle;
mAudioStream.own(stream);
DebugOnly<int> rv =
cubeb_stream_set_volume(mAudioStream, CubebUtils::GetVolumeScale());
@ -702,13 +694,11 @@ void AudioCallbackDriver::Start() {
if (AudioCallbackDriver* previousAudioCallback =
mPreviousDriver->AsAudioCallbackDriver()) {
LOG(LogLevel::Debug, ("Releasing audio driver off main thread."));
MOZ_ALWAYS_SUCCEEDS(
previousAudioCallback->mCubebOperationThread->Dispatch(
NS_NewRunnableFunction(
"AudioCallbackDriver previousDriver::Stop()",
[previousDriver = RefPtr{previousAudioCallback}] {
previousDriver->Stop();
})));
mCubebOperationThread->Dispatch(NS_NewRunnableFunction(
"AudioCallbackDriver previousDriver::Stop()",
[previousDriver = RefPtr{previousAudioCallback}] {
previousDriver->Stop();
}));
} else {
LOG(LogLevel::Debug,
("Dropping driver reference for SystemClockDriver."));
@ -719,11 +709,11 @@ void AudioCallbackDriver::Start() {
LOG(LogLevel::Debug, ("Starting new audio driver off main thread, "
"to ensure it runs after previous shutdown."));
MOZ_ALWAYS_SUCCEEDS(mCubebOperationThread->Dispatch(
mCubebOperationThread->Dispatch(
NS_NewRunnableFunction("AudioCallbackDriver Init()",
[self = RefPtr{this}, streamName = mStreamName] {
self->Init(streamName);
})));
}));
}
bool AudioCallbackDriver::StartStream() {
@ -798,11 +788,11 @@ void AudioCallbackDriver::SetStreamName(const nsACString& aStreamName) {
AudioStreamState streamState = mAudioStreamState;
if (streamState != AudioStreamState::None &&
streamState != AudioStreamState::Stopping) {
MOZ_ALWAYS_SUCCEEDS(mCubebOperationThread->Dispatch(
mCubebOperationThread->Dispatch(
NS_NewRunnableFunction("AudioCallbackDriver SetStreamName()",
[self = RefPtr{this}, streamName = mStreamName] {
self->SetCubebStreamName(streamName);
})));
}));
}
}

View File

@ -15,7 +15,7 @@
#include "mozilla/Atomics.h"
#include "mozilla/dom/AudioContext.h"
#include "mozilla/DataMutex.h"
#include "mozilla/TaskQueue.h"
#include "mozilla/SharedThreadPool.h"
#include "mozilla/StaticPtr.h"
#include "WavDumper.h"
@ -549,8 +549,7 @@ class AudioCallbackDriver : public GraphDriver, public MixerCallbackReceiver {
class FallbackWrapper;
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_DELETE_ON_EVENT_TARGET(
AudioCallbackDriver, mCubebOperationThread, override);
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AudioCallbackDriver, override);
/** If aInputChannelCount is zero, then this driver is output-only. */
AudioCallbackDriver(GraphInterface* aGraphInterface,
@ -689,9 +688,6 @@ class AudioCallbackDriver : public GraphDriver, public MixerCallbackReceiver {
* audio buffer cubeb passes us. This is only ever accessed on the audio
* callback thread. */
AudioCallbackBufferWrapper<AudioDataValue> mBuffer;
// mAudioStream (a cubeb_stream) has a bare pointer to the cubeb context, so
// we hold a strong reference on its behalf.
RefPtr<CubebUtils::CubebHandle> mCubeb;
/* cubeb stream for this graph. This is non-null after a successful
* cubeb_stream_init(). CubebOperation thread only. */
nsAutoRef<cubeb_stream> mAudioStream;
@ -714,12 +710,10 @@ class AudioCallbackDriver : public GraphDriver, public MixerCallbackReceiver {
AudioCallbackDriver* mDriver;
};
static already_AddRefed<TaskQueue> CreateTaskQueue();
/* Shared thread pool with up to one thread for off-main-thread
* initialization and shutdown of the audio stream and for other tasks that
* must run serially for access to mAudioStream. */
const RefPtr<TaskQueue> mCubebOperationThread;
const RefPtr<SharedThreadPool> mCubebOperationThread;
cubeb_device_pref mInputDevicePreference;
/* Contains the id of the audio thread, from profiler_current_thread_id. */
std::atomic<ProfilerThreadId> mAudioThreadId;

View File

@ -58,9 +58,8 @@ CubebDeviceEnumerator::CubebDeviceEnumerator()
// before the MTA thread gets shutdown.
mozilla::mscom::EnsureMTA([&]() -> void {
#endif
RefPtr<CubebHandle> handle = GetCubeb();
int rv = cubeb_register_device_collection_changed(
handle->Context(), CUBEB_DEVICE_TYPE_OUTPUT,
GetCubebContext(), CUBEB_DEVICE_TYPE_OUTPUT,
&OutputAudioDeviceListChanged_s, this);
if (rv != CUBEB_OK) {
NS_WARNING(
@ -69,7 +68,7 @@ CubebDeviceEnumerator::CubebDeviceEnumerator()
mManualOutputInvalidation = true;
}
rv = cubeb_register_device_collection_changed(
handle->Context(), CUBEB_DEVICE_TYPE_INPUT,
GetCubebContext(), CUBEB_DEVICE_TYPE_INPUT,
&InputAudioDeviceListChanged_s, this);
if (rv != CUBEB_OK) {
NS_WARNING(
@ -94,22 +93,19 @@ CubebDeviceEnumerator::~CubebDeviceEnumerator() {
#ifdef XP_WIN
mozilla::mscom::EnsureMTA([&]() -> void {
#endif
RefPtr<CubebHandle> handle = GetCubeb();
if (handle) {
int rv = cubeb_register_device_collection_changed(
handle->Context(), CUBEB_DEVICE_TYPE_OUTPUT, nullptr, this);
if (rv != CUBEB_OK) {
NS_WARNING(
"Could not unregister the audio output"
" device collection changed callback.");
}
rv = cubeb_register_device_collection_changed(
handle->Context(), CUBEB_DEVICE_TYPE_INPUT, nullptr, this);
if (rv != CUBEB_OK) {
NS_WARNING(
"Could not unregister the audio input"
" device collection changed callback.");
}
int rv = cubeb_register_device_collection_changed(
GetCubebContext(), CUBEB_DEVICE_TYPE_OUTPUT, nullptr, this);
if (rv != CUBEB_OK) {
NS_WARNING(
"Could not unregister the audio output"
" device collection changed callback.");
}
rv = cubeb_register_device_collection_changed(
GetCubebContext(), CUBEB_DEVICE_TYPE_INPUT, nullptr, this);
if (rv != CUBEB_OK) {
NS_WARNING(
"Could not unregister the audio input"
" device collection changed callback.");
}
#ifdef XP_WIN
});
@ -185,13 +181,13 @@ static uint16_t ConvertCubebFormat(cubeb_device_fmt aFormat) {
static RefPtr<AudioDeviceSet> GetDeviceCollection(Side aSide) {
RefPtr set = new AudioDeviceSet();
RefPtr<CubebHandle> handle = GetCubeb();
if (handle) {
cubeb* context = GetCubebContext();
if (context) {
cubeb_device_collection collection = {nullptr, 0};
# ifdef XP_WIN
mozilla::mscom::EnsureMTA([&]() -> void {
# endif
if (cubeb_enumerate_devices(handle->Context(),
if (cubeb_enumerate_devices(context,
aSide == Input ? CUBEB_DEVICE_TYPE_INPUT
: CUBEB_DEVICE_TYPE_OUTPUT,
&collection) == CUBEB_OK) {
@ -213,7 +209,7 @@ static RefPtr<AudioDeviceSet> GetDeviceCollection(Side aSide) {
set->AppendElement(std::move(info));
}
}
cubeb_device_collection_destroy(handle->Context(), &collection);
cubeb_device_collection_destroy(context, &collection);
# ifdef XP_WIN
});
# endif
@ -238,7 +234,8 @@ RefPtr<const AudioDeviceSet> CubebDeviceEnumerator::EnumerateAudioDevices(
manualInvalidation = mManualOutputInvalidation;
}
if (!GetCubeb()) {
cubeb* context = GetCubebContext();
if (!context) {
return new AudioDeviceSet();
}
if (!manualInvalidation) {