зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 3 changesets (bug 1650277) for RunWatchdog crashes CLOSED TREE
Backed out changeset 07863e9844f0 (bug 1650277) Backed out changeset 1bf131a86868 (bug 1650277) Backed out changeset 11aa7071f858 (bug 1650277)
This commit is contained in:
Родитель
d813074347
Коммит
3fa273fbc7
|
@ -6,6 +6,9 @@
|
|||
|
||||
#include "CubebUtils.h"
|
||||
|
||||
#ifdef MOZ_WEBRTC
|
||||
# include "CubebDeviceEnumerator.h"
|
||||
#endif
|
||||
#include "MediaInfo.h"
|
||||
#include "mozilla/AbstractThread.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
|
@ -630,6 +633,11 @@ void ShutdownLibrary() {
|
|||
Preferences::UnregisterCallbacks(PrefChanged, gInitCallbackPrefs);
|
||||
Preferences::UnregisterCallbacks(PrefChanged, gCallbackPrefs);
|
||||
|
||||
#ifdef MOZ_WEBRTC
|
||||
// This must be done before cubeb destroy.
|
||||
CubebDeviceEnumerator::Shutdown();
|
||||
#endif
|
||||
|
||||
StaticMutexAutoLock lock(sMutex);
|
||||
if (sCubebContext) {
|
||||
cubeb_destroy(sCubebContext);
|
||||
|
|
|
@ -9,15 +9,27 @@
|
|||
#include "AudioCaptureTrack.h"
|
||||
#include "AudioDeviceInfo.h"
|
||||
#include "AudioStreamTrack.h"
|
||||
#include "CubebDeviceEnumerator.h"
|
||||
#include "MediaTimer.h"
|
||||
#include "MediaTrackConstraints.h"
|
||||
#include "MediaTrackGraphImpl.h"
|
||||
#include "MediaTrackListener.h"
|
||||
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
|
||||
#include "VideoStreamTrack.h"
|
||||
#include "VideoUtils.h"
|
||||
#include "mozilla/Base64.h"
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/FeaturePolicyUtils.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/MediaDeviceInfo.h"
|
||||
#include "mozilla/dom/MediaDevices.h"
|
||||
#include "mozilla/dom/MediaStreamBinding.h"
|
||||
#include "mozilla/dom/MediaStreamTrackBinding.h"
|
||||
#include "mozilla/dom/GetUserMediaRequestBinding.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/UserActivation.h"
|
||||
#include "mozilla/dom/WindowContext.h"
|
||||
#include "mozilla/ipc/BackgroundChild.h"
|
||||
#include "mozilla/media/MediaChild.h"
|
||||
#include "mozilla/media/MediaTaskUtils.h"
|
||||
#include "mozilla/MozPromise.h"
|
||||
#include "mozilla/NullPrincipal.h"
|
||||
#include "mozilla/PeerIdentity.h"
|
||||
|
@ -26,22 +38,6 @@
|
|||
#include "mozilla/StaticPrefs_media.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/Types.h"
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/FeaturePolicyUtils.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/GetUserMediaRequestBinding.h"
|
||||
#include "mozilla/dom/MediaDeviceInfo.h"
|
||||
#include "mozilla/dom/MediaDevices.h"
|
||||
#include "mozilla/dom/MediaStreamBinding.h"
|
||||
#include "mozilla/dom/MediaStreamTrackBinding.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/UserActivation.h"
|
||||
#include "mozilla/dom/WindowContext.h"
|
||||
#include "mozilla/ipc/BackgroundChild.h"
|
||||
#include "mozilla/media/MediaChild.h"
|
||||
#include "mozilla/media/MediaTaskUtils.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "nsArray.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
@ -57,11 +53,15 @@
|
|||
#include "nsNetCID.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsProxyRelease.h"
|
||||
#include "nsVariant.h"
|
||||
#include "nspr.h"
|
||||
#include "nsProxyRelease.h"
|
||||
#include "nss.h"
|
||||
#include "nsVariant.h"
|
||||
#include "pk11pub.h"
|
||||
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
|
||||
#include "VideoStreamTrack.h"
|
||||
#include "VideoUtils.h"
|
||||
#include "CubebDeviceEnumerator.h"
|
||||
|
||||
/* Using WebRTC backend on Desktops (Mac, Windows, Linux), otherwise default */
|
||||
#include "MediaEngineDefault.h"
|
||||
|
@ -72,12 +72,11 @@
|
|||
#endif
|
||||
|
||||
#if defined(XP_WIN)
|
||||
# include <iphlpapi.h>
|
||||
# include <objbase.h>
|
||||
# include <tchar.h>
|
||||
# include <winsock2.h>
|
||||
|
||||
# include "mozilla/WindowsVersion.h"
|
||||
# include <objbase.h>
|
||||
# include <winsock2.h>
|
||||
# include <iphlpapi.h>
|
||||
# include <tchar.h>
|
||||
#endif
|
||||
|
||||
// XXX Workaround for bug 986974 to maintain the existing broken semantics
|
||||
|
@ -1413,9 +1412,9 @@ RefPtr<MediaManager::BadConstraintsPromise> MediaManager::SelectSettings(
|
|||
// Algorithm accesses device capabilities code and must run on media thread.
|
||||
// Modifies passed-in aSources.
|
||||
|
||||
return MediaManager::Dispatch<BadConstraintsPromise>(
|
||||
__func__, [aConstraints, aSources,
|
||||
aIsChrome](MozPromiseHolder<BadConstraintsPromise>& holder) {
|
||||
return MediaManager::PostTask<BadConstraintsPromise>(
|
||||
__func__, [aConstraints, aSources, aIsChrome](
|
||||
MozPromiseHolder<BadConstraintsPromise>& holder) mutable {
|
||||
auto& sources = *aSources;
|
||||
|
||||
// Since the advanced part of the constraints algorithm needs to know
|
||||
|
@ -1895,14 +1894,14 @@ RefPtr<MediaManager::MgrPromise> MediaManager::EnumerateRawDevices(
|
|||
} else {
|
||||
// Don't need to ask permission to retrieve list of all devices;
|
||||
// post the retrieval task immediately.
|
||||
MediaManager::Dispatch(task.forget());
|
||||
MediaManager::PostTask(task.forget());
|
||||
}
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
MediaManager::MediaManager(already_AddRefed<nsISerialEventTarget> aMediaThread)
|
||||
: mMediaThread(aMediaThread), mBackend(nullptr) {
|
||||
MediaManager::MediaManager(UniquePtr<base::Thread> aMediaThread)
|
||||
: mMediaThread(std::move(aMediaThread)), mBackend(nullptr) {
|
||||
mPrefs.mFreq = 1000; // 1KHz test tone
|
||||
mPrefs.mWidth = 0; // adaptive default
|
||||
mPrefs.mHeight = 0; // adaptive default
|
||||
|
@ -1964,10 +1963,34 @@ StaticMutex MediaManager::sSingletonMutex;
|
|||
/* static */
|
||||
bool MediaManager::IsInMediaThread() {
|
||||
StaticMutexAutoLock lock(sSingletonMutex);
|
||||
return sSingleton && sSingleton->mMediaThread->IsOnCurrentThread();
|
||||
return sSingleton ? (sSingleton->mMediaThread->thread_id() ==
|
||||
PlatformThread::CurrentId())
|
||||
: false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
class MTAThread : public base::Thread {
|
||||
public:
|
||||
explicit MTAThread(const char* aName)
|
||||
: base::Thread(aName), mResult(E_FAIL) {}
|
||||
|
||||
protected:
|
||||
virtual void Init() override {
|
||||
mResult = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
|
||||
}
|
||||
|
||||
virtual void CleanUp() override {
|
||||
if (SUCCEEDED(mResult)) {
|
||||
CoUninitialize();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
HRESULT mResult;
|
||||
};
|
||||
#endif
|
||||
|
||||
// NOTE: never Dispatch(....,NS_DISPATCH_SYNC) to the MediaManager
|
||||
// thread from the MainThread, as we NS_DISPATCH_SYNC to MainThread
|
||||
// from MediaManager thread.
|
||||
|
@ -1983,11 +2006,24 @@ MediaManager* MediaManager::Get() {
|
|||
timesCreated++;
|
||||
MOZ_RELEASE_ASSERT(timesCreated == 1);
|
||||
|
||||
RefPtr<TaskQueue> mediaThread = new TaskQueue(
|
||||
GetMediaThreadPool(MediaThreadType::PLAYBACK), "MediaManager");
|
||||
LOG("New Media thread for gum");
|
||||
{
|
||||
UniquePtr<base::Thread> mediaThread =
|
||||
#ifdef XP_WIN
|
||||
MakeUnique<MTAThread>("MediaManager");
|
||||
#else
|
||||
MakeUnique<base::Thread>("MediaManager");
|
||||
#endif
|
||||
|
||||
sSingleton = new MediaManager(mediaThread.forget());
|
||||
base::Thread::Options options;
|
||||
options.message_loop_type = MessageLoop::TYPE_MOZILLA_NONMAINTHREAD;
|
||||
if (!mediaThread->StartWithOptions(options)) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
LOG("New Media thread for gum");
|
||||
|
||||
sSingleton = new MediaManager(std::move(mediaThread));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
|
||||
if (obs) {
|
||||
|
@ -2093,7 +2129,7 @@ void MediaManager::StartupInit() {
|
|||
}
|
||||
|
||||
/* static */
|
||||
void MediaManager::Dispatch(already_AddRefed<Runnable> task) {
|
||||
void MediaManager::PostTask(already_AddRefed<Runnable> task) {
|
||||
if (sHasShutdown) {
|
||||
// Can't safely delete task here since it may have items with specific
|
||||
// thread-release requirements.
|
||||
|
@ -2104,16 +2140,16 @@ void MediaManager::Dispatch(already_AddRefed<Runnable> task) {
|
|||
}
|
||||
NS_ASSERTION(Get(), "MediaManager singleton?");
|
||||
NS_ASSERTION(Get()->mMediaThread, "No thread yet");
|
||||
Get()->mMediaThread->Dispatch(std::move(task));
|
||||
Get()->mMediaThread->message_loop()->PostTask(std::move(task));
|
||||
}
|
||||
|
||||
template <typename MozPromiseType, typename FunctionType>
|
||||
/* static */
|
||||
RefPtr<MozPromiseType> MediaManager::Dispatch(const char* aName,
|
||||
RefPtr<MozPromiseType> MediaManager::PostTask(const char* aName,
|
||||
FunctionType&& aFunction) {
|
||||
MozPromiseHolder<MozPromiseType> holder;
|
||||
RefPtr<MozPromiseType> promise = holder.Ensure(aName);
|
||||
MediaManager::Dispatch(NS_NewRunnableFunction(
|
||||
MediaManager::PostTask(NS_NewRunnableFunction(
|
||||
aName, [h = std::move(holder), func = std::forward<FunctionType>(
|
||||
aFunction)]() mutable { func(h); }));
|
||||
return promise;
|
||||
|
@ -3502,7 +3538,7 @@ void MediaManager::GetPrefs(nsIPrefBranch* aBranch, const char* aData) {
|
|||
// shutdown here. This is called either on construction, or when a pref has
|
||||
// changed. The pref observers are disconnected during shutdown.
|
||||
MOZ_DIAGNOSTIC_ASSERT(!sHasShutdown);
|
||||
mMediaThread->Dispatch(NS_NewRunnableFunction(
|
||||
mMediaThread->message_loop()->PostTask(NS_NewRunnableFunction(
|
||||
"MediaManager::SetFakeDeviceChangeEventsEnabled",
|
||||
[enable = mPrefs.mFakeDeviceChangeEventOn] {
|
||||
if (MediaManager* mm = MediaManager::GetIfExists()) {
|
||||
|
@ -3638,21 +3674,25 @@ void MediaManager::Shutdown() {
|
|||
#endif
|
||||
|
||||
// Release the backend (and call Shutdown()) from within the MediaManager
|
||||
// thread Don't use MediaManager::Dispatch() because we're sHasShutdown=true
|
||||
// thread Don't use MediaManager::PostTask() because we're sHasShutdown=true
|
||||
// here!
|
||||
auto shutdown = MakeRefPtr<ShutdownTask>(
|
||||
this, media::NewRunnableFrom([]() {
|
||||
this, media::NewRunnableFrom([this, self = RefPtr<MediaManager>(this)]() {
|
||||
LOG("MediaManager shutdown lambda running, releasing MediaManager "
|
||||
"singleton and thread");
|
||||
if (mMediaThread) {
|
||||
mMediaThread->Stop();
|
||||
}
|
||||
StaticMutexAutoLock lock(sSingletonMutex);
|
||||
// Remove async shutdown blocker
|
||||
media::GetShutdownBarrier()->RemoveBlocker(
|
||||
sSingleton->mShutdownBlocker);
|
||||
|
||||
// we hold a ref to 'self' which is the same as sSingleton
|
||||
sSingleton = nullptr;
|
||||
return NS_OK;
|
||||
}));
|
||||
mMediaThread->Dispatch(shutdown.forget());
|
||||
mMediaThread->message_loop()->PostTask(shutdown.forget());
|
||||
}
|
||||
|
||||
void MediaManager::SendPendingGUMRequest() {
|
||||
|
@ -3699,7 +3739,7 @@ nsresult MediaManager::Observe(nsISupports* aSubject, const char* aTopic,
|
|||
} else if (!strcmp(aTopic, "getUserMedia:got-device-permission")) {
|
||||
MOZ_ASSERT(aSubject);
|
||||
nsCOMPtr<nsIRunnable> task = do_QueryInterface(aSubject);
|
||||
MediaManager::Dispatch(NewTaskFrom([task] { task->Run(); }));
|
||||
MediaManager::PostTask(NewTaskFrom([task] { task->Run(); }));
|
||||
return NS_OK;
|
||||
} else if (!strcmp(aTopic, "getUserMedia:privileged:allow") ||
|
||||
!strcmp(aTopic, "getUserMedia:response:allow")) {
|
||||
|
@ -3764,7 +3804,7 @@ nsresult MediaManager::Observe(nsISupports* aSubject, const char* aTopic,
|
|||
return task->Denied(MediaMgrError::Name::AbortError, u"In shutdown"_ns);
|
||||
}
|
||||
// Reuse the same thread to save memory.
|
||||
MediaManager::Dispatch(task.forget());
|
||||
MediaManager::PostTask(task.forget());
|
||||
return NS_OK;
|
||||
|
||||
} else if (IsGUMResponseNoAccess(aTopic, gumNoAccessError)) {
|
||||
|
@ -4089,7 +4129,7 @@ SourceListener::InitializeAsync() {
|
|||
MOZ_ASSERT(NS_IsMainThread(), "Only call on main thread");
|
||||
MOZ_DIAGNOSTIC_ASSERT(!mStopped);
|
||||
|
||||
return MediaManager::Dispatch<SourceListenerPromise>(
|
||||
return MediaManager::PostTask<SourceListenerPromise>(
|
||||
__func__,
|
||||
[principal = GetPrincipalHandle(),
|
||||
audioDevice =
|
||||
|
@ -4248,7 +4288,7 @@ void SourceListener::StopTrack(MediaTrack* aTrack) {
|
|||
|
||||
state.mDisableTimer->Cancel();
|
||||
|
||||
MediaManager::Dispatch(NewTaskFrom([device = state.mDevice]() {
|
||||
MediaManager::PostTask(NewTaskFrom([device = state.mDevice]() {
|
||||
device->Stop();
|
||||
device->Deallocate();
|
||||
}));
|
||||
|
@ -4377,7 +4417,7 @@ void SourceListener::SetEnabledFor(MediaTrack* aTrack, bool aEnable) {
|
|||
nsString inputDeviceGroupId;
|
||||
state.mDevice->GetRawGroupId(inputDeviceGroupId);
|
||||
|
||||
return MediaManager::Dispatch<DeviceOperationPromise>(
|
||||
return MediaManager::PostTask<DeviceOperationPromise>(
|
||||
__func__,
|
||||
[self, device = state.mDevice, aEnable, inputDeviceGroupId](
|
||||
MozPromiseHolder<DeviceOperationPromise>& h) {
|
||||
|
@ -4576,7 +4616,7 @@ SourceListener::ApplyConstraintsToTrack(
|
|||
return SourceListenerPromise::CreateAndResolve(false, __func__);
|
||||
}
|
||||
|
||||
return MediaManager::Dispatch<SourceListenerPromise>(
|
||||
return MediaManager::PostTask<SourceListenerPromise>(
|
||||
__func__, [device = state.mDevice, aConstraints,
|
||||
isChrome = aCallerType == CallerType::System](
|
||||
MozPromiseHolder<SourceListenerPromise>& aHolder) mutable {
|
||||
|
|
|
@ -37,8 +37,11 @@
|
|||
# include "mtransport/runnable_utils.h"
|
||||
#endif
|
||||
|
||||
// Note, these suck in Windows headers, unfortunately.
|
||||
#include "base/thread.h"
|
||||
#include "base/task.h"
|
||||
|
||||
class nsIPrefBranch;
|
||||
class nsISerialEventTarget;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -145,7 +148,7 @@ class MediaManager final : public nsIMediaManagerService, public nsIObserver {
|
|||
static MediaManager* Get();
|
||||
static MediaManager* GetIfExists();
|
||||
static void StartupInit();
|
||||
static void Dispatch(already_AddRefed<Runnable> task);
|
||||
static void PostTask(already_AddRefed<Runnable> task);
|
||||
|
||||
/**
|
||||
* Posts an async operation to the media manager thread.
|
||||
|
@ -155,7 +158,7 @@ class MediaManager final : public nsIMediaManagerService, public nsIObserver {
|
|||
* manager thread.
|
||||
*/
|
||||
template <typename MozPromiseType, typename FunctionType>
|
||||
static RefPtr<MozPromiseType> Dispatch(const char* aName,
|
||||
static RefPtr<MozPromiseType> PostTask(const char* aName,
|
||||
FunctionType&& aFunction);
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -318,7 +321,7 @@ class MediaManager final : public nsIMediaManagerService, public nsIObserver {
|
|||
void GetPrefs(nsIPrefBranch* aBranch, const char* aData);
|
||||
|
||||
// Make private because we want only one instance of this class
|
||||
explicit MediaManager(already_AddRefed<nsISerialEventTarget> aMediaThread);
|
||||
explicit MediaManager(UniquePtr<base::Thread> aMediaThread);
|
||||
|
||||
~MediaManager() = default;
|
||||
void Shutdown();
|
||||
|
@ -343,7 +346,7 @@ class MediaManager final : public nsIMediaManagerService, public nsIObserver {
|
|||
nsTArray<RefPtr<dom::GetUserMediaRequest>> mPendingGUMRequest;
|
||||
|
||||
// Always exists
|
||||
const nsCOMPtr<nsISerialEventTarget> mMediaThread;
|
||||
const UniquePtr<base::Thread> mMediaThread;
|
||||
nsCOMPtr<nsIAsyncShutdownBlocker> mShutdownBlocker;
|
||||
|
||||
// ONLY accessed from MediaManagerThread
|
||||
|
|
|
@ -5,44 +5,20 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "CubebDeviceEnumerator.h"
|
||||
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/SchedulerGroup.h"
|
||||
#include "mozilla/StaticMutex.h"
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#ifdef XP_WIN
|
||||
# include "mozilla/mscom/EnsureMTA.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
using namespace CubebUtils;
|
||||
|
||||
/* static */
|
||||
static StaticRefPtr<CubebDeviceEnumerator> sInstance;
|
||||
static StaticMutex sInstanceMutex;
|
||||
StaticRefPtr<CubebDeviceEnumerator> CubebDeviceEnumerator::sInstance;
|
||||
|
||||
/* static */
|
||||
CubebDeviceEnumerator* CubebDeviceEnumerator::GetInstance() {
|
||||
StaticMutexAutoLock lock(sInstanceMutex);
|
||||
if (!sInstance) {
|
||||
sInstance = new CubebDeviceEnumerator();
|
||||
static bool clearOnShutdownSetup = []() -> bool {
|
||||
auto setClearOnShutdown = []() -> void {
|
||||
ClearOnShutdown(&sInstance, ShutdownPhase::ShutdownThreads);
|
||||
};
|
||||
if (NS_IsMainThread()) {
|
||||
setClearOnShutdown();
|
||||
} else {
|
||||
SchedulerGroup::Dispatch(
|
||||
TaskCategory::Other,
|
||||
NS_NewRunnableFunction("CubebDeviceEnumerator::::GetInstance()",
|
||||
std::move(setClearOnShutdown)));
|
||||
}
|
||||
return true;
|
||||
}();
|
||||
Unused << clearOnShutdownSetup;
|
||||
}
|
||||
return sInstance.get();
|
||||
}
|
||||
|
@ -51,61 +27,48 @@ CubebDeviceEnumerator::CubebDeviceEnumerator()
|
|||
: mMutex("CubebDeviceListMutex"),
|
||||
mManualInputInvalidation(false),
|
||||
mManualOutputInvalidation(false) {
|
||||
#ifdef XP_WIN
|
||||
mozilla::mscom::EnsureMTA([&]() -> void {
|
||||
#endif
|
||||
int rv = cubeb_register_device_collection_changed(
|
||||
GetCubebContext(), CUBEB_DEVICE_TYPE_OUTPUT,
|
||||
&OutputAudioDeviceListChanged_s, this);
|
||||
if (rv != CUBEB_OK) {
|
||||
NS_WARNING(
|
||||
"Could not register the audio output"
|
||||
" device collection changed callback.");
|
||||
mManualOutputInvalidation = true;
|
||||
}
|
||||
rv = cubeb_register_device_collection_changed(
|
||||
GetCubebContext(), CUBEB_DEVICE_TYPE_INPUT,
|
||||
&InputAudioDeviceListChanged_s, this);
|
||||
if (rv != CUBEB_OK) {
|
||||
NS_WARNING(
|
||||
"Could not register the audio input"
|
||||
" device collection changed callback.");
|
||||
mManualInputInvalidation = true;
|
||||
}
|
||||
#ifdef XP_WIN
|
||||
});
|
||||
#endif
|
||||
int rv = cubeb_register_device_collection_changed(
|
||||
GetCubebContext(), CUBEB_DEVICE_TYPE_OUTPUT,
|
||||
&OutputAudioDeviceListChanged_s, this);
|
||||
if (rv != CUBEB_OK) {
|
||||
NS_WARNING(
|
||||
"Could not register the audio output"
|
||||
" device collection changed callback.");
|
||||
mManualOutputInvalidation = true;
|
||||
}
|
||||
rv = cubeb_register_device_collection_changed(
|
||||
GetCubebContext(), CUBEB_DEVICE_TYPE_INPUT,
|
||||
&InputAudioDeviceListChanged_s, this);
|
||||
if (rv != CUBEB_OK) {
|
||||
NS_WARNING(
|
||||
"Could not register the audio input"
|
||||
" device collection changed callback.");
|
||||
mManualInputInvalidation = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
void CubebDeviceEnumerator::Shutdown() {
|
||||
StaticMutexAutoLock lock(sInstanceMutex);
|
||||
if (sInstance) {
|
||||
sInstance = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
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.");
|
||||
}
|
||||
#ifdef XP_WIN
|
||||
});
|
||||
#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.");
|
||||
}
|
||||
}
|
||||
|
||||
void CubebDeviceEnumerator::EnumerateAudioInputDevices(
|
||||
|
@ -186,32 +149,26 @@ static void GetDeviceCollection(nsTArray<RefPtr<AudioDeviceInfo>>& aDeviceInfos,
|
|||
cubeb* context = GetCubebContext();
|
||||
if (context) {
|
||||
cubeb_device_collection collection = {nullptr, 0};
|
||||
# ifdef XP_WIN
|
||||
mozilla::mscom::EnsureMTA([&]() -> void {
|
||||
# endif
|
||||
if (cubeb_enumerate_devices(context,
|
||||
aSide == Input ? CUBEB_DEVICE_TYPE_INPUT
|
||||
: CUBEB_DEVICE_TYPE_OUTPUT,
|
||||
&collection) == CUBEB_OK) {
|
||||
for (unsigned int i = 0; i < collection.count; ++i) {
|
||||
auto device = collection.device[i];
|
||||
RefPtr<AudioDeviceInfo> info = new AudioDeviceInfo(
|
||||
device.devid, NS_ConvertUTF8toUTF16(device.friendly_name),
|
||||
NS_ConvertUTF8toUTF16(device.group_id),
|
||||
NS_ConvertUTF8toUTF16(device.vendor_name),
|
||||
ConvertCubebType(device.type), ConvertCubebState(device.state),
|
||||
ConvertCubebPreferred(device.preferred),
|
||||
ConvertCubebFormat(device.format),
|
||||
ConvertCubebFormat(device.default_format), device.max_channels,
|
||||
device.default_rate, device.max_rate, device.min_rate,
|
||||
device.latency_hi, device.latency_lo);
|
||||
aDeviceInfos.AppendElement(info);
|
||||
}
|
||||
if (cubeb_enumerate_devices(
|
||||
context,
|
||||
aSide == Input ? CUBEB_DEVICE_TYPE_INPUT : CUBEB_DEVICE_TYPE_OUTPUT,
|
||||
&collection) == CUBEB_OK) {
|
||||
for (unsigned int i = 0; i < collection.count; ++i) {
|
||||
auto device = collection.device[i];
|
||||
RefPtr<AudioDeviceInfo> info = new AudioDeviceInfo(
|
||||
device.devid, NS_ConvertUTF8toUTF16(device.friendly_name),
|
||||
NS_ConvertUTF8toUTF16(device.group_id),
|
||||
NS_ConvertUTF8toUTF16(device.vendor_name),
|
||||
ConvertCubebType(device.type), ConvertCubebState(device.state),
|
||||
ConvertCubebPreferred(device.preferred),
|
||||
ConvertCubebFormat(device.format),
|
||||
ConvertCubebFormat(device.default_format), device.max_channels,
|
||||
device.default_rate, device.max_rate, device.min_rate,
|
||||
device.latency_hi, device.latency_lo);
|
||||
aDeviceInfos.AppendElement(info);
|
||||
}
|
||||
cubeb_device_collection_destroy(context, &collection);
|
||||
# ifdef XP_WIN
|
||||
});
|
||||
# endif
|
||||
}
|
||||
cubeb_device_collection_destroy(context, &collection);
|
||||
}
|
||||
}
|
||||
#endif // non ANDROID
|
||||
|
@ -370,14 +327,16 @@ void CubebDeviceEnumerator::OutputAudioDeviceListChanged_s(cubeb* aContext,
|
|||
}
|
||||
|
||||
void CubebDeviceEnumerator::AudioDeviceListChanged(Side aSide) {
|
||||
MutexAutoLock lock(mMutex);
|
||||
if (aSide == Side::INPUT) {
|
||||
mInputDevices.Clear();
|
||||
mOnInputDeviceListChange.Notify();
|
||||
} else {
|
||||
MOZ_ASSERT(aSide == Side::OUTPUT);
|
||||
mOutputDevices.Clear();
|
||||
mOnOutputDeviceListChange.Notify();
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
if (aSide == Side::INPUT) {
|
||||
mInputDevices.Clear();
|
||||
mOnInputDeviceListChange.Notify();
|
||||
} else {
|
||||
MOZ_ASSERT(aSide == Side::OUTPUT);
|
||||
mOutputDevices.Clear();
|
||||
mOnOutputDeviceListChange.Notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -80,6 +80,8 @@ class CubebDeviceEnumerator final {
|
|||
bool mManualOutputInvalidation;
|
||||
MediaEventProducer<void> mOnInputDeviceListChange;
|
||||
MediaEventProducer<void> mOnOutputDeviceListChange;
|
||||
// The singleton instance.
|
||||
static StaticRefPtr<CubebDeviceEnumerator> sInstance;
|
||||
};
|
||||
|
||||
typedef CubebDeviceEnumerator Enumerator;
|
||||
|
|
|
@ -33,7 +33,7 @@ enum { kVideoTrack = 1, kAudioTrack = 2, kTrackCount };
|
|||
class MediaEngine {
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaEngine)
|
||||
NS_DECL_OWNINGEVENTTARGET
|
||||
NS_DECL_OWNINGTHREAD
|
||||
|
||||
void AssertIsOnOwningThread() const { NS_ASSERT_OWNINGTHREAD(MediaEngine); }
|
||||
|
||||
|
|
|
@ -236,7 +236,7 @@ nsresult MediaEngineDefaultVideoSource::Start() {
|
|||
MOZ_ASSERT(mState == kAllocated || mState == kStopped);
|
||||
MOZ_ASSERT(mTrack, "SetTrack() must happen before Start()");
|
||||
|
||||
mTimer = NS_NewTimer(GetCurrentSerialEventTarget());
|
||||
mTimer = NS_NewTimer();
|
||||
if (!mTimer) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
|
|
@ -235,7 +235,7 @@ class MediaEngineSource : public MediaEngineSourceInterface {
|
|||
static bool IsVideo(dom::MediaSourceEnum aSource);
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaEngineSource)
|
||||
NS_DECL_OWNINGEVENTTARGET
|
||||
NS_DECL_OWNINGTHREAD
|
||||
|
||||
void AssertIsOnOwningThread() const {
|
||||
NS_ASSERT_OWNINGTHREAD(MediaEngineSource);
|
||||
|
|
|
@ -71,8 +71,7 @@ void MediaEngineWebRTC::SetFakeDeviceChangeEventsEnabled(bool aEnable) {
|
|||
getter_AddRefs(mFakeDeviceChangeEventTimer),
|
||||
&FakeDeviceChangeEventTimerTick, this,
|
||||
FAKE_ONDEVICECHANGE_EVENT_PERIOD_IN_MS, nsITimer::TYPE_REPEATING_SLACK,
|
||||
"MediaEngineWebRTC::mFakeDeviceChangeEventTimer",
|
||||
GetCurrentSerialEventTarget());
|
||||
"MediaEngineWebRTC::mFakeDeviceChangeEventTimer");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -323,7 +322,6 @@ void MediaEngineWebRTC::Shutdown() {
|
|||
/* static */ void MediaEngineWebRTC::FakeDeviceChangeEventTimerTick(
|
||||
nsITimer* aTimer, void* aClosure) {
|
||||
MediaEngineWebRTC* self = static_cast<MediaEngineWebRTC*>(aClosure);
|
||||
self->AssertIsOnOwningThread();
|
||||
self->DeviceListChanged();
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче