Bug 1595994 - P6: Change Supports to take SupportDecoderParams. r=kamidphish

This is a subset of the parameters passed via CreateDecoderParams and is so
Supports() calls have access to KnowsCompositor and Options when determining
if decoding is supported.

Depends on D54877

Differential Revision: https://phabricator.services.mozilla.com/D54878
This commit is contained in:
Jean-Yves Avenard 2020-10-20 23:26:25 +00:00
Родитель 9ef1beee14
Коммит f8343f2b4d
12 изменённых файлов: 157 добавлений и 77 удалений

Просмотреть файл

@ -29,9 +29,9 @@ bool GpuDecoderModule::SupportsMimeType(
return mWrapped->SupportsMimeType(aMimeType, aDiagnostics); return mWrapped->SupportsMimeType(aMimeType, aDiagnostics);
} }
bool GpuDecoderModule::Supports(const TrackInfo& aTrackInfo, bool GpuDecoderModule::Supports(const SupportDecoderParams& aParams,
DecoderDoctorDiagnostics* aDiagnostics) const { DecoderDoctorDiagnostics* aDiagnostics) const {
return mWrapped->Supports(aTrackInfo, aDiagnostics); return mWrapped->Supports(aParams, aDiagnostics);
} }
static inline bool IsRemoteAcceleratedCompositor(KnowsCompositor* aKnows) { static inline bool IsRemoteAcceleratedCompositor(KnowsCompositor* aKnows) {

Просмотреть файл

@ -27,7 +27,7 @@ class GpuDecoderModule : public PlatformDecoderModule {
bool SupportsMimeType(const nsACString& aMimeType, bool SupportsMimeType(const nsACString& aMimeType,
DecoderDoctorDiagnostics* aDiagnostics) const override; DecoderDoctorDiagnostics* aDiagnostics) const override;
bool Supports(const TrackInfo& aTrackInfo, bool Supports(const SupportDecoderParams& aParams,
DecoderDoctorDiagnostics* aDiagnostics) const override; DecoderDoctorDiagnostics* aDiagnostics) const override;
already_AddRefed<MediaDataDecoder> CreateVideoDecoder( already_AddRefed<MediaDataDecoder> CreateVideoDecoder(

Просмотреть файл

@ -215,7 +215,8 @@ already_AddRefed<Promise> MediaCapabilities::DecodingInfo(
// There's no need to create an audio decoder has we only want to know if // There's no need to create an audio decoder has we only want to know if
// such codec is supported // such codec is supported
RefPtr<PDMFactory> pdm = new PDMFactory(); RefPtr<PDMFactory> pdm = new PDMFactory();
if (!pdm->Supports(*config, nullptr /* decoder doctor */)) { SupportDecoderParams params{*config};
if (!pdm->Supports(params, nullptr /* decoder doctor */)) {
auto info = MakeUnique<MediaCapabilitiesInfo>( auto info = MakeUnique<MediaCapabilitiesInfo>(
false /* supported */, false /* smooth */, false /* supported */, false /* smooth */,
false /* power efficient */); false /* power efficient */);

Просмотреть файл

@ -171,7 +171,8 @@ bool MP4Decoder::IsSupportedType(const MediaContainerType& aType,
// Verify that we have a PDM that supports the whitelisted types. // Verify that we have a PDM that supports the whitelisted types.
RefPtr<PDMFactory> platform = new PDMFactory(); RefPtr<PDMFactory> platform = new PDMFactory();
for (const auto& track : tracks) { for (const auto& track : tracks) {
if (!track || !platform->Supports(*track, aDiagnostics)) { if (!track ||
!platform->Supports(SupportDecoderParams(*track), aDiagnostics)) {
return false; return false;
} }
} }

Просмотреть файл

@ -221,7 +221,7 @@ already_AddRefed<MediaDataDecoder> PDMFactory::CreateDecoder(
} }
for (auto& current : mCurrentPDMs) { for (auto& current : mCurrentPDMs) {
if (!current->Supports(config, diagnostics)) { if (!current->Supports(SupportDecoderParams(aParams), diagnostics)) {
continue; continue;
} }
decoder = CreateDecoderWithPDM(current, aParams); decoder = CreateDecoderWithPDM(current, aParams);
@ -313,15 +313,15 @@ bool PDMFactory::SupportsMimeType(
if (!trackInfo) { if (!trackInfo) {
return false; return false;
} }
return Supports(*trackInfo, aDiagnostics); return Supports(SupportDecoderParams(*trackInfo), aDiagnostics);
} }
bool PDMFactory::Supports(const TrackInfo& aTrackInfo, bool PDMFactory::Supports(const SupportDecoderParams& aParams,
DecoderDoctorDiagnostics* aDiagnostics) const { DecoderDoctorDiagnostics* aDiagnostics) const {
if (mEMEPDM) { if (mEMEPDM) {
return mEMEPDM->Supports(aTrackInfo, aDiagnostics); return mEMEPDM->Supports(aParams, aDiagnostics);
} }
if (VPXDecoder::IsVPX(aTrackInfo.mMimeType, if (VPXDecoder::IsVPX(aParams.MimeType(),
VPXDecoder::VP8 | VPXDecoder::VP9)) { VPXDecoder::VP8 | VPXDecoder::VP9)) {
// Work around bug 1521370, where trying to instantiate an external decoder // Work around bug 1521370, where trying to instantiate an external decoder
// could cause a crash. // could cause a crash.
@ -329,7 +329,9 @@ bool PDMFactory::Supports(const TrackInfo& aTrackInfo,
// So we can speed up the test by assuming that this codec is supported. // So we can speed up the test by assuming that this codec is supported.
return true; return true;
} }
RefPtr<PlatformDecoderModule> current = GetDecoder(aTrackInfo, aDiagnostics);
RefPtr<PlatformDecoderModule> current =
GetDecoderModule(aParams, aDiagnostics);
return !!current; return !!current;
} }
@ -433,8 +435,9 @@ bool PDMFactory::StartupPDM(already_AddRefed<PlatformDecoderModule> aPDM,
return false; return false;
} }
already_AddRefed<PlatformDecoderModule> PDMFactory::GetDecoder( already_AddRefed<PlatformDecoderModule> PDMFactory::GetDecoderModule(
const TrackInfo& aTrackInfo, DecoderDoctorDiagnostics* aDiagnostics) const { const SupportDecoderParams& aParams,
DecoderDoctorDiagnostics* aDiagnostics) const {
if (aDiagnostics) { if (aDiagnostics) {
// If libraries failed to load, the following loop over mCurrentPDMs // If libraries failed to load, the following loop over mCurrentPDMs
// will not even try to use them. So we record failures now. // will not even try to use them. So we record failures now.
@ -451,7 +454,7 @@ already_AddRefed<PlatformDecoderModule> PDMFactory::GetDecoder(
RefPtr<PlatformDecoderModule> pdm; RefPtr<PlatformDecoderModule> pdm;
for (auto& current : mCurrentPDMs) { for (auto& current : mCurrentPDMs) {
if (current->Supports(aTrackInfo, aDiagnostics)) { if (current->Supports(aParams, aDiagnostics)) {
pdm = current; pdm = current;
break; break;
} }

Просмотреть файл

@ -35,7 +35,7 @@ class PDMFactory final {
bool SupportsMimeType(const nsACString& aMimeType, bool SupportsMimeType(const nsACString& aMimeType,
DecoderDoctorDiagnostics* aDiagnostics) const; DecoderDoctorDiagnostics* aDiagnostics) const;
bool Supports(const TrackInfo& aTrackInfo, bool Supports(const SupportDecoderParams& aParams,
DecoderDoctorDiagnostics* aDiagnostics) const; DecoderDoctorDiagnostics* aDiagnostics) const;
// Creates a PlatformDecoderModule that uses a CDMProxy to decrypt or // Creates a PlatformDecoderModule that uses a CDMProxy to decrypt or
@ -67,8 +67,8 @@ class PDMFactory final {
bool StartupPDM(already_AddRefed<PlatformDecoderModule> aPDM, bool StartupPDM(already_AddRefed<PlatformDecoderModule> aPDM,
bool aInsertAtBeginning = false); bool aInsertAtBeginning = false);
// Returns the first PDM in our list supporting the mimetype. // Returns the first PDM in our list supporting the mimetype.
already_AddRefed<PlatformDecoderModule> GetDecoder( already_AddRefed<PlatformDecoderModule> GetDecoderModule(
const TrackInfo& aTrackInfo, const SupportDecoderParams& aParams,
DecoderDoctorDiagnostics* aDiagnostics) const; DecoderDoctorDiagnostics* aDiagnostics) const;
already_AddRefed<MediaDataDecoder> CreateDecoderWithPDM( already_AddRefed<MediaDataDecoder> CreateDecoderWithPDM(

Просмотреть файл

@ -41,45 +41,54 @@ class CDMProxy;
static LazyLogModule sPDMLog("PlatformDecoderModule"); static LazyLogModule sPDMLog("PlatformDecoderModule");
namespace media {
enum class Option {
Default,
LowLatency,
HardwareDecoderNotAllowed,
FullH264Parsing,
ErrorIfNoInitializationData, // By default frames delivered before
// initialization data are dropped. Pass this
// option to raise an error if frames are
// delivered before initialization data.
DefaultPlaybackDeviceMono, // Currently only used by Opus on RDD to avoid
// initialization of audio backends on RDD
SENTINEL // one past the last valid value
};
using OptionSet = EnumSet<Option>;
struct UseNullDecoder {
UseNullDecoder() = default;
explicit UseNullDecoder(bool aUseNullDecoder) : mUse(aUseNullDecoder) {}
bool mUse = false;
};
// Do not wrap H264 decoder in a H264Converter.
struct NoWrapper {
NoWrapper() = default;
explicit NoWrapper(bool aDontUseWrapper) : mDontUseWrapper(aDontUseWrapper) {}
bool mDontUseWrapper = false;
};
struct VideoFrameRate {
VideoFrameRate() = default;
explicit VideoFrameRate(float aFramerate) : mValue(aFramerate) {}
float mValue = 0.0f;
};
} // namespace media
struct MOZ_STACK_CLASS CreateDecoderParams final { struct MOZ_STACK_CLASS CreateDecoderParams final {
using Option = media::Option;
using OptionSet = media::OptionSet;
using UseNullDecoder = media::UseNullDecoder;
using NoWrapper = media::NoWrapper;
using VideoFrameRate = media::VideoFrameRate;
explicit CreateDecoderParams(const TrackInfo& aConfig) : mConfig(aConfig) {} explicit CreateDecoderParams(const TrackInfo& aConfig) : mConfig(aConfig) {}
enum class Option {
Default,
LowLatency,
HardwareDecoderNotAllowed,
FullH264Parsing,
ErrorIfNoInitializationData, // By default frames delivered before
// initialization data are dropped. Pass this
// option to raise an error if frames are
// delivered before initialization data.
DefaultPlaybackDeviceMono, // Currently only used by Opus on RDD to avoid
// initialization of audio backends on RDD
SENTINEL // one past the last valid value
};
using OptionSet = EnumSet<Option>;
struct UseNullDecoder {
UseNullDecoder() = default;
explicit UseNullDecoder(bool aUseNullDecoder) : mUse(aUseNullDecoder) {}
bool mUse = false;
};
// Do not wrap decoder in a MediaChangeMonitor.
struct NoWrapper {
NoWrapper() = default;
explicit NoWrapper(bool aDontUseWrapper)
: mDontUseWrapper(aDontUseWrapper) {}
bool mDontUseWrapper = false;
};
struct VideoFrameRate {
VideoFrameRate() = default;
explicit VideoFrameRate(float aFramerate) : mValue(aFramerate) {}
float mValue = 0.0f;
};
template <typename T1, typename... Ts> template <typename T1, typename... Ts>
CreateDecoderParams(const TrackInfo& aConfig, T1&& a1, Ts&&... args) CreateDecoderParams(const TrackInfo& aConfig, T1&& a1, Ts&&... args)
: mConfig(aConfig) { : mConfig(aConfig) {
@ -115,12 +124,12 @@ struct MOZ_STACK_CLASS CreateDecoderParams final {
MediaResult* mError = nullptr; MediaResult* mError = nullptr;
RefPtr<layers::KnowsCompositor> mKnowsCompositor; RefPtr<layers::KnowsCompositor> mKnowsCompositor;
RefPtr<GMPCrashHelper> mCrashHelper; RefPtr<GMPCrashHelper> mCrashHelper;
UseNullDecoder mUseNullDecoder; media::UseNullDecoder mUseNullDecoder;
NoWrapper mNoWrapper; media::NoWrapper mNoWrapper;
TrackInfo::TrackType mType = TrackInfo::kUndefinedTrack; TrackInfo::TrackType mType = TrackInfo::kUndefinedTrack;
MediaEventProducer<TrackInfo::TrackType>* mOnWaitingForKeyEvent = nullptr; MediaEventProducer<TrackInfo::TrackType>* mOnWaitingForKeyEvent = nullptr;
OptionSet mOptions = OptionSet(Option::Default); OptionSet mOptions = OptionSet(Option::Default);
VideoFrameRate mRate; media::VideoFrameRate mRate;
private: private:
void Set(DecoderDoctorDiagnostics* aDiagnostics) { void Set(DecoderDoctorDiagnostics* aDiagnostics) {
@ -154,6 +163,67 @@ struct MOZ_STACK_CLASS CreateDecoderParams final {
} }
}; };
struct MOZ_STACK_CLASS SupportDecoderParams final {
using Option = media::Option;
using OptionSet = media::OptionSet;
using UseNullDecoder = media::UseNullDecoder;
using NoWrapper = media::NoWrapper;
using VideoFrameRate = media::VideoFrameRate;
explicit SupportDecoderParams(const TrackInfo& aConfig) : mConfig(aConfig) {}
explicit SupportDecoderParams(const CreateDecoderParams& aParams)
: mConfig(aParams.mConfig),
mDiagnostics(aParams.mDiagnostics),
mError(aParams.mError),
mKnowsCompositor(aParams.mKnowsCompositor),
mUseNullDecoder(aParams.mUseNullDecoder),
mNoWrapper(aParams.mNoWrapper),
mOptions(aParams.mOptions),
mRate(aParams.mRate) {}
template <typename T1, typename... Ts>
SupportDecoderParams(const TrackInfo& aConfig, T1&& a1, Ts&&... args)
: mConfig(aConfig) {
Set(std::forward<T1>(a1), std::forward<Ts>(args)...);
}
const nsCString& MimeType() const { return mConfig.mMimeType; }
const TrackInfo& mConfig;
DecoderDoctorDiagnostics* mDiagnostics = nullptr;
MediaResult* mError = nullptr;
RefPtr<layers::KnowsCompositor> mKnowsCompositor;
UseNullDecoder mUseNullDecoder;
NoWrapper mNoWrapper;
OptionSet mOptions = OptionSet(Option::Default);
VideoFrameRate mRate;
private:
void Set(DecoderDoctorDiagnostics* aDiagnostics) {
mDiagnostics = aDiagnostics;
}
void Set(MediaResult* aError) { mError = aError; }
void Set(media::UseNullDecoder aUseNullDecoder) {
mUseNullDecoder = aUseNullDecoder;
}
void Set(media::NoWrapper aNoWrapper) { mNoWrapper = aNoWrapper; }
void Set(media::OptionSet aOptions) { mOptions = aOptions; }
void Set(media::VideoFrameRate aRate) { mRate = aRate; }
void Set(layers::KnowsCompositor* aKnowsCompositor) {
if (aKnowsCompositor) {
mKnowsCompositor = aKnowsCompositor;
MOZ_ASSERT(aKnowsCompositor->IsThreadSafe());
}
}
template <typename T1, typename T2, typename... Ts>
void Set(T1&& a1, T2&& a2, Ts&&... args) {
Set(std::forward<T1>(a1));
Set(std::forward<T2>(a2), std::forward<Ts>(args)...);
}
};
// Used for IPDL serialization. // Used for IPDL serialization.
// The 'value' have to be the biggest enum from CreateDecoderParams::Option. // The 'value' have to be the biggest enum from CreateDecoderParams::Option.
template <> template <>
@ -189,12 +259,13 @@ class PlatformDecoderModule {
const nsACString& aMimeType, const nsACString& aMimeType,
DecoderDoctorDiagnostics* aDiagnostics) const = 0; DecoderDoctorDiagnostics* aDiagnostics) const = 0;
virtual bool Supports(const TrackInfo& aTrackInfo, virtual bool Supports(const SupportDecoderParams& aParams,
DecoderDoctorDiagnostics* aDiagnostics) const { DecoderDoctorDiagnostics* aDiagnostics) const {
if (!SupportsMimeType(aTrackInfo.mMimeType, aDiagnostics)) { const TrackInfo& trackInfo = aParams.mConfig;
if (!SupportsMimeType(trackInfo.mMimeType, aDiagnostics)) {
return false; return false;
} }
const auto videoInfo = aTrackInfo.GetAsVideoInfo(); const auto* videoInfo = trackInfo.GetAsVideoInfo();
return !videoInfo || return !videoInfo ||
SupportsColorDepth(videoInfo->mColorDepth, aDiagnostics); SupportsColorDepth(videoInfo->mColorDepth, aDiagnostics);
} }

Просмотреть файл

@ -77,12 +77,14 @@ bool AppleDecoderModule::SupportsMimeType(
} }
bool AppleDecoderModule::Supports( bool AppleDecoderModule::Supports(
const TrackInfo& aTrackInfo, DecoderDoctorDiagnostics* aDiagnostics) const { const SupportDecoderParams& aParams,
if (aTrackInfo.IsAudio()) { DecoderDoctorDiagnostics* aDiagnostics) const {
return SupportsMimeType(aTrackInfo.mMimeType, aDiagnostics); const auto& trackInfo = aParams.mConfig;
if (trackInfo.IsAudio()) {
return SupportsMimeType(trackInfo.mMimeType, aDiagnostics);
} }
return aTrackInfo.GetAsVideoInfo() && return trackInfo.GetAsVideoInfo() &&
IsVideoSupported(*aTrackInfo.GetAsVideoInfo()); IsVideoSupported(*trackInfo.GetAsVideoInfo());
} }
bool AppleDecoderModule::IsVideoSupported( bool AppleDecoderModule::IsVideoSupported(

Просмотреть файл

@ -31,7 +31,7 @@ class AppleDecoderModule : public PlatformDecoderModule {
bool SupportsMimeType(const nsACString& aMimeType, bool SupportsMimeType(const nsACString& aMimeType,
DecoderDoctorDiagnostics* aDiagnostics) const override; DecoderDoctorDiagnostics* aDiagnostics) const override;
bool Supports(const TrackInfo& aTrackInfo, bool Supports(const SupportDecoderParams& aParams,
DecoderDoctorDiagnostics* aDiagnostics) const override; DecoderDoctorDiagnostics* aDiagnostics) const override;
static void Init(); static void Init();

Просмотреть файл

@ -224,20 +224,21 @@ bool WMFDecoderModule::SupportsMimeType(
if (!trackInfo) { if (!trackInfo) {
return false; return false;
} }
return Supports(*trackInfo, aDiagnostics); return Supports(SupportDecoderParams(*trackInfo), aDiagnostics);
} }
bool WMFDecoderModule::Supports(const TrackInfo& aTrackInfo, bool WMFDecoderModule::Supports(const SupportDecoderParams& aParams,
DecoderDoctorDiagnostics* aDiagnostics) const { DecoderDoctorDiagnostics* aDiagnostics) const {
const auto videoInfo = aTrackInfo.GetAsVideoInfo(); const auto& trackInfo = aParams.mConfig;
const auto* videoInfo = trackInfo.GetAsVideoInfo();
if (videoInfo && !SupportsColorDepth(videoInfo->mColorDepth, aDiagnostics)) { if (videoInfo && !SupportsColorDepth(videoInfo->mColorDepth, aDiagnostics)) {
return false; return false;
} }
if ((aTrackInfo.mMimeType.EqualsLiteral("audio/mp4a-latm") || if ((trackInfo.mMimeType.EqualsLiteral("audio/mp4a-latm") ||
aTrackInfo.mMimeType.EqualsLiteral("audio/mp4")) && trackInfo.mMimeType.EqualsLiteral("audio/mp4")) &&
WMFDecoderModule::HasAAC()) { WMFDecoderModule::HasAAC()) {
const auto audioInfo = aTrackInfo.GetAsAudioInfo(); const auto audioInfo = trackInfo.GetAsAudioInfo();
if (audioInfo && audioInfo->mRate > 0) { if (audioInfo && audioInfo->mRate > 0) {
// Supported sampling rates per: // Supported sampling rates per:
// https://msdn.microsoft.com/en-us/library/windows/desktop/dd742784(v=vs.85).aspx // https://msdn.microsoft.com/en-us/library/windows/desktop/dd742784(v=vs.85).aspx
@ -249,19 +250,19 @@ bool WMFDecoderModule::Supports(const TrackInfo& aTrackInfo,
} }
return true; return true;
} }
if (MP4Decoder::IsH264(aTrackInfo.mMimeType) && WMFDecoderModule::HasH264()) { if (MP4Decoder::IsH264(trackInfo.mMimeType) && WMFDecoderModule::HasH264()) {
return true; return true;
} }
if (aTrackInfo.mMimeType.EqualsLiteral("audio/mpeg") && if (trackInfo.mMimeType.EqualsLiteral("audio/mpeg") &&
!StaticPrefs::media_ffvpx_mp3_enabled() && !StaticPrefs::media_ffvpx_mp3_enabled() &&
CanCreateWMFDecoder<CLSID_CMP3DecMediaObject>()) { CanCreateWMFDecoder<CLSID_CMP3DecMediaObject>()) {
return true; return true;
} }
if (sUsableVPXMFT) { if (sUsableVPXMFT) {
static const uint32_t VP8_USABLE_BUILD = 16287; static const uint32_t VP8_USABLE_BUILD = 16287;
if ((VPXDecoder::IsVP8(aTrackInfo.mMimeType) && if ((VPXDecoder::IsVP8(trackInfo.mMimeType) &&
IsWindowsBuildOrLater(VP8_USABLE_BUILD)) || IsWindowsBuildOrLater(VP8_USABLE_BUILD)) ||
VPXDecoder::IsVP9(aTrackInfo.mMimeType)) { VPXDecoder::IsVP9(trackInfo.mMimeType)) {
return CanCreateWMFDecoder<CLSID_WebmMfVpxDec>(); return CanCreateWMFDecoder<CLSID_WebmMfVpxDec>();
} }
} }

Просмотреть файл

@ -26,7 +26,7 @@ class WMFDecoderModule : public PlatformDecoderModule {
bool SupportsMimeType(const nsACString& aMimeType, bool SupportsMimeType(const nsACString& aMimeType,
DecoderDoctorDiagnostics* aDiagnostics) const override; DecoderDoctorDiagnostics* aDiagnostics) const override;
bool Supports(const TrackInfo& aTrackInfo, bool Supports(const SupportDecoderParams& aParams,
DecoderDoctorDiagnostics* aDiagnostics) const override; DecoderDoctorDiagnostics* aDiagnostics) const override;
// Called on main thread. // Called on main thread.

Просмотреть файл

@ -106,7 +106,8 @@ bool WebMDecoder::IsSupportedType(const MediaContainerType& aContainerType) {
// color depth // color depth
RefPtr<PDMFactory> platform = new PDMFactory(); RefPtr<PDMFactory> platform = new PDMFactory();
for (const auto& track : tracks) { for (const auto& track : tracks) {
if (!track || !platform->Supports(*track, nullptr /* diagnostic */)) { if (!track || !platform->Supports(SupportDecoderParams(*track),
nullptr /* diagnostic */)) {
return false; return false;
} }
} }