mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2026-02-16 02:30:52 +00:00
Avoid D3D9 fallback on lack of codec support unless a D3D11 FL11.0 GPU wasn't found
We'd rather not waste time (and risk crashes) loading the D3D9 driver if the GPU doesn't have the physical decoding hardware at all.
This commit is contained in:
@@ -888,6 +888,7 @@ bool FFmpegVideoDecoder::tryInitializeRenderer(const AVCodec* decoder,
|
||||
enum AVPixelFormat requiredFormat,
|
||||
PDECODER_PARAMETERS params,
|
||||
const AVCodecHWConfig* hwConfig,
|
||||
IFFmpegRenderer::InitFailureReason* failureReason, // Out - Optional
|
||||
std::function<IFFmpegRenderer*()> createRendererFunc)
|
||||
{
|
||||
DECODER_PARAMETERS testFrameDecoderParams = *params;
|
||||
@@ -905,6 +906,10 @@ bool FFmpegVideoDecoder::tryInitializeRenderer(const AVCodec* decoder,
|
||||
|
||||
m_HwDecodeCfg = hwConfig;
|
||||
|
||||
if (failureReason != nullptr) {
|
||||
*failureReason = IFFmpegRenderer::InitFailureReason::Unknown;
|
||||
}
|
||||
|
||||
// i == 0 - Indirect via EGL or DRM frontend with zero-copy DMA-BUF passing
|
||||
// i == 1 - Direct rendering or indirect via SDL read-back
|
||||
#ifdef HAVE_EGL
|
||||
@@ -936,6 +941,11 @@ bool FFmpegVideoDecoder::tryInitializeRenderer(const AVCodec* decoder,
|
||||
else {
|
||||
SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Decoder failed to initialize after successful test");
|
||||
|
||||
if (m_BackendRenderer != nullptr && failureReason != nullptr) {
|
||||
*failureReason = m_BackendRenderer->getInitFailureReason();
|
||||
}
|
||||
|
||||
reset();
|
||||
}
|
||||
}
|
||||
@@ -945,6 +955,10 @@ bool FFmpegVideoDecoder::tryInitializeRenderer(const AVCodec* decoder,
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (m_BackendRenderer != nullptr && failureReason != nullptr) {
|
||||
*failureReason = m_BackendRenderer->getInitFailureReason();
|
||||
}
|
||||
|
||||
// Failed to initialize, so keep looking
|
||||
reset();
|
||||
}
|
||||
@@ -962,7 +976,7 @@ bool FFmpegVideoDecoder::tryInitializeRenderer(const AVCodec* decoder,
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, \
|
||||
"Trying " #RENDERER_TYPE " for codec %s due to preferred pixel format: 0x%x", \
|
||||
decoder->name, decoder->pix_fmts[i]); \
|
||||
if (tryInitializeRenderer(decoder, decoder->pix_fmts[i], params, nullptr, \
|
||||
if (tryInitializeRenderer(decoder, decoder->pix_fmts[i], params, nullptr, nullptr, \
|
||||
[]() -> IFFmpegRenderer* { return new RENDERER_TYPE(); })) { \
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, \
|
||||
"Chose " #RENDERER_TYPE " for codec %s due to preferred pixel format: 0x%x", \
|
||||
@@ -980,7 +994,7 @@ bool FFmpegVideoDecoder::tryInitializeRenderer(const AVCodec* decoder,
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, \
|
||||
"Trying " #RENDERER_TYPE " for codec %s due to compatible pixel format: 0x%x", \
|
||||
decoder->name, decoder->pix_fmts[i]); \
|
||||
if (tryInitializeRenderer(decoder, decoder->pix_fmts[i], params, nullptr, \
|
||||
if (tryInitializeRenderer(decoder, decoder->pix_fmts[i], params, nullptr, nullptr, \
|
||||
[]() -> IFFmpegRenderer* { return new RENDERER_TYPE(); })) { \
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, \
|
||||
"Chose " #RENDERER_TYPE " for codec %s due to compatible pixel format: 0x%x", \
|
||||
@@ -1008,10 +1022,16 @@ bool FFmpegVideoDecoder::tryInitializeRendererForUnknownDecoder(const AVCodec* d
|
||||
}
|
||||
|
||||
// Initialize the hardware codec and submit a test frame if the renderer needs it
|
||||
if (tryInitializeRenderer(decoder, AV_PIX_FMT_NONE, params, config,
|
||||
IFFmpegRenderer::InitFailureReason failureReason;
|
||||
if (tryInitializeRenderer(decoder, AV_PIX_FMT_NONE, params, config, &failureReason,
|
||||
[config]() -> IFFmpegRenderer* { return createHwAccelRenderer(config, 0); })) {
|
||||
return true;
|
||||
}
|
||||
else if (failureReason == IFFmpegRenderer::InitFailureReason::NoHardwareSupport) {
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Skipping remaining hwaccels due lack of hardware support for specified codec");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1019,13 +1039,13 @@ bool FFmpegVideoDecoder::tryInitializeRendererForUnknownDecoder(const AVCodec* d
|
||||
// Supported output pixel formats are unknown. We'll just try DRM/SDL and hope it can cope.
|
||||
|
||||
#if defined(HAVE_DRM) && defined(GL_IS_SLOW)
|
||||
if (tryInitializeRenderer(decoder, AV_PIX_FMT_NONE, params, nullptr,
|
||||
if (tryInitializeRenderer(decoder, AV_PIX_FMT_NONE, params, nullptr, nullptr,
|
||||
[]() -> IFFmpegRenderer* { return new DrmRenderer(); })) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (tryInitializeRenderer(decoder, AV_PIX_FMT_NONE, params, nullptr,
|
||||
if (tryInitializeRenderer(decoder, AV_PIX_FMT_NONE, params, nullptr, nullptr,
|
||||
[]() -> IFFmpegRenderer* { return new SdlRenderer(); })) {
|
||||
return true;
|
||||
}
|
||||
@@ -1178,6 +1198,8 @@ bool FFmpegVideoDecoder::initialize(PDECODER_PARAMETERS params)
|
||||
|
||||
// Look for a hardware decoder first unless software-only
|
||||
if (params->vds != StreamingPreferences::VDS_FORCE_SOFTWARE) {
|
||||
QSet<const AVCodec*> terminallyFailedHardwareDecoders;
|
||||
|
||||
// Iterate through tier-1 hwaccel decoders
|
||||
codecIterator = NULL;
|
||||
while ((decoder = av_codec_iterate(&codecIterator))) {
|
||||
@@ -1203,6 +1225,11 @@ bool FFmpegVideoDecoder::initialize(PDECODER_PARAMETERS params)
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip hardware decoders that have returned a terminal failure status
|
||||
if (terminallyFailedHardwareDecoders.contains(decoder)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Look for the first matching hwaccel hardware decoder (pass 0)
|
||||
for (int i = 0;; i++) {
|
||||
const AVCodecHWConfig *config = avcodec_get_hw_config(decoder, i);
|
||||
@@ -1212,10 +1239,17 @@ bool FFmpegVideoDecoder::initialize(PDECODER_PARAMETERS params)
|
||||
}
|
||||
|
||||
// Initialize the hardware codec and submit a test frame if the renderer needs it
|
||||
if (tryInitializeRenderer(decoder, AV_PIX_FMT_NONE, params, config,
|
||||
IFFmpegRenderer::InitFailureReason failureReason;
|
||||
if (tryInitializeRenderer(decoder, AV_PIX_FMT_NONE, params, config, &failureReason,
|
||||
[config]() -> IFFmpegRenderer* { return createHwAccelRenderer(config, 0); })) {
|
||||
return true;
|
||||
}
|
||||
else if (failureReason == IFFmpegRenderer::InitFailureReason::NoHardwareSupport) {
|
||||
terminallyFailedHardwareDecoders.insert(decoder);
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Skipping remaining hwaccels due lack of hardware support for specified codec");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1244,6 +1278,11 @@ bool FFmpegVideoDecoder::initialize(PDECODER_PARAMETERS params)
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip hardware decoders that have returned a terminal failure status
|
||||
if (terminallyFailedHardwareDecoders.contains(decoder)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Try to initialize this decoder both as hwaccel and non-hwaccel
|
||||
if (tryInitializeRendererForUnknownDecoder(decoder, params, true)) {
|
||||
return true;
|
||||
@@ -1270,6 +1309,11 @@ bool FFmpegVideoDecoder::initialize(PDECODER_PARAMETERS params)
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip hardware decoders that have returned a terminal failure status
|
||||
if (terminallyFailedHardwareDecoders.contains(decoder)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Look for the first matching hwaccel hardware decoder (pass 1)
|
||||
// This picks up "second-tier" hwaccels like CUDA.
|
||||
for (int i = 0;; i++) {
|
||||
@@ -1280,10 +1324,17 @@ bool FFmpegVideoDecoder::initialize(PDECODER_PARAMETERS params)
|
||||
}
|
||||
|
||||
// Initialize the hardware codec and submit a test frame if the renderer needs it
|
||||
if (tryInitializeRenderer(decoder, AV_PIX_FMT_NONE, params, config,
|
||||
IFFmpegRenderer::InitFailureReason failureReason;
|
||||
if (tryInitializeRenderer(decoder, AV_PIX_FMT_NONE, params, config, &failureReason,
|
||||
[config]() -> IFFmpegRenderer* { return createHwAccelRenderer(config, 1); })) {
|
||||
return true;
|
||||
}
|
||||
else if (failureReason == IFFmpegRenderer::InitFailureReason::NoHardwareSupport) {
|
||||
terminallyFailedHardwareDecoders.insert(decoder);
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Skipping remaining hwaccels due lack of hardware support for specified codec");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user