зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
4bf54def7a
Коммит
8413544b59
|
@ -48,6 +48,7 @@ public:
|
|||
dom::MediaSourceEnum,
|
||||
nsTArray<RefPtr<MediaEngineSource>>*) = 0;
|
||||
|
||||
virtual void ReleaseResourcesForWindow(uint64_t aWindowId) = 0;
|
||||
virtual void Shutdown() = 0;
|
||||
|
||||
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
|
||||
// re-use that. This is no longer possible since the resolution gets set
|
||||
// in Allocate().
|
||||
|
||||
nsTArray<RefPtr<MediaEngineSource>>*
|
||||
devicesForThisWindow = mVSources.LookupOrAdd(aWindowId);
|
||||
auto newSource = MakeRefPtr<MediaEngineDefaultVideoSource>();
|
||||
mVSources.AppendElement(newSource);
|
||||
devicesForThisWindow->AppendElement(newSource);
|
||||
aSources->AppendElement(newSource);
|
||||
return;
|
||||
}
|
||||
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()) {
|
||||
aSources->AppendElement(source);
|
||||
}
|
||||
|
@ -576,7 +581,7 @@ MediaEngineDefault::EnumerateDevices(uint64_t aWindowId,
|
|||
if (aSources->IsEmpty()) {
|
||||
// All streams are currently busy, just make a new one.
|
||||
auto newSource = MakeRefPtr<MediaEngineDefaultAudioSource>();
|
||||
mASources.AppendElement(newSource);
|
||||
devicesForThisWindow->AppendElement(newSource);
|
||||
aSources->AppendElement(newSource);
|
||||
}
|
||||
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
|
||||
MediaEngineDefault::Shutdown()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
for (RefPtr<MediaEngineDefaultVideoSource>& source : mVSources) {
|
||||
source->Shutdown();
|
||||
for (auto iter = mVSources.Iter(); !iter.Done(); iter.Next()) {
|
||||
for (const RefPtr<MediaEngineSource>& source : *iter.UserData()) {
|
||||
if (source) {
|
||||
source->Shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
for (RefPtr<MediaEngineDefaultAudioSource>& source : mASources) {
|
||||
source->Shutdown();
|
||||
for (auto iter = mASources.Iter(); !iter.Done(); iter.Next()) {
|
||||
for (const RefPtr<MediaEngineDefaultAudioSource>& source : *iter.UserData()) {
|
||||
if (source) {
|
||||
source->Shutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
mVSources.Clear();
|
||||
mASources.Clear();
|
||||
|
|
|
@ -191,12 +191,16 @@ public:
|
|||
dom::MediaSourceEnum,
|
||||
nsTArray<RefPtr<MediaEngineSource>>*) override;
|
||||
void Shutdown() override;
|
||||
void ReleaseResourcesForWindow(uint64_t aWindowId) override;
|
||||
|
||||
private:
|
||||
~MediaEngineDefault() = default;
|
||||
|
||||
nsTArray<RefPtr<MediaEngineDefaultVideoSource>> mVSources;
|
||||
nsTArray<RefPtr<MediaEngineDefaultAudioSource>> mASources;
|
||||
// WindowID -> Array of devices.
|
||||
nsClassHashtable<nsUint64HashKey,
|
||||
nsTArray<RefPtr<MediaEngineSource>>> mVSources;
|
||||
nsClassHashtable<nsUint64HashKey,
|
||||
nsTArray<RefPtr<MediaEngineDefaultAudioSource>>> mASources;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -238,15 +238,20 @@ MediaEngineWebRTC::EnumerateDevices(uint64_t aWindowId,
|
|||
}
|
||||
|
||||
NS_ConvertUTF8toUTF16 uuid(uniqueId);
|
||||
RefPtr<MediaEngineSource> vSource = mVideoSources.Get(uuid);
|
||||
if (vSource && vSource->RequiresSharing()) {
|
||||
RefPtr<MediaEngineSource> vSource;
|
||||
|
||||
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.
|
||||
static_cast<MediaEngineRemoteVideoSource*>(vSource.get())->Refresh(i);
|
||||
aSources->AppendElement(vSource.get());
|
||||
} else {
|
||||
vSource = new MediaEngineRemoteVideoSource(i, capEngine, aMediaSource,
|
||||
scaryKind || scarySource);
|
||||
mVideoSources.Put(uuid, vSource);
|
||||
devicesForThisWindow->Put(uuid, vSource);
|
||||
aSources->AppendElement(vSource);
|
||||
}
|
||||
}
|
||||
|
@ -300,9 +305,15 @@ MediaEngineWebRTC::EnumerateDevices(uint64_t aWindowId,
|
|||
strcpy(uniqueId, deviceName); // safe given assert and initialization/error-check
|
||||
}
|
||||
|
||||
|
||||
RefPtr<MediaEngineSource> aSource;
|
||||
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.
|
||||
aSources->AppendElement(aSource.get());
|
||||
} else {
|
||||
|
@ -310,7 +321,7 @@ MediaEngineWebRTC::EnumerateDevices(uint64_t aWindowId,
|
|||
new mozilla::AudioInputCubeb(i),
|
||||
i, deviceName, uniqueId,
|
||||
mDelayAgnostic, mExtendedFilter);
|
||||
mAudioSources.Put(uuid, aSource); // Hashtable takes ownership.
|
||||
devicesForThisWindow->Put(uuid, aSource);
|
||||
aSources->AppendElement(aSource);
|
||||
}
|
||||
}
|
||||
|
@ -323,6 +334,53 @@ MediaEngineWebRTC::SupportsDuplex()
|
|||
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
|
||||
MediaEngineWebRTC::Shutdown()
|
||||
{
|
||||
|
@ -337,20 +395,8 @@ MediaEngineWebRTC::Shutdown()
|
|||
LOG(("%s", __FUNCTION__));
|
||||
// Shutdown all the sources, since we may have dangling references to the
|
||||
// sources in nsDOMUserMediaStreams waiting for GC/CC
|
||||
for (auto iter = mVideoSources.Iter(); !iter.Done(); iter.Next()) {
|
||||
MediaEngineSource* source = iter.UserData();
|
||||
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();
|
||||
ShutdownSources(mVideoSources);
|
||||
ShutdownSources(mAudioSources);
|
||||
|
||||
mozilla::camera::Shutdown();
|
||||
AudioInputCubeb::CleanupGlobalData();
|
||||
|
|
|
@ -621,6 +621,7 @@ public:
|
|||
void EnumerateDevices(uint64_t aWindowId,
|
||||
dom::MediaSourceEnum,
|
||||
nsTArray<RefPtr<MediaEngineSource>>*) override;
|
||||
void ReleaseResourcesForWindow(uint64_t aWindowId) override;
|
||||
private:
|
||||
~MediaEngineWebRTC() = default;
|
||||
|
||||
|
@ -634,10 +635,14 @@ private:
|
|||
bool mExtendedFilter;
|
||||
bool mHasTabVideoSource;
|
||||
|
||||
// Store devices we've already seen in a hashtable for quick return.
|
||||
// Maps UUID to MediaEngineSource (one set for audio, one for video).
|
||||
nsRefPtrHashtable<nsStringHashKey, MediaEngineSource> mVideoSources;
|
||||
nsRefPtrHashtable<nsStringHashKey, MediaEngineSource> mAudioSources;
|
||||
// Maps WindowID to a map of device uuid to their MediaEngineSource,
|
||||
// separately for audio and video.
|
||||
nsClassHashtable<nsUint64HashKey,
|
||||
nsRefPtrHashtable<nsStringHashKey,
|
||||
MediaEngineSource>> mVideoSources;
|
||||
nsClassHashtable<nsUint64HashKey,
|
||||
nsRefPtrHashtable<nsStringHashKey,
|
||||
MediaEngineSource>> mAudioSources;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче