Skip to content

Commit 7126633

Browse files
committed
[MSE][GStreamer] Advertise AC4 in systems supporting it
https://bugs.webkit.org/show_bug.cgi?id=310845 Reviewed by NOBODY (OOPS!). This patch enables Dolby AC-4 support in systems that have a GStreamer decoder that supports it. As of writing AC-4 support is still not mature in desktop but it is present in some set top boxes. The changes involve adding support for the MIME type and codec strings in MSE and whitelisting the caps in WebKitThunderDecryptorGStreamer. The codec string is also checked for format correctness and presentation version support. Unfortunately, as of writing the existing GStreamer decoders don't have a established way of querying AC-4 support levels in a fine grained manner. This patch will accept codec strings for presentation version 1. Presentation version 1 is the minimum version supported by bitstream version 2, which is the only bitstream version that is part of the current Dolby AC-4 Kit (1.5) test signals. This combination is also the only one supported in CMAF according to the current version of the AC-4 spec (ETSI TS 103 190-2 V1.3.1, 2025-07). This is understood to be a reasonable baseline for what is commonly supported for a contemporary AC-4 decoder. It is possible however that in the future we need to add support for e.g. environment variables to further customize support level, assuming that by then there is still no way of querying the support level from WebKit. Original author: Andrzej Surdej <Andrzej_Surdej@comcast.com> See: WebPlatformForEmbedded/WPEWebKit#1641 * Source/WebCore/platform/graphics/gstreamer/GStreamerRegistryScanner.cpp: (WebCore::GStreamerRegistryScanner::initializeDecoders): (WebCore::GStreamerRegistryScanner::isCodecSupported const): (WebCore::parseAC4LevelAndProfile): * Source/WebCore/platform/graphics/gstreamer/eme/GStreamerEMEUtilities.h: * Source/WebCore/platform/graphics/gstreamer/eme/WebKitThunderDecryptorGStreamer.cpp: * Source/WebCore/platform/graphics/gstreamer/eme/WebKitThunderParser.cpp:
1 parent b271e70 commit 7126633

4 files changed

Lines changed: 41 additions & 2 deletions

File tree

Source/WebCore/platform/graphics/gstreamer/GStreamerRegistryScanner.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ namespace WebCore {
4949
GST_DEBUG_CATEGORY_STATIC(webkit_media_gst_registry_scanner_debug);
5050
#define GST_CAT_DEFAULT webkit_media_gst_registry_scanner_debug
5151

52+
static bool parseAC4LevelAndProfile(const String& codec);
53+
5254
struct VideoDecodingLimits {
5355
unsigned mediaMaxWidth = 0;
5456
unsigned mediaMaxHeight = 0;
@@ -552,6 +554,7 @@ void GStreamerRegistryScanner::initializeDecoders(const GStreamerRegistryScanner
552554
Vector<GstCapsWebKitMapping> mseCompatibleMapping = {
553555
{ ElementFactories::Type::AudioDecoder, "audio/x-ac3"_s, { }, { "x-ac3"_s, "ac-3"_s, "ac3"_s } },
554556
{ ElementFactories::Type::AudioDecoder, "audio/x-eac3"_s, { "audio/x-ac3"_s }, { "x-eac3"_s, "ec3"_s, "ec-3"_s, "eac3"_s } },
557+
{ ElementFactories::Type::AudioDecoder, "audio/x-ac4"_s, { }, { "x-ac4"_s, "ac-4*"_s, "ac4"_s } },
555558
{ ElementFactories::Type::AudioDecoder, "audio/x-flac"_s, { "audio/x-flac"_s, "audio/flac"_s }, { "x-flac"_s, "flac"_s, "fLaC"_s } },
556559
};
557560
fillMimeTypeSetFromCapsMapping(factories, mseCompatibleMapping);
@@ -800,6 +803,8 @@ GStreamerRegistryScanner::CodecLookupResult GStreamerRegistryScanner::isCodecSup
800803
result = isAVC1CodecSupported(configuration, codecName, shouldCheckForHardwareUse);
801804
else if (codecName.startsWith("hev1"_s) || codecName.startsWith("hvc1"_s))
802805
result = isHEVCCodecSupported(configuration, codecName, shouldCheckForHardwareUse);
806+
else if (codecName.startsWith("ac-4"_s) && !parseAC4LevelAndProfile(codecName))
807+
result = { false, nullptr };
803808
else {
804809
auto& codecMap = configuration == Configuration::Decoding ? m_decoderCodecMap : m_encoderCodecMap;
805810
for (const auto& [codecId, lookupResult] : codecMap) {
@@ -1028,6 +1033,38 @@ ASCIILiteral GStreamerRegistryScanner::configurationNameForLogging(Configuration
10281033
return ""_s;
10291034
}
10301035

1036+
static bool parseAC4LevelAndProfile(const String& codec)
1037+
{
1038+
auto parts = codec.split('.');
1039+
// "ac-4" with no dots is valid (generic, unconstrained).
1040+
if (parts.size() == 1 && equalIgnoringASCIICase(parts[0], "ac-4"_s))
1041+
return true;
1042+
// Full format requires exactly 4 components: ["ac-4", bitstream_version, presentation_version, mdcompat].
1043+
// See ETSI TS 103 190-2 v1.3.1 Appendix E.13.
1044+
if (parts.size() != 4) {
1045+
GST_WARNING("AC-4 codec string has wrong number of components: %s", codec.utf8().data());
1046+
return false;
1047+
}
1048+
1049+
// The current available AC-4 decoders don't have an agreed upon API to query support in a fine-grained manner,
1050+
// so instead we make some conservative assumptions, matching the subset of AC-4 supported in CMAF.
1051+
1052+
// presentation_version must be 1 (stereo/5.1); value 2 denotes IMS which is assumed not supported.
1053+
auto presentationVersion = parseInteger<unsigned>(parts[2]);
1054+
if (!presentationVersion || *presentationVersion != 1) {
1055+
GST_DEBUG("AC-4 codec string has unsupported presentation_version: %s", codec.utf8().data());
1056+
return false;
1057+
}
1058+
// md_compat (level): only levels 0-3 are assumed supported.
1059+
// Levels 4-6 are reserved by the AC-4 spec. Level 7 (unlimited number of tracks) is assumed unsupported.
1060+
auto mdcompat = parseInteger<unsigned>(parts[3]);
1061+
if (!mdcompat || *mdcompat > 3) {
1062+
GST_DEBUG("AC-4 codec string has unsupported mdcompat level: %s", codec.utf8().data());
1063+
return false;
1064+
}
1065+
return true;
1066+
}
1067+
10311068
GStreamerRegistryScanner::RegistryLookupResult GStreamerRegistryScanner::isConfigurationSupported(Configuration configuration, const PlatformMediaConfiguration& mediaConfiguration) const
10321069
{
10331070
#ifndef GST_DISABLE_GST_DEBUG

Source/WebCore/platform/graphics/gstreamer/eme/GStreamerEMEUtilities.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,8 @@ class GStreamerEMEUtilities {
9898
static constexpr auto s_unspecifiedUUID = GST_PROTECTION_UNSPECIFIED_SYSTEM_ID ""_s;
9999
static constexpr auto s_unspecifiedKeySystem = GST_PROTECTION_UNSPECIFIED_SYSTEM_ID ""_s;
100100

101-
static constexpr std::array<ASCIILiteral, 11> s_cencEncryptionMediaTypes = { "video/mp4"_s, "audio/mp4"_s, "video/x-h264"_s, "video/x-h265"_s, "audio/mpeg"_s,
102-
"audio/x-eac3"_s, "audio/x-ac3"_s, "audio/x-flac"_s, "audio/x-opus"_s, "video/x-vp9"_s, "video/x-av1"_s };
101+
static constexpr std::array<ASCIILiteral, 12> s_cencEncryptionMediaTypes = { "video/mp4"_s, "audio/mp4"_s, "video/x-h264"_s, "video/x-h265"_s, "audio/mpeg"_s,
102+
"audio/x-eac3"_s, "audio/x-ac3"_s, "audio/x-ac4"_s, "audio/x-flac"_s, "audio/x-opus"_s, "video/x-vp9"_s, "video/x-av1"_s };
103103
static constexpr std::array<ASCIILiteral, 7> s_webmEncryptionMediaTypes = { "video/webm"_s, "audio/webm"_s, "video/x-vp9"_s, "video/x-av1"_s, "audio/x-opus"_s, "audio/x-vorbis"_s, "video/x-vp8"_s };
104104

105105
static bool isClearKeyKeySystem(const String& keySystem)

Source/WebCore/platform/graphics/gstreamer/eme/WebKitThunderDecryptorGStreamer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ static GstStaticPadTemplate thunderSrcTemplate = GST_STATIC_PAD_TEMPLATE("src",
5656
"audio/x-flac; "
5757
"audio/x-eac3; "
5858
"audio/x-ac3; "
59+
"audio/x-ac4; "
5960
"video/x-h264; "
6061
"video/x-h265; "
6162
"video/x-vp9; video/x-vp8; "

Source/WebCore/platform/graphics/gstreamer/eme/WebKitThunderParser.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ static GstStaticPadTemplate thunderParseSrcTemplate = GST_STATIC_PAD_TEMPLATE("s
6767
"audio/x-flac; "
6868
"audio/x-eac3; "
6969
"audio/x-ac3; "
70+
"audio/x-ac4; "
7071
"video/x-h264; "
7172
"video/x-h265; "
7273
"video/x-vp9; video/x-vp8; "

0 commit comments

Comments
 (0)