Bug 1876526: Make cubeb singleton refcounted. r=pehrsons
Differential Revision: https://phabricator.services.mozilla.com/D200178
This commit is contained in:
@@ -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::GetCubebContext();
|
||||
Unused << CubebUtils::GetCubeb();
|
||||
}
|
||||
|
||||
if (sandboxEnabled) {
|
||||
|
||||
@@ -245,14 +245,15 @@ nsresult AudioStream::Init(AudioDeviceInfo* aSinkInfo)
|
||||
// This is noop if MOZ_DUMP_AUDIO is not set.
|
||||
mDumpFile.Open("AudioStream", mOutChannels, mAudioClock.GetInputRate());
|
||||
|
||||
cubeb* cubebContext = CubebUtils::GetCubebContext();
|
||||
if (!cubebContext) {
|
||||
RefPtr<CubebUtils::CubebHandle> handle = CubebUtils::GetCubeb();
|
||||
if (!handle) {
|
||||
LOGE("Can't get cubeb context!");
|
||||
CubebUtils::ReportCubebStreamInitFailure(true);
|
||||
return NS_ERROR_DOM_MEDIA_CUBEB_INITIALIZATION_ERR;
|
||||
}
|
||||
|
||||
return OpenCubeb(cubebContext, params, startTime,
|
||||
mCubeb = handle;
|
||||
return OpenCubeb(handle->Context(), params, startTime,
|
||||
CubebUtils::GetFirstStream());
|
||||
}
|
||||
|
||||
|
||||
@@ -337,6 +337,8 @@ 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;
|
||||
|
||||
@@ -83,8 +83,8 @@ UniquePtr<CubebInputStream> CubebInputStream::Create(cubeb_devid aDeviceId,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
cubeb* context = CubebUtils::GetCubebContext();
|
||||
if (!context) {
|
||||
RefPtr<CubebUtils::CubebHandle> handle = CubebUtils::GetCubeb();
|
||||
if (!handle) {
|
||||
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(
|
||||
context, &cubebStream, "input-only stream", aDeviceId, ¶ms,
|
||||
nullptr, nullptr, latencyFrames, DataCallback_s, StateCallback_s,
|
||||
listener.get());
|
||||
handle->Context(), &cubebStream, "input-only stream", aDeviceId,
|
||||
¶ms, 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,7 +120,9 @@ UniquePtr<CubebInputStream> CubebInputStream::Create(cubeb_devid aDeviceId,
|
||||
CubebInputStream::CubebInputStream(
|
||||
already_AddRefed<Listener>&& aListener,
|
||||
UniquePtr<cubeb_stream, CubebDestroyPolicy>&& aStream)
|
||||
: mListener(aListener), mStream(std::move(aStream)) {
|
||||
: mListener(aListener),
|
||||
mCubeb(CubebUtils::GetCubeb()),
|
||||
mStream(std::move(aStream)) {
|
||||
MOZ_ASSERT(mListener);
|
||||
MOZ_ASSERT(mStream);
|
||||
}
|
||||
|
||||
@@ -76,6 +76,8 @@ 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;
|
||||
};
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ enum class CubebState {
|
||||
Initialized,
|
||||
Shutdown
|
||||
} sCubebState = CubebState::Uninitialized;
|
||||
cubeb* sCubebContext;
|
||||
StaticRefPtr<CubebUtils::CubebHandle> sCubebHandle;
|
||||
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 {
|
||||
cubeb* GetCubebContextUnlocked();
|
||||
RefPtr<CubebHandle> GetCubebUnlocked();
|
||||
|
||||
void GetPrefAndSetString(const char* aPref, StaticAutoPtr<char>& aStorage) {
|
||||
nsAutoCString value;
|
||||
@@ -292,18 +292,19 @@ double GetVolumeScale() {
|
||||
return sVolumeScale;
|
||||
}
|
||||
|
||||
cubeb* GetCubebContext() {
|
||||
RefPtr<CubebHandle> GetCubeb() {
|
||||
StaticMutexAutoLock lock(sMutex);
|
||||
return GetCubebContextUnlocked();
|
||||
return GetCubebUnlocked();
|
||||
}
|
||||
|
||||
// This is only exported when running tests.
|
||||
void ForceSetCubebContext(cubeb* aCubebContext) {
|
||||
StaticMutexAutoLock lock(sMutex);
|
||||
if (sCubebContext) {
|
||||
cubeb_destroy(sCubebContext);
|
||||
if (aCubebContext) {
|
||||
sCubebHandle = new CubebHandle(aCubebContext);
|
||||
} else {
|
||||
sCubebHandle = nullptr;
|
||||
}
|
||||
sCubebContext = aCubebContext;
|
||||
sCubebState = CubebState::Initialized;
|
||||
}
|
||||
|
||||
@@ -339,12 +340,12 @@ bool InitPreferredSampleRate() {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
cubeb* context = GetCubebContextUnlocked();
|
||||
if (!context) {
|
||||
RefPtr<CubebHandle> handle = GetCubebUnlocked();
|
||||
if (!handle) {
|
||||
return false;
|
||||
}
|
||||
uint32_t rate;
|
||||
if (cubeb_get_preferred_sample_rate(context, &rate) != CUBEB_OK) {
|
||||
if (cubeb_get_preferred_sample_rate(handle->Context(), &rate) != CUBEB_OK) {
|
||||
return false;
|
||||
}
|
||||
sPreferredSampleRate = rate;
|
||||
@@ -473,7 +474,7 @@ ipc::FileDescriptor CreateAudioIPCConnection() {
|
||||
#endif
|
||||
}
|
||||
|
||||
cubeb* GetCubebContextUnlocked() {
|
||||
RefPtr<CubebHandle> GetCubebUnlocked() {
|
||||
sMutex.AssertCurrentThreadOwns();
|
||||
if (sCubebForceNullContext) {
|
||||
// Pref set such that we should return a null context
|
||||
@@ -485,7 +486,7 @@ cubeb* GetCubebContextUnlocked() {
|
||||
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 sCubebContext;
|
||||
return sCubebHandle;
|
||||
}
|
||||
|
||||
if (!sBrandName && NS_IsMainThread()) {
|
||||
@@ -527,14 +528,21 @@ cubeb* GetCubebContextUnlocked() {
|
||||
};
|
||||
initParams.mThreadDestroyCallback = []() { PROFILER_UNREGISTER_THREAD(); };
|
||||
|
||||
rv = audioipc2::audioipc2_client_init(&sCubebContext, sBrandName,
|
||||
&initParams);
|
||||
cubeb* temp = nullptr;
|
||||
rv = audioipc2::audioipc2_client_init(&temp, sBrandName, &initParams);
|
||||
if (temp) {
|
||||
sCubebHandle = new CubebHandle(temp);
|
||||
}
|
||||
} else {
|
||||
#endif // MOZ_CUBEB_REMOTING
|
||||
#ifdef XP_WIN
|
||||
mozilla::mscom::EnsureMTA([&]() -> void {
|
||||
#endif
|
||||
rv = cubeb_init(&sCubebContext, sBrandName, sCubebBackendName);
|
||||
cubeb* temp = nullptr;
|
||||
rv = cubeb_init(&temp, sBrandName, sCubebBackendName);
|
||||
if (temp) {
|
||||
sCubebHandle = new CubebHandle(temp);
|
||||
}
|
||||
#ifdef XP_WIN
|
||||
});
|
||||
#endif
|
||||
@@ -546,17 +554,21 @@ cubeb* GetCubebContextUnlocked() {
|
||||
sCubebState =
|
||||
(rv == CUBEB_OK) ? CubebState::Initialized : CubebState::Uninitialized;
|
||||
|
||||
return sCubebContext;
|
||||
return sCubebHandle;
|
||||
}
|
||||
|
||||
void ReportCubebBackendUsed() {
|
||||
StaticMutexAutoLock lock(sMutex);
|
||||
RefPtr<CubebHandle> handle;
|
||||
|
||||
sAudioStreamInitEverSucceeded = true;
|
||||
handle = sCubebHandle;
|
||||
|
||||
MOZ_RELEASE_ASSERT(handle.get());
|
||||
|
||||
LABELS_MEDIA_AUDIO_BACKEND label = LABELS_MEDIA_AUDIO_BACKEND::unknown;
|
||||
auto backend =
|
||||
kTelemetryBackendLabel.find(cubeb_get_backend_id(sCubebContext));
|
||||
kTelemetryBackendLabel.find(cubeb_get_backend_id(handle->Context()));
|
||||
if (backend != kTelemetryBackendLabel.end()) {
|
||||
label = backend->second;
|
||||
}
|
||||
@@ -605,12 +617,13 @@ uint32_t GetCubebMTGLatencyInFrames(cubeb_stream_params* params) {
|
||||
return 512;
|
||||
}
|
||||
#else
|
||||
cubeb* context = GetCubebContextUnlocked();
|
||||
if (!context) {
|
||||
RefPtr<CubebHandle> handle = GetCubebUnlocked();
|
||||
if (!handle) {
|
||||
return sCubebMTGLatencyInFrames; // default 512
|
||||
}
|
||||
uint32_t latency_frames = 0;
|
||||
if (cubeb_get_min_latency(context, params, &latency_frames) != CUBEB_OK) {
|
||||
if (cubeb_get_min_latency(handle->Context(), params, &latency_frames) !=
|
||||
CUBEB_OK) {
|
||||
NS_WARNING("Could not get minimal latency from cubeb.");
|
||||
return sCubebMTGLatencyInFrames; // default 512
|
||||
}
|
||||
@@ -673,9 +686,11 @@ void ShutdownLibrary() {
|
||||
|
||||
StaticMutexAutoLock lock(sMutex);
|
||||
cubeb_set_log_callback(CUBEB_LOG_DISABLED, nullptr);
|
||||
if (sCubebContext) {
|
||||
cubeb_destroy(sCubebContext);
|
||||
sCubebContext = nullptr;
|
||||
if (sCubebHandle) {
|
||||
nsrefcnt count = sCubebHandle.forget().take()->Release();
|
||||
MOZ_RELEASE_ASSERT(!count,
|
||||
"ShutdownLibrary should be releasing the last reference "
|
||||
"to the cubeb ctx!");
|
||||
}
|
||||
sBrandName = nullptr;
|
||||
sCubebBackendName = nullptr;
|
||||
@@ -698,10 +713,10 @@ bool SandboxEnabled() {
|
||||
}
|
||||
|
||||
uint32_t MaxNumberOfChannels() {
|
||||
cubeb* cubebContext = GetCubebContext();
|
||||
RefPtr<CubebHandle> handle = GetCubeb();
|
||||
uint32_t maxNumberOfChannels;
|
||||
if (cubebContext && cubeb_get_max_channel_count(
|
||||
cubebContext, &maxNumberOfChannels) == CUBEB_OK) {
|
||||
if (handle && cubeb_get_max_channel_count(handle->Context(),
|
||||
&maxNumberOfChannels) == CUBEB_OK) {
|
||||
return maxNumberOfChannels;
|
||||
}
|
||||
|
||||
@@ -709,9 +724,9 @@ uint32_t MaxNumberOfChannels() {
|
||||
}
|
||||
|
||||
void GetCurrentBackend(nsAString& aBackend) {
|
||||
cubeb* cubebContext = GetCubebContext();
|
||||
if (cubebContext) {
|
||||
const char* backend = cubeb_get_backend_id(cubebContext);
|
||||
RefPtr<CubebHandle> handle = GetCubeb();
|
||||
if (handle) {
|
||||
const char* backend = cubeb_get_backend_id(handle->Context());
|
||||
if (backend) {
|
||||
aBackend.AssignASCII(backend);
|
||||
return;
|
||||
@@ -745,6 +760,7 @@ 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
|
||||
@@ -752,7 +768,7 @@ bool EstimatedRoundTripLatencyDefaultDevices(double* aMean, double* aStdDev) {
|
||||
int rv;
|
||||
uint32_t rate;
|
||||
uint32_t latencyFrames;
|
||||
rv = cubeb_get_preferred_sample_rate(GetCubebContext(), &rate);
|
||||
rv = cubeb_get_preferred_sample_rate(handle->Context(), &rate);
|
||||
if (rv != CUBEB_OK) {
|
||||
MOZ_LOG(gCubebLog, LogLevel::Error, ("Could not get preferred rate"));
|
||||
return false;
|
||||
@@ -775,7 +791,7 @@ bool EstimatedRoundTripLatencyDefaultDevices(double* aMean, double* aStdDev) {
|
||||
input_params.prefs = GetDefaultStreamPrefs(CUBEB_DEVICE_TYPE_INPUT);
|
||||
|
||||
cubeb_stream* stm;
|
||||
rv = cubeb_stream_init(GetCubebContext(), &stm,
|
||||
rv = cubeb_stream_init(handle->Context(), &stm,
|
||||
"about:support latency estimation", NULL,
|
||||
&input_params, NULL, &output_params, latencyFrames,
|
||||
datacb, statecb, NULL);
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
# include "AudioSampleFormat.h"
|
||||
# include "nsString.h"
|
||||
# include "nsISupportsImpl.h"
|
||||
|
||||
class AudioDeviceInfo;
|
||||
|
||||
@@ -34,6 +35,23 @@ 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();
|
||||
@@ -65,7 +83,7 @@ enum Side { Input, Output };
|
||||
|
||||
double GetVolumeScale();
|
||||
bool GetFirstStream();
|
||||
cubeb* GetCubebContext();
|
||||
RefPtr<CubebHandle> GetCubeb();
|
||||
void ReportCubebStreamInitFailure(bool aIsFirstStream);
|
||||
void ReportCubebBackendUsed();
|
||||
uint32_t GetCubebPlaybackLatencyInMilliseconds();
|
||||
|
||||
@@ -521,8 +521,8 @@ void AudioCallbackDriver::Init(const nsCString& aStreamName) {
|
||||
return;
|
||||
}
|
||||
bool fromFallback = fallbackState == FallbackDriverState::Running;
|
||||
cubeb* cubebContext = CubebUtils::GetCubebContext();
|
||||
if (!cubebContext) {
|
||||
RefPtr<CubebUtils::CubebHandle> handle = CubebUtils::GetCubeb();
|
||||
if (!handle) {
|
||||
NS_WARNING("Could not get cubeb context.");
|
||||
LOG(LogLevel::Warning, ("%s: Could not get cubeb context", __func__));
|
||||
mAudioStreamState = AudioStreamState::None;
|
||||
@@ -631,10 +631,11 @@ void AudioCallbackDriver::Init(const nsCString& aStreamName) {
|
||||
CubebUtils::AudioDeviceID inputId = mInputDeviceID;
|
||||
|
||||
if (CubebUtils::CubebStreamInit(
|
||||
cubebContext, &stream, streamName, inputId,
|
||||
handle->Context(), &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());
|
||||
|
||||
@@ -689,6 +689,9 @@ 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;
|
||||
|
||||
@@ -58,8 +58,9 @@ CubebDeviceEnumerator::CubebDeviceEnumerator()
|
||||
// before the MTA thread gets shutdown.
|
||||
mozilla::mscom::EnsureMTA([&]() -> void {
|
||||
#endif
|
||||
RefPtr<CubebHandle> handle = GetCubeb();
|
||||
int rv = cubeb_register_device_collection_changed(
|
||||
GetCubebContext(), CUBEB_DEVICE_TYPE_OUTPUT,
|
||||
handle->Context(), CUBEB_DEVICE_TYPE_OUTPUT,
|
||||
&OutputAudioDeviceListChanged_s, this);
|
||||
if (rv != CUBEB_OK) {
|
||||
NS_WARNING(
|
||||
@@ -68,7 +69,7 @@ CubebDeviceEnumerator::CubebDeviceEnumerator()
|
||||
mManualOutputInvalidation = true;
|
||||
}
|
||||
rv = cubeb_register_device_collection_changed(
|
||||
GetCubebContext(), CUBEB_DEVICE_TYPE_INPUT,
|
||||
handle->Context(), CUBEB_DEVICE_TYPE_INPUT,
|
||||
&InputAudioDeviceListChanged_s, this);
|
||||
if (rv != CUBEB_OK) {
|
||||
NS_WARNING(
|
||||
@@ -93,19 +94,22 @@ CubebDeviceEnumerator::~CubebDeviceEnumerator() {
|
||||
#ifdef XP_WIN
|
||||
mozilla::mscom::EnsureMTA([&]() -> void {
|
||||
#endif
|
||||
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.");
|
||||
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.");
|
||||
}
|
||||
}
|
||||
#ifdef XP_WIN
|
||||
});
|
||||
@@ -181,13 +185,13 @@ static uint16_t ConvertCubebFormat(cubeb_device_fmt aFormat) {
|
||||
|
||||
static RefPtr<AudioDeviceSet> GetDeviceCollection(Side aSide) {
|
||||
RefPtr set = new AudioDeviceSet();
|
||||
cubeb* context = GetCubebContext();
|
||||
if (context) {
|
||||
RefPtr<CubebHandle> handle = GetCubeb();
|
||||
if (handle) {
|
||||
cubeb_device_collection collection = {nullptr, 0};
|
||||
# ifdef XP_WIN
|
||||
mozilla::mscom::EnsureMTA([&]() -> void {
|
||||
# endif
|
||||
if (cubeb_enumerate_devices(context,
|
||||
if (cubeb_enumerate_devices(handle->Context(),
|
||||
aSide == Input ? CUBEB_DEVICE_TYPE_INPUT
|
||||
: CUBEB_DEVICE_TYPE_OUTPUT,
|
||||
&collection) == CUBEB_OK) {
|
||||
@@ -209,7 +213,7 @@ static RefPtr<AudioDeviceSet> GetDeviceCollection(Side aSide) {
|
||||
set->AppendElement(std::move(info));
|
||||
}
|
||||
}
|
||||
cubeb_device_collection_destroy(context, &collection);
|
||||
cubeb_device_collection_destroy(handle->Context(), &collection);
|
||||
# ifdef XP_WIN
|
||||
});
|
||||
# endif
|
||||
@@ -234,8 +238,7 @@ RefPtr<const AudioDeviceSet> CubebDeviceEnumerator::EnumerateAudioDevices(
|
||||
manualInvalidation = mManualOutputInvalidation;
|
||||
}
|
||||
|
||||
cubeb* context = GetCubebContext();
|
||||
if (!context) {
|
||||
if (!GetCubeb()) {
|
||||
return new AudioDeviceSet();
|
||||
}
|
||||
if (!manualInvalidation) {
|
||||
|
||||
Reference in New Issue
Block a user