Skip to content

Commit

Permalink
[GStreamer][MSE][CMake] make configurable video decoder limits
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=245660

Reviewed by Xabier Rodriguez-Calvar.

* Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp:
(videoDecoderLimitsDefaults):
(WebCore::MediaPlayerPrivateGStreamerMSE::MediaPlayerPrivateGStreamerMSE):
(WebCore::MediaPlayerPrivateGStreamerMSE::supportsType):
* Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.h:
* Source/cmake/OptionsGTK.cmake:
* Source/cmake/OptionsWPE.cmake:

Canonical link: https://commits.webkit.org/255380@main
  • Loading branch information
pgorszkowski-igalia authored and calvaris committed Oct 11, 2022
1 parent fb53134 commit 8e1c25c
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 18 deletions.
5 changes: 5 additions & 0 deletions Source/WebCore/platform/GStreamer.cmake
Expand Up @@ -139,6 +139,11 @@ if (ENABLE_VIDEO OR ENABLE_WEB_AUDIO)

# Avoiding a GLib deprecation warning due to GStreamer API using deprecated classes.
set_source_files_properties(platform/audio/gstreamer/WebKitWebAudioSourceGStreamer.cpp PROPERTIES COMPILE_DEFINITIONS "GLIB_DISABLE_DEPRECATION_WARNINGS=1")

if (VIDEO_DECODING_LIMIT)
# Specify video decoding limits.
set_source_files_properties(platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp PROPERTIES COMPILE_DEFINITIONS VIDEO_DECODING_LIMIT="${VIDEO_DECODING_LIMIT}")
endif ()
endif ()

if (USE_GSTREAMER_TRANSCODER)
Expand Down
Expand Up @@ -56,20 +56,72 @@
#include <wtf/text/AtomStringHash.h>
#include <wtf/text/StringToIntegerConversion.h>

namespace {
struct VideoDecodingLimits {
unsigned mediaMaxWidth = 0;
unsigned mediaMaxHeight = 0;
unsigned mediaMaxFrameRate = 0;
VideoDecodingLimits(unsigned mediaMaxWidth, unsigned mediaMaxHeight, unsigned mediaMaxFrameRate)
: mediaMaxWidth(mediaMaxWidth)
, mediaMaxHeight(mediaMaxHeight)
, mediaMaxFrameRate(mediaMaxFrameRate)
{
}
};
}

#ifdef VIDEO_DECODING_LIMIT
static std::optional<VideoDecodingLimits> videoDecoderLimitsDefaults()
{
// VIDEO_DECODING_LIMIT should be in format: WIDTHxHEIGHT@FRAMERATE.
String videoDecodingLimit(String::fromUTF8(VIDEO_DECODING_LIMIT));

if (videoDecodingLimit.isEmpty())
return { };

Vector<String> entries;

// Extract frame rate part from the VIDEO_DECODING_LIMIT: WIDTHxHEIGHT@FRAMERATE.
videoDecodingLimit.split('@', [&entries](StringView item) {
entries.append(item.toString());
});

if (entries.size() != 2)
return { };

auto frameRate = parseIntegerAllowingTrailingJunk<unsigned>(entries[1]);

if (!frameRate.has_value())
return { };

String widthAndHeight = entries[0];
entries.clear();

// Extract WIDTH and HEIGHT from: WIDTHxHEIGHT.
widthAndHeight.split('x', [&entries](StringView item) {
entries.append(item.toString());
});

if (entries.size() != 2)
return { };

auto width = parseIntegerAllowingTrailingJunk<unsigned>(entries[0]);

if (!width.has_value())
return { };

auto height = parseIntegerAllowingTrailingJunk<unsigned>(entries[1]);

if (!height.has_value())
return { };

return { VideoDecodingLimits(width.value(), height.value(), frameRate.value()) };
}
#endif

// We shouldn't accept media that the player can't actually play.
// AAC supports up to 96 channels.
#define MEDIA_MAX_AAC_CHANNELS 96
#if USE(FULLHD_VIDEO_DECODING_LIMIT)
// Raspberry Pi only supports up to 1080p@30fps hardware video decoding.
#define MEDIA_MAX_WIDTH 1920.0f
#define MEDIA_MAX_HEIGHT 1080.0f
#define MEDIA_MAX_FRAMERATE 30.0f
#else
// Assume hardware video decoding acceleration up to 8K@60fps for the rest of the cases.
#define MEDIA_MAX_WIDTH 7680.0f
#define MEDIA_MAX_HEIGHT 4320.0f
#define MEDIA_MAX_FRAMERATE 60.0f
#endif

static const char* dumpReadyState(WebCore::MediaPlayer::ReadyState readyState)
{
Expand Down Expand Up @@ -376,6 +428,18 @@ void MediaPlayerPrivateGStreamerMSE::getSupportedTypes(HashSet<String, ASCIICase

MediaPlayer::SupportsType MediaPlayerPrivateGStreamerMSE::supportsType(const MediaEngineSupportParameters& parameters)
{
static std::optional<VideoDecodingLimits> videoDecodingLimits;
#ifdef VIDEO_DECODING_LIMIT
static std::once_flag onceFlag;
std::call_once(onceFlag, [] {
videoDecodingLimits = videoDecoderLimitsDefaults();
if (!videoDecodingLimits) {
GST_WARNING("Parsing VIDEO_DECODING_LIMIT failed");
ASSERT_NOT_REACHED();
}
});
#endif

MediaPlayer::SupportsType result = MediaPlayer::SupportsType::IsNotSupported;
if (!parameters.isMediaSource)
return result;
Expand All @@ -401,11 +465,12 @@ MediaPlayer::SupportsType MediaPlayerPrivateGStreamerMSE::supportsType(const Med
if (!ok)
height = 0;

if (width > MEDIA_MAX_WIDTH || height > MEDIA_MAX_HEIGHT)
if (videoDecodingLimits && (width > videoDecodingLimits->mediaMaxWidth || height > videoDecodingLimits->mediaMaxHeight))
return result;

float framerate = parameters.type.parameter("framerate"_s).toFloat(&ok);
if (ok && framerate > MEDIA_MAX_FRAMERATE)
float frameRate = parameters.type.parameter("framerate"_s).toFloat(&ok);
// Limit frameRate only in case of highest supported resolution.
if (ok && videoDecodingLimits && width == videoDecodingLimits->mediaMaxWidth && height == videoDecodingLimits->mediaMaxHeight && frameRate > videoDecodingLimits->mediaMaxFrameRate)
return result;

GST_DEBUG("Checking mime-type \"%s\"", parameters.type.raw().utf8().data());
Expand Down
2 changes: 0 additions & 2 deletions Source/cmake/OptionsGTK.cmake
Expand Up @@ -261,8 +261,6 @@ SET_AND_EXPOSE_TO_BUILD(WTF_PLATFORM_QUARTZ ${ENABLE_QUARTZ_TARGET})
SET_AND_EXPOSE_TO_BUILD(WTF_PLATFORM_X11 ${ENABLE_X11_TARGET})
SET_AND_EXPOSE_TO_BUILD(WTF_PLATFORM_WAYLAND ${ENABLE_WAYLAND_TARGET})

SET_AND_EXPOSE_TO_BUILD(USE_FULLHD_VIDEO_DECODING_LIMIT ${ENABLE_FULLHD_VIDEO_DECODING_LIMIT})

SET_AND_EXPOSE_TO_BUILD(ENABLE_PLUGIN_PROCESS FALSE)

add_definitions(-DBUILDING_GTK__=1)
Expand Down
2 changes: 0 additions & 2 deletions Source/cmake/OptionsWPE.cmake
Expand Up @@ -353,8 +353,6 @@ SET_AND_EXPOSE_TO_BUILD(USE_NICOSIA TRUE)
SET_AND_EXPOSE_TO_BUILD(USE_ANGLE ${ENABLE_WEBGL})
SET_AND_EXPOSE_TO_BUILD(HAVE_OS_DARK_MODE_SUPPORT 1)

SET_AND_EXPOSE_TO_BUILD(USE_FULLHD_VIDEO_DECODING_LIMIT ${ENABLE_FULLHD_VIDEO_DECODING_LIMIT})

# GUri is available in GLib since version 2.66, but we only want to use it if version is >= 2.67.1.
if (PC_GLIB_VERSION VERSION_GREATER "2.67.1" OR PC_GLIB_VERSION STREQUAL "2.67.1")
SET_AND_EXPOSE_TO_BUILD(HAVE_GURI 1)
Expand Down

0 comments on commit 8e1c25c

Please sign in to comment.