Bug 1271491: P6. Remove the need to call PDMFactory::Init(). r?cpearce
PDMFactory will automatically load and initialize the required frameworks upon first use.
Also fix constness of some methods.
MozReview-Commit-ID: HFbvTMRFAey
--- a/dom/media/ADTSDecoder.cpp
+++ b/dom/media/ADTSDecoder.cpp
@@ -27,17 +27,16 @@ ADTSDecoder::CreateStateMachine()
RefPtr<MediaDecoderReader> reader =
new MediaFormatReader(this, new ADTSDemuxer(GetResource()));
return new MediaDecoderStateMachine(this, reader);
}
/* static */ bool
ADTSDecoder::IsEnabled()
{
- PDMFactory::Init();
RefPtr<PDMFactory> platform = new PDMFactory();
return platform->SupportsMimeType(NS_LITERAL_CSTRING("audio/mp4a-latm"),
/* DecoderDoctorDiagnostics* */ nullptr);
}
/* static */ bool
ADTSDecoder::CanHandleMediaType(const nsACString& aType,
const nsAString& aCodecs)
--- a/dom/media/Benchmark.cpp
+++ b/dom/media/Benchmark.cpp
@@ -2,16 +2,17 @@
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "Benchmark.h"
#include "BufferMediaResource.h"
#include "MediaData.h"
+#include "MediaPrefs.h"
#include "PDMFactory.h"
#include "WebMDemuxer.h"
#include "mozilla/Preferences.h"
#include "mozilla/Telemetry.h"
#include "mozilla/dom/ContentChild.h"
#ifndef MOZ_WIDGET_ANDROID
#include "WebMSample.h"
@@ -40,18 +41,16 @@ VP9Benchmark::IsVP9DecodeFast()
uint32_t hadRecentUpdate = Preferences::GetUint(sBenchmarkFpsVersionCheck, 0U);
if (!sHasRunTest && (!hasPref || hadRecentUpdate != sBenchmarkVersionID)) {
sHasRunTest = true;
RefPtr<WebMDemuxer> demuxer =
new WebMDemuxer(new BufferMediaResource(sWebMSample, sizeof(sWebMSample), nullptr,
NS_LITERAL_CSTRING("video/webm")));
- PDMFactory::Init();
-
RefPtr<Benchmark> estimiser =
new Benchmark(demuxer,
{
Preferences::GetInt("media.benchmark.frames", 300), // frames to measure
1, // start benchmarking after decoding this frame.
8, // loop after decoding that many frames.
TimeDuration::FromMilliseconds(
Preferences::GetUint("media.benchmark.timeout", 1000))
@@ -130,17 +129,17 @@ Benchmark::Dispose()
mPromise.RejectIfExists(false, __func__);
}
void
Benchmark::Init()
{
MOZ_ASSERT(NS_IsMainThread());
- PDMFactory::Init();
+ MediaPrefs::GetSingleton();
}
BenchmarkPlayback::BenchmarkPlayback(Benchmark* aMainThreadState,
MediaDataDemuxer* aDemuxer)
: QueueObject(new TaskQueue(GetMediaThreadPool(MediaThreadType::PLAYBACK)))
, mMainThreadState(aMainThreadState)
, mDecoderTaskQueue(new FlushableTaskQueue(GetMediaThreadPool(
MediaThreadType::PLATFORM_DECODER)))
--- a/dom/media/MP3Decoder.cpp
+++ b/dom/media/MP3Decoder.cpp
@@ -26,17 +26,16 @@ MP3Decoder::CreateStateMachine() {
RefPtr<MediaDecoderReader> reader =
new MediaFormatReader(this, new mp3::MP3Demuxer(GetResource()));
return new MediaDecoderStateMachine(this, reader);
}
/* static */
bool
MP3Decoder::IsEnabled() {
- PDMFactory::Init();
RefPtr<PDMFactory> platform = new PDMFactory();
return platform->SupportsMimeType(NS_LITERAL_CSTRING("audio/mpeg"),
/* DecoderDoctorDiagnostics* */ nullptr);
}
/* static */
bool MP3Decoder::CanHandleMediaType(const nsACString& aType,
const nsAString& aCodecs)
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -167,17 +167,16 @@ MediaFormatReader::InitLayersBackendType
mLayersBackendType = layerManager->GetCompositorBackendType();
}
nsresult
MediaFormatReader::Init()
{
MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread.");
- PDMFactory::Init();
InitLayersBackendType();
mAudio.mTaskQueue =
new FlushableTaskQueue(GetMediaThreadPool(MediaThreadType::PLATFORM_DECODER));
mVideo.mTaskQueue =
new FlushableTaskQueue(GetMediaThreadPool(MediaThreadType::PLATFORM_DECODER));
--- a/dom/media/fmp4/MP4Decoder.cpp
+++ b/dom/media/fmp4/MP4Decoder.cpp
@@ -146,17 +146,16 @@ MP4Decoder::CanHandleMediaType(const nsA
continue;
}
// Some unsupported codec.
return false;
}
}
// Verify that we have a PDM that supports the whitelisted types.
- PDMFactory::Init();
RefPtr<PDMFactory> platform = new PDMFactory();
for (const nsCString& codecMime : codecMimes) {
if (!platform->SupportsMimeType(codecMime, aDiagnostics)) {
return false;
}
}
return true;
@@ -225,18 +224,16 @@ CreateTestH264Decoder(layers::LayersBack
aConfig.mId = 1;
aConfig.mDuration = 40000;
aConfig.mMediaTime = 0;
aConfig.mImage = aConfig.mDisplay = nsIntSize(640, 360);
aConfig.mExtraData = new MediaByteBuffer();
aConfig.mExtraData->AppendElements(sTestH264ExtraData,
MOZ_ARRAY_LENGTH(sTestH264ExtraData));
- PDMFactory::Init();
-
RefPtr<PDMFactory> platform = new PDMFactory();
RefPtr<MediaDataDecoder> decoder(
platform->CreateDecoder(aConfig, aTaskQueue, nullptr,
/* DecoderDoctorDiagnostics* */ nullptr,
aBackend, nullptr));
return decoder.forget();
}
--- a/dom/media/platforms/PDMFactory.cpp
+++ b/dom/media/platforms/PDMFactory.cpp
@@ -21,84 +21,97 @@
#ifdef MOZ_GONK_MEDIACODEC
#include "GonkDecoderModule.h"
#endif
#ifdef MOZ_WIDGET_ANDROID
#include "AndroidDecoderModule.h"
#endif
#include "GMPDecoderModule.h"
+#include "mozilla/ClearOnShutdown.h"
+#include "mozilla/SharedThreadPool.h"
+#include "mozilla/StaticPtr.h"
#include "mozilla/TaskQueue.h"
-#include "mozilla/SharedThreadPool.h"
-
#include "MediaInfo.h"
#include "MediaPrefs.h"
#include "FuzzingWrapper.h"
#include "H264Converter.h"
#include "AgnosticDecoderModule.h"
#ifdef MOZ_EME
#include "EMEDecoderModule.h"
#include "mozilla/CDMProxy.h"
#endif
#include "DecoderDoctorDiagnostics.h"
+
namespace mozilla {
extern already_AddRefed<PlatformDecoderModule> CreateAgnosticDecoderModule();
extern already_AddRefed<PlatformDecoderModule> CreateBlankDecoderModule();
-/* static */
-void
-PDMFactory::Init()
-{
- MOZ_ASSERT(NS_IsMainThread());
- static bool alreadyInitialized = false;
- if (alreadyInitialized) {
- return;
- }
- alreadyInitialized = true;
-
- // Ensure MediaPrefs are initialized.
- MediaPrefs::GetSingleton();
-
+class PDMFactoryImpl final {
+public:
+ PDMFactoryImpl()
+ {
#ifdef XP_WIN
- WMFDecoderModule::Init();
+ WMFDecoderModule::Init();
#endif
#ifdef MOZ_APPLEMEDIA
- AppleDecoderModule::Init();
+ AppleDecoderModule::Init();
#endif
#ifdef MOZ_FFVPX
- FFVPXRuntimeLinker::Init();
+ FFVPXRuntimeLinker::Init();
#endif
#ifdef MOZ_FFMPEG
- FFmpegRuntimeLinker::Init();
+ FFmpegRuntimeLinker::Init();
#endif
- GMPDecoderModule::Init();
-}
+ GMPDecoderModule::Init();
+ }
+};
+
+StaticAutoPtr<PDMFactoryImpl> PDMFactory::sInstance;
+StaticMutex PDMFactory::sMonitor;
PDMFactory::PDMFactory()
{
+ EnsureInit();
CreatePDMs();
}
PDMFactory::~PDMFactory()
{
}
+void
+PDMFactory::EnsureInit() const
+{
+ StaticMutexAutoLock mon(sMonitor);
+ if (!sInstance) {
+ sInstance = new PDMFactoryImpl();
+ if (NS_IsMainThread()) {
+ ClearOnShutdown(&sInstance);
+ } else {
+ nsCOMPtr<nsIRunnable> runnable =
+ NS_NewRunnableFunction([]() { ClearOnShutdown(&sInstance); });
+ NS_DispatchToMainThread(runnable);
+ }
+ }
+}
+
already_AddRefed<MediaDataDecoder>
PDMFactory::CreateDecoder(const TrackInfo& aConfig,
FlushableTaskQueue* aTaskQueue,
MediaDataDecoderCallback* aCallback,
DecoderDoctorDiagnostics* aDiagnostics,
layers::LayersBackend aLayersBackend,
- layers::ImageContainer* aImageContainer)
+ layers::ImageContainer* aImageContainer) const
{
bool isEncrypted = mEMEPDM && aConfig.mCrypto.mValid;
if (isEncrypted) {
return CreateDecoderWithPDM(mEMEPDM,
aConfig,
aTaskQueue,
aCallback,
@@ -143,17 +156,17 @@ PDMFactory::CreateDecoder(const TrackInf
already_AddRefed<MediaDataDecoder>
PDMFactory::CreateDecoderWithPDM(PlatformDecoderModule* aPDM,
const TrackInfo& aConfig,
FlushableTaskQueue* aTaskQueue,
MediaDataDecoderCallback* aCallback,
DecoderDoctorDiagnostics* aDiagnostics,
layers::LayersBackend aLayersBackend,
- layers::ImageContainer* aImageContainer)
+ layers::ImageContainer* aImageContainer) const
{
MOZ_ASSERT(aPDM);
RefPtr<MediaDataDecoder> m;
if (aConfig.GetAsAudioInfo()) {
m = aPDM->CreateAudioDecoder(*aConfig.GetAsAudioInfo(),
aTaskQueue,
aCallback,
--- a/dom/media/platforms/PDMFactory.h
+++ b/dom/media/platforms/PDMFactory.h
@@ -3,45 +3,44 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#if !defined(PDMFactory_h_)
#define PDMFactory_h_
#include "PlatformDecoderModule.h"
+#include "mozilla/StaticMutex.h"
class CDMProxy;
namespace mozilla {
class DecoderDoctorDiagnostics;
+class PDMFactoryImpl;
+template<class T> class StaticAutoPtr;
class PDMFactory final {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PDMFactory)
PDMFactory();
- // Call on the main thread to initialize the static state
- // needed by Create().
- static void Init();
-
// Factory method that creates the appropriate PlatformDecoderModule for
// the platform we're running on. Caller is responsible for deleting this
// instance. It's expected that there will be multiple
// PlatformDecoderModules alive at the same time.
// This is called on the decode task queue.
already_AddRefed<MediaDataDecoder>
CreateDecoder(const TrackInfo& aConfig,
FlushableTaskQueue* aTaskQueue,
MediaDataDecoderCallback* aCallback,
DecoderDoctorDiagnostics* aDiagnostics,
layers::LayersBackend aLayersBackend = layers::LayersBackend::LAYERS_NONE,
- layers::ImageContainer* aImageContainer = nullptr);
+ layers::ImageContainer* aImageContainer = nullptr) const;
bool SupportsMimeType(const nsACString& aMimeType,
DecoderDoctorDiagnostics* aDiagnostics) const;
#ifdef MOZ_EME
// Creates a PlatformDecoderModule that uses a CDMProxy to decrypt or
// decrypt-and-decode EME encrypted content. If the CDM only decrypts and
// does not decode, we create a PDM and use that to create MediaDataDecoders
@@ -62,21 +61,26 @@ private:
already_AddRefed<MediaDataDecoder>
CreateDecoderWithPDM(PlatformDecoderModule* aPDM,
const TrackInfo& aConfig,
FlushableTaskQueue* aTaskQueue,
MediaDataDecoderCallback* aCallback,
DecoderDoctorDiagnostics* aDiagnostics,
layers::LayersBackend aLayersBackend,
- layers::ImageContainer* aImageContainer);
+ layers::ImageContainer* aImageContainer) const;
nsTArray<RefPtr<PlatformDecoderModule>> mCurrentPDMs;
RefPtr<PlatformDecoderModule> mEMEPDM;
bool mWMFFailedToLoad = false;
bool mFFmpegFailedToLoad = false;
bool mGMPPDMFailedToStartup = false;
+
+ void EnsureInit() const;
+ template<class T> friend class StaticAutoPtr;
+ static StaticAutoPtr<PDMFactoryImpl> sInstance;
+ static StaticMutex sMonitor;
};
} // namespace mozilla
#endif /* PDMFactory_h_ */
--- a/dom/media/wave/WaveDecoder.cpp
+++ b/dom/media/wave/WaveDecoder.cpp
@@ -35,17 +35,16 @@ WaveDecoder::CreateStateMachine()
/* static */
bool
WaveDecoder::IsEnabled()
{
MOZ_ASSERT(NS_IsMainThread());
if (!Preferences::GetBool("media.wave.decoder.enabled", false)) {
return false;
}
- PDMFactory::Init();
RefPtr<PDMFactory> platform = new PDMFactory();
return platform->SupportsMimeType(NS_LITERAL_CSTRING("audio/x-wav"),
/* DecoderDoctorDiagnostics* */ nullptr);
}
/* static */
bool
WaveDecoder::CanHandleMediaType(const nsACString& aType,