Skip to content

Commit

Permalink
Bug 1928484 - add origin check to determine the HEVC support for CanP…
Browse files Browse the repository at this point in the history
…layType() and IsTypeSupported(). r=jrmuizel,aosmond, a=dmeehan

When the pref 'media.wmf.hevc.enabled' is not equal to `1`, the HEVC is
only enabled through the media engine, which is used for EME playback
only.

Therefore, a quick workaround to prevent websites from using HEVC on
non-EME playback is to block HEVC on HTMLMediaElement::CanPlayType() and
MediaSource::IsTypeSupported().

This workaround should be removed after enaling HEVC for all playback in
the bug 1928536.

Differential Revision: https://phabricator.services.mozilla.com/D227572
  • Loading branch information
alastor0325 committed Nov 1, 2024
1 parent f78c915 commit 41bfc1c
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 4 deletions.
24 changes: 23 additions & 1 deletion dom/html/HTMLMediaElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,11 @@
#endif
#include "xpcpublic.h"

// TODO : remove this workaround after enabling HEVC by default in bug 1928536.
#ifdef MOZ_WMF
# include "mozilla/EMEUtils.h"
#endif

mozilla::LazyLogModule gMediaElementLog("HTMLMediaElement");
mozilla::LazyLogModule gMediaElementEventsLog("HTMLMediaElementEvents");

Expand Down Expand Up @@ -5020,7 +5025,24 @@ CanPlayStatus HTMLMediaElement::GetCanPlay(

void HTMLMediaElement::CanPlayType(const nsAString& aType, nsAString& aResult) {
DecoderDoctorDiagnostics diagnostics;
CanPlayStatus canPlay = GetCanPlay(aType, &diagnostics);
CanPlayStatus canPlay;
#ifdef MOZ_WMF
// TODO : remove this workaround after enabling HEVC by default in bug
// 1928536.
bool isHEVC = false;
Maybe<MediaContainerType> containerType = MakeMediaContainerType(aType);
if (containerType) {
const auto& codecString = containerType->ExtendedType().Codecs().AsString();
isHEVC = StringBeginsWith(codecString, u"hev1"_ns) ||
StringBeginsWith(codecString, u"hvc1"_ns);
}
if (isHEVC && !IsHEVCAllowedByOrigin(GetOrigin(OwnerDoc()))) {
canPlay = CANPLAY_NO;
} else
#endif
{
canPlay = GetCanPlay(aType, &diagnostics);
}
diagnostics.StoreFormatDiagnostics(OwnerDoc(), aType, canPlay != CANPLAY_NO,
__func__);
switch (canPlay) {
Expand Down
25 changes: 25 additions & 0 deletions dom/media/eme/EMEUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,4 +277,29 @@ Maybe<nsCString> GetOrigin(const dom::Document* aDocument) {
return Some(origin);
}

#ifdef MOZ_WMF
bool IsHEVCAllowedByOrigin(const Maybe<nsCString>& aOrigin) {
if (StaticPrefs::media_wmf_hevc_enabled() == 1) {
return true;
}
if (!aOrigin) {
return false;
}
// This should be the same as the list in IsMFCDMAllowedByOrigin.
static nsTArray<nsCString> kAllowedOrigins({
"https://www.netflix.com"_ns,
});
for (const auto& allowedOrigin : kAllowedOrigins) {
if (FindInReadable(allowedOrigin, *aOrigin)) {
EME_LOG("IsHEVCAllowedByOrigin, origin (%s) is ALLOWED to use HEVC",
aOrigin->get());
return true;
}
}
EME_LOG("IsHEVCAllowedByOrigin, origin (%s) is NOT ALLOWED to use HEVC",
aOrigin->get());
return false;
}
#endif

} // namespace mozilla
5 changes: 5 additions & 0 deletions dom/media/eme/EMEUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ void DeprecationWarningLog(const dom::Document* aDocument,

Maybe<nsCString> GetOrigin(const dom::Document* aDocument);

#ifdef MOZ_WMF
// TODO : remove this workaround after enabling HEVC by default in bug 1928536.
bool IsHEVCAllowedByOrigin(const Maybe<nsCString>& aOrigin);
#endif

} // namespace mozilla

#endif // EME_LOG_H_
22 changes: 20 additions & 2 deletions dom/media/mediasource/MediaSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@
# include "mozilla/java/HardwareCodecCapabilityUtilsWrappers.h"
#endif

// TODO : remove this workaround after enabling HEVC by default in bug 1928536.
#ifdef MOZ_WMF
# include "mozilla/EMEUtils.h"
#endif

struct JSContext;
class JSObject;

Expand Down Expand Up @@ -133,7 +138,8 @@ static void RecordTypeForTelemetry(const nsAString& aType,
void MediaSource::IsTypeSupported(const nsAString& aType,
DecoderDoctorDiagnostics* aDiagnostics,
ErrorResult& aRv,
Maybe<bool> aShouldResistFingerprinting) {
Maybe<bool> aShouldResistFingerprinting,
Maybe<nsCString> aOrigin) {
if (aType.IsEmpty()) {
return aRv.ThrowTypeError("Empty type");
}
Expand All @@ -157,6 +163,17 @@ void MediaSource::IsTypeSupported(const nsAString& aType,
}
}

#ifdef MOZ_WMF
// TODO : remove this workaround after enabling HEVC by default in bug
// 1928536.
const auto& codecString = containerType->ExtendedType().Codecs().AsString();
const bool isHEVC = StringBeginsWith(codecString, u"hev1"_ns) ||
StringBeginsWith(codecString, u"hvc1"_ns);
if (isHEVC && !IsHEVCAllowedByOrigin(aOrigin)) {
return aRv.ThrowNotSupportedError("Can't play type");
}
#endif

// Now we know that this media type could be played.
// MediaSource imposes extra restrictions, and some prefs.
// Avoid leaking information about the fact that it's pref-disabled,
Expand Down Expand Up @@ -452,7 +469,8 @@ bool MediaSource::IsTypeSupported(const GlobalObject& aOwner,
IsTypeSupported(
aType, &diagnostics, rv,
doc ? Some(doc->ShouldResistFingerprinting(RFPTarget::MediaCapabilities))
: Nothing());
: Nothing(),
doc ? GetOrigin(doc) : Nothing());
bool supported = !rv.Failed();
RecordTypeForTelemetry(aType, window);
diagnostics.StoreFormatDiagnostics(doc, aType, supported, __func__);
Expand Down
5 changes: 4 additions & 1 deletion dom/media/mediasource/MediaSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,13 @@ class MediaSource final : public DOMEventTargetHelper,

static bool IsTypeSupported(const GlobalObject&, const nsAString& aType);
// Throws on aRv if not supported.
// TODO : origin check should be removed after enabling HEVC by default in bug
// 1928536.
static void IsTypeSupported(const nsAString& aType,
DecoderDoctorDiagnostics* aDiagnostics,
ErrorResult& aRv,
Maybe<bool> aShouldResistFingerprinting);
Maybe<bool> aShouldResistFingerprinting,
Maybe<nsCString> aOrigin = Nothing());

IMPL_EVENT_HANDLER(sourceopen);
IMPL_EVENT_HANDLER(sourceended);
Expand Down

0 comments on commit 41bfc1c

Please sign in to comment.