mirror of
https://github.com/moonlight-stream/moonlight-qt
synced 2025-01-25 00:55:01 +00:00
Improve AV1 support
This commit is contained in:
parent
a589e8e3de
commit
abc391f32a
7 changed files with 194 additions and 51 deletions
|
@ -137,7 +137,7 @@ NvComputer::NvComputer(NvHTTP& http, QString serverInfo)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Assume H.264 is always supported
|
// Assume H.264 is always supported
|
||||||
this->serverCodecModeSupport = 0x3;
|
this->serverCodecModeSupport = SCM_H264;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString maxLumaPixelsHEVC = NvHTTP::getXmlString(serverInfo, "MaxLumaPixelsHEVC");
|
QString maxLumaPixelsHEVC = NvHTTP::getXmlString(serverInfo, "MaxLumaPixelsHEVC");
|
||||||
|
|
|
@ -1391,7 +1391,6 @@ Flickable {
|
||||||
|
|
||||||
id: codecComboBox
|
id: codecComboBox
|
||||||
textRole: "text"
|
textRole: "text"
|
||||||
enabled: !enableHdr.checked
|
|
||||||
model: ListModel {
|
model: ListModel {
|
||||||
id: codecListModel
|
id: codecListModel
|
||||||
ListElement {
|
ListElement {
|
||||||
|
@ -1406,6 +1405,10 @@ Flickable {
|
||||||
text: qsTr("HEVC (H.265)")
|
text: qsTr("HEVC (H.265)")
|
||||||
val: StreamingPreferences.VCC_FORCE_HEVC
|
val: StreamingPreferences.VCC_FORCE_HEVC
|
||||||
}
|
}
|
||||||
|
ListElement {
|
||||||
|
text: qsTr("AV1 (Experimental)")
|
||||||
|
val: StreamingPreferences.VCC_FORCE_AV1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// ::onActivated must be used, as it only listens for when the index is changed by a human
|
// ::onActivated must be used, as it only listens for when the index is changed by a human
|
||||||
onActivated : {
|
onActivated : {
|
||||||
|
@ -1413,21 +1416,6 @@ Flickable {
|
||||||
StreamingPreferences.videoCodecConfig = codecListModel.get(currentIndex).val
|
StreamingPreferences.videoCodecConfig = codecListModel.get(currentIndex).val
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This handles the state of the enableHdr checkbox changing
|
|
||||||
onEnabledChanged: {
|
|
||||||
if (enabled) {
|
|
||||||
StreamingPreferences.videoCodecConfig = codecListModel.get(currentIndex).val
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
StreamingPreferences.videoCodecConfig = StreamingPreferences.VCC_FORCE_HEVC_HDR
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ToolTip.delay: 1000
|
|
||||||
ToolTip.timeout: 5000
|
|
||||||
ToolTip.visible: hovered && !enabled
|
|
||||||
ToolTip.text: qsTr("Enabling HDR overrides manual codec selections.")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckBox {
|
CheckBox {
|
||||||
|
@ -1435,8 +1423,12 @@ Flickable {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: qsTr("Enable HDR (Experimental)")
|
text: qsTr("Enable HDR (Experimental)")
|
||||||
font.pointSize: 12
|
font.pointSize: 12
|
||||||
|
|
||||||
enabled: SystemProperties.supportsHdr
|
enabled: SystemProperties.supportsHdr
|
||||||
checked: enabled && StreamingPreferences.videoCodecConfig == StreamingPreferences.VCC_FORCE_HEVC_HDR
|
checked: enabled && StreamingPreferences.enableHdr
|
||||||
|
onCheckedChanged: {
|
||||||
|
StreamingPreferences.enableHdr = checked
|
||||||
|
}
|
||||||
|
|
||||||
// Updating StreamingPreferences.videoCodecConfig is handled above
|
// Updating StreamingPreferences.videoCodecConfig is handled above
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#define SER_MULTICONT "multicontroller"
|
#define SER_MULTICONT "multicontroller"
|
||||||
#define SER_AUDIOCFG "audiocfg"
|
#define SER_AUDIOCFG "audiocfg"
|
||||||
#define SER_VIDEOCFG "videocfg"
|
#define SER_VIDEOCFG "videocfg"
|
||||||
|
#define SER_HDR "hdr"
|
||||||
#define SER_VIDEODEC "videodec"
|
#define SER_VIDEODEC "videodec"
|
||||||
#define SER_WINDOWMODE "windowmode"
|
#define SER_WINDOWMODE "windowmode"
|
||||||
#define SER_UNSUPPORTEDFPS "unsupportedfps"
|
#define SER_UNSUPPORTEDFPS "unsupportedfps"
|
||||||
|
@ -104,6 +105,7 @@ void StreamingPreferences::reload()
|
||||||
reverseScrollDirection = settings.value(SER_REVERSESCROLL, false).toBool();
|
reverseScrollDirection = settings.value(SER_REVERSESCROLL, false).toBool();
|
||||||
swapFaceButtons = settings.value(SER_SWAPFACEBUTTONS, false).toBool();
|
swapFaceButtons = settings.value(SER_SWAPFACEBUTTONS, false).toBool();
|
||||||
keepAwake = settings.value(SER_KEEPAWAKE, true).toBool();
|
keepAwake = settings.value(SER_KEEPAWAKE, true).toBool();
|
||||||
|
enableHdr = settings.value(SER_HDR, false).toBool();
|
||||||
captureSysKeysMode = static_cast<CaptureSysKeysMode>(settings.value(SER_CAPTURESYSKEYS,
|
captureSysKeysMode = static_cast<CaptureSysKeysMode>(settings.value(SER_CAPTURESYSKEYS,
|
||||||
static_cast<int>(CaptureSysKeysMode::CSK_OFF)).toInt());
|
static_cast<int>(CaptureSysKeysMode::CSK_OFF)).toInt());
|
||||||
audioConfig = static_cast<AudioConfig>(settings.value(SER_AUDIOCFG,
|
audioConfig = static_cast<AudioConfig>(settings.value(SER_AUDIOCFG,
|
||||||
|
@ -137,6 +139,12 @@ void StreamingPreferences::reload()
|
||||||
windowMode = WindowMode::WM_FULLSCREEN_DESKTOP;
|
windowMode = WindowMode::WM_FULLSCREEN_DESKTOP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fixup VCC value to the new settings format with codec and HDR separate
|
||||||
|
if (videoCodecConfig == VCC_FORCE_HEVC_HDR_DEPRECATED) {
|
||||||
|
videoCodecConfig = VCC_AUTO;
|
||||||
|
enableHdr = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StreamingPreferences::retranslate()
|
bool StreamingPreferences::retranslate()
|
||||||
|
@ -273,6 +281,7 @@ void StreamingPreferences::save()
|
||||||
settings.setValue(SER_PACKETSIZE, packetSize);
|
settings.setValue(SER_PACKETSIZE, packetSize);
|
||||||
settings.setValue(SER_DETECTNETBLOCKING, detectNetworkBlocking);
|
settings.setValue(SER_DETECTNETBLOCKING, detectNetworkBlocking);
|
||||||
settings.setValue(SER_AUDIOCFG, static_cast<int>(audioConfig));
|
settings.setValue(SER_AUDIOCFG, static_cast<int>(audioConfig));
|
||||||
|
settings.setValue(SER_HDR, enableHdr);
|
||||||
settings.setValue(SER_VIDEOCFG, static_cast<int>(videoCodecConfig));
|
settings.setValue(SER_VIDEOCFG, static_cast<int>(videoCodecConfig));
|
||||||
settings.setValue(SER_VIDEODEC, static_cast<int>(videoDecoderSelection));
|
settings.setValue(SER_VIDEODEC, static_cast<int>(videoDecoderSelection));
|
||||||
settings.setValue(SER_WINDOWMODE, static_cast<int>(windowMode));
|
settings.setValue(SER_WINDOWMODE, static_cast<int>(windowMode));
|
||||||
|
|
|
@ -32,7 +32,8 @@ public:
|
||||||
VCC_AUTO,
|
VCC_AUTO,
|
||||||
VCC_FORCE_H264,
|
VCC_FORCE_H264,
|
||||||
VCC_FORCE_HEVC,
|
VCC_FORCE_HEVC,
|
||||||
VCC_FORCE_HEVC_HDR
|
VCC_FORCE_HEVC_HDR_DEPRECATED, // Kept for backwards compatibility
|
||||||
|
VCC_FORCE_AV1
|
||||||
};
|
};
|
||||||
Q_ENUM(VideoCodecConfig)
|
Q_ENUM(VideoCodecConfig)
|
||||||
|
|
||||||
|
@ -118,9 +119,10 @@ public:
|
||||||
Q_PROPERTY(bool connectionWarnings MEMBER connectionWarnings NOTIFY connectionWarningsChanged)
|
Q_PROPERTY(bool connectionWarnings MEMBER connectionWarnings NOTIFY connectionWarningsChanged)
|
||||||
Q_PROPERTY(bool richPresence MEMBER richPresence NOTIFY richPresenceChanged)
|
Q_PROPERTY(bool richPresence MEMBER richPresence NOTIFY richPresenceChanged)
|
||||||
Q_PROPERTY(bool gamepadMouse MEMBER gamepadMouse NOTIFY gamepadMouseChanged)
|
Q_PROPERTY(bool gamepadMouse MEMBER gamepadMouse NOTIFY gamepadMouseChanged)
|
||||||
Q_PROPERTY(bool detectNetworkBlocking MEMBER detectNetworkBlocking NOTIFY detectNetworkBlockingChanged);
|
Q_PROPERTY(bool detectNetworkBlocking MEMBER detectNetworkBlocking NOTIFY detectNetworkBlockingChanged)
|
||||||
Q_PROPERTY(AudioConfig audioConfig MEMBER audioConfig NOTIFY audioConfigChanged)
|
Q_PROPERTY(AudioConfig audioConfig MEMBER audioConfig NOTIFY audioConfigChanged)
|
||||||
Q_PROPERTY(VideoCodecConfig videoCodecConfig MEMBER videoCodecConfig NOTIFY videoCodecConfigChanged)
|
Q_PROPERTY(VideoCodecConfig videoCodecConfig MEMBER videoCodecConfig NOTIFY videoCodecConfigChanged)
|
||||||
|
Q_PROPERTY(bool enableHdr MEMBER enableHdr NOTIFY enableHdrChanged)
|
||||||
Q_PROPERTY(VideoDecoderSelection videoDecoderSelection MEMBER videoDecoderSelection NOTIFY videoDecoderSelectionChanged)
|
Q_PROPERTY(VideoDecoderSelection videoDecoderSelection MEMBER videoDecoderSelection NOTIFY videoDecoderSelectionChanged)
|
||||||
Q_PROPERTY(WindowMode windowMode MEMBER windowMode NOTIFY windowModeChanged)
|
Q_PROPERTY(WindowMode windowMode MEMBER windowMode NOTIFY windowModeChanged)
|
||||||
Q_PROPERTY(WindowMode recommendedFullScreenMode MEMBER recommendedFullScreenMode CONSTANT)
|
Q_PROPERTY(WindowMode recommendedFullScreenMode MEMBER recommendedFullScreenMode CONSTANT)
|
||||||
|
@ -164,6 +166,7 @@ public:
|
||||||
int packetSize;
|
int packetSize;
|
||||||
AudioConfig audioConfig;
|
AudioConfig audioConfig;
|
||||||
VideoCodecConfig videoCodecConfig;
|
VideoCodecConfig videoCodecConfig;
|
||||||
|
bool enableHdr;
|
||||||
VideoDecoderSelection videoDecoderSelection;
|
VideoDecoderSelection videoDecoderSelection;
|
||||||
WindowMode windowMode;
|
WindowMode windowMode;
|
||||||
WindowMode recommendedFullScreenMode;
|
WindowMode recommendedFullScreenMode;
|
||||||
|
@ -185,6 +188,7 @@ signals:
|
||||||
void absoluteTouchModeChanged();
|
void absoluteTouchModeChanged();
|
||||||
void audioConfigChanged();
|
void audioConfigChanged();
|
||||||
void videoCodecConfigChanged();
|
void videoCodecConfigChanged();
|
||||||
|
void enableHdrChanged();
|
||||||
void videoDecoderSelectionChanged();
|
void videoDecoderSelectionChanged();
|
||||||
void uiDisplayModeChanged();
|
void uiDisplayModeChanged();
|
||||||
void windowModeChanged();
|
void windowModeChanged();
|
||||||
|
|
|
@ -373,6 +373,10 @@ void Session::getDecoderInfo(SDL_Window* window,
|
||||||
{
|
{
|
||||||
IVideoDecoder* decoder;
|
IVideoDecoder* decoder;
|
||||||
|
|
||||||
|
// Since AV1 support on the host side is in its infancy, let's not consider
|
||||||
|
// _only_ a working AV1 decoder to be acceptable and still show the warning
|
||||||
|
// dialog indicating lack of hardware decoding support.
|
||||||
|
|
||||||
// Try an HEVC Main10 decoder first to see if we have HDR support
|
// Try an HEVC Main10 decoder first to see if we have HDR support
|
||||||
if (chooseDecoder(StreamingPreferences::VDS_FORCE_HARDWARE,
|
if (chooseDecoder(StreamingPreferences::VDS_FORCE_HARDWARE,
|
||||||
window, VIDEO_FORMAT_H265_MAIN10, 1920, 1080, 60,
|
window, VIDEO_FORMAT_H265_MAIN10, 1920, 1080, 60,
|
||||||
|
@ -386,9 +390,21 @@ void Session::getDecoderInfo(SDL_Window* window,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// HDR can only be supported by a hardware codec that can handle HEVC Main10.
|
// Try an AV1 Main10 decoder next to see if we have HDR support
|
||||||
|
if (chooseDecoder(StreamingPreferences::VDS_FORCE_HARDWARE,
|
||||||
|
window, VIDEO_FORMAT_AV1_MAIN10, 1920, 1080, 60,
|
||||||
|
false, false, true, decoder)) {
|
||||||
|
// If we've got a working AV1 Main 10-bit decoder, we'll enable the HDR checkbox
|
||||||
|
// but we will still continue probing to get other attributes for HEVC or H.264
|
||||||
|
// decoders. See the AV1 comment at the top of the function for more info.
|
||||||
|
isHdrSupported = decoder->isHdrSupported();
|
||||||
|
delete decoder;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// HDR can only be supported by a hardware codec that can handle 10-bit video.
|
||||||
// If we made it this far, we don't have one, so HDR will not be available.
|
// If we made it this far, we don't have one, so HDR will not be available.
|
||||||
isHdrSupported = false;
|
isHdrSupported = false;
|
||||||
|
}
|
||||||
|
|
||||||
// Try a regular hardware accelerated HEVC decoder now
|
// Try a regular hardware accelerated HEVC decoder now
|
||||||
if (chooseDecoder(StreamingPreferences::VDS_FORCE_HARDWARE,
|
if (chooseDecoder(StreamingPreferences::VDS_FORCE_HARDWARE,
|
||||||
|
@ -402,6 +418,20 @@ void Session::getDecoderInfo(SDL_Window* window,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0 // See AV1 comment at the top of this function
|
||||||
|
if (chooseDecoder(StreamingPreferences::VDS_FORCE_HARDWARE,
|
||||||
|
window, VIDEO_FORMAT_AV1_MAIN8, 1920, 1080, 60,
|
||||||
|
false, false, true, decoder)) {
|
||||||
|
isHardwareAccelerated = decoder->isHardwareAccelerated();
|
||||||
|
isFullScreenOnly = decoder->isAlwaysFullScreen();
|
||||||
|
maxResolution = decoder->getDecoderMaxResolution();
|
||||||
|
delete decoder;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// If we still didn't find a hardware decoder, try H.264 now.
|
// If we still didn't find a hardware decoder, try H.264 now.
|
||||||
// This will fall back to software decoding, so it should always work.
|
// This will fall back to software decoding, so it should always work.
|
||||||
if (chooseDecoder(StreamingPreferences::VDS_AUTO,
|
if (chooseDecoder(StreamingPreferences::VDS_AUTO,
|
||||||
|
@ -441,7 +471,13 @@ bool Session::populateDecoderProperties(SDL_Window* window)
|
||||||
IVideoDecoder* decoder;
|
IVideoDecoder* decoder;
|
||||||
|
|
||||||
int videoFormat;
|
int videoFormat;
|
||||||
if (m_StreamConfig.supportedVideoFormats & VIDEO_FORMAT_H265_MAIN10) {
|
if (m_StreamConfig.supportedVideoFormats & VIDEO_FORMAT_AV1_MAIN10) {
|
||||||
|
videoFormat = VIDEO_FORMAT_AV1_MAIN10;
|
||||||
|
}
|
||||||
|
else if (m_StreamConfig.supportedVideoFormats & VIDEO_FORMAT_AV1_MAIN8) {
|
||||||
|
videoFormat = VIDEO_FORMAT_AV1_MAIN8;
|
||||||
|
}
|
||||||
|
else if (m_StreamConfig.supportedVideoFormats & VIDEO_FORMAT_H265_MAIN10) {
|
||||||
videoFormat = VIDEO_FORMAT_H265_MAIN10;
|
videoFormat = VIDEO_FORMAT_H265_MAIN10;
|
||||||
}
|
}
|
||||||
else if (m_StreamConfig.supportedVideoFormats & VIDEO_FORMAT_H265) {
|
else if (m_StreamConfig.supportedVideoFormats & VIDEO_FORMAT_H265) {
|
||||||
|
@ -616,8 +652,36 @@ bool Session::initialize()
|
||||||
switch (m_Preferences->videoCodecConfig)
|
switch (m_Preferences->videoCodecConfig)
|
||||||
{
|
{
|
||||||
case StreamingPreferences::VCC_AUTO:
|
case StreamingPreferences::VCC_AUTO:
|
||||||
|
#if 0
|
||||||
|
// TODO: Determine if AV1 is better depending on the decoder
|
||||||
|
if (m_Preferences->enableHdr && isHardwareDecodeAvailable(testWindow,
|
||||||
|
m_Preferences->videoDecoderSelection,
|
||||||
|
VIDEO_FORMAT_AV1_MAIN10,
|
||||||
|
m_StreamConfig.width,
|
||||||
|
m_StreamConfig.height,
|
||||||
|
m_StreamConfig.fps)) {
|
||||||
|
m_StreamConfig.supportedVideoFormats |= VIDEO_FORMAT_AV1_MAIN8 | VIDEO_FORMAT_AV1_MAIN10;
|
||||||
|
}
|
||||||
|
else if (isHardwareDecodeAvailable(testWindow,
|
||||||
|
m_Preferences->videoDecoderSelection,
|
||||||
|
VIDEO_FORMAT_AV1_MAIN8,
|
||||||
|
m_StreamConfig.width,
|
||||||
|
m_StreamConfig.height,
|
||||||
|
m_StreamConfig.fps)) {
|
||||||
|
m_StreamConfig.supportedVideoFormats |= VIDEO_FORMAT_AV1_MAIN8;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// TODO: Determine if HEVC is better depending on the decoder
|
// TODO: Determine if HEVC is better depending on the decoder
|
||||||
if (isHardwareDecodeAvailable(testWindow,
|
if (m_Preferences->enableHdr && isHardwareDecodeAvailable(testWindow,
|
||||||
|
m_Preferences->videoDecoderSelection,
|
||||||
|
VIDEO_FORMAT_H265_MAIN10,
|
||||||
|
m_StreamConfig.width,
|
||||||
|
m_StreamConfig.height,
|
||||||
|
m_StreamConfig.fps)) {
|
||||||
|
m_StreamConfig.supportedVideoFormats |= VIDEO_FORMAT_H265 | VIDEO_FORMAT_H265_MAIN10;
|
||||||
|
}
|
||||||
|
else if (isHardwareDecodeAvailable(testWindow,
|
||||||
m_Preferences->videoDecoderSelection,
|
m_Preferences->videoDecoderSelection,
|
||||||
VIDEO_FORMAT_H265,
|
VIDEO_FORMAT_H265,
|
||||||
m_StreamConfig.width,
|
m_StreamConfig.width,
|
||||||
|
@ -638,7 +702,7 @@ bool Session::initialize()
|
||||||
(gfeVersion[0] == 3 && gfeVersion[1] < 11)) {
|
(gfeVersion[0] == 3 && gfeVersion[1] < 11)) {
|
||||||
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
"Disabling HEVC on macOS due to old GFE version");
|
"Disabling HEVC on macOS due to old GFE version");
|
||||||
m_StreamConfig.supportedVideoFormats &= ~VIDEO_FORMAT_H265;
|
m_StreamConfig.supportedVideoFormats &= ~VIDEO_FORMAT_MASK_H265;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -646,10 +710,17 @@ bool Session::initialize()
|
||||||
case StreamingPreferences::VCC_FORCE_H264:
|
case StreamingPreferences::VCC_FORCE_H264:
|
||||||
break;
|
break;
|
||||||
case StreamingPreferences::VCC_FORCE_HEVC:
|
case StreamingPreferences::VCC_FORCE_HEVC:
|
||||||
|
case StreamingPreferences::VCC_FORCE_HEVC_HDR_DEPRECATED:
|
||||||
m_StreamConfig.supportedVideoFormats |= VIDEO_FORMAT_H265;
|
m_StreamConfig.supportedVideoFormats |= VIDEO_FORMAT_H265;
|
||||||
|
if (m_Preferences->enableHdr) {
|
||||||
|
m_StreamConfig.supportedVideoFormats |= VIDEO_FORMAT_H265_MAIN10;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case StreamingPreferences::VCC_FORCE_HEVC_HDR:
|
case StreamingPreferences::VCC_FORCE_AV1:
|
||||||
m_StreamConfig.supportedVideoFormats |= VIDEO_FORMAT_H265 | VIDEO_FORMAT_H265_MAIN10;
|
m_StreamConfig.supportedVideoFormats |= VIDEO_FORMAT_AV1_MAIN8;
|
||||||
|
if (m_Preferences->enableHdr) {
|
||||||
|
m_StreamConfig.supportedVideoFormats |= VIDEO_FORMAT_AV1_MAIN10;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -731,7 +802,7 @@ bool Session::validateLaunch(SDL_Window* testWindow)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_Preferences->videoDecoderSelection == StreamingPreferences::VDS_FORCE_SOFTWARE) {
|
if (m_Preferences->videoDecoderSelection == StreamingPreferences::VDS_FORCE_SOFTWARE) {
|
||||||
if (m_Preferences->videoCodecConfig == StreamingPreferences::VCC_FORCE_HEVC_HDR) {
|
if (m_Preferences->enableHdr) {
|
||||||
emitLaunchWarning(tr("HDR is not supported with software decoding."));
|
emitLaunchWarning(tr("HDR is not supported with software decoding."));
|
||||||
m_StreamConfig.supportedVideoFormats &= ~VIDEO_FORMAT_MASK_10BIT;
|
m_StreamConfig.supportedVideoFormats &= ~VIDEO_FORMAT_MASK_10BIT;
|
||||||
}
|
}
|
||||||
|
@ -749,9 +820,7 @@ bool Session::validateLaunch(SDL_Window* testWindow)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_StreamConfig.supportedVideoFormats & VIDEO_FORMAT_MASK_H265) {
|
if (m_StreamConfig.supportedVideoFormats & VIDEO_FORMAT_MASK_H265) {
|
||||||
bool hevcForced = m_Preferences->videoCodecConfig == StreamingPreferences::VCC_FORCE_HEVC ||
|
bool hevcForced = m_Preferences->videoCodecConfig == StreamingPreferences::VCC_FORCE_HEVC;
|
||||||
m_Preferences->videoCodecConfig == StreamingPreferences::VCC_FORCE_HEVC_HDR;
|
|
||||||
|
|
||||||
if (m_Computer->maxLumaPixelsHEVC == 0) {
|
if (m_Computer->maxLumaPixelsHEVC == 0) {
|
||||||
if (hevcForced) {
|
if (hevcForced) {
|
||||||
emitLaunchWarning(tr("Your host PC doesn't support encoding HEVC."));
|
emitLaunchWarning(tr("Your host PC doesn't support encoding HEVC."));
|
||||||
|
@ -774,6 +843,30 @@ bool Session::validateLaunch(SDL_Window* testWindow)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_StreamConfig.supportedVideoFormats & VIDEO_FORMAT_MASK_AV1) {
|
||||||
|
bool av1Forced = m_Preferences->videoCodecConfig == StreamingPreferences::VCC_FORCE_AV1;
|
||||||
|
if (!(m_Computer->serverCodecModeSupport & SCM_MASK_AV1)) {
|
||||||
|
if (av1Forced) {
|
||||||
|
emitLaunchWarning(tr("Your host software or GPU doesn't support encoding AV1."));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Moonlight-common-c will handle this case already, but we want
|
||||||
|
// to set this explicitly here so we can do our hardware acceleration
|
||||||
|
// check below.
|
||||||
|
m_StreamConfig.supportedVideoFormats &= ~VIDEO_FORMAT_MASK_AV1;
|
||||||
|
}
|
||||||
|
else if (m_Preferences->videoDecoderSelection == StreamingPreferences::VDS_AUTO && // Force hardware decoding checked below
|
||||||
|
av1Forced && // Auto VCC is already checked in initialize()
|
||||||
|
!isHardwareDecodeAvailable(testWindow,
|
||||||
|
m_Preferences->videoDecoderSelection,
|
||||||
|
VIDEO_FORMAT_AV1_MAIN8,
|
||||||
|
m_StreamConfig.width,
|
||||||
|
m_StreamConfig.height,
|
||||||
|
m_StreamConfig.fps)) {
|
||||||
|
emitLaunchWarning(tr("Using software decoding due to your selection to force AV1 without GPU support. This may cause poor streaming performance."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!(m_StreamConfig.supportedVideoFormats & VIDEO_FORMAT_MASK_H265) &&
|
if (!(m_StreamConfig.supportedVideoFormats & VIDEO_FORMAT_MASK_H265) &&
|
||||||
m_Preferences->videoDecoderSelection == StreamingPreferences::VDS_AUTO &&
|
m_Preferences->videoDecoderSelection == StreamingPreferences::VDS_AUTO &&
|
||||||
!isHardwareDecodeAvailable(testWindow,
|
!isHardwareDecodeAvailable(testWindow,
|
||||||
|
@ -802,23 +895,51 @@ bool Session::validateLaunch(SDL_Window* testWindow)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_StreamConfig.supportedVideoFormats & VIDEO_FORMAT_MASK_10BIT) {
|
if (m_Preferences->enableHdr) {
|
||||||
// Check that the server GPU supports HDR
|
// Check that the server GPU supports HDR
|
||||||
if (!(m_Computer->serverCodecModeSupport & 0x2200)) {
|
if (!(m_Computer->serverCodecModeSupport & SCM_MASK_10BIT)) {
|
||||||
emitLaunchWarning(tr("Your host PC doesn't support HDR streaming."));
|
emitLaunchWarning(tr("Your host PC doesn't support HDR streaming."));
|
||||||
m_StreamConfig.supportedVideoFormats &= ~VIDEO_FORMAT_MASK_10BIT;
|
m_StreamConfig.supportedVideoFormats &= ~VIDEO_FORMAT_MASK_10BIT;
|
||||||
}
|
}
|
||||||
else if (!isHardwareDecodeAvailable(testWindow,
|
else if (m_Preferences->videoCodecConfig == StreamingPreferences::VCC_FORCE_H264) {
|
||||||
|
emitLaunchWarning(tr("HDR is not supported using the H.264 codec."));
|
||||||
|
m_StreamConfig.supportedVideoFormats &= ~VIDEO_FORMAT_MASK_10BIT;
|
||||||
|
}
|
||||||
|
else if (m_Preferences->videoCodecConfig != StreamingPreferences::VCC_AUTO) { // Auto was already checked during init
|
||||||
|
// Check that the available HDR-capable codecs on the client and server are compatible
|
||||||
|
if ((m_Computer->serverCodecModeSupport & SCM_AV1_MAIN10) && (m_StreamConfig.supportedVideoFormats & VIDEO_FORMAT_AV1_MAIN10)) {
|
||||||
|
if (!isHardwareDecodeAvailable(testWindow,
|
||||||
|
m_Preferences->videoDecoderSelection,
|
||||||
|
VIDEO_FORMAT_AV1_MAIN10,
|
||||||
|
m_StreamConfig.width,
|
||||||
|
m_StreamConfig.height,
|
||||||
|
m_StreamConfig.fps)) {
|
||||||
|
emitLaunchWarning(tr("This PC's GPU doesn't support AV1 Main10 decoding for HDR streaming."));
|
||||||
|
m_StreamConfig.supportedVideoFormats &= ~VIDEO_FORMAT_AV1_MAIN10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((m_Computer->serverCodecModeSupport & SCM_HEVC_MAIN10) && (m_StreamConfig.supportedVideoFormats & VIDEO_FORMAT_H265_MAIN10)) {
|
||||||
|
if (!isHardwareDecodeAvailable(testWindow,
|
||||||
m_Preferences->videoDecoderSelection,
|
m_Preferences->videoDecoderSelection,
|
||||||
VIDEO_FORMAT_H265_MAIN10,
|
VIDEO_FORMAT_H265_MAIN10,
|
||||||
m_StreamConfig.width,
|
m_StreamConfig.width,
|
||||||
m_StreamConfig.height,
|
m_StreamConfig.height,
|
||||||
m_StreamConfig.fps)) {
|
m_StreamConfig.fps)) {
|
||||||
emitLaunchWarning(tr("This PC's GPU doesn't support HEVC Main10 decoding for HDR streaming."));
|
emitLaunchWarning(tr("This PC's GPU doesn't support HEVC Main10 decoding for HDR streaming."));
|
||||||
m_StreamConfig.supportedVideoFormats &= ~VIDEO_FORMAT_MASK_10BIT;
|
m_StreamConfig.supportedVideoFormats &= ~VIDEO_FORMAT_H265_MAIN10;
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
// TODO: Also validate display capabilities
|
}
|
||||||
|
else if (!(m_StreamConfig.supportedVideoFormats & VIDEO_FORMAT_MASK_10BIT)) {
|
||||||
|
emitLaunchWarning(tr("This PC's GPU doesn't support 10-bit HEVC or AV1 decoding for HDR streaming."));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for compatibility between server and client codecs
|
||||||
|
if ((m_StreamConfig.supportedVideoFormats & VIDEO_FORMAT_MASK_10BIT) && // Ignore this check if we already failed one above
|
||||||
|
!(((m_StreamConfig.supportedVideoFormats & VIDEO_FORMAT_H265_MAIN10) && (m_Computer->serverCodecModeSupport & SCM_HEVC_MAIN10)) ||
|
||||||
|
((m_StreamConfig.supportedVideoFormats & VIDEO_FORMAT_AV1_MAIN10) && (m_Computer->serverCodecModeSupport & SCM_AV1_MAIN10)))) {
|
||||||
|
emitLaunchWarning(tr("Your host PC and client PC don't support the same HDR video codecs."));
|
||||||
|
m_StreamConfig.supportedVideoFormats &= ~VIDEO_FORMAT_MASK_10BIT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -864,7 +985,7 @@ bool Session::validateLaunch(SDL_Window* testWindow)
|
||||||
if ((m_StreamConfig.width > 4096 || m_StreamConfig.height > 4096) && m_Computer->isNvidiaServerSoftware) {
|
if ((m_StreamConfig.width > 4096 || m_StreamConfig.height > 4096) && m_Computer->isNvidiaServerSoftware) {
|
||||||
// Pascal added support for 8K HEVC encoding support. Maxwell 2 could encode HEVC but only up to 4K.
|
// Pascal added support for 8K HEVC encoding support. Maxwell 2 could encode HEVC but only up to 4K.
|
||||||
// We can't directly identify Pascal, but we can look for HEVC Main10 which was added in the same generation.
|
// We can't directly identify Pascal, but we can look for HEVC Main10 which was added in the same generation.
|
||||||
if (m_Computer->maxLumaPixelsHEVC == 0 || !(m_Computer->serverCodecModeSupport & 0x200)) {
|
if (m_Computer->maxLumaPixelsHEVC == 0 || !(m_Computer->serverCodecModeSupport & SCM_HEVC_MAIN10)) {
|
||||||
emit displayLaunchError(tr("Your host PC's GPU doesn't support streaming video resolutions over 4K."));
|
emit displayLaunchError(tr("Your host PC's GPU doesn't support streaming video resolutions over 4K."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -878,7 +999,8 @@ bool Session::validateLaunch(SDL_Window* testWindow)
|
||||||
!(m_StreamConfig.supportedVideoFormats & VIDEO_FORMAT_MASK_10BIT) && // HDR was already checked for hardware decode support above
|
!(m_StreamConfig.supportedVideoFormats & VIDEO_FORMAT_MASK_10BIT) && // HDR was already checked for hardware decode support above
|
||||||
!isHardwareDecodeAvailable(testWindow,
|
!isHardwareDecodeAvailable(testWindow,
|
||||||
m_Preferences->videoDecoderSelection,
|
m_Preferences->videoDecoderSelection,
|
||||||
(m_StreamConfig.supportedVideoFormats & VIDEO_FORMAT_MASK_H265) ? VIDEO_FORMAT_H265 : VIDEO_FORMAT_H264,
|
(m_StreamConfig.supportedVideoFormats & VIDEO_FORMAT_MASK_AV1) ? VIDEO_FORMAT_AV1_MAIN8 :
|
||||||
|
((m_StreamConfig.supportedVideoFormats & VIDEO_FORMAT_MASK_H265) ? VIDEO_FORMAT_H265 : VIDEO_FORMAT_H264),
|
||||||
m_StreamConfig.width,
|
m_StreamConfig.width,
|
||||||
m_StreamConfig.height,
|
m_StreamConfig.height,
|
||||||
m_StreamConfig.fps)) {
|
m_StreamConfig.fps)) {
|
||||||
|
|
|
@ -417,6 +417,22 @@ public:
|
||||||
[device release];
|
[device release];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (params->videoFormat & VIDEO_FORMAT_MASK_AV1) {
|
||||||
|
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 130000
|
||||||
|
if (!VTIsHardwareDecodeSupported(kCMVideoCodecType_AV1)) {
|
||||||
|
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"No HW accelerated AV1 decode via VT");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 10-bit is part of the Main profile for AV1, so it will always
|
||||||
|
// be present on hardware that supports 8-bit.
|
||||||
|
#else
|
||||||
|
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"AV1 requires building with Xcode 14 or later");
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
SDL_SysWMinfo info;
|
SDL_SysWMinfo info;
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit a3b28eb4d7433d4f492df117a75a5edd8855eb80
|
Subproject commit 27428e655ba7f7b2367c512cbc72c40e04e5e751
|
Loading…
Reference in a new issue