mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 11:55:49 +00:00
Bug 1434600 - Add a method to clean up by window ID, on a MediaEngine. r=pehrsons
MozReview-Commit-ID: 12w4StZE2eg --HG-- extra : rebase_source : 3c3ddf24da24e42e53d9e5352cb83945c97ead99
This commit is contained in:
parent
4bf54def7a
commit
8413544b59
@ -48,6 +48,7 @@ public:
|
|||||||
dom::MediaSourceEnum,
|
dom::MediaSourceEnum,
|
||||||
nsTArray<RefPtr<MediaEngineSource>>*) = 0;
|
nsTArray<RefPtr<MediaEngineSource>>*) = 0;
|
||||||
|
|
||||||
|
virtual void ReleaseResourcesForWindow(uint64_t aWindowId) = 0;
|
||||||
virtual void Shutdown() = 0;
|
virtual void Shutdown() = 0;
|
||||||
|
|
||||||
virtual void SetFakeDeviceChangeEvents() {}
|
virtual void SetFakeDeviceChangeEvents() {}
|
||||||
|
@ -561,13 +561,18 @@ MediaEngineDefault::EnumerateDevices(uint64_t aWindowId,
|
|||||||
// We once had code here to find a VideoSource with the same settings and
|
// We once had code here to find a VideoSource with the same settings and
|
||||||
// re-use that. This is no longer possible since the resolution gets set
|
// re-use that. This is no longer possible since the resolution gets set
|
||||||
// in Allocate().
|
// in Allocate().
|
||||||
|
|
||||||
|
nsTArray<RefPtr<MediaEngineSource>>*
|
||||||
|
devicesForThisWindow = mVSources.LookupOrAdd(aWindowId);
|
||||||
auto newSource = MakeRefPtr<MediaEngineDefaultVideoSource>();
|
auto newSource = MakeRefPtr<MediaEngineDefaultVideoSource>();
|
||||||
mVSources.AppendElement(newSource);
|
devicesForThisWindow->AppendElement(newSource);
|
||||||
aSources->AppendElement(newSource);
|
aSources->AppendElement(newSource);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case dom::MediaSourceEnum::Microphone: {
|
case dom::MediaSourceEnum::Microphone: {
|
||||||
for (const RefPtr<MediaEngineDefaultAudioSource>& source : mASources) {
|
nsTArray<RefPtr<MediaEngineDefaultAudioSource>>*
|
||||||
|
devicesForThisWindow = mASources.LookupOrAdd(aWindowId);
|
||||||
|
for (const RefPtr<MediaEngineDefaultAudioSource>& source : *devicesForThisWindow) {
|
||||||
if (source->IsAvailable()) {
|
if (source->IsAvailable()) {
|
||||||
aSources->AppendElement(source);
|
aSources->AppendElement(source);
|
||||||
}
|
}
|
||||||
@ -576,7 +581,7 @@ MediaEngineDefault::EnumerateDevices(uint64_t aWindowId,
|
|||||||
if (aSources->IsEmpty()) {
|
if (aSources->IsEmpty()) {
|
||||||
// All streams are currently busy, just make a new one.
|
// All streams are currently busy, just make a new one.
|
||||||
auto newSource = MakeRefPtr<MediaEngineDefaultAudioSource>();
|
auto newSource = MakeRefPtr<MediaEngineDefaultAudioSource>();
|
||||||
mASources.AppendElement(newSource);
|
devicesForThisWindow->AppendElement(newSource);
|
||||||
aSources->AppendElement(newSource);
|
aSources->AppendElement(newSource);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -587,16 +592,52 @@ MediaEngineDefault::EnumerateDevices(uint64_t aWindowId,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaEngineDefault::ReleaseResourcesForWindow(uint64_t aWindowId)
|
||||||
|
{
|
||||||
|
nsTArray<RefPtr<MediaEngineDefaultAudioSource>>* audioDevicesForThisWindow =
|
||||||
|
mASources.Get(aWindowId);
|
||||||
|
|
||||||
|
if (audioDevicesForThisWindow) {
|
||||||
|
for (const RefPtr<MediaEngineDefaultAudioSource>& source :
|
||||||
|
*audioDevicesForThisWindow) {
|
||||||
|
source->Shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mASources.Remove(aWindowId);
|
||||||
|
|
||||||
|
nsTArray<RefPtr<MediaEngineSource>>* videoDevicesForThisWindow =
|
||||||
|
mVSources.Get(aWindowId);
|
||||||
|
|
||||||
|
if (videoDevicesForThisWindow) {
|
||||||
|
for (const RefPtr<MediaEngineSource>& source :
|
||||||
|
*videoDevicesForThisWindow) {
|
||||||
|
source->Shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mVSources.Remove(aWindowId);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MediaEngineDefault::Shutdown()
|
MediaEngineDefault::Shutdown()
|
||||||
{
|
{
|
||||||
AssertIsOnOwningThread();
|
AssertIsOnOwningThread();
|
||||||
|
|
||||||
for (RefPtr<MediaEngineDefaultVideoSource>& source : mVSources) {
|
for (auto iter = mVSources.Iter(); !iter.Done(); iter.Next()) {
|
||||||
source->Shutdown();
|
for (const RefPtr<MediaEngineSource>& source : *iter.UserData()) {
|
||||||
|
if (source) {
|
||||||
|
source->Shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (RefPtr<MediaEngineDefaultAudioSource>& source : mASources) {
|
for (auto iter = mASources.Iter(); !iter.Done(); iter.Next()) {
|
||||||
source->Shutdown();
|
for (const RefPtr<MediaEngineDefaultAudioSource>& source : *iter.UserData()) {
|
||||||
|
if (source) {
|
||||||
|
source->Shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mVSources.Clear();
|
mVSources.Clear();
|
||||||
mASources.Clear();
|
mASources.Clear();
|
||||||
|
@ -191,12 +191,16 @@ public:
|
|||||||
dom::MediaSourceEnum,
|
dom::MediaSourceEnum,
|
||||||
nsTArray<RefPtr<MediaEngineSource>>*) override;
|
nsTArray<RefPtr<MediaEngineSource>>*) override;
|
||||||
void Shutdown() override;
|
void Shutdown() override;
|
||||||
|
void ReleaseResourcesForWindow(uint64_t aWindowId) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
~MediaEngineDefault() = default;
|
~MediaEngineDefault() = default;
|
||||||
|
|
||||||
nsTArray<RefPtr<MediaEngineDefaultVideoSource>> mVSources;
|
// WindowID -> Array of devices.
|
||||||
nsTArray<RefPtr<MediaEngineDefaultAudioSource>> mASources;
|
nsClassHashtable<nsUint64HashKey,
|
||||||
|
nsTArray<RefPtr<MediaEngineSource>>> mVSources;
|
||||||
|
nsClassHashtable<nsUint64HashKey,
|
||||||
|
nsTArray<RefPtr<MediaEngineDefaultAudioSource>>> mASources;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
@ -238,15 +238,20 @@ MediaEngineWebRTC::EnumerateDevices(uint64_t aWindowId,
|
|||||||
}
|
}
|
||||||
|
|
||||||
NS_ConvertUTF8toUTF16 uuid(uniqueId);
|
NS_ConvertUTF8toUTF16 uuid(uniqueId);
|
||||||
RefPtr<MediaEngineSource> vSource = mVideoSources.Get(uuid);
|
RefPtr<MediaEngineSource> vSource;
|
||||||
if (vSource && vSource->RequiresSharing()) {
|
|
||||||
|
nsRefPtrHashtable<nsStringHashKey, MediaEngineSource>*
|
||||||
|
devicesForThisWindow = mVideoSources.LookupOrAdd(aWindowId);
|
||||||
|
|
||||||
|
if (devicesForThisWindow->Get(uuid, getter_AddRefs(vSource)) &&
|
||||||
|
vSource->RequiresSharing()) {
|
||||||
// We've already seen this shared device, just refresh and append.
|
// We've already seen this shared device, just refresh and append.
|
||||||
static_cast<MediaEngineRemoteVideoSource*>(vSource.get())->Refresh(i);
|
static_cast<MediaEngineRemoteVideoSource*>(vSource.get())->Refresh(i);
|
||||||
aSources->AppendElement(vSource.get());
|
aSources->AppendElement(vSource.get());
|
||||||
} else {
|
} else {
|
||||||
vSource = new MediaEngineRemoteVideoSource(i, capEngine, aMediaSource,
|
vSource = new MediaEngineRemoteVideoSource(i, capEngine, aMediaSource,
|
||||||
scaryKind || scarySource);
|
scaryKind || scarySource);
|
||||||
mVideoSources.Put(uuid, vSource);
|
devicesForThisWindow->Put(uuid, vSource);
|
||||||
aSources->AppendElement(vSource);
|
aSources->AppendElement(vSource);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -300,9 +305,15 @@ MediaEngineWebRTC::EnumerateDevices(uint64_t aWindowId,
|
|||||||
strcpy(uniqueId, deviceName); // safe given assert and initialization/error-check
|
strcpy(uniqueId, deviceName); // safe given assert and initialization/error-check
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RefPtr<MediaEngineSource> aSource;
|
||||||
NS_ConvertUTF8toUTF16 uuid(uniqueId);
|
NS_ConvertUTF8toUTF16 uuid(uniqueId);
|
||||||
RefPtr<MediaEngineSource> aSource = mAudioSources.Get(uuid);
|
|
||||||
if (aSource && aSource->RequiresSharing()) {
|
nsRefPtrHashtable<nsStringHashKey, MediaEngineSource>*
|
||||||
|
devicesForThisWindow = mAudioSources.LookupOrAdd(aWindowId);
|
||||||
|
|
||||||
|
if (devicesForThisWindow->Get(uuid, getter_AddRefs(aSource)) &&
|
||||||
|
aSource->RequiresSharing()) {
|
||||||
// We've already seen this device, just append.
|
// We've already seen this device, just append.
|
||||||
aSources->AppendElement(aSource.get());
|
aSources->AppendElement(aSource.get());
|
||||||
} else {
|
} else {
|
||||||
@ -310,7 +321,7 @@ MediaEngineWebRTC::EnumerateDevices(uint64_t aWindowId,
|
|||||||
new mozilla::AudioInputCubeb(i),
|
new mozilla::AudioInputCubeb(i),
|
||||||
i, deviceName, uniqueId,
|
i, deviceName, uniqueId,
|
||||||
mDelayAgnostic, mExtendedFilter);
|
mDelayAgnostic, mExtendedFilter);
|
||||||
mAudioSources.Put(uuid, aSource); // Hashtable takes ownership.
|
devicesForThisWindow->Put(uuid, aSource);
|
||||||
aSources->AppendElement(aSource);
|
aSources->AppendElement(aSource);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -323,6 +334,53 @@ MediaEngineWebRTC::SupportsDuplex()
|
|||||||
return mFullDuplex;
|
return mFullDuplex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MediaEngineWebRTC::ReleaseResourcesForWindow(uint64_t aWindowId)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
nsRefPtrHashtable<nsStringHashKey, MediaEngineSource>*
|
||||||
|
audioDevicesForThisWindow = mAudioSources.Get(aWindowId);
|
||||||
|
|
||||||
|
if (audioDevicesForThisWindow) {
|
||||||
|
for (auto iter = audioDevicesForThisWindow->Iter(); !iter.Done();
|
||||||
|
iter.Next()) {
|
||||||
|
iter.UserData()->Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
// This makes audioDevicesForThisWindow invalid.
|
||||||
|
mAudioSources.Remove(aWindowId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
nsRefPtrHashtable<nsStringHashKey, MediaEngineSource>*
|
||||||
|
videoDevicesForThisWindow = mVideoSources.Get(aWindowId);
|
||||||
|
if (videoDevicesForThisWindow) {
|
||||||
|
for (auto iter = videoDevicesForThisWindow->Iter(); !iter.Done();
|
||||||
|
iter.Next()) {
|
||||||
|
iter.UserData()->Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
// This makes videoDevicesForThisWindow invalid.
|
||||||
|
mVideoSources.Remove(aWindowId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
template<typename T>
|
||||||
|
void ShutdownSources(T& aHashTable)
|
||||||
|
{
|
||||||
|
for (auto iter = aHashTable.Iter(); !iter.Done(); iter.Next()) {
|
||||||
|
for (auto iterInner = iter.UserData()->Iter(); !iterInner.Done();
|
||||||
|
iterInner.Next()) {
|
||||||
|
MediaEngineSource* source = iterInner.UserData();
|
||||||
|
source->Shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MediaEngineWebRTC::Shutdown()
|
MediaEngineWebRTC::Shutdown()
|
||||||
{
|
{
|
||||||
@ -337,20 +395,8 @@ MediaEngineWebRTC::Shutdown()
|
|||||||
LOG(("%s", __FUNCTION__));
|
LOG(("%s", __FUNCTION__));
|
||||||
// Shutdown all the sources, since we may have dangling references to the
|
// Shutdown all the sources, since we may have dangling references to the
|
||||||
// sources in nsDOMUserMediaStreams waiting for GC/CC
|
// sources in nsDOMUserMediaStreams waiting for GC/CC
|
||||||
for (auto iter = mVideoSources.Iter(); !iter.Done(); iter.Next()) {
|
ShutdownSources(mVideoSources);
|
||||||
MediaEngineSource* source = iter.UserData();
|
ShutdownSources(mAudioSources);
|
||||||
if (source) {
|
|
||||||
source->Shutdown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (auto iter = mAudioSources.Iter(); !iter.Done(); iter.Next()) {
|
|
||||||
MediaEngineSource* source = iter.UserData();
|
|
||||||
if (source) {
|
|
||||||
source->Shutdown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mVideoSources.Clear();
|
|
||||||
mAudioSources.Clear();
|
|
||||||
|
|
||||||
mozilla::camera::Shutdown();
|
mozilla::camera::Shutdown();
|
||||||
AudioInputCubeb::CleanupGlobalData();
|
AudioInputCubeb::CleanupGlobalData();
|
||||||
|
@ -621,6 +621,7 @@ public:
|
|||||||
void EnumerateDevices(uint64_t aWindowId,
|
void EnumerateDevices(uint64_t aWindowId,
|
||||||
dom::MediaSourceEnum,
|
dom::MediaSourceEnum,
|
||||||
nsTArray<RefPtr<MediaEngineSource>>*) override;
|
nsTArray<RefPtr<MediaEngineSource>>*) override;
|
||||||
|
void ReleaseResourcesForWindow(uint64_t aWindowId) override;
|
||||||
private:
|
private:
|
||||||
~MediaEngineWebRTC() = default;
|
~MediaEngineWebRTC() = default;
|
||||||
|
|
||||||
@ -634,10 +635,14 @@ private:
|
|||||||
bool mExtendedFilter;
|
bool mExtendedFilter;
|
||||||
bool mHasTabVideoSource;
|
bool mHasTabVideoSource;
|
||||||
|
|
||||||
// Store devices we've already seen in a hashtable for quick return.
|
// Maps WindowID to a map of device uuid to their MediaEngineSource,
|
||||||
// Maps UUID to MediaEngineSource (one set for audio, one for video).
|
// separately for audio and video.
|
||||||
nsRefPtrHashtable<nsStringHashKey, MediaEngineSource> mVideoSources;
|
nsClassHashtable<nsUint64HashKey,
|
||||||
nsRefPtrHashtable<nsStringHashKey, MediaEngineSource> mAudioSources;
|
nsRefPtrHashtable<nsStringHashKey,
|
||||||
|
MediaEngineSource>> mVideoSources;
|
||||||
|
nsClassHashtable<nsUint64HashKey,
|
||||||
|
nsRefPtrHashtable<nsStringHashKey,
|
||||||
|
MediaEngineSource>> mAudioSources;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user