Download raw body.
games/moonlight-qt: compatibility with ffmpeg 9.0
ports@,
I'd like to backport two commits:
- https://github.com/moonlight-stream/moonlight-qt/commit/13880353d8741ae331bf13433c5ad80071d5f44f
- https://github.com/moonlight-stream/moonlight-qt/commit/6ce02616f04fb83cd7c5d1492b03367f2220ac46
which brings support of ffmpeg-9.0 to games/moonlight-qt
Build tested against ffmpeg-9.0 and ffmpeg-8.1.2
Ok?
Index: Makefile
===================================================================
RCS file: /home/cvs/ports/games/moonlight-qt/Makefile,v
diff -u -p -r1.12 Makefile
--- Makefile 18 Feb 2026 18:25:17 -0000 1.12
+++ Makefile 12 Aug 2026 22:45:00 -0000
@@ -5,7 +5,7 @@ PKGNAME = moonlight-qt-${V}
DISTNAME = MoonlightSrc-${V}
SITES = https://github.com/moonlight-stream/moonlight-qt/releases/download/v${V}/
-REVISION = 1
+REVISION = 2
CATEGORIES = games
Index: patches/patch-app_streaming_video_ffmpeg-renderers_plvk_cpp
===================================================================
RCS file: patches/patch-app_streaming_video_ffmpeg-renderers_plvk_cpp
diff -N patches/patch-app_streaming_video_ffmpeg-renderers_plvk_cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-app_streaming_video_ffmpeg-renderers_plvk_cpp 12 Aug 2026 22:46:11 -0000
@@ -0,0 +1,166 @@
+https://github.com/moonlight-stream/moonlight-qt/commit/6ce02616f04fb83cd7c5d1492b03367f2220ac46
+
+Index: app/streaming/video/ffmpeg-renderers/plvk.cpp
+--- app/streaming/video/ffmpeg-renderers/plvk.cpp.orig
++++ app/streaming/video/ffmpeg-renderers/plvk.cpp
+@@ -14,8 +14,9 @@
+ #include <vector>
+ #include <set>
+
+-#ifndef VK_KHR_VIDEO_DECODE_AV1_EXTENSION_NAME
++#ifndef VK_KHR_video_decode_av1
+ #define VK_KHR_VIDEO_DECODE_AV1_EXTENSION_NAME "VK_KHR_video_decode_av1"
++#define VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR ((VkVideoCodecOperationFlagBitsKHR)0x00000004)
+ #endif
+
+ // Keep these in sync with hwcontext_vulkan.c
+@@ -317,7 +318,7 @@ bool PlVkRenderer::tryInitializeDevice(VkPhysicalDevic
+ vkParams.device = device;
+ vkParams.opt_extensions = k_OptionalDeviceExtensions;
+ vkParams.num_opt_extensions = SDL_arraysize(k_OptionalDeviceExtensions);
+- vkParams.extra_queues = VK_QUEUE_VIDEO_DECODE_BIT_KHR;
++ vkParams.extra_queues = m_HwAccelBackend ? VK_QUEUE_FLAG_BITS_MAX_ENUM : 0;
+ m_Vulkan = pl_vulkan_create(m_Log, &vkParams);
+ if (m_Vulkan == nullptr) {
+ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
+@@ -399,7 +400,7 @@ bool PlVkRenderer::initialize(PDECODER_PARAMETERS para
+
+ // Lookup all Vulkan functions we require
+ POPULATE_FUNCTION(vkDestroySurfaceKHR);
+- POPULATE_FUNCTION(vkGetPhysicalDeviceQueueFamilyProperties);
++ POPULATE_FUNCTION(vkGetPhysicalDeviceQueueFamilyProperties2);
+ POPULATE_FUNCTION(vkGetPhysicalDeviceSurfacePresentModesKHR);
+ POPULATE_FUNCTION(vkGetPhysicalDeviceSurfaceFormatsKHR);
+ POPULATE_FUNCTION(vkEnumeratePhysicalDevices);
+@@ -504,24 +505,13 @@ bool PlVkRenderer::initialize(PDECODER_PARAMETERS para
+ vkDeviceContext->nb_enabled_inst_extensions = m_PlVkInstance->num_extensions;
+ vkDeviceContext->enabled_dev_extensions = m_Vulkan->extensions;
+ vkDeviceContext->nb_enabled_dev_extensions = m_Vulkan->num_extensions;
+- vkDeviceContext->queue_family_index = m_Vulkan->queue_graphics.index;
+- vkDeviceContext->nb_graphics_queues = m_Vulkan->queue_graphics.count;
+- vkDeviceContext->queue_family_tx_index = m_Vulkan->queue_transfer.index;
+- vkDeviceContext->nb_tx_queues = m_Vulkan->queue_transfer.count;
+- vkDeviceContext->queue_family_comp_index = m_Vulkan->queue_compute.index;
+- vkDeviceContext->nb_comp_queues = m_Vulkan->queue_compute.count;
+ #if LIBAVUTIL_VERSION_INT > AV_VERSION_INT(58, 9, 100)
+ vkDeviceContext->lock_queue = lockQueue;
+ vkDeviceContext->unlock_queue = unlockQueue;
+ #endif
+
+- static_assert(sizeof(vkDeviceContext->queue_family_decode_index) == sizeof(uint32_t), "sizeof(int) != sizeof(uint32_t)");
+- static_assert(sizeof(vkDeviceContext->nb_decode_queues) == sizeof(uint32_t), "sizeof(int) != sizeof(uint32_t)");
+- if (!getQueue(VK_QUEUE_VIDEO_DECODE_BIT_KHR, (uint32_t*)&vkDeviceContext->queue_family_decode_index, (uint32_t*)&vkDeviceContext->nb_decode_queues)) {
+- SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
+- "Vulkan video decoding is not supported by the Vulkan device");
+- return false;
+- }
++ // Populate the device queues for decoding this video format
++ populateQueues(params->videoFormat);
+
+ int err = av_hwdevice_ctx_init(m_HwDeviceCtx);
+ if (err < 0) {
+@@ -581,23 +571,86 @@ bool PlVkRenderer::mapAvFrameToPlacebo(const AVFrame *
+ return true;
+ }
+
+-bool PlVkRenderer::getQueue(VkQueueFlags requiredFlags, uint32_t *queueIndex, uint32_t *queueCount)
++bool PlVkRenderer::populateQueues(int videoFormat)
+ {
++ auto vkDeviceContext = (AVVulkanDeviceContext*)((AVHWDeviceContext *)m_HwDeviceCtx->data)->hwctx;
++
+ uint32_t queueFamilyCount = 0;
+- fn_vkGetPhysicalDeviceQueueFamilyProperties(m_Vulkan->phys_device, &queueFamilyCount, nullptr);
++ fn_vkGetPhysicalDeviceQueueFamilyProperties2(m_Vulkan->phys_device, &queueFamilyCount, nullptr);
+
+- std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
+- fn_vkGetPhysicalDeviceQueueFamilyProperties(m_Vulkan->phys_device, &queueFamilyCount, queueFamilies.data());
++ std::vector<VkQueueFamilyProperties2> queueFamilies(queueFamilyCount);
++ std::vector<VkQueueFamilyVideoPropertiesKHR> queueFamilyVideoProps(queueFamilyCount);
++ for (uint32_t i = 0; i < queueFamilyCount; i++) {
++ queueFamilyVideoProps[i].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR;
++ queueFamilies[i].sType = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2;
++ queueFamilies[i].pNext = &queueFamilyVideoProps[i];
++ }
+
++ fn_vkGetPhysicalDeviceQueueFamilyProperties2(m_Vulkan->phys_device, &queueFamilyCount, queueFamilies.data());
++
++#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(58, 34, 100)
++ Q_UNUSED(videoFormat);
++
+ for (uint32_t i = 0; i < queueFamilyCount; i++) {
+- if ((queueFamilies[i].queueFlags & requiredFlags) == requiredFlags) {
+- *queueIndex = i;
+- *queueCount = queueFamilies[i].queueCount;
+- return true;
++ vkDeviceContext->qf[i].idx = i;
++ vkDeviceContext->qf[i].num = queueFamilies[i].queueFamilyProperties.queueCount;
++ vkDeviceContext->qf[i].flags = (VkQueueFlagBits)queueFamilies[i].queueFamilyProperties.queueFlags;
++ vkDeviceContext->qf[i].video_caps = (VkVideoCodecOperationFlagBitsKHR)queueFamilyVideoProps[i].videoCodecOperations;
++ }
++ vkDeviceContext->nb_qf = queueFamilyCount;
++#else
++ vkDeviceContext->queue_family_index = m_Vulkan->queue_graphics.index;
++ vkDeviceContext->nb_graphics_queues = m_Vulkan->queue_graphics.count;
++ vkDeviceContext->queue_family_tx_index = m_Vulkan->queue_transfer.index;
++ vkDeviceContext->nb_tx_queues = m_Vulkan->queue_transfer.count;
++ vkDeviceContext->queue_family_comp_index = m_Vulkan->queue_compute.index;
++ vkDeviceContext->nb_comp_queues = m_Vulkan->queue_compute.count;
++
++ // Select a video decode queue that is capable of decoding our chosen format
++ for (uint32_t i = 0; i < queueFamilyCount; i++) {
++ if (queueFamilies[i].queueFamilyProperties.queueFlags & VK_QUEUE_VIDEO_DECODE_BIT_KHR) {
++ if (videoFormat & VIDEO_FORMAT_MASK_H264) {
++ if (queueFamilyVideoProps[i].videoCodecOperations & VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR) {
++ vkDeviceContext->queue_family_decode_index = i;
++ vkDeviceContext->nb_decode_queues = queueFamilies[i].queueFamilyProperties.queueCount;
++ break;
++ }
++ }
++ else if (videoFormat & VIDEO_FORMAT_MASK_H265) {
++ if (queueFamilyVideoProps[i].videoCodecOperations & VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR) {
++ vkDeviceContext->queue_family_decode_index = i;
++ vkDeviceContext->nb_decode_queues = queueFamilies[i].queueFamilyProperties.queueCount;
++ break;
++ }
++ }
++ else if (videoFormat & VIDEO_FORMAT_MASK_AV1) {
++#if LIBAVCODEC_VERSION_MAJOR >= 61
++ // VK_KHR_video_decode_av1 added VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR to check for AV1
++ // decoding support on this queue. Since FFmpeg 6.1 used the older Mesa-specific AV1 extension,
++ // we'll just assume all video decode queues on this device support AV1 (since we checked that
++ // the physical device supports it earlier.
++ if (queueFamilyVideoProps[i].videoCodecOperations & VK_VIDEO_CODEC_OPERATION_DECODE_AV1_BIT_KHR)
++#endif
++ {
++ vkDeviceContext->queue_family_decode_index = i;
++ vkDeviceContext->nb_decode_queues = queueFamilies[i].queueFamilyProperties.queueCount;
++ break;
++ }
++ }
++ else {
++ SDL_assert(false);
++ }
+ }
+ }
+
+- return false;
++ if (vkDeviceContext->queue_family_decode_index < 0) {
++ SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
++ "Unable to find compatible video decode queue!");
++ return false;
++ }
++#endif
++
++ return true;
+ }
+
+ bool PlVkRenderer::isPresentModeSupportedByPhysicalDevice(VkPhysicalDevice device, VkPresentModeKHR presentMode)
+@@ -637,7 +690,7 @@ bool PlVkRenderer::isColorSpaceSupportedByPhysicalDevi
+ bool PlVkRenderer::isSurfacePresentationSupportedByPhysicalDevice(VkPhysicalDevice device)
+ {
+ uint32_t queueFamilyCount = 0;
+- fn_vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr);
++ fn_vkGetPhysicalDeviceQueueFamilyProperties2(device, &queueFamilyCount, nullptr);
+
+ for (uint32_t i = 0; i < queueFamilyCount; i++) {
+ VkBool32 supported = VK_FALSE;
Index: patches/patch-app_streaming_video_ffmpeg-renderers_plvk_h
===================================================================
RCS file: patches/patch-app_streaming_video_ffmpeg-renderers_plvk_h
diff -N patches/patch-app_streaming_video_ffmpeg-renderers_plvk_h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-app_streaming_video_ffmpeg-renderers_plvk_h 12 Aug 2026 22:46:14 -0000
@@ -0,0 +1,23 @@
+https://github.com/moonlight-stream/moonlight-qt/commit/6ce02616f04fb83cd7c5d1492b03367f2220ac46
+
+Index: app/streaming/video/ffmpeg-renderers/plvk.h
+--- app/streaming/video/ffmpeg-renderers/plvk.h.orig
++++ app/streaming/video/ffmpeg-renderers/plvk.h
+@@ -37,7 +37,7 @@ class PlVkRenderer : public IFFmpegRenderer { (private
+ static void overlayUploadComplete(void* opaque);
+
+ bool mapAvFrameToPlacebo(const AVFrame *frame, pl_frame* mappedFrame);
+- bool getQueue(VkQueueFlags requiredFlags, uint32_t* queueIndex, uint32_t* queueCount);
++ bool populateQueues(int videoFormat);
+ bool chooseVulkanDevice(PDECODER_PARAMETERS params, bool hdrOutputRequired);
+ bool tryInitializeDevice(VkPhysicalDevice device, VkPhysicalDeviceProperties* deviceProps,
+ PDECODER_PARAMETERS decoderParams, bool hdrOutputRequired);
+@@ -95,7 +95,7 @@ class PlVkRenderer : public IFFmpegRenderer { (private
+
+ // Vulkan functions we call directly
+ PFN_vkDestroySurfaceKHR fn_vkDestroySurfaceKHR = nullptr;
+- PFN_vkGetPhysicalDeviceQueueFamilyProperties fn_vkGetPhysicalDeviceQueueFamilyProperties = nullptr;
++ PFN_vkGetPhysicalDeviceQueueFamilyProperties2 fn_vkGetPhysicalDeviceQueueFamilyProperties2 = nullptr;
+ PFN_vkGetPhysicalDeviceSurfacePresentModesKHR fn_vkGetPhysicalDeviceSurfacePresentModesKHR = nullptr;
+ PFN_vkGetPhysicalDeviceSurfaceFormatsKHR fn_vkGetPhysicalDeviceSurfaceFormatsKHR = nullptr;
+ PFN_vkEnumeratePhysicalDevices fn_vkEnumeratePhysicalDevices = nullptr;
Index: patches/patch-app_streaming_video_ffmpeg_cpp
===================================================================
RCS file: patches/patch-app_streaming_video_ffmpeg_cpp
diff -N patches/patch-app_streaming_video_ffmpeg_cpp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-app_streaming_video_ffmpeg_cpp 12 Aug 2026 22:45:37 -0000
@@ -0,0 +1,152 @@
+https://github.com/moonlight-stream/moonlight-qt/commit/13880353d8741ae331bf13433c5ad80071d5f44f
+
+Index: app/streaming/video/ffmpeg.cpp
+--- app/streaming/video/ffmpeg.cpp.orig
++++ app/streaming/video/ffmpeg.cpp
+@@ -1076,15 +1076,15 @@ bool FFmpegVideoDecoder::tryInitializeRenderer(const A
+ #define TRY_PREFERRED_PIXEL_FORMAT(RENDERER_TYPE) \
+ { \
+ RENDERER_TYPE renderer; \
+- if (renderer.getPreferredPixelFormat(params->videoFormat) == decoder->pix_fmts[i]) { \
++ if (renderer.getPreferredPixelFormat(params->videoFormat) == decoder_pix_fmts[i]) { \
+ 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, nullptr, \
++ decoder->name, decoder_pix_fmts[i]); \
++ 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", \
+- decoder->name, decoder->pix_fmts[i]); \
++ decoder->name, decoder_pix_fmts[i]); \
+ return true; \
+ } \
+ } \
+@@ -1093,16 +1093,16 @@ bool FFmpegVideoDecoder::tryInitializeRenderer(const A
+ #define TRY_SUPPORTED_NON_PREFERRED_PIXEL_FORMAT(RENDERER_TYPE) \
+ { \
+ RENDERER_TYPE renderer; \
+- if (decoder->pix_fmts[i] != renderer.getPreferredPixelFormat(params->videoFormat) && \
+- renderer.isPixelFormatSupported(params->videoFormat, decoder->pix_fmts[i])) { \
++ if (decoder_pix_fmts[i] != renderer.getPreferredPixelFormat(params->videoFormat) && \
++ renderer.isPixelFormatSupported(params->videoFormat, decoder_pix_fmts[i])) { \
+ 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, nullptr, \
++ decoder->name, decoder_pix_fmts[i]); \
++ 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", \
+- decoder->name, decoder->pix_fmts[i]); \
++ decoder->name, decoder_pix_fmts[i]); \
+ return true; \
+ } \
+ } \
+@@ -1116,6 +1116,16 @@ bool FFmpegVideoDecoder::tryInitializeRendererForUnkno
+ return false;
+ }
+
++ const AVPixelFormat* decoder_pix_fmts;
++#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100)
++ if (avcodec_get_supported_config(nullptr, decoder, AV_CODEC_CONFIG_PIX_FORMAT, 0,
++ (const void**)&decoder_pix_fmts, nullptr) < 0) {
++ decoder_pix_fmts = nullptr;
++ }
++#else
++ decoder_pix_fmts = decoder->pix_fmts;
++#endif
++
+ // This might be a hwaccel decoder, so try any hw configs first
+ if (tryHwAccel) {
+ for (int pass = 0; pass <= MAX_DECODER_PASS; pass++) {
+@@ -1141,7 +1151,7 @@ bool FFmpegVideoDecoder::tryInitializeRendererForUnkno
+ }
+ }
+
+- if (decoder->pix_fmts == NULL) {
++ if (decoder_pix_fmts == NULL) {
+ // 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)
+@@ -1177,11 +1187,11 @@ bool FFmpegVideoDecoder::tryInitializeRendererForUnkno
+ // Even if it didn't completely deadlock us, the performance would likely be atrocious.
+ if (strcmp(decoder->name, "h264_mmal") == 0) {
+ #ifdef HAVE_MMAL
+- for (int i = 0; decoder->pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
++ for (int i = 0; decoder_pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
+ TRY_PREFERRED_PIXEL_FORMAT(MmalRenderer);
+ }
+
+- for (int i = 0; decoder->pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
++ for (int i = 0; decoder_pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
+ TRY_SUPPORTED_NON_PREFERRED_PIXEL_FORMAT(MmalRenderer);
+ }
+ #endif
+@@ -1191,7 +1201,7 @@ bool FFmpegVideoDecoder::tryInitializeRendererForUnkno
+ }
+
+ // Check if any of our decoders prefer any of the pixel formats first
+- for (int i = 0; decoder->pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
++ for (int i = 0; decoder_pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
+ #ifdef HAVE_DRM
+ TRY_PREFERRED_PIXEL_FORMAT(DrmRenderer);
+ #endif
+@@ -1204,7 +1214,7 @@ bool FFmpegVideoDecoder::tryInitializeRendererForUnkno
+ }
+
+ // Nothing prefers any of them. Let's see if anyone will tolerate one.
+- for (int i = 0; decoder->pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
++ for (int i = 0; decoder_pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
+ #ifdef HAVE_DRM
+ TRY_SUPPORTED_NON_PREFERRED_PIXEL_FORMAT(DrmRenderer);
+ #endif
+@@ -1219,10 +1229,10 @@ bool FFmpegVideoDecoder::tryInitializeRendererForUnkno
+ #if defined(HAVE_LIBPLACEBO_VULKAN) && defined(VULKAN_IS_SLOW)
+ // If we got here with VULKAN_IS_SLOW, DrmRenderer didn't work,
+ // so we have to resort to PlVkRenderer.
+- for (int i = 0; decoder->pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
++ for (int i = 0; decoder_pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
+ TRY_PREFERRED_PIXEL_FORMAT(PlVkRenderer);
+ }
+- for (int i = 0; decoder->pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
++ for (int i = 0; decoder_pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
+ TRY_SUPPORTED_NON_PREFERRED_PIXEL_FORMAT(PlVkRenderer);
+ }
+ #endif
+@@ -1230,10 +1240,10 @@ bool FFmpegVideoDecoder::tryInitializeRendererForUnkno
+ #ifdef GL_IS_SLOW
+ // If we got here with GL_IS_SLOW, DrmRenderer didn't work, so we have
+ // to resort to SdlRenderer.
+- for (int i = 0; decoder->pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
++ for (int i = 0; decoder_pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
+ TRY_PREFERRED_PIXEL_FORMAT(SdlRenderer);
+ }
+- for (int i = 0; decoder->pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
++ for (int i = 0; decoder_pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
+ TRY_SUPPORTED_NON_PREFERRED_PIXEL_FORMAT(SdlRenderer);
+ }
+ #endif
+@@ -1369,9 +1379,18 @@ bool FFmpegVideoDecoder::tryInitializeNonHwAccelDecode
+
+ // Skip decoders without zero-copy output formats if requested
+ if (requireZeroCopyFormat) {
++ const AVPixelFormat* decoder_pix_fmts;
++#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(61, 13, 100)
++ if (avcodec_get_supported_config(nullptr, decoder, AV_CODEC_CONFIG_PIX_FORMAT, 0,
++ (const void**)&decoder_pix_fmts, nullptr) < 0) {
++ decoder_pix_fmts = nullptr;
++ }
++#else
++ decoder_pix_fmts = decoder->pix_fmts;
++#endif
+ bool foundZeroCopyFormat = false;
+- for (int i = 0; decoder->pix_fmts && decoder->pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
+- if (isZeroCopyFormat(decoder->pix_fmts[i])) {
++ for (int i = 0; decoder_pix_fmts && decoder_pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
++ if (isZeroCopyFormat(decoder_pix_fmts[i])) {
+ foundZeroCopyFormat = true;
+ break;
+ }
--
wbr, Kirill
games/moonlight-qt: compatibility with ffmpeg 9.0