зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1674043 - P6. Remove sync PDecoderMananger::Supports API. r=mattwoodrow,bryce,mjf,ipc-reviewers,nika
In bug 1595994 we attempted to streamline the ability to determine which decoder was available regardless of the process they would be running in. This was subsequently done via the PDMFactory. As there are several JS API that can query which codec are supported, it requires a synchronous mechanism. This allowed to make a determination during the PlatformDecoderModule::Supports call, depending on which process it was going to be called frome. Having a synchronous IPC call to the RemoteDecoderManagerParent has too many caveats to be workable. So what we do instead is first determine at launch if the required external framework are available and pass this information to each content process. When checking if a decoder is available, we make a best guess at determining if the PDM would support such codec, without actually loading such framework when running in the content process. Supports can no longer make a decision based on the process currently running and as such PDM::CreateAudio/VideoDecoder using an optional system framework now need to further check the validity of the CreateDecoderParam argument. Differential Revision: https://phabricator.services.mozilla.com/D95245
This commit is contained in:
Родитель
bedf73be6e
Коммит
c938c7416c
|
@ -1306,6 +1306,7 @@ void ContentChild::InitXPCOM(
|
|||
|
||||
DataStorage::SetCachedStorageEntries(aXPCOMInit.dataStorage());
|
||||
|
||||
PDMFactory::SetSupported(aXPCOMInit.codecsSupported());
|
||||
// Initialize the RemoteDecoderManager thread and its associated PBackground
|
||||
// channel.
|
||||
RemoteDecoderManagerChild::Init();
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "Geolocation.h"
|
||||
#include "GfxInfoBase.h"
|
||||
#include "MMPrinter.h"
|
||||
#include "PDMFactory.h"
|
||||
#include "PreallocatedProcessManager.h"
|
||||
#include "ProcessPriorityManager.h"
|
||||
#include "SandboxHal.h"
|
||||
|
@ -2761,6 +2762,10 @@ bool ContentParent::InitInternal(ProcessPriority aInitialPriority) {
|
|||
// Send the dynamic scalar definitions to the new process.
|
||||
TelemetryIPC::GetDynamicScalarDefinitions(xpcomInit.dynamicScalarDefs());
|
||||
|
||||
// Pre-calculate the various PlatformDecoderModule (PDM) supported on this
|
||||
// machine.
|
||||
xpcomInit.codecsSupported() = PDMFactory::Supported();
|
||||
|
||||
// Must send screen info before send initialData
|
||||
ScreenManager& screenManager = ScreenManager::GetSingleton();
|
||||
screenManager.CopyScreensToRemote(this);
|
||||
|
|
|
@ -132,6 +132,7 @@ using refcounted class nsILayoutHistoryState from "nsILayoutHistoryState.h";
|
|||
using class mozilla::dom::SessionHistoryInfo from "mozilla/dom/SessionHistoryEntry.h";
|
||||
using nsPoint from "mozilla/GfxMessageUtils.h";
|
||||
using struct mozilla::dom::LoadingSessionHistoryInfo from "mozilla/dom/SessionHistoryEntry.h";
|
||||
using mozilla::PDMFactory::MediaCodecsSupported from "PDMFactory.h";
|
||||
|
||||
union ChromeRegistryItem
|
||||
{
|
||||
|
@ -312,6 +313,7 @@ struct XPCOMInitData
|
|||
nsCString[] requestedLocales;
|
||||
DynamicScalarDefinition[] dynamicScalarDefs;
|
||||
SystemParameterKVPair[] systemParameters;
|
||||
MediaCodecsSupported codecsSupported;
|
||||
};
|
||||
|
||||
struct VisitedQueryResult
|
||||
|
|
|
@ -33,11 +33,6 @@ sync protocol PRemoteDecoderManager
|
|||
manages PRemoteDecoder;
|
||||
|
||||
parent:
|
||||
sync Supports(RemoteDecoderInfoIPDL info,
|
||||
TextureFactoryIdentifier? identifier)
|
||||
returns (bool success,
|
||||
DecoderDoctorDiagnostics diagnostics);
|
||||
|
||||
sync PRemoteDecoder(RemoteDecoderInfoIPDL info,
|
||||
OptionSet options,
|
||||
TextureFactoryIdentifier? identifier)
|
||||
|
|
|
@ -64,13 +64,6 @@ ShutdownObserver::Observe(nsISupports* aSubject, const char* aTopic,
|
|||
|
||||
StaticRefPtr<ShutdownObserver> sObserver;
|
||||
|
||||
static Maybe<layers::TextureFactoryIdentifier> MaybeTextureFactoryIdentifier(
|
||||
const SupportDecoderParams& aParams) {
|
||||
return aParams.mKnowsCompositor
|
||||
? Some(aParams.mKnowsCompositor->GetTextureFactoryIdentifier())
|
||||
: Nothing();
|
||||
}
|
||||
|
||||
/* static */
|
||||
void RemoteDecoderManagerChild::Init() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
@ -186,41 +179,18 @@ nsISerialEventTarget* RemoteDecoderManagerChild::GetManagerThread() {
|
|||
bool RemoteDecoderManagerChild::Supports(
|
||||
RemoteDecodeIn aLocation, const SupportDecoderParams& aParams,
|
||||
DecoderDoctorDiagnostics* aDiagnostics) {
|
||||
bool supports = false;
|
||||
DecoderDoctorDiagnostics diagnostics;
|
||||
|
||||
nsCOMPtr<nsISerialEventTarget> managerThread = GetManagerThread();
|
||||
if (managerThread) {
|
||||
RefPtr<Runnable> task =
|
||||
NS_NewRunnableFunction("RemoteDecoderManager::Supports", [&]() {
|
||||
auto* rdm = GetSingleton(aLocation);
|
||||
if (!rdm) {
|
||||
// The RDD process failed to launch. Fail for now.
|
||||
// Creation will be attempted again later.
|
||||
return;
|
||||
}
|
||||
const auto& trackInfo = aParams.mConfig;
|
||||
if (trackInfo.GetAsVideoInfo()) {
|
||||
VideoDecoderInfoIPDL info(*trackInfo.GetAsVideoInfo(),
|
||||
aParams.mRate.mValue);
|
||||
Unused << rdm->SendSupports(info,
|
||||
MaybeTextureFactoryIdentifier(aParams),
|
||||
&supports, &diagnostics);
|
||||
} else if (trackInfo.GetAsAudioInfo()) {
|
||||
Unused << rdm->SendSupports(*trackInfo.GetAsAudioInfo(), Nothing(),
|
||||
&supports, &diagnostics);
|
||||
}
|
||||
});
|
||||
// If we've already got shutdown, the dispatch will fail and SyncRunnable
|
||||
// will immediately return.
|
||||
SyncRunnable::DispatchToThread(managerThread, task);
|
||||
RefPtr<PDMFactory> pdm;
|
||||
switch (aLocation) {
|
||||
case RemoteDecodeIn::RddProcess:
|
||||
pdm = PDMFactory::PDMFactoryForRdd();
|
||||
break;
|
||||
case RemoteDecodeIn::GpuProcess:
|
||||
pdm = PDMFactory::PDMFactoryForGpu();
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aDiagnostics) {
|
||||
*aDiagnostics = diagnostics;
|
||||
}
|
||||
|
||||
return supports;
|
||||
return pdm->Supports(aParams, aDiagnostics);
|
||||
}
|
||||
|
||||
/* static */
|
||||
|
|
|
@ -227,40 +227,6 @@ void RemoteDecoderManagerParent::Open(
|
|||
|
||||
void RemoteDecoderManagerParent::ActorDealloc() { Release(); }
|
||||
|
||||
mozilla::ipc::IPCResult RemoteDecoderManagerParent::RecvSupports(
|
||||
const RemoteDecoderInfoIPDL& aInfo,
|
||||
const Maybe<layers::TextureFactoryIdentifier>& aIdentifier, bool* aSuccess,
|
||||
DecoderDoctorDiagnostics* aDiagnostics) {
|
||||
auto& factory = EnsurePDMFactory();
|
||||
MediaResult error(NS_OK);
|
||||
|
||||
// It's important to initialize aSuccess because it is passed uninitialized
|
||||
// which will cause an assert on the receiving side.
|
||||
*aSuccess = false;
|
||||
if (aInfo.type() == RemoteDecoderInfoIPDL::TAudioInfo) {
|
||||
SupportDecoderParams params(aInfo.get_AudioInfo(), &error);
|
||||
*aSuccess = factory.Supports(params, aDiagnostics);
|
||||
} else if (aInfo.type() == RemoteDecoderInfoIPDL::TVideoDecoderInfoIPDL) {
|
||||
RefPtr<KnowsCompositorVideo> knowsCompositor;
|
||||
if (aIdentifier) {
|
||||
// Check to see if we have a direct PVideoBridge connection to the
|
||||
// destination process specified in aIdentifier, and create a
|
||||
// KnowsCompositor representing that connection if so. If this fails, then
|
||||
// we fall back to returning the decoded frames directly via Output().
|
||||
knowsCompositor =
|
||||
KnowsCompositorVideo::TryCreateForIdentifier(*aIdentifier);
|
||||
}
|
||||
|
||||
const VideoDecoderInfoIPDL& info = aInfo.get_VideoDecoderInfoIPDL();
|
||||
SupportDecoderParams params(info.videoInfo(), knowsCompositor,
|
||||
media::VideoFrameRate(info.framerate()),
|
||||
&error);
|
||||
*aSuccess = factory.Supports(params, aDiagnostics);
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult RemoteDecoderManagerParent::RecvReadback(
|
||||
const SurfaceDescriptorGPUVideo& aSD, SurfaceDescriptor* aResult) {
|
||||
const SurfaceDescriptorRemoteDecoder& sd = aSD;
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include "VorbisDecoder.h"
|
||||
#include "WAVDecoder.h"
|
||||
#include "gfxConfig.h"
|
||||
#include "nsIXULRuntime.h" // for BrowserTabsRemoteAutostart
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
|
|
@ -53,6 +53,10 @@
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
// Set on the main thread, in content processes before any PDMFactory will ever
|
||||
// be created; never modified after.
|
||||
static Maybe<PDMFactory::MediaCodecsSupported> sSupported;
|
||||
|
||||
extern already_AddRefed<PlatformDecoderModule> CreateNullDecoderModule();
|
||||
|
||||
class PDMFactoryImpl final {
|
||||
|
@ -62,7 +66,14 @@ class PDMFactoryImpl final {
|
|||
InitGpuPDMs();
|
||||
} else if (XRE_IsRDDProcess()) {
|
||||
InitRddPDMs();
|
||||
} else if (XRE_IsContentProcess()) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(sSupported.isSome(),
|
||||
"PDMFactory accessed while not initialized");
|
||||
InitContentPDMs();
|
||||
} else {
|
||||
MOZ_DIAGNOSTIC_ASSERT(
|
||||
XRE_IsParentProcess(),
|
||||
"PDMFactory is only usable in the Parent/GPU/RDD/Content process");
|
||||
InitDefaultPDMs();
|
||||
}
|
||||
}
|
||||
|
@ -95,6 +106,27 @@ class PDMFactoryImpl final {
|
|||
#endif
|
||||
}
|
||||
|
||||
void InitContentPDMs() {
|
||||
#ifdef XP_WIN
|
||||
if (!IsWin7AndPre2000Compatible()) {
|
||||
WMFDecoderModule::Init();
|
||||
}
|
||||
#endif
|
||||
#ifdef MOZ_APPLEMEDIA
|
||||
AppleDecoderModule::Init();
|
||||
#endif
|
||||
#ifdef MOZ_OMX
|
||||
OmxDecoderModule::Init();
|
||||
#endif
|
||||
#ifdef MOZ_FFVPX
|
||||
FFVPXRuntimeLinker::Init();
|
||||
#endif
|
||||
#ifdef MOZ_FFMPEG
|
||||
FFmpegRuntimeLinker::Init();
|
||||
#endif
|
||||
RemoteDecoderManagerChild::Init();
|
||||
}
|
||||
|
||||
void InitDefaultPDMs() {
|
||||
#ifdef XP_WIN
|
||||
if (!IsWin7AndPre2000Compatible()) {
|
||||
|
@ -113,9 +145,6 @@ class PDMFactoryImpl final {
|
|||
#ifdef MOZ_FFMPEG
|
||||
FFmpegRuntimeLinker::Init();
|
||||
#endif
|
||||
if (XRE_IsContentProcess()) {
|
||||
RemoteDecoderManagerChild::Init();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -199,6 +228,31 @@ PDMFactory::PDMFactory() {
|
|||
CreateNullPDM();
|
||||
}
|
||||
|
||||
PDMFactory::PDMFactory(const RemoteDecodeIn& aProcess) {
|
||||
switch (aProcess) {
|
||||
case RemoteDecodeIn::RddProcess:
|
||||
CreateRddPDMs();
|
||||
break;
|
||||
case RemoteDecodeIn::GpuProcess:
|
||||
CreateGpuPDMs();
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Not to be used for any other process");
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<PDMFactory> PDMFactory::PDMFactoryForRdd() {
|
||||
RefPtr<PDMFactory> pdm = new PDMFactory(RemoteDecodeIn::RddProcess);
|
||||
return pdm.forget();
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<PDMFactory> PDMFactory::PDMFactoryForGpu() {
|
||||
RefPtr<PDMFactory> pdm = new PDMFactory(RemoteDecodeIn::GpuProcess);
|
||||
return pdm.forget();
|
||||
}
|
||||
|
||||
/* static */
|
||||
void PDMFactory::EnsureInit() {
|
||||
{
|
||||
|
@ -383,13 +437,17 @@ void PDMFactory::CreatePDMs() {
|
|||
CreateGpuPDMs();
|
||||
} else if (XRE_IsRDDProcess()) {
|
||||
CreateRddPDMs();
|
||||
} else if (XRE_IsContentProcess()) {
|
||||
CreateContentPDMs();
|
||||
} else {
|
||||
MOZ_DIAGNOSTIC_ASSERT(
|
||||
XRE_IsParentProcess(),
|
||||
"PDMFactory is only usable in the Parent/GPU/RDD/Content process");
|
||||
CreateDefaultPDMs();
|
||||
}
|
||||
}
|
||||
|
||||
void PDMFactory::CreateGpuPDMs() {
|
||||
MOZ_ASSERT(XRE_IsGPUProcess());
|
||||
#ifdef XP_WIN
|
||||
if (StaticPrefs::media_wmf_enabled() && !IsWin7AndPre2000Compatible()) {
|
||||
CreateAndStartupPDM<WMFDecoderModule>();
|
||||
|
@ -398,7 +456,6 @@ void PDMFactory::CreateGpuPDMs() {
|
|||
}
|
||||
|
||||
void PDMFactory::CreateRddPDMs() {
|
||||
MOZ_ASSERT(XRE_IsRDDProcess());
|
||||
#ifdef XP_WIN
|
||||
if (StaticPrefs::media_wmf_enabled() &&
|
||||
StaticPrefs::media_rdd_wmf_enabled()) {
|
||||
|
@ -428,14 +485,12 @@ void PDMFactory::CreateRddPDMs() {
|
|||
CreateAndStartupPDM<AgnosticDecoderModule>();
|
||||
}
|
||||
|
||||
void PDMFactory::CreateDefaultPDMs() {
|
||||
MOZ_ASSERT(!XRE_IsGPUProcess() && !XRE_IsRDDProcess());
|
||||
void PDMFactory::CreateContentPDMs() {
|
||||
if (StaticPrefs::media_gpu_process_decoder()) {
|
||||
CreateAndStartupPDM<RemoteDecoderModule>(RemoteDecodeIn::GpuProcess);
|
||||
}
|
||||
|
||||
if (StaticPrefs::media_rdd_process_enabled() &&
|
||||
BrowserTabsRemoteAutostart()) {
|
||||
if (StaticPrefs::media_rdd_process_enabled()) {
|
||||
CreateAndStartupPDM<RemoteDecoderModule>(RemoteDecodeIn::RddProcess);
|
||||
}
|
||||
|
||||
|
@ -484,6 +539,52 @@ void PDMFactory::CreateDefaultPDMs() {
|
|||
}
|
||||
}
|
||||
|
||||
void PDMFactory::CreateDefaultPDMs() {
|
||||
#ifdef XP_WIN
|
||||
if (StaticPrefs::media_wmf_enabled() && !IsWin7AndPre2000Compatible()) {
|
||||
RefPtr<WMFDecoderModule> m = MakeAndAddRef<WMFDecoderModule>();
|
||||
if (!StartupPDM(m.forget())) {
|
||||
mFailureFlags += DecoderDoctorDiagnostics::Flags::WMFFailedToLoad;
|
||||
}
|
||||
} else if (StaticPrefs::media_decoder_doctor_wmf_disabled_is_failure()) {
|
||||
mFailureFlags += DecoderDoctorDiagnostics::Flags::WMFFailedToLoad;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_APPLEMEDIA
|
||||
CreateAndStartupPDM<AppleDecoderModule>();
|
||||
#endif
|
||||
#ifdef MOZ_OMX
|
||||
if (StaticPrefs::media_omx_enabled()) {
|
||||
CreateAndStartupPDM<OmxDecoderModule>();
|
||||
}
|
||||
#endif
|
||||
#ifdef MOZ_FFVPX
|
||||
if (StaticPrefs::media_ffvpx_enabled()) {
|
||||
CreateAndStartupPDM<FFVPXRuntimeLinker>();
|
||||
}
|
||||
#endif
|
||||
#ifdef MOZ_FFMPEG
|
||||
if (StaticPrefs::media_ffmpeg_enabled() &&
|
||||
!CreateAndStartupPDM<FFmpegRuntimeLinker>()) {
|
||||
mFailureFlags += DecoderDoctorDiagnostics::Flags::FFmpegFailedToLoad;
|
||||
}
|
||||
#endif
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
if (StaticPrefs::media_android_media_codec_enabled()) {
|
||||
StartupPDM(AndroidDecoderModule::Create(),
|
||||
StaticPrefs::media_android_media_codec_preferred());
|
||||
}
|
||||
#endif
|
||||
|
||||
CreateAndStartupPDM<AgnosticDecoderModule>();
|
||||
|
||||
if (StaticPrefs::media_gmp_decoder_enabled() &&
|
||||
!CreateAndStartupPDM<GMPDecoderModule>()) {
|
||||
mFailureFlags += DecoderDoctorDiagnostics::Flags::GMPPDMFailedToStartup;
|
||||
}
|
||||
}
|
||||
|
||||
void PDMFactory::CreateNullPDM() {
|
||||
mNullPDM = CreateNullDecoderModule();
|
||||
MOZ_ASSERT(mNullPDM && NS_SUCCEEDED(mNullPDM->Startup()));
|
||||
|
@ -535,4 +636,56 @@ void PDMFactory::SetCDMProxy(CDMProxy* aProxy) {
|
|||
mEMEPDM = MakeRefPtr<EMEDecoderModule>(aProxy, m);
|
||||
}
|
||||
|
||||
/* static */
|
||||
PDMFactory::MediaCodecsSupported PDMFactory::Supported() {
|
||||
if (XRE_IsContentProcess()) {
|
||||
return *sSupported;
|
||||
}
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
static MediaCodecsSupported supported = []() {
|
||||
auto pdm = MakeRefPtr<PDMFactory>();
|
||||
MediaCodecsSupported supported;
|
||||
// H264 and AAC depends on external framework that must be dynamically
|
||||
// loaded.
|
||||
// We currently only ship a single PDM per platform able to decode AAC or
|
||||
// H264. As such we can assert that being able to create a H264 or AAC
|
||||
// decoder indicates that with WMF on Windows or FFmpeg on Unixes is
|
||||
// available.
|
||||
// This logic will have to be revisited if a PDM supporting either codec
|
||||
// will be added in addition to the WMF and FFmpeg PDM (such as OpenH264)
|
||||
if (pdm->SupportsMimeType("video/avc"_ns, nullptr)) {
|
||||
supported += MediaCodecs::H264;
|
||||
}
|
||||
if (pdm->SupportsMimeType("audio/mp4a-latm"_ns, nullptr)) {
|
||||
supported += MediaCodecs::AAC;
|
||||
}
|
||||
// MP3 can be either decoded by ffvpx or WMF/FFmpeg
|
||||
if (pdm->SupportsMimeType("audio/mpeg"_ns, nullptr)) {
|
||||
supported += MediaCodecs::MP3;
|
||||
}
|
||||
// The codecs below are potentially always supported as we ship native
|
||||
// support for them. If they are disabled through pref, it will be handled
|
||||
// in MediaDecoder class that could use those.
|
||||
supported += MediaCodecs::VP9;
|
||||
supported += MediaCodecs::VP8;
|
||||
supported += MediaCodecs::AV1;
|
||||
supported += MediaCodecs::Theora;
|
||||
supported += MediaCodecs::Opus;
|
||||
supported += MediaCodecs::Vorbis;
|
||||
supported += MediaCodecs::Flac;
|
||||
supported += MediaCodecs::Wave;
|
||||
|
||||
return supported;
|
||||
}();
|
||||
return supported;
|
||||
}
|
||||
|
||||
/* static */
|
||||
void PDMFactory::SetSupported(const MediaCodecsSupported& aSupported) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
sSupported = Some(aSupported);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace mozilla {
|
|||
class PDMFactoryImpl;
|
||||
template <class T>
|
||||
class StaticAutoPtr;
|
||||
enum class RemoteDecodeIn;
|
||||
|
||||
class PDMFactory final {
|
||||
public:
|
||||
|
@ -25,6 +26,11 @@ class PDMFactory final {
|
|||
|
||||
PDMFactory();
|
||||
|
||||
// To be called in the content process only, used to determine which PDMs are
|
||||
// usable in their respective process.
|
||||
static already_AddRefed<PDMFactory> PDMFactoryForRdd();
|
||||
static already_AddRefed<PDMFactory> PDMFactoryForGpu();
|
||||
|
||||
// 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
|
||||
|
@ -50,13 +56,42 @@ class PDMFactory final {
|
|||
static constexpr int kYUV422 = 2;
|
||||
static constexpr int kYUV444 = 3;
|
||||
|
||||
/*
|
||||
* All the codecs we support
|
||||
*/
|
||||
enum class MediaCodecs {
|
||||
H264,
|
||||
VP9,
|
||||
VP8,
|
||||
AV1,
|
||||
Theora,
|
||||
AAC,
|
||||
MP3,
|
||||
Opus,
|
||||
Vorbis,
|
||||
Flac,
|
||||
Wave,
|
||||
|
||||
SENTINEL,
|
||||
};
|
||||
|
||||
using MediaCodecsSupported = EnumSet<MediaCodecs>;
|
||||
|
||||
static MediaCodecsSupported Supported();
|
||||
static void SetSupported(const MediaCodecsSupported& aSupported);
|
||||
|
||||
private:
|
||||
virtual ~PDMFactory() = default;
|
||||
// Will set PDM list for the required process.
|
||||
// This is used to determine which PDMs are available on the given process
|
||||
// from the content process.
|
||||
explicit PDMFactory(const RemoteDecodeIn& aProcess);
|
||||
|
||||
void CreatePDMs();
|
||||
void CreateNullPDM();
|
||||
void CreateGpuPDMs();
|
||||
void CreateRddPDMs();
|
||||
void CreateContentPDMs();
|
||||
void CreateDefaultPDMs();
|
||||
|
||||
template <typename DECODER_MODULE, typename... ARGS>
|
||||
|
@ -89,6 +124,14 @@ class PDMFactory final {
|
|||
static StaticMutex sMonitor;
|
||||
};
|
||||
|
||||
// Used for IPDL serialization.
|
||||
// The 'value' have to be the biggest enum from MediaCodecs.
|
||||
template <>
|
||||
struct MaxEnumValue<PDMFactory::MediaCodecs> {
|
||||
static constexpr unsigned int value =
|
||||
static_cast<unsigned int>(PDMFactory::MediaCodecs::SENTINEL);
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* PDMFactory_h_ */
|
||||
|
|
|
@ -298,6 +298,9 @@ class PlatformDecoderModule {
|
|||
// Returns nullptr if the decoder can't be created.
|
||||
// It is safe to store a reference to aConfig.
|
||||
// This is called on the decode task queue.
|
||||
// CreateVideoDecoder may need to make additional checks if the
|
||||
// CreateDecoderParams argument is actually supported and return nullptr if
|
||||
// not to allow for fallback PDMs to be tried.
|
||||
virtual already_AddRefed<MediaDataDecoder> CreateVideoDecoder(
|
||||
const CreateDecoderParams& aParams) = 0;
|
||||
|
||||
|
@ -310,6 +313,9 @@ class PlatformDecoderModule {
|
|||
// COINIT_MULTITHREADED.
|
||||
// It is safe to store a reference to aConfig.
|
||||
// This is called on the decode task queue.
|
||||
// CreateAudioDecoder may need to make additional checks if the
|
||||
// CreateDecoderParams argument is actually supported and return nullptr if
|
||||
// not to allow for fallback PDMs to be tried.
|
||||
virtual already_AddRefed<MediaDataDecoder> CreateAudioDecoder(
|
||||
const CreateDecoderParams& aParams) = 0;
|
||||
};
|
||||
|
|
|
@ -37,11 +37,7 @@ static bool IsAvailableInDefault(DecoderType type) {
|
|||
switch (type) {
|
||||
#ifdef MOZ_AV1
|
||||
case DecoderType::AV1:
|
||||
// We remove support for decoding AV1 here if RDD is enabled so that
|
||||
// decoding on the content process doesn't accidentally happen in case
|
||||
// something goes wrong with launching the RDD process.
|
||||
return StaticPrefs::media_av1_enabled() &&
|
||||
!StaticPrefs::media_rdd_process_enabled();
|
||||
return StaticPrefs::media_av1_enabled();
|
||||
#endif
|
||||
case DecoderType::Opus:
|
||||
case DecoderType::Theora:
|
||||
|
@ -128,14 +124,21 @@ bool AgnosticDecoderModule::Supports(
|
|||
|
||||
already_AddRefed<MediaDataDecoder> AgnosticDecoderModule::CreateVideoDecoder(
|
||||
const CreateDecoderParams& aParams) {
|
||||
if (!Supports(SupportDecoderParams(aParams), aParams.mDiagnostics)) {
|
||||
return nullptr;
|
||||
}
|
||||
RefPtr<MediaDataDecoder> m;
|
||||
|
||||
if (VPXDecoder::IsVPX(aParams.mConfig.mMimeType)) {
|
||||
m = new VPXDecoder(aParams);
|
||||
}
|
||||
#ifdef MOZ_AV1
|
||||
// see comment above about AV1 and the RDD process
|
||||
else if (AOMDecoder::IsAV1(aParams.mConfig.mMimeType)) {
|
||||
// We remove support for decoding AV1 here if RDD is enabled so that
|
||||
// decoding on the content process doesn't accidentally happen in case
|
||||
// something goes wrong with launching the RDD process.
|
||||
if (StaticPrefs::media_av1_enabled() &&
|
||||
(!StaticPrefs::media_rdd_process_enabled() || XRE_IsRDDProcess()) &&
|
||||
AOMDecoder::IsAV1(aParams.mConfig.mMimeType)) {
|
||||
if (StaticPrefs::media_av1_use_dav1d()) {
|
||||
m = new DAV1DDecoder(aParams);
|
||||
} else {
|
||||
|
@ -152,6 +155,9 @@ already_AddRefed<MediaDataDecoder> AgnosticDecoderModule::CreateVideoDecoder(
|
|||
|
||||
already_AddRefed<MediaDataDecoder> AgnosticDecoderModule::CreateAudioDecoder(
|
||||
const CreateDecoderParams& aParams) {
|
||||
if (!Supports(SupportDecoderParams(aParams), aParams.mDiagnostics)) {
|
||||
return nullptr;
|
||||
}
|
||||
RefPtr<MediaDataDecoder> m;
|
||||
|
||||
const TrackInfo& config = aParams.mConfig;
|
||||
|
|
|
@ -54,6 +54,9 @@ nsresult AppleDecoderModule::Startup() {
|
|||
|
||||
already_AddRefed<MediaDataDecoder> AppleDecoderModule::CreateVideoDecoder(
|
||||
const CreateDecoderParams& aParams) {
|
||||
if (!Supports(SupportDecoderParams(aParams), aParams.mDiagnostics)) {
|
||||
return nullptr;
|
||||
}
|
||||
RefPtr<MediaDataDecoder> decoder;
|
||||
if (IsVideoSupported(aParams.VideoConfig(), aParams.mOptions)) {
|
||||
decoder = new AppleVTDecoder(aParams.VideoConfig(), aParams.mImageContainer,
|
||||
|
@ -64,6 +67,9 @@ already_AddRefed<MediaDataDecoder> AppleDecoderModule::CreateVideoDecoder(
|
|||
|
||||
already_AddRefed<MediaDataDecoder> AppleDecoderModule::CreateAudioDecoder(
|
||||
const CreateDecoderParams& aParams) {
|
||||
if (!Supports(SupportDecoderParams(aParams), aParams.mDiagnostics)) {
|
||||
return nullptr;
|
||||
}
|
||||
RefPtr<MediaDataDecoder> decoder = new AppleATDecoder(aParams.AudioConfig());
|
||||
return decoder.forget();
|
||||
}
|
||||
|
|
|
@ -32,6 +32,9 @@ class FFmpegDecoderModule : public PlatformDecoderModule {
|
|||
|
||||
already_AddRefed<MediaDataDecoder> CreateVideoDecoder(
|
||||
const CreateDecoderParams& aParams) override {
|
||||
if (!Supports(SupportDecoderParams(aParams), aParams.mDiagnostics)) {
|
||||
return nullptr;
|
||||
}
|
||||
RefPtr<MediaDataDecoder> decoder = new FFmpegVideoDecoder<V>(
|
||||
mLib, aParams.VideoConfig(), aParams.mKnowsCompositor,
|
||||
aParams.mImageContainer,
|
||||
|
@ -43,6 +46,9 @@ class FFmpegDecoderModule : public PlatformDecoderModule {
|
|||
|
||||
already_AddRefed<MediaDataDecoder> CreateAudioDecoder(
|
||||
const CreateDecoderParams& aParams) override {
|
||||
if (!Supports(SupportDecoderParams(aParams), aParams.mDiagnostics)) {
|
||||
return nullptr;
|
||||
}
|
||||
RefPtr<MediaDataDecoder> decoder =
|
||||
new FFmpegAudioDecoder<V>(mLib, aParams.AudioConfig());
|
||||
return decoder.forget();
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "MFTDecoder.h"
|
||||
#include "MP4Decoder.h"
|
||||
#include "MediaInfo.h"
|
||||
#include "PDMFactory.h"
|
||||
#include "VPXDecoder.h"
|
||||
#include "WMF.h"
|
||||
#include "WMFAudioMFTManager.h"
|
||||
|
@ -28,6 +29,7 @@
|
|||
#include "mozilla/mscom/EnsureMTA.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsIXULRuntime.h"
|
||||
#include "nsIXULRuntime.h" // for BrowserTabsRemoteAutostart
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsWindowsHelpers.h"
|
||||
#include "prsystem.h"
|
||||
|
@ -94,26 +96,21 @@ static bool CanCreateMFTDecoder(const GUID& aGuid) {
|
|||
/* static */
|
||||
void WMFDecoderModule::Init() {
|
||||
MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
|
||||
bool testForVPx;
|
||||
if (XRE_IsContentProcess()) {
|
||||
// If we're in the content process and the UseGPUDecoder pref is set, it
|
||||
// means that we've given up on the GPU process (it's been crashing) so we
|
||||
// should disable DXVA
|
||||
sDXVAEnabled = !StaticPrefs::media_gpu_process_decoder();
|
||||
// We need to test for VPX in the content process as the GPUDecoderModule
|
||||
// directly calls WMFDecoderModule::Supports in the content process.
|
||||
// This unnecessary requirement will be fixed in bug 1534815.
|
||||
testForVPx = true;
|
||||
} else if (XRE_IsGPUProcess() || XRE_IsRDDProcess()) {
|
||||
// Always allow DXVA in the GPU or RDD process.
|
||||
testForVPx = sDXVAEnabled = true;
|
||||
sDXVAEnabled = true;
|
||||
} else {
|
||||
// Only allow DXVA in the UI process if we aren't in e10s Firefox
|
||||
testForVPx = sDXVAEnabled = !mozilla::BrowserTabsRemoteAutostart();
|
||||
sDXVAEnabled = !mozilla::BrowserTabsRemoteAutostart();
|
||||
}
|
||||
|
||||
sDXVAEnabled = sDXVAEnabled && gfx::gfxVars::CanUseHardwareVideoDecoding();
|
||||
testForVPx = testForVPx && gfx::gfxVars::CanUseHardwareVideoDecoding();
|
||||
bool testForVPx = gfx::gfxVars::CanUseHardwareVideoDecoding();
|
||||
if (testForVPx && StaticPrefs::media_wmf_vp9_enabled_AtStartup()) {
|
||||
gfx::WMFVPXVideoCrashGuard guard;
|
||||
if (!guard.Crashed()) {
|
||||
|
@ -214,14 +211,44 @@ static bool CanCreateWMFDecoder() {
|
|||
|
||||
/* static */
|
||||
bool WMFDecoderModule::HasH264() {
|
||||
if (XRE_IsContentProcess()) {
|
||||
return PDMFactory::Supported().contains(PDMFactory::MediaCodecs::H264);
|
||||
}
|
||||
return CanCreateWMFDecoder<CLSID_CMSH264DecoderMFT>();
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool WMFDecoderModule::HasVP8() {
|
||||
if (XRE_IsContentProcess()) {
|
||||
return PDMFactory::Supported().contains(PDMFactory::MediaCodecs::VP8);
|
||||
}
|
||||
return sUsableVPXMFT && CanCreateWMFDecoder<CLSID_WebmMfVpxDec>();
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool WMFDecoderModule::HasVP9() {
|
||||
if (XRE_IsContentProcess()) {
|
||||
return PDMFactory::Supported().contains(PDMFactory::MediaCodecs::VP9);
|
||||
}
|
||||
return sUsableVPXMFT && CanCreateWMFDecoder<CLSID_WebmMfVpxDec>();
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool WMFDecoderModule::HasAAC() {
|
||||
if (XRE_IsContentProcess()) {
|
||||
return PDMFactory::Supported().contains(PDMFactory::MediaCodecs::AAC);
|
||||
}
|
||||
return CanCreateWMFDecoder<CLSID_CMSAACDecMFT>();
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool WMFDecoderModule::HasMP3() {
|
||||
if (XRE_IsContentProcess()) {
|
||||
return PDMFactory::Supported().contains(PDMFactory::MediaCodecs::MP3);
|
||||
}
|
||||
return CanCreateWMFDecoder<CLSID_CMP3DecMediaObject>();
|
||||
}
|
||||
|
||||
bool WMFDecoderModule::SupportsMimeType(
|
||||
const nsACString& aMimeType, DecoderDoctorDiagnostics* aDiagnostics) const {
|
||||
UniquePtr<TrackInfo> trackInfo = CreateTrackInfoWithMIMEType(aMimeType);
|
||||
|
@ -269,17 +296,16 @@ bool WMFDecoderModule::Supports(const SupportDecoderParams& aParams,
|
|||
return true;
|
||||
}
|
||||
if (trackInfo.mMimeType.EqualsLiteral("audio/mpeg") &&
|
||||
!StaticPrefs::media_ffvpx_mp3_enabled() &&
|
||||
CanCreateWMFDecoder<CLSID_CMP3DecMediaObject>()) {
|
||||
!StaticPrefs::media_ffvpx_mp3_enabled() && WMFDecoderModule::HasMP3()) {
|
||||
return true;
|
||||
}
|
||||
if (sUsableVPXMFT) {
|
||||
static const uint32_t VP8_USABLE_BUILD = 16287;
|
||||
if ((VPXDecoder::IsVP8(trackInfo.mMimeType) &&
|
||||
IsWindowsBuildOrLater(VP8_USABLE_BUILD)) ||
|
||||
VPXDecoder::IsVP9(trackInfo.mMimeType)) {
|
||||
return CanCreateWMFDecoder<CLSID_WebmMfVpxDec>();
|
||||
}
|
||||
static const uint32_t VP8_USABLE_BUILD = 16287;
|
||||
if (VPXDecoder::IsVP8(trackInfo.mMimeType) &&
|
||||
IsWindowsBuildOrLater(VP8_USABLE_BUILD) && WMFDecoderModule::HasVP8()) {
|
||||
return true;
|
||||
}
|
||||
if (VPXDecoder::IsVP9(trackInfo.mMimeType) && WMFDecoderModule::HasVP9()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Some unsupported codec.
|
||||
|
|
|
@ -40,8 +40,11 @@ class WMFDecoderModule : public PlatformDecoderModule {
|
|||
// H.264/AAC decoders if the "Platform Update Supplement for Windows Vista"
|
||||
// is not installed, and Window N and KN variants also require a "Media
|
||||
// Feature Pack" to be installed. Windows XP doesn't have WMF.
|
||||
static bool HasAAC();
|
||||
static bool HasH264();
|
||||
static bool HasVP8();
|
||||
static bool HasVP9();
|
||||
static bool HasAAC();
|
||||
static bool HasMP3();
|
||||
|
||||
private:
|
||||
virtual ~WMFDecoderModule();
|
||||
|
|
|
@ -884,8 +884,6 @@ description = legacy sync IPC - please add detailed description
|
|||
description = legacy sync IPC - please add detailed description
|
||||
[PRemoteDecoderManager::PRemoteDecoder]
|
||||
description = See Bug 1505976 - investigate changing to async instead of matching GPU pattern
|
||||
[PRemoteDecoderManager::Supports]
|
||||
description = See Bug 1672072 - We will always need a synchronous call in the worse case scenario, follow-up calls will be cached; however it could be made fully asynchronous under some circumstances..
|
||||
[PRemoteDecoderManager::Readback]
|
||||
description = legacy sync IPC - please add detailed description
|
||||
[PBackground::EnsureRDDProcessAndCreateBridge]
|
||||
|
|
Загрузка…
Ссылка в новой задаче